internal static void QueueRecord(MutationRecord Record) {/* Docs: https://dom.spec.whatwg.org/#queueing-a-mutation-record */ /* 1) Let interestedObservers be an empty map. */ Dictionary <MutationObserver, string> interestedObservers = new Dictionary <MutationObserver, string>(); /* 2) Let nodes be the inclusive ancestors of target. */ List <Node> Nodes = new List <Node>(); TreeWalker tree = new TreeWalker(Record.target, ENodeFilterMask.SHOW_ALL); Node ancestor = Record.target; while (ancestor != null) { ancestor = tree.parentNode(); Nodes.Add(ancestor); } /* 3) For each node in nodes, and then for each registered of node’s registered observer list: */ foreach (Node node in Nodes) { foreach (var registered in node.RegisteredObservers) { /* 1) Let options be registered’s options. */ var options = registered.options; /* 2) If none of the following are true */ if (!(!ReferenceEquals(node, Record.target) && !options.subtree) && !(Record.type == EMutationType.Attributes && !options.attributes) && !(Record.type == EMutationType.Attributes && (options.attributeFilter == null || (!options.attributeFilter.Contains("name") && options.attributeFilter.Contains("namespace")))) && !(Record.type == EMutationType.CharacterData && !options.characterData) && !(Record.type == EMutationType.ChildList && !options.childList)) { /* 1) Let mo be registered’s observer. */ var mo = registered.observer; /* 2) If interestedObservers[mo] does not exist, then set interestedObservers[mo] to null. */ if (!interestedObservers.ContainsKey(mo)) { interestedObservers.Add(mo, null); } /* 3) If either type is "attributes" and options’s attributeOldValue is true, or type is "characterData" and options’s characterDataOldValue is true, then set interestedObservers[mo] to oldValue. */ if ((Record.type == EMutationType.Attributes && options.attributeOldValue) || (Record.type == EMutationType.CharacterData && options.characterDataOldValue)) { interestedObservers[mo] = Record.oldValue; } } } } /* 4) For each observer → mappedOldValue of interestedObservers: */ foreach (KeyValuePair <MutationObserver, string> kv in interestedObservers) { /* 1) Let record be a new MutationRecord object with its type set to type, target set to target, attributeName set to name, attributeNamespace set to namespace, oldValue set to mappedOldValue, addedNodes set to addedNodes, removedNodes set to removedNodes, previousSibling set to previousSibling, and nextSibling set to nextSibling. */ var record = new MutationRecord(Record.type, Record.target, Record.attributeName, Record.attributeNamespace, kv.Value, Record.addedNodes, Record.removedNodes, Record.previousSibling, Record.nextSibling); /* 2) Enqueue record to observer’s record queue. */ kv.Key.Enqueue(record); } /* 5) Queue a mutation observer microtask. */ Record.target.ownerDocument.defaultView.QueueObserverMicroTask(); }
internal static void Queue_Tree_Mutation_Record(Node target, IEnumerable <Node> addedNodes, IEnumerable <Node> removedNodes, Node previousSibling, Node nextSibling) { MutationRecord record = new MutationRecord(EMutationType.ChildList, target, null, null, null, addedNodes, removedNodes, previousSibling, nextSibling); MutationRecord.QueueRecord(record); }
internal static void Queue_Text_Mutation_Record(Node target, string oldData) { MutationRecord record = new MutationRecord(EMutationType.CharacterData, target, null, null, oldData, null, null, null, null); MutationRecord.QueueRecord(record); }
internal static void Queue_Attribute_Mutation_Record(Node target, string localName, string Namespace, dynamic oldValue) { MutationRecord record = new MutationRecord(EMutationType.Attributes, target, localName, Namespace, oldValue); MutationRecord.QueueRecord(record); }
public void Enqueue(MutationRecord Record) { this.RecordQueue.Enqueue(Record); }