WEBELO
HTML Visualizer & DOM Library
Loading...
Searching...
No Matches
Webelo.cpp
1#include "base.cpp"
2#include "exceptions.cpp"
3#include <vector>
4#include <variant>
5#include <algorithm>
6#include <optional>
7#include <any>
8#include <functional>
9#include <memory>
10#include <cassert>
11#include <iostream>
12#include <map>
13#include <set>
14#include <initializer_list>
15
16
17// Macros
18
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
25
26#define START_TO_START 0
27#define START_TO_END 1
28#define END_TO_END 2
29#define END_TO_START 3
30
31#define FILTER_ACCEPT 1
32#define FILTER_REJECT 2
33#define FILTER_SKIP 3
34
35#define SHOW_ALL 0xFFFFFFFF
36#define SHOW_ELEMENT 0x1
37#define SHOW_ATTRIBUTE 0x2
38#define SHOW_TEXT 0x4
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
48
49
50// Class Declarations
51
52class EventListener;
53struct event_listener;
54struct EventListenerOptions;
56class EventTarget;
57class AbortSignal;
58class AbortController;
59struct path_structs;
60class Event;
61class CustomEvent;
62class Node;
63class NodeList;
64class Document;
65class Element;
68class NodeFilter;
69class NodeIterator;
70class TreeWalker;
71class AbstractRange;
72struct StaticRangeInit;
73class StaticRange;
74class Range;
76class HTMLCollection;
77class ParentNode;
78class Attr;
79class Text;
80class CharacterData;
81class CDATASection;
82class Comment;
84class DocumentType;
86class ShadowRoot;
88struct ShadowRootInit;
89class NamedNodeMap;
90class XMLDocument;
92class DOMTokenList;
93class Window;
94class HTMLSlotElement;
95
96
97
98// Enums
99
100// Types of Node objects possible !!
101enum node_type{
102 ELEMENT_NODE = 1,
103 ATTRIBUTE_NODE = 2,
104 TEXT_NODE = 3,
105 CDATA_SECTION_NODE = 4,
106 ENTITY_REFERENCE_NODE = 5,
107 ENTITY_NODE = 6,
108 PROCESSING_INSTRUCTION_NODE = 7,
109 COMMENT_NODE = 8,
110 DOCUMENT_NODE = 9,
111 DOCUMENT_TYPE_NODE = 10,
112 DOCUMENT_FRAGMENT_NODE = 11,
113 NOTATION_NODE = 12
114};
115
116// *Phase/State of the Event
117enum event_phase: unsigned int{
118 NONE,
119 CAPTURING_PHASE, //top to bottom
120 AT_TARGET, //reached
121 BUBBLING_PHASE //bottom to top again !
122};
123
124enum ShadowRootMode{ openh, closed};
125enum SlotAssignmentMode{ manual, named};
126
127enum DocType{
128 XML,
129 HTML,
130 XML_XHTML
131};
132
133enum DocMode{
134 NO_QUIRKS,
135 QUIRKS,
136 LIMITED_QUIRKS
137};
138
139enum ElementState{
140 UNDEFINED, FAILED, UNCUSTOMIZED, PRECUSTOMIZED, CUSTOM
141};
142
143
144
145// Algos (functions) declarations
146
147event_listener* flatten(DOMString &type, EventListener *callback, std::variant<AddEventListenerOptions,bool> options);
148void remove_event_listener(EventTarget* eventTarget, event_listener *listener);
149void add_abort_algo(const std::function<void()> &algo, AbortSignal* signal);
150void run_abort_steps(AbortSignal* signal);
151void signal_abort(AbortSignal* signal, std::any reason = nullptr);
152void add_event_listener(EventTarget* eventTarget, event_listener *listener);
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);
155Event* create_event(Event* eventInterface, Realm* realm = nullptr);
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);
159void adopt(Node* node, Document* document);
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);
168Attr* set_attribute(Attr* attr, Element* element);
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);
173Node* insert_adjacent(Element* element, DOMString where, Node* node);
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);
183bool static_range_valid(StaticRange* range);
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);
189DocumentFragment* extract_range(Range* range);
190DocumentFragment* clone_contents(Range* range);
191void insert_node_in_range(Node* node, Range* range);
192void pre_remove_steps(NodeIterator* node_iterator, Node* toBeRemovedNode);
193Node* traverse(NodeIterator* iterator, unsigned long direction);
194Node* traverse_children(TreeWalker* walker, unsigned long type);
195Node* traverse_sibling(TreeWalker* walker, unsigned long type);
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);
199Node* clone_node(Node* node, Document* document = nullptr, bool subtree = false, Node* parent = nullptr, CustomElementRegistry* fallbackRegistry = nullptr);
200Node* clone_a_single_node(Node* node, Document* document, CustomElementRegistry* fallbackRegistry);
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);
205EventTarget* retard(EventTarget* a, EventTarget* b);
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);
210bool check_node_precedes(Document* doc, Node* node, Node* target);
211bool check_shadow_including_descendant(Node* node, Node* target, bool inclusive = false);
212bool is_closed_shadow_hidden(Node* A, Node* B);
213Node* retarget(Node* A, Node* B);
214bool host_including_inclusive_ancestor(Node* A, Node* B);
215void ensure_pre_insert_validity(Node* node, Node* parent, Node* child);
216void move_node(Node* node,Node* node2,Node* Child){};
217void replace(Node* obj, Node* node, Node* parent){};
218// void replace_data(Node* node, unsigned long offset, unsigned long count, DOMString data){}
219void insert_node(Node* node, Node* parent, Node* child, bool suppress_observers = false);
220void queue_tree_mutation_record(Node* node, NodeList* gg,NodeList* nodes,Node* boi,Node* girl){};
221Node* pre_insert_node(Node* node, Node* parent, Node* child);
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);
227Node* pre_remove_node(Node* child, Node* parent);
228Node* replace_node(Node* node, Node* child, Node* parent);
229
230
231//hehe
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);
234
235
236
237
238
239// Classes & Structs
240
241class Window{
242 //TODO: LATER DO IT FULL !
243 protected:
244 Event* event = nullptr; //Replaceable
245 public:
246 Event* getEvent(){
247 return this->event;
248 }
249
250 virtual ~Window() = default;
251};
252
253// EVENT -TARGET STUFF
254
256 public:
257 void handleEvent(const Event* event);
258
259 virtual ~EventListener() = default;
260};
261
262struct event_listener{
263 DOMString type;
264 EventListener* callback = nullptr;
265 bool capture = false;
266 std::optional<bool> passive = std::nullopt;
267 bool once = false;
268 AbortSignal *signal = nullptr;
269 bool removed = false;
270
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){
272 this->type = type;
273 this->callback = callback;
274 this->capture = capture;
275 this->passive = passive;
276 this->once = once;
277 this->signal = signal;
278 this->removed = removed;
279 }
280
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);
283 }
284 bool operator!=(event_listener &ev) const{
285 return !(*this==ev);
286 }
287};
288
289
290struct AddEventListenerOptions{
291 bool capture;
292 std::optional<bool> passive = std::nullopt;
293 bool once = false;
294 AbortSignal *signal;
295
296 AddEventListenerOptions(bool capture, std::optional<bool> passive, bool once, AbortSignal* signal = nullptr){
297 this->capture = capture;
298 this->passive = passive;
299 this->once = once;
300 this->signal = signal;
301 }
302};
303
304class EventTarget{
305 public:
306 bool has_activation_behavior = false;
307 bool has_legacy_canceled_activation_behavior = false;
308 bool has_legacy_pre_activation_behavior = false;
309
310 // These are kept for future use-cases for specific elements in HTML
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 = []() {};
314
315 std::vector<event_listener*> event_listener_list = {};
316
317 EventTarget(){};
318
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);
323
324 bool operator==(const EventTarget &a){
325 if (this->event_listener_list.size()!=a.event_listener_list.size()){
326 return false;
327 }
328
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])){
331 return false;
332 }
333 }
334 return true;
335 }
336
337 bool operator!=(const EventTarget &a){
338 return !(*this==a);
339 }
340
341 virtual EventTarget* get_the_parent(const Event* event){
342 return nullptr;
343 }
344
345 virtual ~EventTarget() = default;
346};
347
348class AbortSignal: public EventTarget{
349 public:
350 bool aborted;
351 bool dependent = false;
352 std::any reason = nullptr;
353 EventHandler onabort; //TODO: event handler IDL attribute whose event handler event type is abort.
354
355 //NEW-OBJECT
356 static AbortSignal* abort(std::any reason = nullptr);
357 static AbortSignal* timeout(unsigned long long milliseconds);
358 static AbortSignal* _any(std::vector<AbortSignal*> signals);
359
360
361 void throwIfAborted();
362
363
364 std::vector<AbortSignal*> source_signals = {};
365 std::vector<AbortSignal*> dependent_signals = {};
366
367 std::vector<std::function<void()>> abort_algos = {};
368
369 AbortSignal* create_object() {
370 return new AbortSignal();
371 }
372
373 bool getaborted(){
374 return this->isaborted();
375 }
376 bool isaborted(){
377 if (this->reason.has_value()){
378 try{
379 auto k = std::any_cast<std::nullptr_t>(this->reason);
380 return false;
381 }
382 catch(std::bad_any_cast){
383 return true;
384 }
385 }
386 return false;
387 }
388 bool getdependent(){
389 return this->dependent;
390 }
391 void setdependent(bool dependent){
392 this->dependent = dependent;
393 }
394 std::any getreason(){
395 return this->reason;
396 }
397
398 virtual ~AbortSignal() = default;
399};
400
401class AbortController{
402 public:
403 AbortSignal* signal;
404 AbortController();
405 void abort(std::any reason = nullptr) const;
406
407 virtual ~AbortController() = default;
408};
409
410
411
412// *Structs to be stored in path for Event !
413struct path_structs{
414 EventTarget* invocation_target;
415 bool invocation_target_in_shadow_tree;
416 EventTarget *shadow_adjusted_target;
417 EventTarget *related_target;
418 std::vector<EventTarget*> touch_target_list = {};
419 bool root_of_closed_tree;
420 bool slot_in_closed_tree;
421
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;
430 }
431};
432
433class Event{
434 public:
435 DOMString type = "";
436 EventTarget *target = nullptr;
437 EventTarget *relatedTarget = nullptr;
438 EventTarget *currentTarget = nullptr;
439 enum event_phase eventPhase = NONE;
440 bool bubbles;
441 bool cancelable;
442 bool composed;
443 DOMHighResTimeStamp timeStamp;
444
445 bool isTrusted = false;
446
447 // Constructor
448 Event(const DOMString &type, bool bubbles = false, bool cancelable = false, bool composed = false);
449 Event(const Event* temp);
450
451 void inner_event_creation_steps(Event* event, Realm* realm, DOMHighResTimeStamp &time, bool bubbles = false, bool cancelable = false, bool composed = false);
452
453 // FLAGS BRO !!
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;
461
462 // See path_structs for more reference future me :) ! Also, this is
463 std::vector<path_structs> path = {};
464 std::vector<EventTarget*> touch_target_list = {}; //mostly no use until TouchEvent Interface
465
466 void initEvent(DOMString type, bool bubbles = false, bool cancelable = false); // legacy
467 void stopPropagation();
468 void stopImmediatePropagation();
469 void preventDefault();
470 std::vector<EventTarget*> composedPath();
471 void set_canceled_flag();
472
473 // *GETTER-SETTER METHODS
474
475 DOMString gettype() const{
476 return this->type;
477 };
478 EventTarget* gettarget() const{
479 return this->target;
480 };
481 EventTarget* getsrcElement() const{
482 return this->target;
483 }
484 EventTarget* getrelatedTarget() const{
485 return this->relatedTarget;
486 };
487 EventTarget* getcurrentTarget() const{
488 return this->currentTarget;
489 };
490 enum event_phase geteventPhase() const{
491 return this->eventPhase;
492 };
493 void seteventPhase(enum event_phase temp){
494 this->eventPhase = temp;
495 }
496 bool getbubbles() const{
497 return this->bubbles;
498 };
499 bool getcancelable() const{
500 return this->cancelable;
501 };
502 bool getdefaultPrevented() const{
503 return this->canceled_flag;
504 };
505 bool getcomposed() const{
506 return this->composed_flag;
507 };
508 bool getisTrusted() const{
509 return this->isTrusted;
510 };
511 DOMHighResTimeStamp gettimeStamp() const{
512 return this->timeStamp;
513 };
514
515 bool getcancelBubble() const{
516 return this->stop_propagation_flag;
517 }
518 void setcancelBubble(bool value){
519 if (value){
520 this->stop_propagation_flag = true;
521 }
522 };
523
524 bool getreturnValue() const{
525 return !this->canceled_flag;
526 };
527 void setreturnValue(bool value){
528 if (!value){
529 this->set_canceled_flag();
530 }
531 };
532
533
534 virtual bool operator==(Event* ev){
535 if (this->type == ev->gettype() && this->target == ev->gettarget() && this->timeStamp == ev->gettimeStamp()){
536 return true;
537 }
538 return false;
539 }
540
541 virtual Event* newObject(){
542 return new Event(this->type);
543 }
544
545 virtual ~Event() = default;
546};
547
548
549class CustomEvent: public Event{
550 public:
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);
554
555 std::any getdetail() const{
556 return this->detail;
557 }
558
559 CustomEvent(const CustomEvent* temp): Event(temp->type, temp->bubbles, temp->cancelable, temp->composed){
560 this->detail = temp->detail;
561 };
562
563 virtual ~CustomEvent() = default;
564};
565
566
567//Remember to remove when rewriting it
568class MouseEvent: public Event{
569 public:
570 MouseEvent(const DOMString &type, bool bubbles = false, bool cancelable = false, bool composed = false):Event(type,bubbles,cancelable,composed){};
571
572 virtual ~MouseEvent() = default;
573};
574
575
576/*
577Collection of Node objects
578
579Attributes:
580 None
581
582Methods:
583 item(unsigned long index) - Returns ptr to node object at index if present else nullptr
584 length() - Number of elements in the nodelist
585
586Operators:
587 [unsigned long index] - Operator using item() method internally
588
589 */
591 public:
592 std::vector<Node*> node_list = {};
593
594 // Returns the Node ptr on the index provided !
595 Node* item(const unsigned long index) const;
596
597 // Returns the Node ptr on the index provided !
598 Node* operator[](unsigned long index) const {
599 return this->item(index);
600 }
601
602 bool operator==(const NodeList* otherNodeList) const;
603
604 // Returns the length of the list stored ! Must be stored in a variable.
605 [[nodiscard]] unsigned long length() const;
606
607 void append(Node* node){
608 this->node_list.push_back(node);
609 }
610
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);
614 }
615
616 void remove(Node* node);
617
618 ~NodeList();
619};
620
621
622
623// The Mega Boss & almost everything in a DOM tree - Node object !! Abstract class
624class Node: public EventTarget{
625 //Basic INFO.
626 public:
627 node_type nodeType;
628 DOMString nodeName;
629 USVString baseURI;
630 Document* ownerDocument; // it is referenced as nodeDocument in the DOM at lots of places
631 // Not necessary that parent is element ! could be some other type of node baby !
632 Node* parentNode;
633 Element* parentElement = nullptr;
634 bool isConnected();
635
636 //Babies !!! ( Children )
637 NodeList childNodes;
638 virtual Node* firstChild();
639 virtual Node* lastChild();
640 virtual Node* previousSibling();
641 virtual Node* nextSibling();
642
643 bool hasChildNodes() const;
644
645 Node* getRootNode(bool composed = false);
646
647 DOMString nodeValue;
648 DOMString textContent;
649 void normalize();
650 Node* cloneNode(bool subtree);
651
652
653 Node(node_type nodeType, DOMString nodeName, Document* ownerDocument = nullptr, Node* parentNode = nullptr);
654
655 unsigned long length(){
656 //if (dynamic_cast<DocumentType*>(this) || dynamic_cast<Attr*>(this)){
657 // return 0;
658 //}
659 //CharacterData* temp = dynamic_cast<CharacterData*>(this);
660 //if (temp){
661 // return temp->getdata().length();
662 //}
663 //return this->childNodes.length();
664 return 0;
665 }
666
667 bool isEqualNode(Node* otherNode);
668 bool isSameNode(Node* otherNode);
669
670 unsigned short compareDocumentPosition(Node* other);
671 bool contains(Node* other);
672
673 virtual std::optional<DOMString> lookupPrefix(std::optional<DOMString> &namesp);
674 std::optional<DOMString> lookupNamespaceURI(std::optional<DOMString> &prefix);
675
676 bool isDefaultNamespace(std::optional<DOMString> &namesp);
677
678 Node* insertBefore(Node* node, Node* child);
679 Node* appendChild(Node* node);
680 Node* replaceChild(Node* node, Node* child);
681 Node* removeChild(Node* child);
682
683 virtual Node* get_the_parent(Event* event);
684
685 virtual std::optional<DOMString> getnodeValue(){
686 return std::nullopt;
687 }
688 virtual void setnodeValue(DOMString &val){};
689 virtual std::optional<DOMString> gettextContent(){
690 return std::nullopt;
691 }
692 virtual void settextContent(DOMString &val){};
693
694
695 bool operator==(Node& other){ return this->isEqualNode(&other); }
696
697 // Based on the follows algorithm !!
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){
703 return true;
704 }
705 if (currentNode->childNodes.length()!=0){
706 temp.push_back(currentNode);
707 currentNode = currentNode->firstChild();
708 continue;
709 }
710 currentNode = currentNode->nextSibling();
711 while (currentNode==nullptr && !temp.empty()){
712 currentNode = (*(temp.end() -1))->nextSibling();
713 temp.erase(temp.end()-1);
714 }
715 }
716 return false;
717 }
718
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();
722 }
723
724 virtual ~Node() = default;
725};
726
727std::ostream& operator<<(std::ostream& os, const Node& node) {
728 if (node.nodeType == 1) { // Example: ELEMENT_NODE
729 os << "ELEMENT NODE\n" << node.nodeName;
730 } else {
731 os << "OTHER NODE\n" << node.nodeName;
732 }
733 return os;
734}
735
737 CustomElementRegistry* customElementRegistry;
738 bool selfOnly = false;
739};
740
742 public:
743 void acceptNode(Node* node){};
744
745 virtual ~NodeFilter() = default;
746};
747
748class NodeIterator{
749 public:
750 Node* root;
751 Node* referenceNode;
752 bool pointerBeforeReferenceNode;
753 unsigned long whatToShow;
754 NodeFilter* filter;
755
756 bool active = false;
757
758 Node* nextNode();
759 Node* previousNode();
760
761 void detach(){};
762
763 unsigned short filter_node(Node* node);
764
765 NodeIterator(){};
766
767 virtual ~NodeIterator() = default;
768};
769
770class TreeWalker{
771 public:
772 Node* root;
773 unsigned long whatToShow;
774 NodeFilter* filter;
775 Node* currentNode;
776
777 bool active = false;
778
779 TreeWalker(){};
780
781 unsigned short filter_node(Node* node);
782
783 Node* parentNode();
784 Node* firstChild();
785 Node* lastChild();
786 Node* previousSibling();
787 Node* nextSibling();
788 Node* previousNode();
789 Node* nextNode();
790
791 virtual ~TreeWalker() = default;
792};
793
794
795
797 public:
798 Node* startContainer;
799 unsigned long startOffset;
800 Node* endContainer;
801 unsigned long endOffset;
802 bool collapsed();
803
804 virtual ~AbstractRange() = default;
805};
806
807struct StaticRangeInit{
808 Node* startContainer;
809 unsigned long startOffset;
810 Node* endContainer;
811 unsigned long endOffset;
812 StaticRangeInit(Node* sc, unsigned long sos, Node* ec, unsigned long eos){
813 startContainer = sc;
814 startOffset = sos;
815 endContainer = ec;
816 endOffset = eos;
817 }
818};
819
820//Exposed to window only
821class StaticRange: public AbstractRange{
822 public:
823 StaticRange(StaticRangeInit init);
824
825 virtual ~StaticRange() = default;
826};
827
828
829class Range: public AbstractRange{
830 public:
831 Node* commonAncestorContainer();
832 Range();
833
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);
843
844 short compareBoundaryPoints(unsigned short how, Range* sourceRange);
845
846 //CEReactions
847 void deleteContents();
848 DocumentFragment* extraContents(); //NewObject
849 DocumentFragment* cloneContents(); //NewObject
850 void insertNode(Node* node);
851 void surroundContents(Node* newParent);
852
853 Range* cloneRange(); //NewObject
854 void detach(){};
855 bool isPointInRange(Node* node, unsigned long offset);
856 short comparePoint(Node* node, unsigned long offset);
857 bool intersectsNode(Node* node);
858
859 //TODO: stringifier;
860 DOMString stringification_behavior();
861
862
863 virtual ~Range() = default;
864};
865
866
867/*
868Collection of Element objects
869
870Attributes:
871 None
872
873Methods:
874 item(unsigned long index) - Returns ptr to node object at index if present else nullptr
875 namedItem(DOMString name)
876 length() - Number of elements in the nodelist
877
878Operators:
879 [unsigned long index] - Operator using item() method internally
880 [DOMString name] - Operator using namedItem() method internally
881 */
883 public:
884 std::vector<Element*> element_list = {};
885
886 // Returns the Node ptr on the index provided !
887 Element* item(const unsigned long &index) const;
888
889 // Returns the Node ptr on the index provided !
890 Element* operator[](const unsigned long &index) const {
891 return this->item(index);
892 }
893
894 Element* namedItem(const DOMString &name) const;
895
896 Element* operator[](const DOMString &name) const{
897 return this->namedItem(name);
898 }
899
900 // Returns the length of the list stored ! Must be stored in a variable.
901 [[nodiscard]] unsigned long length() const;
902
903 void append(Element* node){
904 this->element_list.push_back(node);
905 }
906
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);
910 }
911
912 void remove(Element* node){
913 unsigned int i = 0;
914 for (auto a: this->element_list){
915 // if (dynamic_cast<Node*>(a)->isEqualNode(dynamic_cast<Node*>(node))){
916 // this->element_list.erase(this->element_list.begin()+i);
917 // return;
918 // }
919 i++;
920 }
921 }
922
924};
925
926
927class ParentNode: public Node {
928 public:
929 HTMLCollection children;
930 Element* firstElementChild() const{
931 return children.item(0);
932 };
933 Element* lastElementChild() const{
934 return this->children.item(this->children.length()-1);
935 };
936
937 unsigned long childElementCount() const{
938 return children.length();
939 };
940
941 void evaluate_children(){
942 for (auto a: this->childNodes.node_list){
943 // if (dynamic_cast<Element*>(a)){
944 // this->children.append(dynamic_cast<Element*>(a));
945 // }
946 }
947 }
948
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);
953
954 Element* querySelector(DOMString selectors);
955 NodeList querySelectorAll(DOMString selectors);
956
957 virtual void making_it_abstract(){};
958
959 ParentNode(node_type nodeType, DOMString nodeName, Document* ownerDocument, Node* parentNode): Node(nodeType, nodeName, ownerDocument, parentNode){};
960
961 virtual ~ParentNode() = default;
962};
963
964//Exposed to window only
965class Attr: public Node{
966 public:
967 std::optional<DOMString> namespaceURI = std::nullopt;
968 std::optional<DOMString> prefix = std::nullopt;
969 DOMString localName;
970 DOMString name;
971 Element* ownerElement = nullptr;
972 bool specified = true;
973 //CEReactions
974 DOMString value = "";
975 DOMString qualifiedName();
976
977 Attr(DOMString localName);
978
979
980 void setvalue(DOMString value){
981 if (this->ownerElement==nullptr){ this->value = value; }
982 // else{ change_attribute_value(this, value); }
983 }
984
985 virtual ~Attr() = default;
986};
987
988
989class CharacterData: public Node{
990 protected:
991 DOMString data;
992 public:
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();
1001
1002 // friend void before(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1003 // friend void after(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1004 // friend void replaceWith(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1005 // friend void remove(Node* obj);
1006
1007 CharacterData(Document* ownerdoc = nullptr, Node* parentnode = nullptr): Node(CDATA_SECTION_NODE, "#cdata-section", ownerdoc, parentnode){};
1008
1009 DOMString getdata(){ return this->data; }
1010 virtual void setdata(DOMString data){
1011 replace_data(this, 0, this->length(),data);
1012 }
1013
1014 virtual ~CharacterData() = default;
1015};
1016
1017class Text: public CharacterData{
1018 public:
1019 DOMString wholeText();
1020 DOMString slot="";
1022
1023 virtual void setdata(DOMString data) override{
1024 replace_data(this, 0, this->length(),data);
1025 }
1026
1027 Text(DOMString data = ""):CharacterData(){
1028 this->setdata(data);
1029 };
1030 Text* splitText(unsigned long offset); //NewObject
1031
1032 virtual ~Text() = default;
1033
1034};
1035
1036//Exposed to window only
1037class ProcessingInstruction: public CharacterData{
1038 public:
1039 DOMString target;
1040
1041 virtual void setdata(DOMString data) override{
1042 replace_data(this, 0, this->length(),data);
1043 }
1044
1045 ProcessingInstruction(Document* ownerdoc = nullptr, Node* parentnode = nullptr): CharacterData(ownerdoc, parentnode){};
1046
1047 virtual ~ProcessingInstruction() = default;
1048
1049};
1050
1051//Exposed to window only
1052class Comment: public CharacterData{
1053 public:
1054
1055 virtual void setdata(DOMString data) override{
1056 replace_data(this, 0, this->length(),data);
1057 }
1058
1059 Comment(DOMString data = ""){
1060 this->setdata(data);
1061 };
1062
1063 virtual ~Comment() = default;
1064
1065};
1066
1067//Exposed to window only
1068class CDATASection: public Text{
1069 public:
1070
1071 virtual void setdata(DOMString data) override{
1072 replace_data(dynamic_cast<Node*>(this),0, this->length(),data);
1073 }
1074
1075 virtual ~CDATASection() = default;
1076};
1077
1078
1079class Document: public ParentNode{
1080 public:
1081 CustomElementRegistry* custom_element_registry = nullptr;
1082 DOMImplementation* implementation;
1083 USVString URL = "about:blank";
1084 USVString documentURI = URL;
1085 DOMString characterSet = "utf-8";
1086 DOMString contentType = "application/xml";
1087
1088 DocumentType* doctype();
1089 Element* documentElement();
1090
1091 DOMString encoding = "utf-8";
1092 DocType type = XML;
1093 DOMString* origin = nullptr; //lateeeeeer
1094 DocMode mode = NO_QUIRKS;
1095 bool allow_declarative_shodow_roots = false;
1096
1097 Document(Document* ownerdoc = nullptr, Node* parentnode = nullptr): ParentNode(DOCUMENT_NODE, "#document", ownerdoc, parentnode){
1098 // this->implementation->associated_doc = this;
1099 };
1100
1101 DOMString compatMode();
1102
1103 DOMString* lookupPrefix(std::optional<DOMString> namesp); //Redefining for Node class
1104
1105 HTMLCollection* getElementsByTagName(DOMString qualifiedName);
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);
1109
1110
1111 Element* createElement(DOMString localName, std::variant<DOMString,ElementCreationOptions> options); //NOTE: Keep last argument as optional
1112 Element* createElementNS(std::optional<DOMString> namesp, DOMString qualifiedName, std::variant<DOMString,ElementCreationOptions> options); //NOTE: Keep last argument as optional
1113 Node* importNode(Node* node, std::variant<bool,ImportNodeOptions> options = false);
1114 Node* adoptNode(Node* node); //no NewObject
1115
1116 //NewObject
1117 DocumentFragment* createDocumentFragment();
1118 Text* createTextNode(DOMString data);
1119 CDATASection* createCDATASection(DOMString data);
1120 Comment* createComment(DOMString data);
1121 ProcessingInstruction* createProcessingInstruction(DOMString target, DOMString data);
1122 Attr* createAttribute(DOMString localName);
1123 Attr* createAttributeNS(std::optional<DOMString> namesp, DOMString qualifiedName);
1124 Event* createEvent(DOMString interface); //LEGACY
1125 Range* createRange();
1126 NodeIterator* createNodeIterator(Node* root, unsigned long whatToShow = 0xFFFFFFFF, NodeFilter* filter = nullptr);
1127 TreeWalker* createTreeWalker(Node* root, unsigned long whatToShow = 0xFFFFFFFF, NodeFilter* filter = nullptr);
1128
1129 CustomElementRegistry* get_custom_element_registry() const{
1130 return this->custom_element_registry;
1131 }
1132
1133 virtual Node* get_the_parent(Event* event){
1134 if (event->gettype()=="load"){
1135 return nullptr;
1136 }
1137 return nullptr;
1138 }
1139
1140 virtual void making_it_abstract(){};
1141
1142 virtual ~Document() = default;
1143};
1144
1145//Exposed to window only
1146class DocumentType: public Node{
1147 public:
1148 DOMString name;
1149 DOMString publicId;
1150 DOMString systemId;
1151
1152 // friend void before(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1153 // friend void after(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1154 // friend void replaceWith(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1155 // friend void remove(Node* obj);
1156
1157 DocumentType(DOMString name,DOMString publicId="",DOMString systemId="",Document* ownerdoc = nullptr, Node* parentnode = nullptr): Node(DOCUMENT_TYPE_NODE, name, ownerdoc, parentnode){
1158 this->name = name;
1159 this->publicId = publicId;
1160 this->systemId = systemId;
1161 }
1162 DOMString getname(){
1163 return name;
1164 }
1165 DOMString getpublicId(){
1166 return publicId;
1167 }
1168 DOMString getsystemId(){
1169 return systemId;
1170 }
1171
1172 virtual ~DocumentType() = default;
1173
1174};
1175
1176class DocumentFragment: public ParentNode{
1177 public:
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){};
1181
1182 virtual ~DocumentFragment() = default;
1183
1184};
1185
1186//Exposed to window only
1187class ShadowRoot: public DocumentFragment{
1188 public:
1189 CustomElementRegistry* custom_element_registry = nullptr;
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; }
1198 EventHandler onslotchange;
1199
1200 bool keepCustomElementRegistryNull = false;
1201
1202 // virtual Element* get_the_parent(Event* event);
1203 // virtual Element* get_the_parent(Event* event) override{
1204 // if (!event->composed_flag && !event->path.empty() && dynamic_cast<EventTarget*>(this) == event->path.at(0).invocation_target){
1205 // return nullptr;
1206 // }
1207 // return this->associatedHost;
1208 // }
1209
1210 virtual ~ShadowRoot() = default;
1211};
1212
1213
1214struct ElementCreationOptions{
1215 CustomElementRegistry* CustomElementRegistry = nullptr;
1216 std::optional<DOMString> is = std::nullopt;
1217
1218 ElementCreationOptions(){};
1219};
1220
1221struct ShadowRootInit{
1222 ShadowRootMode mode;
1223 bool delegatesFocus = false;
1224 SlotAssignmentMode slotAssignment = named;
1225 bool clonable = false;
1226 bool serializable = false;
1227 CustomElementRegistry* customElementRegistry = nullptr;
1228
1229 ShadowRootInit(ShadowRootMode mod){
1230 mode = mod;
1231 }
1232};
1233
1234//Exposed to window only + LegacyUnenumerableNamedProperties
1236 public:
1237 std::vector<Attr*> attribute_list = {};
1238 Element* associatedElement;
1239 unsigned long length();
1240 Attr* item(unsigned long index);
1241 Attr* getNamedItem(DOMString qualifiedName);
1242
1243 Attr* getNamedItemNS(std::optional<DOMString> namesp, DOMString localName);
1244
1245 //CEReactions
1246 Attr* setNamedItem(Attr* attr);
1247 Attr* setNamedItemNS(Attr* attr);
1248 Attr* removeNamedItem(DOMString qualifiedName);
1249 Attr* removeNamedItemNS(std::optional<DOMString> namesp, DOMString localName);
1250
1251 virtual ~NamedNodeMap() = default;
1252};
1253
1254
1255class Element: public ParentNode{
1256 public:
1257 std::optional<DOMString> namespaceURI;
1258 std::optional<DOMString> prefix;
1259 DOMString localName;
1260 // DOMTokenList classList;
1261 NamedNodeMap attributes;
1262 ShadowRoot* shadow_root = nullptr;
1263 CustomElementRegistry* customElementRegistry;
1264 ElementState customElementState;
1265 //CEReactions
1266 DOMString id;
1267 DOMString className;
1268 DOMString slot="";
1269 HTMLSlotElement* assignedSlot;
1270 std::optional<DOMString> is;
1271
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; }
1276 // if (this->ownerDocument->type != XML){
1277 // std::transform(qualified_name.begin(), qualified_name.end(), qualified_name.begin(), [](unsigned char c){ return std::toupper(c); });
1278 // }
1279 return qualified_name;
1280 }
1281
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;
1288 }
1289
1290 Element* previousElementSibling();
1291 Element* nextElementSibling();
1292
1293 DOMString tagName(){
1294 return this->html_uppercased_qualified_name();
1295 };
1296
1297
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); //force is optional
1303 Attr* setAttributeNode(Attr* attr);
1304 Attr* setAttributeNodeNS(Attr* attr);
1305 Attr* removeAttributeNode(Attr* attr);
1306
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);
1313
1314 Attr* getAttributeNode(DOMString qualifiedName);
1315 Attr* getAttributeNodeNS(std::optional<DOMString> namesp, DOMString localName);
1316
1317 ShadowRoot* attachShadow(ShadowRootInit init);
1318 std::optional<Element> closest(DOMString selectors);
1319 bool matches(DOMString selectors);
1320
1321 HTMLCollection* getElementsByTagName(DOMString qualifiedName);
1322 HTMLCollection* getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localName);
1323 HTMLCollection* getElementsByClassName(DOMString classNames);
1324
1325 Element* insertAdjacentElement(DOMString where, Element element); //legacy
1326 void insertAdjacentText(DOMString where, DOMString data); //legacy
1327
1328 // friend void before(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1329 // friend void after(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1330 // friend void replaceWith(std::vector<std::variant<Node*, DOMString>> &nodes, const Node* obj);
1331 // friend void remove(Node* obj);
1332
1333 bool operator==(Element* other){ return dynamic_cast<Node*>(this)->isEqualNode(dynamic_cast<Node*>(other)); }
1334
1335 virtual void making_it_abstract(){};
1336
1337
1338
1339 //Getter Setters
1340 DOMString getid(){
1341 // return fetch_attribute(this, "id");
1342 return "";
1343 }
1344 void setid(DOMString value){
1345 // set_attribute_value(this, "id", value);
1346 }
1347
1348 DOMString getclassName(){
1349 // return fetch_attribute(this, "class");
1350 return "";
1351 }
1352 void setclassName(DOMString value){
1353 // set_attribute_value(this, "class", value);
1354 }
1355
1356 DOMString getslot(){
1357 // return fetch_attribute(this, "slot");
1358 return "";
1359 }
1360 void setslot(DOMString value){
1361 // set_attribute_value(this, "slot", value);
1362 }
1363
1364 ShadowRoot* getshadow_root(){
1365 if (this->shadow_root==nullptr || this->shadow_root->mode==closed){ return nullptr; }
1366 return this->shadow_root;
1367 }
1368
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 = "";
1375 }
1376 else{
1377 this->localName = value.value();
1378 }
1379 // assign_slottables_for_tree(this->getRootNode())
1380 }
1381
1382 virtual ~Element() = default;
1383
1384};
1385
1386class HTMLSlotElement: public Element{};
1387
1388class XMLDocument: public Document{};
1389
1390
1392 public:
1393 Document* associated_doc = nullptr;
1394 //NewObject
1395 DocumentType* createDocumentType(DOMString name, DOMString publicId, DOMString systemId);
1396 XMLDocument* createDocument(std::optional<DOMString> namesp, DOMString qualifiedName, std::optional<DocumentType> doctype = std::nullopt);
1397 //qualifiedName is LegacyNullToEmptyString
1398 Document* createHTMLDocument(std::optional<DOMString> title);
1399 bool hasFeature();
1400
1401 virtual ~DOMImplementation() = default;
1402};
1403
1404
1405class DOMTokenList{
1406 public:
1407 std::optional<DOMString> item(unsigned long index){
1408 if (index>=this->length()){
1409 return std::nullopt;
1410 }
1411 return "";
1412 };
1413 bool contains(DOMString token){
1414 auto a = this->list.find(token);
1415 if (a == this->list.end()){
1416 return false;
1417 }
1418 return true;
1419 };
1420
1421 //CEReactions
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();
1428 }
1429 void setvalue(DOMString value){
1430 // set_attribute_value(this->associatedElement, this->associatedAttribute->localName, value);
1431 }
1432
1433
1434 bool supports(DOMString token);
1435 std::set<DOMString> list = {};
1436
1437 Element* associatedElement = nullptr;
1438 Attr* associatedAttribute = nullptr;
1439
1440 unsigned long length(){
1441 return this->list.size();
1442 }
1443
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); });
1447 return false;
1448 }
1449
1450 void update(){
1451 if (!this->associatedAttribute){
1452 return;
1453 }
1454 // set_attribute_value(associatedElement, associatedAttribute->localName, SerializeOrderedSet(this->list));
1455 }
1456
1457 DOMString serialize(){
1458 // return fetch_attribute(this->associatedElement, this->associatedAttribute->localName);
1459 return "";
1460 }
1461
1462
1463 DOMTokenList(Element* element = nullptr, Attr* attribute = nullptr){
1464 this->associatedElement = element;
1465 this->associatedAttribute = attribute;
1466 // this->setvalue(fetch_attribute(element, attribute->localName));
1467 if (this->getvalue()==""){
1468 list.clear();
1469 }
1470 // else{
1471 // this->list = ParseOrderedSet(this->getvalue());
1472 // }
1473 }
1474
1475 virtual ~DOMTokenList() = default;
1476};
1477
1478
1479
1480
1481
1482
1483
1484// Algos
1485
1486
1487// Returns a set of strings. It separates all the substrings based on ASCII whitespace in the input !!
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){
1493 tokens.insert(a);
1494 }
1495 return tokens;
1496}
1497
1498// Concatenates all the strings in the set provided with U+0020 (SPACE)
1499DOMString serialize_ordered_set(std::set<DOMString> input){
1500 DOMString str = "";
1501 int i=0;
1502 for (auto a: input){
1503 (void)str.append(a);
1504 if (i!=(input.size()-1)){
1505 str.append(" ");
1506 }
1507 i++;
1508 }
1509 return str;
1510}
1511
1512/*
1513Validates Namespace Prefix !
1514These characters aren't allowed:
1515- ASCII WHITESPACE (U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE)
1516- U+0000 NULL
1517- U+002F (/)
1518- U+003E (>)
1519*/
1520bool valid_namespace_prefix(DOMString input){
1521 if (input.size()==0){ return false; }
1522 unsigned int temp;
1523 for (auto it=input.begin(); it!=input.end();){
1524 try{
1525 temp = utf8::next(it, input.end());
1526 }
1527 catch (utf8::not_enough_room){
1528 break;
1529 }
1530 if (temp==9 || temp==10 || temp==12 || temp==13 || temp==32 || temp==0 || temp==47 || temp==62){
1531 return false;
1532 }
1533 }
1534 return true;
1535}
1536
1537
1538/*
1539Validates Attribute Names !
1540These characters aren't allowed:
1541- ASCII WHITESPACE (U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE)
1542- U+0000 NULL
1543- U+002F (/)
1544- U+003D (=)
1545- U+003E (>)
1546*/
1547bool valid_attribute_local_name(DOMString input){
1548 if (input.size()==0){ return false; }
1549 int temp;
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){
1552 return false;
1553 }
1554 }
1555 return true;
1556}
1557
1558
1559
1560//Validates Element Names !
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());
1565 unsigned int temp;
1566 if ((first>=65 && first<=90) || (first>=97 && first<=122)){
1567 for (;it<input.end();){
1568 try{
1569 temp = utf8::next(it, input.end());
1570 }
1571 catch (utf8::not_enough_room){
1572 break;
1573 }
1574 if (temp==9 || temp==10 || temp==12 || temp==13 || temp==32 || temp==0 || temp==47 || temp==62){
1575 return false;
1576 }
1577 }
1578 return true;
1579 }
1580 if (first!=58 && first!=95 && (first<128 || first>1114111)){
1581 return false;
1582 }
1583 for (it=input.begin();it<input.end();){
1584 try{
1585 temp = utf8::next(it, input.end());
1586 }
1587 catch (utf8::not_enough_room){
1588 break;
1589 }
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)){
1591 return false;
1592 }
1593 }
1594 return true;
1595}
1596
1597
1598/*
1599Validates DocType Names !
1600These characters aren't allowed:
1601- ASCII WHITESPACE (U+0009 TAB, U+000A LF, U+000C FF, U+000D CR, or U+0020 SPACE)
1602- U+0000 NULL
1603- U+003E (>)
1604*/
1605bool valid_doctype_name(DOMString input){
1606 unsigned int temp;
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){
1610 return false;
1611 }
1612 }
1613 return true;
1614}
1615
1616
1617
1618// From the HTML Specification
1619bool valid_custom_element_name(DOMString name){
1620 if (!valid_element_local_name(name)){ return false; }
1621 int a = name.at(0);
1622 if (a<97 && a>122){ return false; }
1623 bool containsHyphen = false;
1624 for (auto ch: name){
1625 if (ch=='-'){ containsHyphen = true; }
1626 int c = ch;
1627 if (c>=65 && c<=90){ return false; }
1628 }
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"){
1631 return false;
1632 }
1633 return true;
1634}
1635
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"){
1639 return false;
1640 }
1641 return true;
1642}
1643
1644
1645
1646/*
1647It validates and extracts namespace `prefix` and `localName` based on other args.
1648If the `qualifiedName` contains a (:) it cuts it in half to feed `prefix` and `localName`. Else, `localName` gets `qualifiedName` and `prefix` is null
1649`prefix` is validated and matched with it's corresponding namespace (1st arg) whereas
1650the `localName` is being validated to be an `attribute` or an `element` based on the value of `context`
1651*/
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 !"); }
1661 }
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 !"); }
1669}
1670
1671
1672
1673
1674
1675
1676
1677
1678// More algos
1679
1680event_listener* flatten(DOMString &type, EventListener *callback, std::variant<AddEventListenerOptions,bool> options){
1681 event_listener* temp = new event_listener(type);
1682 temp->type = type;
1683 temp->callback = callback;
1684 temp->once = false;
1685 temp->passive = std::nullopt;
1686 temp->signal = nullptr;
1687 if (std::holds_alternative<bool>(options)){
1688 temp->capture = std::get<bool>(options);
1689 }
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;
1696 }
1697 if (opts.signal){
1698 temp->signal = opts.signal;
1699 }
1700 }
1701 return temp;
1702}
1703
1704void remove_event_listener(EventTarget* eventTarget, event_listener *listener){
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);
1709 }
1710}
1711
1712void add_abort_algo(const std::function<void()> &algo, AbortSignal* signal){
1713 if (signal->isaborted()){
1714 return;
1715 }
1716 signal->abort_algos.push_back(algo);
1717}
1718
1719void run_abort_steps(AbortSignal* signal){
1720 for (auto algo: signal->abort_algos){
1721 algo();
1722 }
1723 signal->abort_algos.clear();
1724 fire_event("abort", signal);
1725}
1726
1727void signal_abort(AbortSignal* signal, std::any reason) {
1728 if (signal->isaborted()) {
1729 return;
1730 }
1731 if (reason.has_value()){
1732 signal->reason = reason;
1733 }
1734 else{
1735 signal->reason = new AbortError("Abort errors !!");
1736 }
1737
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);
1743 }
1744 }
1745 run_abort_steps(signal);
1746 for (const auto &dependentSignal: dependentSignalsToAbort) {
1747 run_abort_steps(dependentSignal);
1748 }
1749}
1750
1751void add_event_listener(EventTarget* eventTarget, event_listener *listener){
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);
1756 }
1757 bool found = false;
1758 for (event_listener* ev: eventTarget->event_listener_list){
1759 if (ev->type == listener->type && ev->callback == listener->callback && ev->capture == listener->capture){
1760 found = true;
1761 break;
1762 }
1763 }
1764 if (!found){
1765 eventTarget->event_listener_list.push_back(listener);
1766 }
1767 if (listener->signal != nullptr ){
1768 add_abort_algo(std::bind(remove_event_listener, eventTarget, listener), listener->signal);
1769 }
1770}
1771
1772AbortSignal* create_dependent_abort_signal(std::vector<AbortSignal*> signals, AbortSignal* signalInterface, Realm* realm) {
1773 AbortSignal* resultSignal = signalInterface->create_object();
1774 for (AbortSignal* signal: signals) {
1775 if (signal->isaborted()) {
1776 resultSignal->reason = signal->reason;
1777 return resultSignal;
1778 }
1779 }
1780 resultSignal->dependent = true;
1781 for (AbortSignal* signal: signals) {
1782 if (!(signal-> dependent)) {
1783 resultSignal->source_signals.push_back(signal);
1784 signal->dependent_signals.push_back(resultSignal);
1785 }
1786 else {
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);
1791 }
1792 }
1793 }
1794 return resultSignal;
1795}
1796
1797
1798bool fire_event(DOMString e,EventTarget* target,Event* temporary_class,bool legacy_target_override_flag) {
1799 Event* event;
1800 if (!temporary_class){
1801 event = new Event(e);
1802 }
1803 else{
1804 event = temporary_class->newObject();
1805 }
1806 event->type = e;
1807 bool returning_val = dispatch_event(event, target, legacy_target_override_flag);
1808 delete event;
1809 return returning_val;
1810};
1811
1812
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; }
1817 // queue mutation record
1818 return "";
1819}
1820
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){
1822 Element* temp = new Element("global","e","k",new CustomElementRegistry(), UNDEFINED);
1823 temp->ownerDocument = document;
1824 temp->localName = localName;
1825 temp->namespaceURI = namesp;
1826 temp->prefix = prefix;
1827 temp->is = is;
1828 return temp;
1829}
1830
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)){
1833 ElementCreationOptions temp = std::get<ElementCreationOptions>(options);
1834 if (temp.CustomElementRegistry){
1835 registry = temp.CustomElementRegistry;
1836 }
1837 if (registry!=document->custom_element_registry){
1838 throw NotSupportedError("not supported boi !!");
1839 }
1840 if (temp.is.has_value()){
1841 is = temp.is;
1842 }
1843 if (registry!=nullptr && is!=std::nullopt){
1844 throw NotSupportedError("not supported boi !!");
1845 }
1846 }
1847 if (registry==nullptr){}
1848}
1849
1850void adopt(Node* node, Document* document){
1851 // Document* oldDocument = node->ownerDocument;
1852 if (node->parentNode!=nullptr){ remove_node(node); }
1853 // if (document!=oldDocument){
1854 // for (auto inclusiveDescendant: node->shad)
1855 // }
1856}
1857
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);
1862 CustomElementRegistry* registry;
1863 std::optional<DOMString> is;
1864 flatten_element_creation_options(options, document, registry, is);
1865 // return create_element(document, localName, namesp, prefix, is, true, registry);
1866 return new Element("","","");
1867}
1868
1869
1870void change_attribute_value(Attr* attribute, DOMString value){
1871 DOMString oldValue = attribute->value;
1872 attribute->value = value;
1873 // handle_attribute_changes(attribute, attribute->ownerElement, oldValue, value);
1874}
1875
1876void append_attribute(Attr* attribute, Element* element){
1877 element->attributes.attribute_list.push_back(attribute);
1878 attribute->ownerElement = element;
1879 // attribute->ownerDocument = element->ownerDocument;
1880 // handle_attribute_changes(attribute, element, std::nullopt, attribute->value);
1881}
1882
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;
1887 // handle_attribute_changes(attribute, element, attribute->value, std::nullopt);
1888}
1889
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;
1894 // newAttribute->ownerDocument = element->ownerDocument;
1895 oldAttribute->ownerElement = nullptr;
1896 // handle_attribute_changes(oldAttribute, element, oldAttribute->value, newAttribute->value);
1897}
1898
1899Attr* fetch_attribute(DOMString qualifiedName, Element* element){
1900 // if (element->ownerDocument->type!=XML){
1901 // std::transform(qualifiedName.begin(), qualifiedName.end(), qualifiedName.begin(), [](unsigned char c){ return std::tolower(c); });
1902 // }
1903 for (auto attr: element->attributes.attribute_list){
1904 if (attr->qualifiedName()==qualifiedName){
1905 return attr;
1906 }
1907 }
1908 return nullptr;
1909}
1910
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){
1915 return attr;
1916 }
1917 }
1918 return nullptr;
1919}
1920
1921
1922DOMString fetch_attribute(Element* element, DOMString localName, std::optional<DOMString> namesp){
1923 Attr* attr = fetch_attribute(namesp, localName, element);
1924 if (attr==nullptr){ return ""; }
1925 return attr->value;
1926}
1927
1928
1929Attr* set_attribute(Attr* attr, Element* element){
1930 if (attr->ownerElement!=nullptr && !dynamic_cast<Element*>(attr->ownerElement)){ throw InUseAttributeError("In use !!"); }
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);
1935 }
1936 else{
1937 append_attribute(attr, element);
1938 }
1939 return oldAttr;
1940}
1941
1942
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){
1946 Attr* attr = new Attr(localName);
1947 attr->namespaceURI = namesp;
1948 attr->prefix = prefix;
1949 attr->value = value;
1950 // attr->ownerDocument = element->ownerDocument;
1951 append_attribute(attr, element);
1952 return;
1953 }
1954 change_attribute_value(attribute, value);
1955}
1956
1957Attr* remove_attribute_by_name(DOMString qualifiedName, Element* element){
1958 Attr* attr = fetch_attribute(qualifiedName, element);
1959 if (attr!=nullptr){
1960 remove_attribute(attr);
1961 }
1962 return attr;
1963}
1964
1965Attr* remove_attribute_by_namespace(std::optional<DOMString> namesp, DOMString localName, Element* element){
1966 Attr* attr = fetch_attribute(namesp, localName, element);
1967 if (attr!=nullptr){
1968 remove_attribute(attr);
1969 }
1970 return attr;
1971}
1972
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"); }
1975 // if (!ValidShadowHostName(element->localName)){ throw NotSupportedError("nope not supported boi !!"); }
1976 // if (ValidCustomElementName(element->localName) || element->is!=std::nullopt){}
1977 if (element->getshadow_root()!=nullptr){
1978 ShadowRoot* currentShadowRoot = element->getshadow_root();
1979 if (!currentShadowRoot->declarative || currentShadowRoot->mode!=mode){ throw NotSupportedError("nope not supporting :) !"); }
1980 else{
1981 for (auto child: currentShadowRoot->childNodes.node_list){
1982 remove_node(child);
1983 }
1984 currentShadowRoot->declarative = false;
1985 return;
1986 }
1987 }
1988 ShadowRoot* shadow = new ShadowRoot();
1989 // shadow->ownerDocument = element->ownerDocument;
1990 shadow->associatedHost = element;
1991 shadow->mode = mode;
1992 shadow->delegatesFocus = delegatesFocus;
1993 if (element->customElementState==PRECUSTOMIZED && element->customElementState==CUSTOM){
1994 shadow->availableToElementInternals = true;
1995 }
1996 shadow->slotAssignment = slotAssignment;
1997 shadow->declarative = false;
1998 shadow->clonable = clonable;
1999 shadow->serializable = serializable;
2000 shadow->custom_element_registry = &registry.value();
2001 element->shadow_root = shadow;
2002}
2003
2004Node* insert_adjacent(Element* element, DOMString where, Node* node){
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));
2009 }
2010 else if (where=="afterbegin"){
2011 return pre_insert_node(node, dynamic_cast<Node*>(element), dynamic_cast<Node*>(element)->firstChild());
2012 }
2013 else if (where=="beforeend"){
2014 return pre_insert_node(node, dynamic_cast<Node*>(element), nullptr);
2015 }
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());
2019 }
2020 else{
2021 throw SyntaxError("syntax errrrrror boi !!");
2022 }
2023}
2024
2025DOMString replace_all(Node* node, Node* newParent){
2026 return "";
2027}
2028
2029
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 !!"); }
2033 CharacterData* temp = dynamic_cast<CharacterData*>(node);
2034 if ((offset+count)>length){ return temp->getdata().substr(offset); }
2035 return temp->getdata().substr(offset, count);
2036}
2037
2038
2039bool check_exclusive_text_node(Text* node){
2040 if (dynamic_cast<CDATASection*>(node)){ return false; }
2041 return true;
2042}
2043
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());
2050 }
2051 currentNode = dynamic_cast<Text*>(node->nextSibling());
2052 while (currentNode){
2053 temp.push_back(currentNode);
2054 currentNode = dynamic_cast<Text*>(currentNode->nextSibling());
2055 }
2056 return temp;
2057}
2058
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);
2067 }
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);
2073 }
2074 return temp;
2075}
2076
2077
2078
2079
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(); }
2085 }
2086 return temp;
2087}
2088
2089DOMString descendant_text_content(Node* node){
2090 Node* currentNode = node->childNodes[0];
2091 std::vector<Node*> temp = {currentNode};
2092 Text* temp2;
2093 DOMString data = "";
2094 while (currentNode!=nullptr){
2095 temp2 = dynamic_cast<Text*>(currentNode);
2096 auto temp3 = dynamic_cast<CharacterData*>(currentNode);
2097 if (temp2){
2098 data += temp3->getdata();
2099 }
2100 if (currentNode->childNodes.length()!=0){
2101 temp.push_back(currentNode);
2102 currentNode = currentNode->firstChild();
2103 continue;
2104 }
2105 currentNode = currentNode->nextSibling();
2106 while (currentNode==nullptr && !temp.empty()){
2107 currentNode = (*(temp.end() -1))->nextSibling();
2108 temp.erase(temp.end()-1);
2109 }
2110 }
2111 return data;
2112}
2113
2114
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;
2120
2121 DOMString data = substring_data(smth, offset, count);
2122 Text* new_node = new Text(data);
2123 // new_node->ownerDocument = smth->ownerDocument;
2124
2125 Node* parent = smth->parentNode;
2126 if (parent!=nullptr){
2127 insert_node(dynamic_cast<Node*>(new_node), parent, smth->nextSibling());
2128 }
2129 replace_data(dynamic_cast<Node*>(node), offset, count, "");
2130 return new_node;
2131}
2132
2133int position(Node* nodeA, unsigned long offsetA, Node* nodeB, unsigned long offsetB){
2134 assert(nodeA->getRootNode()==nodeB->getRootNode());
2135 if (nodeA==nodeB){
2136 if (offsetA==offsetB){ return 0; }
2137 if (offsetA<offsetB){ return -1; }
2138 return 1;
2139 }
2140 if (*nodeA^nodeB){
2141 int a = position(nodeB, offsetB, nodeA, offsetA);
2142 if (a==-1){ return 1; }
2143 if (a==1){ return -1; }
2144 }
2145 if (check_ancestor(nodeB, nodeA)){
2146 Node* child = nodeB;
2147 bool ischild = false;
2148 int index;
2149 while (!ischild){
2150 index = 0;
2151 for (auto a: nodeA->childNodes.node_list){
2152 if (a==child){ ischild = true; break; }
2153 index++;
2154 }
2155 if (!ischild){
2156 child = child->parentNode;
2157 }
2158 }
2159 if (index<offsetA){
2160 return 1;
2161 }
2162 }
2163 return -1;
2164}
2165
2166
2167bool static_range_valid(StaticRange* range){
2168 if (range->startContainer->getRootNode(true)!=range->endContainer->getRootNode(true)){
2169 return false;
2170 }
2171 if (range->startOffset<0 || range->startOffset>range->startContainer->length()){
2172 return false;
2173 }
2174 if (range->endOffset<0 || range->endOffset>range->endContainer->length()){
2175 return false;
2176 }
2177 int temp = position(range->startContainer, range->startOffset, range->endContainer, range->endOffset);
2178 if (temp==1){
2179 return false;
2180 }
2181 return true;
2182}
2183
2184bool contained_in_range(Node* node, Range* range){
2185 if (node->getRootNode()!=range->startContainer->getRootNode()){
2186 return false;
2187 }
2188 int temp = position(node, 0, range->startContainer, range->startOffset);
2189 if (temp==0 || temp==-1){
2190 return false;
2191 }
2192 temp = position(node, node->length(), range->endContainer, range->endOffset);
2193 if (temp==0 || temp==1){
2194 return false;
2195 }
2196 return true;
2197}
2198
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)){
2203 return true;
2204 }
2205 return false;
2206}
2207
2208void pre_remove_range(Node* node){
2209 Node* parent = node->parentNode;
2210 assert(parent!=nullptr);
2211 unsigned long index = node->index();
2212}
2213
2214void set_start_end(Range* range, Node* node, int offset, bool start){
2215 if (dynamic_cast<DocumentType*>(node)){ throw InvalidNodeTypeError("invalid node type !!!!!"); }
2216 if (offset>node->length()){ throw IndexSizeError("size issues, fatty !!"); }
2217 if (start){
2218 if ((range->startContainer->getRootNode()!=node->getRootNode()) || position(node, offset, range->endContainer, range->endOffset)==1){
2219 range->endContainer = node;
2220 range->endOffset = offset;
2221 }
2222 range->startContainer = node;
2223 range->startOffset = offset;
2224 }
2225 else{
2226 if ((range->startContainer->getRootNode()!=node->getRootNode()) || position(node, offset, range->startContainer, range->startOffset)==-1){
2227 range->startContainer = node;
2228 range->startOffset = offset;
2229 }
2230 range->endContainer = node;
2231 range->endOffset = offset;
2232 }
2233
2234}
2235
2236void select_node_within_rangee(Node* node, Range* range){
2237 Node* parent = node->parentNode;
2238 if (parent==nullptr){ throw InvalidNodeTypeError("invalid node type dummy !"); }
2239 unsigned long index = node->index();
2240 range->startContainer = parent;
2241 range->startOffset = index;
2242 range->endContainer = parent;
2243 range->endOffset = index + 1;
2244}
2245
2246
2247DocumentFragment* extract_range(Range* range){
2248 DocumentFragment* fragment = new DocumentFragment();
2249 // fragment->ownerDocument = range->startContainer->ownerDocument;
2250 if (range->collapsed()){
2251 return fragment;
2252 }
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;
2257
2258 if (original_startnode==original_endnode && dynamic_cast<CharacterData*>(original_startnode)){
2259 Node* temp = clone_node(original_startnode);
2260 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
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, "");
2264 return fragment;
2265 }
2266 Node* common_ancestor = original_startnode;
2267 while (!check_ancestor(original_endnode, common_ancestor, true)){
2268 common_ancestor = common_ancestor->parentNode;
2269 }
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;
2275 break;
2276 }
2277 }
2278 }
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;
2284 }
2285 }
2286 }
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);
2291 if (dynamic_cast<DocumentType*>(a)){
2292 throw HeirarchyRequestError("hierarchy issue dude !!");
2293 }
2294 }
2295 }
2296 Node* new_node;
2297 unsigned long new_offset;
2298 if (check_ancestor(original_endnode, original_startnode, true)){
2299 new_node = original_startnode;
2300 new_offset = original_startoffset;
2301 }
2302 else{
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;
2308 }
2309 new_node = referenceNode->parentNode;
2310 new_offset = referenceNode->index() + 1;
2311 }
2312 if (dynamic_cast<CharacterData*>(first_partially_contained_child)){
2313 Node* temp = clone_node(original_startnode);
2314 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
2315 clone->setdata(substring_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset));
2316 // pre_insert_node(dynamic_cast<Node*>(clone), fragment, nullptr);
2317 replace_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset, "");
2318 }
2319 else if (first_partially_contained_child!=nullptr){
2320 Node* temp = clone_node(first_partially_contained_child);
2321 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
2322 // pre_insert_node(dynamic_cast<Node*>(clone), fragment, nullptr);
2323 Range* subrange = new Range();
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();
2328 DocumentFragment* subfragment = extract_range(subrange);
2329 // pre_insert_node(subfragment, clone, nullptr);
2330 }
2331 for (auto child: contained_children){
2332 // pre_insert_node(child, fragment, nullptr);
2333 }
2334 if (dynamic_cast<CharacterData*>(last_partially_contained_child)){
2335 Node* temp = clone_node(original_endnode);
2336 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
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, "");
2340 }
2341 else if (first_partially_contained_child!=nullptr){
2342 Node* temp = clone_node(last_partially_contained_child);
2343 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
2344 pre_insert_node(dynamic_cast<Node*>(clone), dynamic_cast<Node*>(fragment), nullptr);
2345 Range* subrange = new Range();
2346 subrange->startContainer = last_partially_contained_child;
2347 subrange->startOffset = 0;
2348 subrange->endContainer = original_endnode;
2349 subrange->endOffset = original_endoffset;
2350 DocumentFragment* subfragment = extract_range(subrange);
2351 pre_insert_node(dynamic_cast<Node*>(subfragment), dynamic_cast<Node*>(clone), nullptr);
2352 }
2353 range->startContainer = new_node;
2354 range->endContainer = new_node;
2355 range->startOffset = new_offset;
2356 range->endOffset = new_offset;
2357 return fragment;
2358}
2359
2360
2361
2362DocumentFragment* clone_contents(Range* range){
2363 DocumentFragment* fragment = new DocumentFragment();
2364 // fragment->ownerDocument = range->startContainer->ownerDocument;
2365 if (range->collapsed()){
2366 return fragment;
2367 }
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;
2372
2373 if (original_startnode==original_endnode && dynamic_cast<CharacterData*>(original_startnode)){
2374 Node* temp = clone_node(original_startnode);
2375 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
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);
2378 return fragment;
2379 }
2380 Node* common_ancestor = original_startnode;
2381 while (!check_ancestor(original_endnode, common_ancestor, true)){
2382 common_ancestor = common_ancestor->parentNode;
2383 }
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;
2389 break;
2390 }
2391 }
2392 }
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;
2398 }
2399 }
2400 }
2401
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);
2406 if (dynamic_cast<DocumentType*>(a)){
2407 throw HeirarchyRequestError("hierarchy issue dude !!");
2408 }
2409 }
2410 }
2411
2412 if (dynamic_cast<CharacterData*>(first_partially_contained_child)){
2413 Node* temp = clone_node(original_startnode);
2414 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
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);
2417 }
2418 else if (first_partially_contained_child!=nullptr){
2419 Node* temp = clone_node(first_partially_contained_child);
2420 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
2421 pre_insert_node(dynamic_cast<Node*>(clone), dynamic_cast<Node*>(fragment), nullptr);
2422 Range* subrange = new Range();
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();
2427 DocumentFragment* subfragment = clone_contents(subrange);
2428 pre_insert_node(dynamic_cast<Node*>(subfragment), dynamic_cast<Node*>(clone), nullptr);
2429 }
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);
2433 }
2434
2435 if (dynamic_cast<CharacterData*>(last_partially_contained_child)){
2436 Node* temp = clone_node(original_endnode);
2437 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
2438 clone->setdata(substring_data(original_endnode, 0, original_endoffset));
2439 pre_insert_node(dynamic_cast<Node*>(clone), dynamic_cast<Node*>(fragment), nullptr);
2440 }
2441 else if (first_partially_contained_child!=nullptr){
2442 Node* temp = clone_node(last_partially_contained_child);
2443 CharacterData* clone = dynamic_cast<CharacterData*>(temp);
2444 pre_insert_node(dynamic_cast<Node*>(clone), dynamic_cast<Node*>(fragment), nullptr);
2445 Range* subrange = new Range();
2446 subrange->startContainer = last_partially_contained_child;
2447 subrange->startOffset = 0;
2448 subrange->endContainer = original_endnode;
2449 subrange->endOffset = original_endoffset;
2450 DocumentFragment* subfragment = clone_contents(subrange);
2451 pre_insert_node(dynamic_cast<Node*>(subfragment), dynamic_cast<Node*>(clone), nullptr);
2452 }
2453 return fragment;
2454}
2455
2456
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){
2459 throw HeirarchyRequestError("hierarchy ! spelling issues :) ");
2460 }
2461 Node* referenceNode = nullptr;
2462 if (dynamic_cast<Text*>(range->startContainer)){
2463 referenceNode = range->startContainer;
2464 }
2465 else{
2466 for (auto a: range->startContainer->childNodes.node_list){
2467 if (a->index()==range->startOffset){
2468 referenceNode = a;
2469 break;
2470 }
2471 }
2472 }
2473 Node* parent;
2474 if (!referenceNode){
2475 parent = range->startContainer;
2476 }
2477 else{
2478 parent = referenceNode->parentNode;
2479 }
2480 ensure_pre_insert_validity(node, parent, referenceNode);
2481 Text* tempji = dynamic_cast<Text*>(range->startContainer);
2482 if (tempji){
2483 referenceNode = dynamic_cast<Node*>(split_text_node(tempji, range->startOffset));
2484 }
2485 if (node==referenceNode){
2486 referenceNode = referenceNode->nextSibling();
2487 }
2488 if (node->parentNode!=nullptr){
2489 remove_node(node);
2490 }
2491
2492 unsigned long newOffset;
2493 if (referenceNode==nullptr){
2494 newOffset = parent->length();
2495 }
2496 else{
2497 newOffset = referenceNode->index();
2498 }
2499
2500 if (dynamic_cast<DocumentFragment*>(node)){
2501 newOffset += node->length();
2502 }
2503 else{
2504 newOffset++;
2505 }
2506
2507 pre_insert_node(node, parent, referenceNode);
2508 if (range->collapsed()){
2509 range->endContainer = parent;
2510 range->endOffset = newOffset;
2511 }
2512}
2513
2514
2515void pre_remove_steps(NodeIterator* node_iterator, Node* toBeRemovedNode){
2516 if (!check_ancestor(node_iterator->referenceNode, toBeRemovedNode,true) || toBeRemovedNode==node_iterator->root){
2517 return;
2518 }
2519 if (node_iterator->pointerBeforeReferenceNode){
2520 // if (next!=nullptr){
2521 // node_iterator->referenceNode = next;
2522 // return;
2523 // }
2524 node_iterator->pointerBeforeReferenceNode = false;
2525 }
2526 if (toBeRemovedNode->previousSibling()==nullptr){
2527 // node_iterator->referenceNode = toBeRemovedNode->parentNode();
2528 }
2529 else{
2530 Node* prev = toBeRemovedNode->previousSibling();
2531 for (auto a: prev->childNodes.node_list){}
2532 }
2533}
2534
2535Node* traverse(NodeIterator* iterator, unsigned long direction){
2536 Node* reference = iterator->referenceNode;
2537 bool beforeNode = iterator->pointerBeforeReferenceNode;
2538 Node* node;
2539 while (true){
2540 if (direction==1){
2541 if (!beforeNode){
2542
2543 }
2544 if (beforeNode){ beforeNode = false; }
2545 }
2546 else if (direction==-1){
2547 if (beforeNode){
2548
2549 }
2550 if (!beforeNode){ beforeNode = true; }
2551 }
2552 unsigned short result = iterator->filter_node(node);
2553 if (result==FILTER_ACCEPT){
2554 break;
2555 }
2556 }
2557 iterator->referenceNode = node;
2558 iterator->pointerBeforeReferenceNode = beforeNode;
2559 return node;
2560}
2561
2562
2563Node* traverse_children(TreeWalker* walker, unsigned long type){
2564 Node* node = walker->currentNode;
2565 Node* child;
2566 if (type==1){
2567 node = node->firstChild();
2568 }
2569 else if (type==-1){
2570 node = node->lastChild();
2571 }
2572 while (node!=nullptr){
2573 unsigned short result = walker->filter_node(node);
2574 if (result==FILTER_ACCEPT){
2575 walker->currentNode = node;
2576 return node;
2577 }
2578 else if (result == FILTER_SKIP){
2579 if (type==1){ child = node->firstChild(); }
2580 else if (type==-1){ child = node->lastChild(); }
2581 }
2582
2583 while (node!=nullptr){
2584 Node* sibling;
2585 if (type==1){
2586 sibling = node->nextSibling();
2587 }
2588 else if (type==-1){
2589 sibling = node->previousSibling();
2590 }
2591 if (sibling!=nullptr){
2592 node = sibling;
2593 break;
2594 }
2595 Node* parent = node->parentNode;
2596 if (parent==nullptr || parent==walker->root || parent==walker->currentNode){
2597 return nullptr;
2598 }
2599 node = parent;
2600 }
2601 }
2602 return nullptr;
2603}
2604
2605
2606Node* traverse_sibling(TreeWalker* walker, unsigned long type){
2607 Node* node = walker->currentNode;
2608 if (node==walker->root){
2609 return nullptr;
2610 }
2611 while (true){
2612 Node* sibling;
2613 if (type==1){
2614 sibling = node->nextSibling();
2615 }
2616 else if (type==-1){
2617 sibling = node->previousSibling();
2618 }
2619 while (sibling!=nullptr){
2620 node = sibling;
2621 unsigned short result = walker->filter_node(node);
2622
2623 if (result==FILTER_ACCEPT){
2624 walker->currentNode = node;
2625 return node;
2626 }
2627
2628 if (type==1){
2629 sibling = node->firstChild();
2630 }
2631 else if (type==-1){
2632 sibling = node->lastChild();
2633 }
2634
2635 if (result==FILTER_REJECT || sibling==nullptr){
2636 if (type==1){
2637 sibling = node->nextSibling();
2638 }
2639 else if (type==-1){
2640 sibling = node->previousSibling();
2641 }
2642 }
2643 }
2644 node = node->parentNode;
2645 if (node==nullptr || node==walker->root){
2646 return nullptr;
2647 }
2648 if (walker->filter_node(node)==FILTER_ACCEPT){
2649 return nullptr;
2650 }
2651 }
2652}
2653
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)){
2657 return true;
2658 }
2659 else{
2660 auto temp = dynamic_cast<Node*>(eventTarget);
2661 if (temp && temp->ownerDocument==(dynamic_cast<Document*>(eventTarget))){
2662 return true;
2663 }
2664 else if (temp && dynamic_cast<Document*>(temp->parentNode)==temp->ownerDocument){
2665 return true;
2666 }
2667 }
2668 }
2669 return false;
2670}
2671
2672
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;
2675
2676 EventTarget* targetOverride;
2677 if (!legacy_target_override_flag.has_value()) {
2678 targetOverride = target;
2679 }
2680 else{
2681 // set targetOverride to target's associatedDocument
2682 }
2683
2684 EventTarget* activationTarget = nullptr;
2685 EventTarget* relatedTarget = retard(event->getrelatedTarget(), target);
2686 bool clearTargets = false;
2687
2688 Node* targetNode = dynamic_cast<Node*>(target);
2689
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));
2694 }
2695
2696 append_to_event_path(event,target,targetOverride,relatedTarget,touchTargets,false);
2697
2698 bool isActivationEvent = false;
2699 if ((dynamic_cast<MouseEvent*>(event)) && event->gettype()=="click"){
2700 isActivationEvent = true;
2701 }
2702
2703 if (isActivationEvent && target->has_activation_behavior){
2704 activationTarget = target;
2705 }
2706 EventTarget* slottable = nullptr;
2707 auto te = dynamic_cast<Element*>(target);
2708 if (te && te->assignedSlot){
2709 slottable = target;
2710 }
2711 else{
2712 auto f = dynamic_cast<Text*>(target);
2713 if (f && f->assignedSlot){
2714 slottable = target;
2715 }
2716 }
2717
2718 bool slot_in_closed_tree = false;
2719 EventTarget* parent = target->get_the_parent(event);
2720 while (parent){
2721 auto parentNode = dynamic_cast<Node*>(parent);
2722 auto parentRoot = dynamic_cast<ShadowRoot*>(parentNode->getRootNode());
2723 if (slottable){
2724 assert(dynamic_cast<Element*>(parent) && parentRoot && parentRoot->host());
2725 slottable = nullptr;
2726 if (parentRoot && parentRoot->mode==closed){
2727 slot_in_closed_tree = true;
2728 }
2729 }
2730 auto te = dynamic_cast<Element*>(parent);
2731 if (te && te->assignedSlot){
2732 slottable = parent;
2733 }
2734 else{
2735 auto f = dynamic_cast<Text*>(parent);
2736 if (f && f->assignedSlot){
2737 slottable = parent;
2738 }
2739 }
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));
2744 }
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;
2748 }
2749 append_to_event_path(event, parent, nullptr, relatedTarget, touchTargets, slot_in_closed_tree);
2750 }
2751 else if (parent==relatedTarget){
2752 parent = nullptr;
2753 }
2754 else{
2755 target = parent;
2756 if (isActivationEvent && !activationTarget && target->has_activation_behavior){
2757 activationTarget = target;
2758 }
2759 append_to_event_path(event, parent, target, relatedTarget, touchTargets, slot_in_closed_tree);
2760 }
2761 if (parent){
2762 parent = parent->get_the_parent(event);
2763 }
2764 slot_in_closed_tree = false;
2765 }
2766
2767 path_structs clearTargetsStruct;
2768 for (path_structs &a: event->path){
2769 if (a.shadow_adjusted_target){
2770 clearTargetsStruct = a;
2771 }
2772 }
2773
2774 auto tempShadowAdjustedTarget = dynamic_cast<Node*>(clearTargetsStruct.shadow_adjusted_target);
2775 if (tempShadowAdjustedTarget && dynamic_cast<ShadowRoot*>(tempShadowAdjustedTarget->getRootNode())){
2776 clearTargets = true;
2777 }
2778 else{
2779 auto tempRelatedTarget = dynamic_cast<Node*>(clearTargetsStruct.related_target);
2780 if (tempRelatedTarget && dynamic_cast<ShadowRoot*>(tempRelatedTarget->getRootNode())){
2781 clearTargets = true;
2782 }
2783 else{
2784 Node* tempNode2;
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;
2789 break;
2790 }
2791 }
2792 }
2793 }
2794
2795
2796 if (activationTarget && activationTarget->has_legacy_pre_activation_behavior){
2797 activationTarget->legacy_pre_activation_behavior_algorithm();
2798 }
2799 std::vector<path_structs> rev_path = std::vector<path_structs>(event->path.rbegin(),event->path.rend());
2800 for (path_structs &struc: rev_path){
2801 if (struc.shadow_adjusted_target){
2802 event->seteventPhase(AT_TARGET);
2803 }
2804 else{
2805 event->seteventPhase(CAPTURING_PHASE);
2806 }
2807 invoke_event(struc, event, CAPTURING_PHASE, legacy_output_did_listeners_throw_flag);
2808 }
2809 for (path_structs& a: event->path){
2810 if (a.shadow_adjusted_target){
2811 event->seteventPhase(AT_TARGET);
2812 }
2813 else{
2814 if (!(event->getbubbles())){
2815 continue;
2816 }
2817 event->seteventPhase(BUBBLING_PHASE);
2818 }
2819 invoke_event(a, event, BUBBLING_PHASE, legacy_output_did_listeners_throw_flag);
2820 }
2821 }
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;
2828 if (clearTargets){
2829 event->target = nullptr;
2830 event->relatedTarget = nullptr;
2831 event->touch_target_list.clear();
2832 }
2833 if (activationTarget){
2834 if (!event->canceled_flag){
2835 activationTarget->activation_behavior_algorithm(event);
2836 }
2837 else if(activationTarget->has_legacy_canceled_activation_behavior){
2838 activationTarget->legacy_canceled_activation_behavior_algorithm;
2839 }
2840 }
2841 if (event->canceled_flag){
2842 return false;
2843 }
2844 return true;
2845}
2846
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;
2852 }
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;
2857 }
2858 event->path.push_back(path_structs(invocationTarget, invocationTargetInShadowTree, shadowAdjustedTarget, relatedTarget, touchTargets, root_of_closed_tree, slot_in_closed_tree));
2859}
2860
2861bool inner_invoke(Event* event, std::vector<event_listener*> &listeners,enum event_phase phase, bool invocationTargetInShadowTree, std::optional<bool> legacyOutputDidListenersThrowFlag){
2862 bool found = false;
2863 for (event_listener* listener: listeners) {
2864 if (!(listener->removed)) {
2865 continue;
2866 }
2867 if (event->type!=listener->type) {
2868 std::cout<<"Event caught of type "<<event->type;
2869 continue;
2870 }
2871 found = true;
2872 if ((phase==CAPTURING_PHASE && !(listener->capture)) || (phase==BUBBLING_PHASE && listener->capture)) {
2873 continue;
2874 }
2875 if (listener->once) {
2876 remove_event_listener(event->currentTarget, listener);
2877 }
2881 Event* currentEvent = nullptr;
2882 if (listener->passive) {
2883 event->in_passive_listener_flag = true;
2884 }
2886 event->in_passive_listener_flag = false;
2887 if (event->stop_immediate_propagation_flag) {
2888 break;
2889 }
2890 }
2891 return found;
2892}
2893
2894
2895void invoke_event(path_structs &struc, Event* event, enum event_phase phase, std::optional<bool> legacyOutputDidListenersThrowFlag) {
2896 event->target = nullptr;
2897 for (const path_structs a: event->path){
2898 if (a.shadow_adjusted_target){
2899 event->target = a.shadow_adjusted_target;
2900 }
2901 }
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);
2907
2908 bool invocationTargetInShadowTree = struc.invocation_target_in_shadow_tree;
2909 bool found = inner_invoke(event, listeners, phase, invocationTargetInShadowTree,legacyOutputDidListenersThrowFlag);
2910
2911 if (!found && event->isTrusted) {
2912 DOMString originalEventType = event->type;
2913 if (event->type=="animationend") {
2914 event->type = "webkitAnimationEnd";
2915 }
2916 else if (event->type=="animationiteration") {
2917 event->type = "webkitAnimationIteration";
2918 }
2919 else if (event->type=="animationstart") {
2920 event->type = "webkitAnimationStart";
2921 }
2922 else if (event->type=="transitionend") {
2923 event->type = "webkitTransitionEnd";
2924 }
2925 else{return;}
2926 inner_invoke(event, listeners, phase, invocationTargetInShadowTree, legacyOutputDidListenersThrowFlag);
2927 event->type = originalEventType;
2928 }
2929}
2930
2931// Node* create_element(Document* document, DOMString name, std::optional<DOMString> namespaceURI, std::optional<DOMString> prefix, bool gtem, CustomElementRegistry*istry){
2932// return dynamic_cast<Node*>(new Element(namespaceURI, prefix, name));
2933// };
2934
2935Node* clone_node(Node* node, Document* document, bool subtree, Node* parent, CustomElementRegistry* fallbackRegistry){
2936 if (document==nullptr){
2937 document = node->ownerDocument;
2938 }
2939 // assert(!dynamic_cast<Document*>(node) || (dynamic_cast<Document*>(node)==document));
2940 Node* copy = clone_a_single_node(node, document, fallbackRegistry);
2941 if (parent != nullptr){
2942 pre_insert_node(copy, parent, nullptr);
2943 }
2944 if (subtree){
2945 for (auto child: node->childNodes.node_list){
2946 clone_node(child, document, subtree, copy, fallbackRegistry);
2947 }
2948 }
2949 // Element* temp = dynamic_cast<Element*>(node);
2950 // if (temp && temp->shadow_root!=nullptr && temp->shadow_root->clonable){
2951 // Element* temp2 = dynamic_cast<Element*>(copy);
2952 // assert(temp2->shadow_root==nullptr);
2953 // CustomElementRegistry* shadowRootRegistry = temp->shadow_root->custom_element_registry;
2954 // attach_shadow_root(temp2, temp->shadow_root->mode, true, temp->shadow_root->serializable, temp->shadow_root->delegatesFocus, temp->shadow_root->slotAssignment, shadowRootRegistry);
2955 // temp2->shadow_root->declarative = temp->shadow_root->declarative;
2956 // for (auto child: temp->shadow_root->childNodes){
2957 // clone_node(child, document, subtree, temp2->shadow_root);
2958 // }
2959 // }
2960 return copy;
2961}
2962
2963
2964Node* clone_a_single_node(Node* node, Document* document, CustomElementRegistry* fallbackRegistry){
2965 Node* copy = nullptr;
2966 // Element* temp = dynamic_cast<Element*>(node);
2967 Element* temp = nullptr;
2968 if (temp){
2969 // CustomElementRegistry* registry = temp->customElementRegistry;
2970 // if (!registry){ registry = fallbackRegistry; }
2971 // copy = create_element(document, temp->localName, temp->namespaceURI, temp->prefix, false, registry);
2972 // for (auto attr: temp->attributes.attribute_list){
2973 // Node* copyAttribute = clone_a_single_node(attr, document, nullptr);
2974 // append_attribute_to_element(copyAttribute, dynamic_cast<Element*>(copy));
2975 // }
2976 }
2977 else{
2978 // Document* temp = dynamic_cast<Document*>(node);
2979 // if (temp){
2980 // Document* temp2 = new Document();
2981 // temp2->encoding = temp->encoding;
2982 // temp2->contentType = temp->contentType;
2983 // temp2->URL = temp->URL;
2984 // temp2->origin = temp->origin;
2985 // temp2->type = temp->type;
2986 // temp2->mode = temp->mode;
2987 // temp2->allow_declarative_shodow_roots = temp->allow_declarative_shodow_roots;
2988 // // step for custom element registry is scoped
2989 // temp2->custom_element_registry = temp->custom_element_registry;
2990 // copy = dynamic_cast<Node*>(temp2);
2991 // }
2992 // else{
2993 // DocumentType* temp = dynamic_cast<DocumentType*>(node);
2994 // if (temp){
2995 // DocumentType* temp2 = new DocumentType();
2996 // temp2->name = temp->name;
2997 // temp2->publicId = temp->publicId;
2998 // temp2->systemId = temp->systemId;
2999 // copy = dynamic_cast<Node*>(temp2);
3000 // }
3001 // else{
3002 // Attr* temp = dynamic_cast<Attr*>(node);
3003 // if (temp){
3004 // Attr* temp2 = new Attr("something");
3005 // temp2->namespaceURI = temp->namespaceURI;
3006 // temp2->prefix = temp->prefix;
3007 // temp2->localName = temp->localName;
3008 // temp2->value = temp->value;
3009 // copy = dynamic_cast<Node*>(temp2);
3010 // }
3011 // else{
3012 // Text* temp = dynamic_cast<Text*>(node);
3013 // if (temp){}
3014 // else{
3015 // Comment* temp = dynamic_cast<Comment*>(node);
3016 // if (temp){
3017 // Comment* temp2 = new Comment();
3018 // temp2->data = temp->data;
3019 // copy = dynamic_cast<Node*>(temp2);
3020 // }
3021 // else{
3022 // ProcessingInstruction* temp = dynamic_cast<ProcessingInstruction*>(node);
3023 // if (temp){
3024 // ProcessingInstruction* temp2 = new ProcessingInstruction();
3025 // temp2->target = temp->target;
3026 // temp2->data = temp->data;
3027 // }
3028 // }
3029 // }
3030 // }
3031 // }
3032 // }
3033 }
3034 assert(dynamic_cast<Node*>(copy));
3035 // if (dynamic_cast<Document*>(node)){ document = dynamic_cast<Document*>(copy); }
3036 copy->ownerDocument = document;
3037 return copy;
3038}
3039
3040bool nodequals(Node* first, Node* second){
3041 if (typeid(first) != typeid(second)){
3042 return false;
3043 }
3044 Document* temp = nullptr;
3045 if (temp){
3046 // DocumentType* temp2 = dynamic_cast<DocumentType*>(second);
3047 // if (temp->getname()!=temp2->getname() || temp->getpublicId()!=temp2->getpublicId() || temp->getsystemId()!=temp2->getsystemId()){
3048 // return false;
3049 // }
3050 }
3051 else{
3052 // Element* temp = dynamic_cast<Element*>(first);
3053 // if (temp){
3054 // Element* temp2 = dynamic_cast<Element*>(second);
3055 // if (temp->namespaceURI!=temp2->namespaceURI || temp->prefix!=temp2->prefix || temp->localName!=temp2->localName){
3056 // return false;
3057 // }
3058 // }
3059 // else{
3060 // Attr* temp = dynamic_cast<Attr*>(first);
3061 // if (temp){
3062 // Attr* temp2 = dynamic_cast<Attr*>(second);
3063 // if (temp->namespaceURI!=temp2->namespaceURI || temp->localName!=temp2->localName || temp->value!=temp2->value){
3064 // return false;
3065 // }
3066 // }
3067 // else{
3068 // ProcessingInstruction* temp = dynamic_cast<ProcessingInstruction*>(first);
3069 // if (temp){
3070 // ProcessingInstruction* temp2 = dynamic_cast<ProcessingInstruction*>(second);
3071 // if (temp->target!=temp2->target || temp->data!=temp2->data){
3072 // return false;
3073 // }
3074 // }
3075 // else{
3076 // Comment* temp = dynamic_cast<Comment*>(first);
3077 // if (temp){
3078 // Comment* temp2 = dynamic_cast<Comment*>(second);
3079 // if (temp->data!=temp2->data){
3080 // return false;
3081 // }
3082 // }
3083 // }
3084 // }
3085 // }
3086 }
3087 // Element* temp = dynamic_cast<Element*>(first);
3088 // if (temp){
3089 // Element* temp2 = dynamic_cast<Element*>(second);
3090 // int i = 0;
3091 // for (auto attribute: temp->attributes.attribute_list){
3092 // if (attribute != temp2->attributes.attribute_list.at(i)){
3093 // return false;
3094 // }
3095 // i++;
3096 // }
3097 // }
3098 if (first->childNodes.length() != second->childNodes.length()){
3099 return false;
3100 }
3101 int i = 0;
3102 for (auto a: first->childNodes.node_list){
3103 if (!nodequals(a, second->childNodes[i])){
3104 return false;
3105 }
3106 i++;
3107 }
3108 return true;
3109}
3110
3111void string_replace_all(std::string &str, Node* parent){
3112 // Node* node = nullptr;
3113 // if (str!=""){
3114 // node = new Text(str);
3115 // node->ownerDocument = parent->ownerDocument;
3116 // }
3117 // replace_all(node, parent);
3118}
3119
3120
3121std::optional<DOMString> locate_a_namespace(Node* node, std::optional<DOMString> prefix){
3122 Element* temp = nullptr;
3123 if (temp){
3124 // if (prefix=="xml"){
3125 // return"http://www.w3.org/XML/1998/namespace";
3126 // }
3127 // if (prefix=="xmlns"){
3128 // return "http://www.w3.org/2000/xmlns/";
3129 // }
3130 // if (temp->namespaceURI.has_value() && temp->prefix==prefix){
3131 // return temp->namespaceURI;
3132 // }
3133 // for (auto attr: temp->attributes.attribute_list){
3134 // if ((attr->namespaceURI=="http://www.w3.org/2000/xmlns/" && attr->prefix=="xmlns" && attr->localName==prefix) || (!prefix.has_value() && attr->namespaceURI=="http://www.w3.org/2000/xmlns/" && !attr->prefix.has_value() && attr->localName=="xmlns")){
3135 // if (atr->value==""){ return std::nullopt; }
3136 // return attr->value;
3137 // }
3138 // }
3139 // if (temp->parentElement==nullptr){ return std::nullopt; }
3140 // return locate_a_namespace(temp->parentElement, prefix);
3141 }
3142 else{
3143 Document* temp = nullptr;
3144 if (temp){
3145 // if (temp->documentElement()){ return locate_a_namespace(temp->documentElement(), prefix); }
3146 // return std::nullopt;
3147 }
3148 // else{
3149 // DocumentType* temp = dynamic_cast<DocumentType*>(node);
3150 // if (temp){}
3151 // else{
3152 // DocumentFragment* temp = dynamic_cast<DocumentFragment*>(node);
3153 // if (temp){
3154 // return std::nullopt;
3155 // }
3156 // else{
3157 // Attr* temp = dynamic_cast<Attr*>(node);
3158 // if (temp){
3159 // if (temp->ownerElement==nullptr){ return nullptr; }
3160 // return locate_a_namespace(temp->ownerElement, prefix);
3161 // }
3162 // else{
3163 // if (node->parentElement==nullptr){ return std::nullopt; }
3164 // return locate_a_namespace(node->parentElement, prefix);
3165 // }
3166 // }
3167 // }
3168 // }
3169 }
3170 return std::nullopt;
3171}
3172
3173std::optional<DOMString> locate_a_namespace_prefix(Element* element, std::optional<DOMString> namesp){
3174 // if (element->namespaceURI==namespace && element->prefix.has_value()){
3175 // return element->prefix;
3176 // }
3177 // for (auto attr: element->attributes.attribute_list){
3178 // // if (attr->prefix=="xmlns" && attr->value==namesp){
3179 // // return attr->localName;
3180 // // }
3181 // }
3182 // if (element->parentElement!=nullptr){
3183 // return locate_a_namespace_prefix(element, namesp);
3184 // }
3185 return std::nullopt;
3186}
3187
3188// HTMLCollection* list_of_elements(DOMString qualifiedName, Node* root){
3189// // if (qualifiedName=="*"){}
3190// // if (root->ownerDocument->type!="xml"){}
3191// return new HTMLCollection();
3192// }
3193
3194// HTMLCollection* list_of_elements(std::optional<DOMString> namesp, DOMString localName, Node* root){
3195// // if (namesp==""){ namesp = std::nullopt; }
3196// // if (namesp=="*" && localName=="*"){}
3197// // if (namesp=="*"){}
3198// // if (localName=="*"){}
3199// return new HTMLCollection();
3200// }
3201
3202// HTMLCollection* list_of_elements(std::vector<DOMString> &classNames, Node* root){
3203// // std::vector<DOMString> classes;
3204// // for (auto class: classes){
3205// // auto something = ParseOrderedSet(class);
3206// // }
3207// return new HTMLCollection();
3208// }
3209
3210EventTarget* retard(EventTarget* a, EventTarget* b){
3211 auto temp = dynamic_cast<Node*>(a);
3212 if (!temp){
3213 return a;
3214 }
3215 if (!dynamic_cast<ShadowRoot*>(temp->getRootNode())){
3216 return a;
3217 }
3218 auto temp2 = dynamic_cast<Node*>(b);
3219 if (temp2 && (check_shadow_including_descendant(temp->getRootNode(), temp2, true))){
3220 return a;
3221 }
3222 auto temp3 = dynamic_cast<ShadowRoot*>(temp->getRootNode());
3223 if (temp3){
3224 a = temp3->host();
3225 }
3226 return retard(a,b);
3227}
3228
3229
3230int determine_node_length(Node* node){
3231 // if ((dynamic_cast<DocumentType*>(node)) || (dynamic_cast<Attr*>(node))){
3232 // return 0;
3233 // }
3234 // if (dynamic_cast<CharacterData*>(node)){
3235 // return node->data.length();
3236 // }
3237 return node->childNodes.node_list.size();
3238}
3239
3240// void update_slot_name(Element* element, DOMString &name, namespace = nullptr){
3241
3242// }
3243
3244Node* convert_nodes_to_node(std::vector<std::variant<Node*, DOMString>> nodes, Document* document) {
3245 Node* node = nullptr;
3246 int count = 0;
3247 for (auto a: nodes){
3248 if (std::holds_alternative<DOMString>(a)){
3249 // Text* temp = new Text(std::get<DOMString>(a));
3250 // temp->nodeDocument = document;
3251 // std::replace (nodes.begin(), nodes.end(), a, temp);
3252 }
3253 count++;
3254 }
3255 if (count==1){
3256 node = std::get<Node*>(nodes.at(0));
3257 }
3258 // else{
3259 // node = new DocumentFragment();
3260 // node->nodeDocument = document;
3261 // node->childNodes = nodes;
3262 // }
3263 return node;
3264}
3265
3266
3267bool check_ancestor(Node* node, Node* target, bool inclusive){
3268 if (inclusive && node->isSameNode(target)){
3269 return true;
3270 }
3271 if (node==nullptr || target==nullptr){
3272 return false;
3273 }
3274 Node* parent = node->parentNode;
3275 // while (!dynamic_cast<Document*>(parent) && parent!=nullptr){
3276 // if (parent == target){
3277 // return true;
3278 // }
3279 // parent = parent->parentNode;
3280 // }
3281 return false;
3282}
3283
3284bool check_descendant(Node* node, Node* target, bool inclusive){
3285 if (node==nullptr || target==nullptr){
3286 return false;
3287 }
3288 if (node->childNodes.length()==0){ return false; }
3289 if (inclusive && node->isSameNode(target)){
3290 return true;
3291 }
3292 Node* currentNode = node->childNodes[0];
3293 std::vector<Node*> temp = {currentNode};
3294 while (currentNode!=nullptr){
3295 if (currentNode == target){
3296 return true;
3297 }
3298 if (currentNode->childNodes.length()!=0){
3299 temp.push_back(currentNode);
3300 currentNode = currentNode->firstChild();
3301 continue;
3302 }
3303 currentNode = currentNode->nextSibling();
3304 while (currentNode==nullptr && !temp.empty()){
3305 currentNode = (*(temp.end() -1))->nextSibling();
3306 temp.erase(temp.end()-1);
3307 }
3308 }
3309 return false;
3310}
3311
3312bool check_node_precedes(Document* doc, Node* node, Node* target){
3313 if (doc==nullptr || node==nullptr || target==nullptr){
3314 return false;
3315 }
3316 // if (doc->childNodes.length()==0){ return false; }
3317 // Node* currentNode = doc->childNodes[0];
3318 // std::vector<Node*> temp = {currentNode};
3319 // while (currentNode!=nullptr){
3320 // if (currentNode == target){
3321 // return true;
3322 // }
3323 // if (currentNode == node){
3324 // break;
3325 // }
3326 // if (currentNode->childNodes.length()!=0){
3327 // temp.push_back(currentNode);
3328 // currentNode = currentNode->firstChild();
3329 // continue;
3330 // }
3331 // currentNode = currentNode->nextSibling();
3332 // while (currentNode==nullptr && !temp.empty()){
3333 // currentNode = (*(temp.end() -1))->nextSibling();
3334 // temp.erase(temp.end()-1);
3335 // }
3336 // }
3337 return false;
3338}
3339
3340
3341bool check_shadow_including_descendant(Node* node, Node* target, bool inclusive){
3342 if (node==nullptr || target==nullptr){
3343 return false;
3344 }
3345 if (check_descendant(node, target, inclusive)){ return true; }
3346 // ShadowRoot* temp = dynamic_cast<ShadowRoot*>(target->getRootNode());
3347 // if (temp){
3348 // return check_shadow_including_descendant(node, dynamic_cast<Node*>(temp->host()));
3349 // }
3350 return false;
3351}
3352
3353
3354bool is_closed_shadow_hidden(Node* A, Node* B){
3355 // ShadowRoot* temp = dynamic_cast<ShadowRoot*>(A->getRootNode());
3356 // if (temp){
3357 // if (!check_shadow_including_descendant(dynamic_cast<Node*>(temp), B, true)){
3358 // if (temp->mode==closed || is_closed_shadow_hidden(dynamic_cast<Node*>(temp->host()), B)){
3359 // return true;
3360 // }
3361 // }
3362 // }
3363 return false;
3364}
3365
3366Node* retarget(Node* A, Node* B){
3367 Node* temp;
3368 while (true){
3369 temp = A->getRootNode();
3370 // if (!dynamic_cast<Node*>(A) || !dynamic_cast<ShadowRoot*>(temp) || (dynamic_cast<Node*>(B) && check_shadow_including_descendant(B, temp))){
3371 // return A;
3372 // }
3373 // A = dynamic_cast<Node*>(dynamic_cast<ShadowRoot*>(temp)->host());
3374 return temp;
3375 }
3376}
3377
3378
3379bool host_including_inclusive_ancestor(Node* A, Node* B){
3380 if (check_ancestor(B, A, true)){
3381 return true;
3382 }
3383 // auto temp = dynamic_cast<ShadowRoot*>(B);
3384 // if (temp && temp->getRootNode()->host() && host_including_inclusive_ancestor(A, B->getRootNode()->host())){}
3385 return false;
3386}
3387
3388
3389void ensure_pre_insert_validity(Node* node, Node* parent, Node* child){
3390 if (!(dynamic_cast<Document*>(parent)) && !(dynamic_cast<DocumentFragment*>(parent)) && !(dynamic_cast<Element*>(parent))){
3391 throw HeirarchyRequestError("Shit boi !");
3392 }
3393
3394 if (host_including_inclusive_ancestor(node, parent)){
3395 throw HeirarchyRequestError("Shit boi !");
3396 }
3397
3398 if (child && child->parentNode != parent){
3399 throw NotFoundError("Not found fudge !");
3400 }
3401 if (!(dynamic_cast<DocumentFragment*>(node)) && !(dynamic_cast<DocumentType*>(node)) && !(dynamic_cast<Element*>(node)) && !(dynamic_cast<CharacterData*>(node))){
3402 throw HeirarchyRequestError("Shit boi !");
3403 }
3404 if ((dynamic_cast<Text*>(node) && dynamic_cast<Document*>(parent)) || (dynamic_cast<DocumentType*>(node) && !(dynamic_cast<Document*>(parent)))){
3405 throw HeirarchyRequestError("Shit boi !");
3406 }
3407 if (true){
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++; }
3413 }
3414 if (dynamic_cast<DocumentFragment*>(node)){
3415 int count = 0;
3416 bool has = false;
3417 for (auto a: node->childNodes.node_list){
3418 if (dynamic_cast<Element*>(a)){ count++; }
3419 if (dynamic_cast<Text*>(a)){ has = true; }
3420 }
3421 if (count>1 || has){
3422 throw HeirarchyRequestError("Shit boi !");
3423 }
3424 if (count==1){
3425 if (element_count>0 && dynamic_cast<DocumentType*>(child)){
3426 throw HeirarchyRequestError("Shit boi !");
3427 }
3428 }
3429 }
3430 else if (dynamic_cast<Element*>(node)){
3431 if (element_count>0 && dynamic_cast<DocumentType*>(child)){
3432 throw HeirarchyRequestError("Shit boi !");
3433 }
3434 }
3435 else if (dynamic_cast<DocumentType*>(node)){
3436 if (doctype_count>0 && child){
3437 throw HeirarchyRequestError("Shit boi !");
3438 }
3439 if (!child && element_count){
3440 throw HeirarchyRequestError("Shit boi !");
3441 }
3442 }
3443 }
3444}
3445
3446
3447
3448
3449Node* pre_insert_node(Node* node, Node* parent, Node* child){
3450 // ensure_pre_insert_validity(node, parent, child);
3451 Node* referenceChild = child;
3452 if (referenceChild == node){
3453 referenceChild = node->nextSibling();
3454 }
3455 insert_node(node, parent, referenceChild);
3456 return node;
3457}
3458
3459void insert_node(Node* node, Node* parent, Node* child, bool suppress_observers){
3460 NodeList* nodes;
3461 if (dynamic_cast<DocumentFragment*>(node)){
3462 nodes = &node->childNodes;
3463 }
3464 else{
3465 nodes = new NodeList();
3466 nodes->node_list.push_back(node);
3467 }
3468 int count = nodes->length();
3469 if (count==0){ return; }
3470 if (dynamic_cast<DocumentFragment*>(node)){
3471 remove_node(node);
3472 queue_tree_mutation_record(node, new NodeList(), nodes, nullptr, nullptr);
3473 }
3474 if (child){
3475 //TODO
3476 }
3477 Node* previousSibling;
3478 if (child){
3479 previousSibling = child->previousSibling();
3480 }
3481 else{
3482 previousSibling = parent->lastChild();
3483 }
3484 for (auto tempnode: nodes->node_list){
3485 // adopt(tempnode, parent->ownerDocument);
3486 if (!child){
3487 parent->childNodes.append(tempnode);
3488 }
3489 else{
3490 auto gg = std::find(parent->childNodes.node_list.begin(), parent->childNodes.node_list.end(), child);
3491 if (gg!=parent->childNodes.node_list.end()){
3492 // parent->childNodes.node_list.insert(parent->childNodes.node_list.begin()+index, node);
3493 }
3494 }
3495 // auto bro = dynamic_cast<Element*>(parent);
3496 // if (bro->shadow_root && bro->shadow_root->slotAssignment==named && (dynamic_cast<Element*>(node) || dynamic_cast<Node*>(node))){
3497 // assign_slot(node);
3498 // }
3499 // assign_slottables_for_tree(node->getRootNode());
3500 }
3501}
3502
3503
3504void remove_node(Node* node){}
3505
3506
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();
3512 bool found = false;
3513 while (prev){
3514 for (auto a: nodes){
3515 if (std::holds_alternative<Node*>(a)){
3516 if (std::get<Node*>(a)->isEqualNode(prev)){
3517 found = true;
3518 break;
3519 }
3520 }
3521 }
3522 if (!found){
3523 viablePreviousSibling = prev;
3524 break;
3525 }
3526 prev = prev->previousSibling();
3527 found = false;
3528 }
3529 DOMString kk = "";
3530 Node* node = new Node(ELEMENT_NODE, kk);
3531 if (viablePreviousSibling==nullptr){
3532 viablePreviousSibling = parent->firstChild();
3533 }
3534 else{
3535 viablePreviousSibling = viablePreviousSibling->nextSibling();
3536 }
3537 pre_insert_node(node, parent, viablePreviousSibling);
3538}
3539
3540
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();
3546 bool found = false;
3547 while (next){
3548 for (auto a: nodes){
3549 if (std::holds_alternative<Node*>(a)){
3550 if (std::get<Node*>(a)->isEqualNode(next)){
3551 found = true;
3552 break;
3553 }
3554 }
3555 }
3556 if (!found){
3557 viableNextSibling = next;
3558 break;
3559 }
3560 next = next->nextSibling();
3561 found = false;
3562 }
3563 DOMString kk = "";
3564 Node* node = new Node(ELEMENT_NODE, kk);
3565 pre_insert_node(node, parent, viableNextSibling);
3566}
3567
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();
3573 bool found = false;
3574 while (next){
3575 for (auto a: nodes){
3576 if (std::holds_alternative<Node*>(a)){
3577 if (std::get<Node*>(a)->isEqualNode(next)){
3578 found = true;
3579 break;
3580 }
3581 }
3582 }
3583 if (!found){
3584 viableNextSibling = next;
3585 break;
3586 }
3587 next = next->nextSibling();
3588 found = false;
3589 }
3590 // Node* node = convert_nodes_to_node(nodes, obj->ownerDocument);
3591 DOMString ff = "";
3592 Node* node = new Node(ELEMENT_NODE,ff);
3593 if (*obj->parentNode==*parent){
3594 replace(obj, node, parent);
3595 }
3596 else{
3597 pre_insert_node(node, parent, viableNextSibling);
3598 }
3599}
3600
3601void remove(Node* obj){
3602 if (obj->parentNode==nullptr){return;}
3603 remove_node(obj);
3604}
3605
3606Node* pre_remove_node(Node* child, Node* parent){
3607 return new Node(ELEMENT_NODE, "");
3608}
3609Node* replace_node(Node* node, Node* child, Node* parent){
3610 return new Node(ELEMENT_NODE, "");
3611}
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
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;
3628}
3629
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);
3633 this->type = type;
3634};
3635
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;
3640}
3641
3642inline void Event::stopPropagation(){
3643 this->stop_propagation_flag = true;
3644};
3645
3646inline void Event::stopImmediatePropagation(){
3647 this->stop_propagation_flag = true;
3648 this->stop_immediate_propagation_flag = true;
3649};
3650
3651inline void Event::set_canceled_flag(){
3652 if (this->cancelable && !this->in_passive_listener_flag){
3653 this->canceled_flag = true;
3654 }
3655};
3656
3657void Event::preventDefault(){
3658 // *Cancels the event (if it is cancelable).
3659 this->set_canceled_flag();
3660};
3661
3662void Event::initEvent(DOMString type, bool bubbles, bool cancelable){
3663 if (this->dispatch_flag){
3664 return;
3665 }
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;
3672 this->type = type;
3673 this->bubbles = bubbles;
3674 this->cancelable = cancelable;
3675}
3676
3677std::vector<EventTarget*> Event::composedPath(){
3678 std::vector<EventTarget*> composed_path = {};
3679 if (this->path.empty()){
3680 return composed_path;
3681 }
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++;
3689 }
3690 if (this->path[index].invocation_target==this->currentTarget){
3691 currentTargetIndex = index;
3692 break;
3693 }
3694 if (this->path[index].slot_in_closed_tree){
3695 currentTargetHiddenSubtreeLevel--;
3696 }
3697 }
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++;
3703 }
3704 if (currentHiddenLevel<=maxHiddenLevel){
3705 composed_path.insert(composed_path.begin(),this->path[index].invocation_target);
3706 }
3707 if (this->path[index].slot_in_closed_tree){
3708 currentHiddenLevel--;
3709 if (currentHiddenLevel<maxHiddenLevel){
3710 maxHiddenLevel = currentHiddenLevel;
3711 }
3712 }
3713 }
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++;
3719 }
3720 if (currentHiddenLevel<=maxHiddenLevel){
3721 composed_path.push_back(this->path[index].invocation_target);
3722 }
3723 if (this->path[index].root_of_closed_tree){
3724 currentHiddenLevel--;
3725 if (currentHiddenLevel<maxHiddenLevel){
3726 maxHiddenLevel = currentHiddenLevel;
3727 };
3728 }
3729 }
3730 return composed_path;
3731};
3732
3733
3734
3735
3736
3737
3738
3739
3740CustomEvent::CustomEvent(DOMString const type, std::any &detail, bool bubbles, bool cancelable, bool composed): Event(type, bubbles, cancelable, composed){
3741 this->detail = detail;
3742}
3743
3744void CustomEvent::initCustomEvent(DOMString const type, bool bubbles, bool cancelable, std::any detail){
3745 if (this->dispatch_flag){
3746 return;
3747 }
3748 this->initEvent(type, bubbles, cancelable);
3749 this->detail = detail;
3750}
3751
3752
3753Event* create_event(Event* eventInterface, Realm* realm){
3754 DOMHighResTimeStamp now = time(NULL);
3755 eventInterface->inner_event_creation_steps(eventInterface, realm, now);
3756 eventInterface->isTrusted = true;
3757 return eventInterface;
3758};
3759
3760
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);
3764}
3765
3766void EventTarget::removeEventListener(DOMString &type, EventListener* callback, bool capture){
3767 int i = 0;
3768 event_listener* el = new event_listener(type, callback, capture);
3769 for (event_listener* ev: this->event_listener_list){
3770 if (*ev == *el){
3771 remove_event_listener(this, el);
3772 }
3773 i++;
3774 }
3775}
3776
3777void EventTarget::removeAllEventListeners(){
3778 for (event_listener* a: event_listener_list){
3779 a->removed = true;
3780 delete a;
3781 }
3782 event_listener_list.clear();
3783}
3784
3785bool EventTarget::dispatchEvent(Event* event) {
3786 if (event->dispatch_flag || !event->initialized_flag){
3787 throw InvalidStateError("Invalid State");
3788 }
3789 event->isTrusted = false;
3790 return dispatch_event(event, this, false);
3791}
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802AbortController::AbortController(){
3803 this->signal = new AbortSignal();
3804}
3805
3806void AbortController::abort(std::any reason) const{
3807 signal_abort(this->signal, reason);
3808}
3809
3810AbortSignal* AbortSignal::abort(std::any reason) {
3811 AbortSignal* signal = new AbortSignal();
3812 if (reason.has_value()) {
3813 signal->reason = reason;
3814 }
3815 else {
3816 signal->reason = AbortError("Damn ! Abort error paji! ");
3817 }
3818 return signal;
3819}
3820
3821AbortSignal* AbortSignal::timeout(unsigned long long milliseconds) {
3822 AbortSignal* signal = new AbortSignal();
3824 // HTML stuff here againnnnnnnnnnnnnnn
3825 return signal;
3826}
3827
3828AbortSignal *AbortSignal::_any(std::vector<AbortSignal *> signals) {
3829 return create_dependent_abort_signal(signals);
3830}
3831
3832void AbortSignal::throwIfAborted() {
3833 if (this->isaborted()) {
3834 reason = nullptr;
3835 }
3836}
3837
3838
3839
3840Node* NodeList::item(const unsigned long index) const{
3841 try {
3842 return node_list.at(index);
3843 }
3844 catch (const std::out_of_range&) {
3845 return nullptr;
3846 }
3847}
3848
3849unsigned long NodeList::length() const{
3850 return node_list.size();
3851}
3852
3853bool NodeList::operator==(const NodeList* otherNodeList) const{
3854 if (this->length() != otherNodeList->length()){
3855 return false;
3856 }
3857 for (size_t i=0; i<this->length(); i++){
3858 if (this->item(i)->isEqualNode(otherNodeList->item(i))){
3859 continue;
3860 }
3861 return false;
3862 }
3863 return true;
3864}
3865
3866void NodeList::remove(Node* node){
3867 unsigned int i = 0;
3868 for (auto a: this->node_list){
3869 if (a->isEqualNode(node)){
3870 this->node_list.erase(this->node_list.begin()+i);
3871 return;
3872 }
3873 i++;
3874 }
3875}
3876
3877
3878NodeList::~NodeList(){
3879 for (auto a: node_list) {
3880 delete a;
3881 }
3882 node_list = {};
3883}
3884
3885
3886// Node
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);
3894 }
3895}
3896
3897bool inline Node::isConnected(){
3898 if (dynamic_cast<Document*>(this->getRootNode(true))){
3899 return true;
3900 }
3901 return false;
3902}
3903
3904Node* Node::getRootNode(bool composed){
3905 if (composed){
3906 auto temp = dynamic_cast<ShadowRoot*>(this);
3907 if (temp){
3908 return temp->host()->getRootNode(composed);
3909 }
3910 }
3911 if (this->parentNode){
3912 return this->parentNode->getRootNode(composed);
3913 }
3914 return this;
3915}
3916
3917inline bool Node::hasChildNodes() const{
3918 if (this->childNodes.length()==0){ return false; }
3919 return true;
3920}
3921
3922inline Node* Node::firstChild(){
3923 return this->childNodes[0];
3924}
3925inline Node* Node::lastChild(){
3926 return this->childNodes.item(this->childNodes.length()-1);
3927}
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; // no previous
3934 return vect[i - 1];
3935 }
3936 }
3937 }
3938 return nullptr;
3939}
3940
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; // no next
3947 return vect[i + 1];
3948 }
3949 }
3950 }
3951 return nullptr;
3952}
3953
3954Node* Node::get_the_parent(Event* event){
3955 Element* temp = dynamic_cast<Element*>(this);
3956 if (temp){
3957 if (temp->assignedSlot!=nullptr){
3958 return temp->assignedSlot;
3959 }
3960 }
3961 Text* temp2 = dynamic_cast<Text*>(this);
3962 if (temp2){
3963 if (temp2->assignedSlot!=nullptr){
3964 return temp2->assignedSlot;
3965 }
3966 }
3967 return this->parentNode;
3968}
3969
3970Node* Node::cloneNode(bool subtree){
3971 // node is self, document is nodeDocument, subtree is arg, parent is null, fallbackRegistry is null
3972 return clone_node(this,nullptr, subtree);
3973 //TODO
3974}
3975
3976bool Node::isEqualNode(Node* otherNode){
3977 if (otherNode==nullptr){ return false; }
3978 if (nodequals(this, otherNode)){
3979 return true;
3980 }
3981 return false;
3982}
3983
3984bool Node::isSameNode(Node* otherNode){
3985 if (otherNode==this){
3986 return true;
3987 }
3988 return false;
3989}
3990
3991unsigned short Node::compareDocumentPosition(Node* other){
3992 if (this->isSameNode(other)){
3993 return 0;
3994 }
3995 Node* node1 = other;
3996 Node* node2 = this;
3997 Attr* attr1 = nullptr;
3998 Attr* attr2 = nullptr;
3999 Attr* temp = dynamic_cast<Attr*>(node1);
4000 Element* temp2;
4001 if (temp){
4002 attr1 = temp;
4003 node1 = dynamic_cast<Node*>(attr1->ownerElement);
4004 temp2 = dynamic_cast<Element*>(attr1->ownerElement);
4005 }
4006 temp = dynamic_cast<Attr*>(node2);
4007 if (temp){
4008 attr2 = temp;
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;
4015 }
4016 if (nodequals(attr, attr2)){
4017 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_FOLLOWING;
4018 }
4019 }
4020 }
4021 }
4022 if (node1==nullptr || node2==nullptr || node1->getRootNode()!=node2->getRootNode()){
4023 return DOCUMENT_POSITION_DISCONNECTED + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_PRECEDING;
4024 }
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;
4027 }
4028 if ((check_descendant(node2, node1) && attr2==nullptr) || (node1==node2 && attr1!=nullptr)){
4029 return DOCUMENT_POSITION_CONTAINED_BY + DOCUMENT_POSITION_FOLLOWING;
4030 }
4031 if (check_node_precedes(node2->ownerDocument, node2, node1)){
4032 return DOCUMENT_POSITION_PRECEDING;
4033 }
4034 return DOCUMENT_POSITION_FOLLOWING;
4035}
4036
4037bool Node::contains(Node* other){
4038 if (other==nullptr){return false;}
4039 return check_descendant(this, other, true);
4040}
4041
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);
4046}
4047
4048std::optional<DOMString> Node::lookupNamespaceURI(std::optional<DOMString> &prefix){
4049 if (prefix==""){ prefix=std::nullopt; }
4050 return locate_a_namespace(this, prefix);
4051}
4052
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; }
4057 return false;
4058}
4059
4060Node* Node::insertBefore(Node* node, Node* child){
4061 return pre_insert_node(node, this, child);
4062}
4063
4064Node* Node::appendChild(Node* node){
4065 return pre_insert_node(node, this, nullptr);
4066}
4067
4068Node* Node::replaceChild(Node* node, Node* child){
4069 return replace_node(node, this, child);
4070}
4071
4072Node* Node::removeChild(Node* child){
4073 return pre_remove_node(child, this);
4074}
4075
4076
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();
4084 if (length==0){
4085 remove_node(currentNode);
4086 }
4087 else{
4088
4089 }
4090 }
4091 if (currentNode->childNodes.length()!=0){
4092 temp.push_back(currentNode);
4093 currentNode = currentNode->firstChild();
4094 continue;
4095 }
4096 currentNode = currentNode->nextSibling();
4097 while (currentNode==nullptr && !temp.empty()){
4098 currentNode = (*(temp.end() -1))->nextSibling();
4099 temp.erase(temp.end()-1);
4100 }
4101 }
4102}
4103
4104Element* HTMLCollection::item(const unsigned long &index) const{
4105 try {
4106 return element_list.at(index);
4107 }
4108 catch (const std::out_of_range&) {
4109 return nullptr;
4110 }
4111}
4112
4113Element* HTMLCollection::namedItem(const DOMString &name) const{
4114 if (name=="") {
4115 return nullptr;
4116 }
4117 for (auto element: element_list) {
4120 if (element->id==name) {
4121 return element;
4122 }
4123 }
4124 return nullptr;
4125}
4126
4127unsigned long HTMLCollection::length() const{
4128 return element_list.size();
4129}
4130
4131HTMLCollection::~HTMLCollection(){
4132 for (auto a: element_list) {
4133 delete a;
4134 }
4135 element_list.clear();
4136}
4137
4138
4139
4140void ParentNode::prepend(std::vector<std::variant<Node*, DOMString>> &nodes) {
4141 DOMString kk = "";
4142 Node* temp = new Node(ELEMENT_NODE, kk);
4143 // Node* temp = convert_nodes_to_node(nodes, this->ownerDocument);
4144 auto smth = dynamic_cast<Node*>(this);
4145 pre_insert_node(temp, dynamic_cast<Node*>(this), smth->firstChild());
4146}
4147
4148void ParentNode::append(std::vector<std::variant<Node*, DOMString>> &nodes){
4149 DOMString kk = "";
4150 Node* temp = new Node(ELEMENT_NODE, kk);
4151 // Node* temp = convert_nodes_to_node(nodes, this->ownerDocument);
4152 pre_insert_node(temp, dynamic_cast<Node*>(this), nullptr);
4153}
4154
4155void ParentNode::replaceChildren(std::vector<std::variant<Node*, DOMString>> &nodes){
4156 DOMString kk = "";
4157 Node* temp = new Node(ELEMENT_NODE, kk);
4158 // Node* temp = convert_nodes_to_node(nodes, this->ownerDocument);
4159 ensure_pre_insert_validity(temp, dynamic_cast<Node*>(this), nullptr);
4160 replace_all(temp, dynamic_cast<Node*>(this));
4161}
4162
4163void ParentNode::moveBefore(Node* node, Node* child){
4164 Node* referenceChild = child;
4165 if (*referenceChild == *node){
4166 referenceChild = node->nextSibling();
4167 }
4168 move_node(node, dynamic_cast<Node*>(this), referenceChild);
4169}
4170
4171
4172
4173
4174
4175
4176Element* Element::previousElementSibling(){
4177 auto smth = dynamic_cast<Node*>(this);
4178 Node* prev = smth->previousSibling();
4179 while (prev){
4180 auto bro = dynamic_cast<Element*>(prev);
4181 if (bro){
4182 return bro;
4183 }
4184 prev = prev->previousSibling();
4185 }
4186 return nullptr;
4187}
4188
4189Element* Element::nextElementSibling(){
4190 auto smth = dynamic_cast<Node*>(this);
4191 Node* next = smth->nextSibling();
4192 while (next){
4193 auto bro = dynamic_cast<Element*>(next);
4194 if (bro){
4195 return bro;
4196 }
4197 next = next->nextSibling();
4198 }
4199 return nullptr;
4200}
4201
4202Element* CharacterData::previousElementSibling(){
4203 auto smth = dynamic_cast<Node*>(this);
4204 Node* prev = smth->previousSibling();
4205 while (prev){
4206 if (dynamic_cast<Element*>(prev)){
4207 return dynamic_cast<Element*>(prev);
4208 }
4209 prev = prev->previousSibling();
4210 }
4211 return nullptr;
4212}
4213
4214Element* CharacterData::nextElementSibling(){
4215 auto smth = dynamic_cast<Node*>(this);
4216 Node* next = smth->nextSibling();
4217 while (next){
4218 if (dynamic_cast<Element*>(next)){
4219 return dynamic_cast<Element*>(next);
4220 }
4221 next = next->nextSibling();
4222 }
4223 return nullptr;
4224}
4225
4226
4227
4228
4229
4230DOMString* Document::lookupPrefix(std::optional<DOMString> namesp){
4231 if (namesp==std::nullopt || namesp.value()==""){ return nullptr; }
4232 if (this->documentElement()==nullptr){ return nullptr; }
4233 // return locate_a_namespace_prefix(this->documentElement() , namesp);
4234 DOMString k = "";
4235 return nullptr;
4236}
4237
4238
4239DOMString Document::compatMode(){
4240 if (this->mode==QUIRKS){
4241 return "BackCompat";
4242 }
4243 return "CSS1Compat";
4244}
4245
4246DocumentType* Document::doctype(){
4247 for (size_t i=0; i<this->childNodes.length(); i++){
4248 DocumentType* temp = dynamic_cast<DocumentType*>(this->childNodes[i]);
4249 if (temp){
4250 return temp;
4251 }
4252 }
4253 return nullptr;
4254}
4255
4256Element* Document::documentElement(){
4257 for (size_t i=0; i<this->childNodes.length(); i++){
4258 Element* temp = dynamic_cast<Element*>(this->childNodes[i]);
4259 if (temp){
4260 return temp;
4261 }
4262 }
4263 return nullptr;
4264}
4265
4266
4267
4268HTMLCollection* Document::getElementsByTagName(DOMString qualifiedName){
4269 // return list_of_elements(qualifiedName, dynamic_cast<Node*>(this));
4270 return new HTMLCollection();
4271}
4272
4273HTMLCollection* Document::getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localname){
4274 // return list_of_elements(namesp, localname, dynamic_cast<Node*>(this));
4275 return new HTMLCollection();
4276}
4277
4278HTMLCollection* Document::getElementsByClassName(std::vector<DOMString> &classNames){
4279 // return list_of_elements(classNames, dynamic_cast<Node*>(this));
4280 return new HTMLCollection();
4281}
4282
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); });
4287 }
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";
4294 }
4295 else{
4296 namesp = std::nullopt;
4297 }
4298 // return create_element(this, localName, namesp, std::nullopt, is, true, registry);
4299 return new Element("","","");
4300}
4301
4302Element* Document::createElementNS(std::optional<DOMString> namesp, DOMString qualifiedName, std::variant<DOMString,ElementCreationOptions> options){
4303 return internal_create_element_ns(this, namesp, qualifiedName, options);
4304}
4305
4306DocumentFragment* Document::createDocumentFragment(){
4307 DocumentFragment* temp = new DocumentFragment();
4308 // temp->ownerDocument = this;
4309 return temp;
4310}
4311
4312Text* Document::createTextNode(DOMString data){
4313 Text* temp = new Text(data);
4314 // temp->ownerDocument = this;
4315 return temp;
4316}
4317
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);
4323 // temp->ownerDocument = this;
4324 return temp;
4325}
4326
4327Comment* Document::createComment(DOMString data){
4328 Comment* temp = new Comment(data);
4329 // temp->ownerDocument = this;
4330 return temp;
4331}
4332
4333ProcessingInstruction* Document::createProcessingInstruction(DOMString target, DOMString data){
4334 // If target doesn't match some Name production, throw InvalidCharacterError exception
4335 if (data.find("?>") != std::string::npos){ throw InvalidCharacterError("Invalid Characters !"); }
4336 ProcessingInstruction* temp = new ProcessingInstruction();
4337 temp->target = target;
4338 temp->setdata(data);
4339 // temp->ownerDocument = this;
4340 return temp;
4341}
4342
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); }
4348 else{
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 :) !"); }
4353 }
4354 return clone_node(node, this, subtree, nullptr, registry);
4355}
4356
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){
4362 return nullptr;
4363 }
4364 adopt(node, this);
4365 return node;
4366}
4367
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); });
4372 }
4373 Attr* temp = new Attr(localName);
4374 // temp->ownerDocument = this;
4375 return temp;
4376}
4377
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;
4385 // temp->ownerDocument = this;
4386 return temp;
4387}
4388
4389Event* Document::createEvent(DOMString interface){
4390 Event* constructor = nullptr;
4391 if (constructor==nullptr){
4392 throw NotSupportedError("Not supported :)) !!");
4393 }
4394 return constructor;
4395}
4396
4397Range* createRange(){
4398 Range* temp = new Range();
4399 return temp;
4400}
4401
4402NodeIterator* createNodeIterator(Node* root, unsigned long whatToShow, NodeFilter* filter){
4403 NodeIterator* iterator = new NodeIterator();
4404 return iterator;
4405}
4406
4407TreeWalker* createTreeWalker(Node* root, unsigned long whatToShow, NodeFilter* filter){
4408 TreeWalker* walker = new TreeWalker();
4409 return walker;
4410}
4411
4412
4413
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);
4417 // temp->ownerDocument = this->associated_doc;
4418 return temp;
4419}
4420
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());
4426 }
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";
4432 }
4433 else if (namesp.value()=="http://www.w3.org/2000/svg"){
4434 document->contentType = "image/svg+xml";
4435 }
4436 else{
4437 document->contentType = "application/xml";
4438 }
4439 return document;
4440}
4441
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);
4459 }
4460 return document;
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;
4463 return document;
4464}
4465
4466
4467
4468bool DOMImplementation::hasFeature(){ return true; }
4469
4470
4471
4472
4473bool Element::hasAttributes(){
4474 if (this->attributes.attribute_list.size()==0){
4475 return false;
4476 }
4477 return true;
4478}
4479
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);
4485 }
4486 else{
4487 attribute_qualified_names.push_back(a->prefix.value() + ":" + a->localName);
4488 }
4489 }
4490 return attribute_qualified_names;
4491}
4492
4493
4494std::optional<DOMString> Element::getAttribute(DOMString qualifiedName){
4495 Attr* attr = fetch_attribute(qualifiedName, this);
4496 if (attr==nullptr){ return std::nullopt; }
4497 return attr->value;
4498}
4499
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; }
4503 return attr->value;
4504}
4505
4506
4507void Element::setAttribute(DOMString qualifiedName, DOMString value){
4508 if (!valid_attribute_local_name(qualifiedName)){ throw InvalidCharacterError("Invalid name for attribute !!"); }
4509 //later !
4510 // if (this->ownerDocument->type!=XML){
4511 // std::transform(qualifiedName.begin(), qualifiedName.end(), qualifiedName.begin(), [](unsigned char c){ return std::tolower(c); });
4512 // }
4513 Attr* attribute = nullptr;
4514 for (auto attr: this->attributes.attribute_list){
4515 DOMString qualif;
4516 if (attr->prefix == std::nullopt){
4517 qualif = attr->localName;
4518 }
4519 else{
4520 qualif = attr->prefix.value() + ":" + attr->localName;
4521 }
4522 if (qualif==qualifiedName){
4523 attribute = attr;
4524 break;
4525 }
4526 }
4527 if (attribute==nullptr){
4528 Attr* temp = new Attr(qualifiedName);
4529 temp->value = value;
4530 // temp->ownerDocument = this->ownerDocument;
4531 append_attribute(temp, this);
4532 return;
4533 }
4534 change_attribute_value(attribute, value);
4535}
4536
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);
4542}
4543
4544void Element::removeAttribute(DOMString qualifiedName){
4545 remove_attribute_by_name(qualifiedName, this);
4546}
4547
4548void Element::removeAttributeNS(std::optional<DOMString> namesp, DOMString localName){
4549 remove_attribute_by_namespace(namesp, localName, this);
4550}
4551
4552
4553bool Element::hasAttribute(DOMString qualifiedName){
4554 // if (this->ownerDocument->type!=XML){
4555 // std::transform(qualifiedName.begin(), qualifiedName.end(), qualifiedName.begin(), [](unsigned char c){ return std::tolower(c); });
4556 // }
4557 for (auto attr: this->attributes.attribute_list){
4558 DOMString qualif;
4559 if (attr->prefix == std::nullopt){
4560 qualif = attr->localName;
4561 }
4562 else{
4563 qualif = attr->prefix.value() + ":" + attr->localName;
4564 }
4565 if (qualif==qualifiedName){
4566 return true;
4567 }
4568 }
4569 return false;
4570}
4571
4572bool Element::toggleAttribute(DOMString qualifiedName, std::optional<bool> force){
4573 if (!valid_attribute_local_name(qualifiedName)){ throw InvalidCharacterError("Invalid Attribute Name boi !"); }
4574 // if (this->ownerDocument->type!=XML){
4575 // std::transform(qualifiedName.begin(), qualifiedName.end(), qualifiedName.begin(), [](unsigned char c){ return std::tolower(c); });
4576 // }
4577 Attr* attribute = nullptr;
4578 for (auto attr: this->attributes.attribute_list){
4579 DOMString qualif;
4580 if (attr->prefix == std::nullopt){
4581 qualif = attr->localName;
4582 }
4583 else{
4584 qualif = attr->prefix.value() + ":" + attr->localName;
4585 }
4586 if (qualif==qualifiedName){
4587 attribute = attr;
4588 break;
4589 }
4590 }
4591 if (attribute==nullptr){
4592 if (!force.has_value() || (force.has_value() && force.value()==true)){
4593 Attr* temp = new Attr(qualifiedName);
4594 temp->value = "";
4595 // temp->ownerDocument = this->ownerDocument;
4596 append_attribute(temp, this);
4597 return true;
4598 }
4599 return false;
4600 }
4601 if (!force.has_value() || (force.has_value() && force.value()==false)){
4602 remove_attribute_by_name(qualifiedName, this);
4603 return false;
4604 }
4605 return true;
4606}
4607
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){
4612 return true;
4613 }
4614 }
4615 return false;
4616}
4617
4618
4619Attr* Element::getAttributeNode(DOMString qualifiedName){
4620 return fetch_attribute(qualifiedName, this);
4621}
4622
4623Attr* Element::getAttributeNodeNS(std::optional<DOMString> namesp, DOMString localName){
4624 return fetch_attribute(namesp, localName, this);
4625}
4626
4627Attr* Element::setAttributeNode(Attr* attr){
4628 return set_attribute(attr, this);
4629}
4630
4631Attr* Element::setAttributeNodeNS(Attr* attr){
4632 return set_attribute(attr, this);
4633}
4634
4635Attr* Element::removeAttributeNode(Attr* attr){
4636 bool found = false;
4637 for (auto a: this->attributes.attribute_list){
4638 if (a==attr){ found = true; }
4639 }
4640 if (!found){ throw NotFoundError("Attribute Not Found !"); }
4641 remove_attribute(attr);
4642 return attr;
4643}
4644
4645
4646ShadowRoot* Element::attachShadow(ShadowRootInit init){
4647 CustomElementRegistry* registry = this->customElementRegistry;
4648 if (init.customElementRegistry!=nullptr){
4649 registry = init.customElementRegistry;
4650 // if (registry!=this->ownerDocument->custom_element_registry){ throw NotSupportedError("This ain't supported !"); }
4651 }
4652 attach_shadow_root(this, init.mode, init.clonable, init.serializable, init.delegatesFocus, init.slotAssignment, *registry);
4653 return this->getshadow_root();
4654}
4655
4656Element* Element::insertAdjacentElement(DOMString where, Element element){
4657 // return dynamic_cast<Element*>(insert_adjacent(this, where, dynamic_cast<Node*>(element)));
4658 return new Element("","","");
4659}
4660
4661void Element::insertAdjacentText(DOMString where, DOMString data){
4662 // Text* text = new Text(data);
4663 // text->ownerDocument = this->ownerDocument;
4664 // insert_adjacent(this, where, dynamic_cast<Node*>(text));
4665}
4666
4667HTMLCollection* Element::getElementsByTagName(DOMString qualifiedName){
4668 // return list_of_elements(qualifiedName, dynamic_cast<Node*>(this));
4669 return new HTMLCollection();
4670}
4671
4672HTMLCollection* Element::getElementsByTagNameNS(std::optional<DOMString> namesp, DOMString localName){
4673 // return list_of_elements(namesp, localName, dynamic_cast<Node*>(this));
4674 return new HTMLCollection();
4675}
4676
4677HTMLCollection* Element::getElementsByClassName(DOMString classNames){
4678 // return list_of_elements(classNames, dynamic_cast<Node*>(this));
4679 return new HTMLCollection();
4680}
4681
4682
4683
4684Attr* NamedNodeMap::item(unsigned long index){
4685 try {
4686 return attribute_list.at(index);
4687 }
4688 catch (const std::out_of_range&) {
4689 return nullptr;
4690 }
4691}
4692
4693
4694unsigned long NamedNodeMap::length(){
4695 return attribute_list.size();
4696}
4697
4698Attr* NamedNodeMap::getNamedItem(DOMString qualifiedName){
4699 return fetch_attribute(qualifiedName, this->associatedElement);
4700}
4701
4702Attr* NamedNodeMap::getNamedItemNS(std::optional<DOMString> namesp, DOMString localName){
4703 return fetch_attribute(namesp, localName, this->associatedElement);
4704}
4705
4706Attr* NamedNodeMap::setNamedItem(Attr* attr){
4707 return set_attribute(attr, this->associatedElement);
4708}
4709
4710Attr* NamedNodeMap::setNamedItemNS(Attr* attr){
4711 return set_attribute(attr, this->associatedElement);
4712}
4713
4714Attr* NamedNodeMap::removeNamedItem(DOMString qualifiedName){
4715 Attr* attr = remove_attribute_by_name(qualifiedName, this->associatedElement);
4716 if (attr==nullptr){ throw NotFoundError("Attribute not found !!"); }
4717 return attr;
4718}
4719
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 !!"); }
4723 return attr;
4724}
4725
4726
4727
4728Attr::Attr(DOMString localName): Node(ATTRIBUTE_NODE, this->qualifiedName()){
4729 this->localName = localName;
4730}
4731
4732DOMString Attr::qualifiedName(){
4733 if (this->prefix==std::nullopt){
4734 return this->localName;
4735 }
4736 return this->prefix.value() + ":" + this->localName;
4737}
4738
4739
4740unsigned long CharacterData::length(){
4741 return this->data.length();
4742}
4743
4744DOMString CharacterData::substringData(unsigned long offset, unsigned long count){
4745 return substring_data(dynamic_cast<Node*>(this), offset, count);
4746}
4747
4748void CharacterData::appendData(DOMString data){
4749 replace_data(dynamic_cast<Node*>(this), this->length(), 0, data);
4750}
4751
4752void CharacterData::insertData(unsigned long offset, DOMString data){
4753 replace_data(dynamic_cast<Node*>(this), offset, 0, data);
4754}
4755
4756void CharacterData::deleteData(unsigned long offset, unsigned long count){
4757 replace_data(dynamic_cast<Node*>(this), offset, count, "");
4758}
4759
4760void CharacterData::replaceData(unsigned long offset, unsigned long count, DOMString data){
4761 replace_data(dynamic_cast<Node*>(this), offset, count, data);
4762}
4763
4764
4765Text* Text::splitText(unsigned long offset){
4766 return split_text_node(this, offset);
4767}
4768
4769DOMString Text::wholeText(){
4770 DOMString data = "";
4771 for (auto a: contiguous_text_nodes(this)){
4772 data += this->data;
4773 }
4774 return data;
4775}
4776
4777
4778
4779
4780bool AbstractRange::collapsed(){
4781 if (this->startContainer==this->endContainer && this->startOffset==this->endOffset){
4782 return true;
4783 }
4784 return false;
4785}
4786
4787
4788StaticRange::StaticRange(StaticRangeInit init){
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 !!");
4791 }
4792 this->startContainer = init.startContainer;
4793 this->startOffset = init.startOffset;
4794 this->endContainer = init.endContainer;
4795 this->endOffset = init.endOffset;
4796}
4797
4798Range::Range(){};
4799
4800Node* Range::commonAncestorContainer(){
4801 Node* container = this->startContainer;
4802 while (!check_ancestor(this->endContainer, container, true)){
4803 container = container->parentNode;
4804 }
4805 return container;
4806}
4807
4808
4809void Range::setStart(Node* node, unsigned long offset){
4810 set_start_end(this, node, offset);
4811}
4812
4813void Range::setEnd(Node* node, unsigned long offset){
4814 set_start_end(this, node, offset, false);
4815}
4816
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());
4821}
4822
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);
4827}
4828
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);
4833}
4834
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);
4839}
4840
4841void Range::collapse(bool toStart){
4842 if (toStart){
4843 this->endContainer = this->startContainer;
4844 this->endOffset = this->startOffset;
4845 }
4846 else{
4847 this->startContainer = this->endContainer;
4848 this->startOffset = this->endOffset;
4849 }
4850}
4851
4852void Range::selectNode(Node* node){
4853 select_node_within_rangee(node, this);
4854}
4855
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;
4863}
4864
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 !");
4868 }
4869 if (this->startContainer->getRootNode()!=sourceRange->startContainer->getRootNode()){
4870 throw WrongDocumentError("wrong document ! read it u sick boi !!");
4871 }
4872 Node* thisnode;
4873 unsigned long thisoffset;
4874 Node* othernode;
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;
4881 }
4882 else if (how==START_TO_END){
4883 thisnode = this->endContainer;
4884 thisoffset = this->endOffset;
4885 othernode = sourceRange->startContainer;
4886 otheroffset = sourceRange->startOffset;
4887 }
4888 else if (how==END_TO_END){
4889 thisnode = this->endContainer;
4890 thisoffset = this->endOffset;
4891 othernode = sourceRange->endContainer;
4892 otheroffset = sourceRange->endOffset;
4893 }
4894 else if (how==END_TO_START){
4895 thisnode = this->startContainer;
4896 thisoffset = this->startOffset;
4897 othernode = sourceRange->endContainer;
4898 otheroffset = sourceRange->endOffset;
4899 }
4900 return position(thisnode, thisoffset, othernode, otheroffset);
4901}
4902
4903
4904void Range::deleteContents(){
4905 if (this->collapsed()){
4906 return;
4907 }
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;
4912
4913 if (original_startnode==original_endnode && dynamic_cast<CharacterData*>(original_startnode)){
4914 replace_data(original_startnode, original_startoffset, original_endoffset - original_startoffset, "");
4915 return;
4916 }
4917 std::vector<Node*> nodes_to_remove = {};
4918 Node* new_node;
4919 unsigned long new_offset;
4920 if (check_ancestor(original_endnode, original_startnode, true)){
4921 new_node = original_startnode;
4922 new_offset = original_startoffset;
4923 }
4924 else{
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;
4928 }
4929 new_node = reference_node->parentNode;
4930 new_offset = reference_node->index() + 1;
4931 }
4932 if (dynamic_cast<CharacterData*>(original_startnode)){
4933 replace_data(original_startnode, original_startoffset, original_startnode->length() - original_startoffset, "");
4934 }
4935 for (auto node: nodes_to_remove){
4936 remove_node(node);
4937 }
4938 if (dynamic_cast<CharacterData*>(original_endnode)){
4939 replace_data(original_endnode, 0, original_endoffset, "");
4940 }
4941 this->startContainer = new_node;
4942 this->startOffset = new_offset;
4943 this->endContainer = new_node;
4944 this->endOffset = new_offset;
4945}
4946
4947DocumentFragment* Range::extraContents(){
4948 return new DocumentFragment();
4949}
4950
4951DocumentFragment* Range::cloneContents(){
4952 return new DocumentFragment();
4953}
4954
4955void Range::insertNode(Node* node){
4956 insert_node_in_range(node, this);
4957}
4958
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 !!");
4962 }
4963 DocumentFragment* fragment = extract_range(this);
4964 if (newParent->hasChildNodes()){
4965 replace_all(nullptr, newParent);
4966 }
4967 insert_node_in_range(newParent, this);
4968 pre_insert_node(dynamic_cast<Node*>(fragment), newParent, nullptr);
4969 select_node_within_rangee(newParent, this);
4970}
4971
4972
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;
4979 return temp;
4980}
4981
4982bool Range::isPointInRange(Node* node, unsigned long offset){
4983 if (node->getRootNode()!=this->startContainer->getRootNode()){
4984 return false;
4985 }
4986 if (dynamic_cast<DocumentType*>(node)){
4987 throw InvalidNodeTypeError("u got from the name !");
4988 }
4989 if (offset>node->length()){
4990 throw IndexSizeError("index is not fit !!");
4991 }
4992 if (position(node, offset, this->startContainer, this->startOffset)==-1 || position(node, offset, this->endContainer, this->endOffset)==1){
4993 return false;
4994 }
4995 return true;
4996}
4997
4998
4999short Range::comparePoint(Node* node, unsigned long offset){
5000 if (node->getRootNode()!=this->startContainer->getRootNode()){
5001 throw WrongDocumentError("Wrong document !!");
5002 }
5003 if (dynamic_cast<DocumentType*>(node)){
5004 throw InvalidNodeTypeError("invalid node type !!");
5005 }
5006 if (offset>node->length()){
5007 throw IndexSizeError("index size issue !!");
5008 }
5009 if (position(node, offset, this->startContainer, this->startOffset)==-1){
5010 return -1;
5011 }
5012 if (position(node, offset, this->endContainer, this->endOffset)==1){
5013 return 1;
5014 }
5015 return 0;
5016}
5017
5018
5019bool Range::intersectsNode(Node* node){
5020 if (node->getRootNode()!=this->startContainer->getRootNode()){
5021 return false;
5022 }
5023 Node* parent = node->parentNode;
5024 if (parent==nullptr){
5025 return true;
5026 }
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){
5029 return true;
5030 }
5031 return false;
5032}
5033
5034DOMString Range::stringification_behavior(){
5035 DOMString s = "";
5036 Text* temp = dynamic_cast<Text*>(this->startContainer);
5037 if (this->startContainer==this->endContainer && temp){
5038 // return temp->getdata().substr(this->startOffset, this->endOffset - this->startOffset);
5039 }
5040 if (temp){
5041 // s += temp->getdata().substr(this->startOffset);
5042 }
5043 temp = dynamic_cast<Text*>(this->endContainer);
5044 if (temp){
5045 // s += temp->getdata().substr(0, this->endOffset);
5046 }
5047 return s;
5048}
5049
5050
5051
5052unsigned short NodeIterator::filter_node(Node* node){
5054
5055 // if (this->active){ throw InvalidStateError("INVALID STATE ! HAHA"); }
5056 // int n = node->nodeType - 1;
5057 // if (this->filter==nullptr){
5058 // return FILTER_ACCEPT;
5059 // }
5060 // this->active = true;
5061 // //some work
5062 // this->active = false;
5063 // return result;
5064 return 1;
5065}
5066
5067unsigned short TreeWalker::filter_node(Node* node){
5069
5070 // if (this->active){ throw InvalidStateError("INVALID STATE ! HAHA"); }
5071 // int n = node->nodeType - 1;
5072 // if (this->filter==nullptr){
5073 // return FILTER_ACCEPT;
5074 // }
5075 // this->active = true;
5076 // //some work
5077 // this->active = false;
5078 // return result;
5079 return 1;
5080}
5081
5082
5083
5084//Node* NodeIterator::nextNode(){
5085// return traverse(this, 1);
5086//}
5087
5088//Node* NodeIterator::previousNode(){
5089// return traverse(this, -1);
5090//}
5091
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;
5098 return node;
5099 }
5100 }
5101 return nullptr;
5102}
5103
5104//Node* TreeWalker::firstChild(){
5105// return traverse_children(this, 1);
5106//}
5107
5108//Node* TreeWalker::lastChild(){
5109// return traverse_children(this, -1);
5110//}
5111
5112
5113//Node* TreeWalker::nextSibling(){
5114// return traverse_sibling(this, 1);
5115//}
5116
5117//Node* TreeWalker::previousSibling(){
5118// return traverse_sibling(this, -1);
5119//}
5120
5121//Node* TreeWalker::previousNode(){
5122// Node* node = this->currentNode;
5123// while (node!=this->root){
5124// Node* sibling = node->previousSibling();
5125// while (sibling!=nullptr){
5126// node = sibling;
5127// int result = this->filter_node(node);
5128// while (result!="FILTER_REJECT" && node->hasChildNodes()){
5129// node = node->lastChild();
5130// result = this->filter_node(node);
5131// }
5132// if (result==FILTER_ACCEPT){
5133// this->currentNode = node;
5134// return node;
5135// }
5136// sibling = node->previousSibling();
5137// }
5138// if (node==this->root || node->parentNode==nullptr){
5139// return nullptr;
5140// }
5141// // node = node->parentNode();
5142// // if (this->filter_node(node)==FILTER_ACCEPT){
5143// // this->currentNode = node;
5144// // return node;
5145// //}
5146// }
5147// return nullptr;
5148//}
5149
5150
5151Node* TreeWalker::nextNode(){
5152 Node* node = this->currentNode;
5153 unsigned short result = FILTER_ACCEPT;
5154 while (true){
5155 while (result!=FILTER_REJECT && node->hasChildNodes()){
5156 node = node->firstChild();
5157 result = this->filter_node(node);
5158 if (result == FILTER_ACCEPT){
5159 this->currentNode = node;
5160 return node;
5161 }
5162 }
5163 Node* sibling = nullptr;
5164 Node* temporary = node;
5165 while (temporary!=nullptr){
5166 if (temporary==this->root){
5167 return nullptr;
5168 }
5169 sibling = temporary->nextSibling();
5170 if (sibling!=nullptr){
5171 node = sibling;
5172 break;
5173 }
5174 temporary = temporary->parentNode;
5175 }
5176 result = this->filter_node(node);
5177 if (result==FILTER_ACCEPT){
5178 this->currentNode = node;
5179 return node;
5180 }
5181 }
5182}
5183
5184
5185
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 !"); }
5190 }
5191 for (auto token: tokens){
5192 this->list.insert(token);
5193 }
5194 this->update();
5195}
5196
5197
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 !"); }
5202 }
5203 for (auto token: tokens){
5204 this->list.erase(token);
5205 }
5206 this->update();
5207}
5208
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);
5215 this->update();
5216 return true;
5217 }
5218 }
5219 else{
5220 if (!force.has_value() || force){
5221 this->list.insert(token);
5222 this->update();
5223 return true;
5224 }
5225 }
5226 return false;
5227}
5228
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);
5235 this->update();
5236 return true;
5237}
5238
5239
5240bool DOMTokenList::supports(DOMString token){
5241 return this->validate(token);
5242}
5243
5244
5245
5246
5247
5248
5249// int main(){
5250// std::cout<<"La lala lalalalalalala";
5251// }
static AbortSignal * timeout(unsigned long long milliseconds)
Definition Webelo.cpp:3821
DOMString characterSet
serialize
Definition Webelo.cpp:1085
USVString documentURI
serialize
Definition Webelo.cpp:1084
Element * namedItem(const DOMString &name) const
Definition Webelo.cpp:4113
unsigned short filter_node(Node *node)
Definition Webelo.cpp:5052
Definition base.cpp:15
HTMLSlotElement * assignedSlot
IMPORTANT SOMEWHERE in dispatch_event (slottable check)
Definition Webelo.cpp:1021
unsigned short filter_node(Node *node)
Definition Webelo.cpp:5067