public void TestNewlyAttachedElements()
        {
            Records = null;

            var done = Assert.Async();

            var root = HtmlHelper.FixtureElement;

            //setup observer
            var observer = new MutationObserver((changes, _) =>
            {
                if (changes.Length > 0)
                {
                    Records = changes;
                }
            });

            observer.Observe(root, new MutationObserverInit
            {
                Subtree   = true,
                ChildList = true
            });

            Task task = new Task(() =>
            {
                // mutate DOM
                // observer will be invoked asynchronously
                root.AppendChild(new HTMLSpanElement());
            });

            var task1 = task.ContinueWith(x =>
            {
                Task.Delay(10);
            });

            task1.ContinueWith(x =>
            {
                try
                {
                    AssertRecords(this.Records);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }

                observer.Disconnect();

                done();
            });

            task.Start();
        }
        public static void Run()
        {
            // ExStart:MutationObserver
            // The path to the documents directory.
            string dataDir = RunExamples.GetDataDir_Data();

            // The MutationObserver interface provides the ability to watch for changes being made to the DOM tree.

            // Create an empty document
            using (var document = new HTMLDocument())
            {
                // Create a WaitHandle for purpose described below
                var @event = new ManualResetEvent(false);

                // Create an observer instance
                var observer = new MutationObserver((mutations, mutationObserver) =>
                {
                    var mutation = mutations[0];
                    Console.WriteLine(mutation.AddedNodes[0]);
                    @event.Set();
                });

                // Options for the observer (which mutations to observe)
                var config = new MutationObserverInit
                {
                    ChildList = true,
                    Subtree   = true
                };

                // Start observing the target node
                observer.Observe(document.DocumentElement, config);

                // An example of user modifications
                var p = document.CreateElement("p");
                document.DocumentElement.AppendChild(p);

                // Since, mutations are working in the async mode you should wait a bit. We use WaitHandle for this purpose.
                @event.WaitOne();


                // Later, you can stop observing
                observer.Disconnect();
            }
            // ExEnd:MutationObserver
        }
        public void MutationObserverDisconnectShouldStopAllEventsAndEmptyTheRecords()
        {
            var document = Html("");
            var div      = document.CreateElement("div");
            var observer = new MutationObserver((obs, mut) => { });

            observer.Connect(div, attributes: true);

            div.SetAttribute("a", "A");
            observer.Disconnect();
            var records = observer.Flush().ToArray();

            Assert.AreEqual(records.Count(), 0);

            div.SetAttribute("b", "B");
            records = observer.Flush().ToArray();
            Assert.AreEqual(records.Count(), 0);
        }
        public void MutationObserverDisconnectShouldNotAffectOtherObservers()
        {
            var document  = Html("");
            var div       = document.CreateElement("div");
            var observer1 = new MutationObserver((obs, mut) => { });

            observer1.Connect(div, attributes: true);
            var observer2 = new MutationObserver((obs, mut) => { });

            observer2.Connect(div, attributes: true);

            div.SetAttribute("a", "A");

            observer1.Disconnect();
            var records1 = observer1.Flush().ToArray();

            Assert.AreEqual(records1.Count(), 0);

            var records2 = observer2.Flush().ToArray();

            Assert.AreEqual(records2.Count(), 1);
            AssertRecord(records2[0], new TestMutationRecord
            {
                Type          = "attributes",
                Target        = div,
                AttributeName = "a"
            });

            div.SetAttribute("b", "B");

            records1 = observer1.Flush().ToArray();
            Assert.AreEqual(records1.Count(), 0);

            records2 = observer2.Flush().ToArray();
            Assert.AreEqual(records2.Count(), 1);
            AssertRecord(records2[0], new TestMutationRecord
            {
                Type          = "attributes",
                Target        = div,
                AttributeName = "b"
            });
        }