Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

MOC-150 handle DOM mutations #165

Merged
merged 5 commits into from
Aug 29, 2024
Merged

MOC-150 handle DOM mutations #165

merged 5 commits into from
Aug 29, 2024

Conversation

jonathankap
Copy link
Contributor

@jonathankap jonathankap commented Aug 29, 2024

Major changes:

  1. Generate a uuid for each modification (AppliableModification) and modification set (AppliedModifications)
  2. Store information about nodes changes in the DOM based on uuids above - added a bunch of infrastructure to AppliableModification base
  3. Implement a global mutation listener that reapplies mutations as nodes are added and automatically removes state for nodes that are removed
  4. Implement a specific mutation listener in replaceAll modification that reapplies as the DOM changes and keeps state up to date
  5. Added a few tests, but a lot more are needed!

Summary by CodeRabbit

  • New Features

    • Introduced unique identification for modifications with a new uuid property.
    • Added methods for managing modified elements, including adding and removing modifications.
    • New function for flexible element matching based on selectors or XPath.
    • Enhanced handling of DOM mutations with a MutationObserver for dynamic updates.
    • Improved state management for multiple elements during HTML modifications.
    • Added a utility function for generating random strings.
  • Bug Fixes

    • Enhanced test coverage and assertions for modification functionalities.
  • Documentation

    • Introduced a custom matcher for the expect assertion library to improve test reliability.

@jonathankap jonathankap requested review from elg0nz and fitzk August 29, 2024 00:07
Copy link

linear bot commented Aug 29, 2024

Copy link

coderabbitai bot commented Aug 29, 2024

Walkthrough

Walkthrough

The changes introduce enhancements to the modification handling system within the Reactor framework. Key updates include the addition of unique identifiers for modifications, improved element state management, and the integration of a mutation observer for dynamic DOM monitoring. New utility functions and testing capabilities have also been added, enhancing the overall functionality and robustness of the system.

Changes

Files Change Summary
packages/reactor/interfaces.ts Added uuid property to AppliableModification class and introduced multiple new methods for managing modified elements.
packages/reactor/modifications.ts Introduced matchesSelector function for flexible element matching based on selectors or XPath expressions.
packages/reactor/modifications/adjacentHTML.ts Replaced element property with elementId in AdjacentHTMLModification class, updated apply and unapply methods for better state management of modified elements.
packages/reactor/modifications/replaceAll.ts Added MutationObserver to ReplaceAllModification class for dynamic DOM monitoring and updated methods to handle mutations effectively.
packages/reactor/mutationObserver.ts Expanded ReactorMutationObserver class functionality, added methods for handling added and removed elements, and integrated with the reactor's modification logic.
packages/reactor/reactor.ts Made doc property public, initialized mutationObserver in the constructor, and improved attachment/detachment logic for the observer during modifications.
packages/reactor/tests/modifications.test.ts Enhanced test assertions with toMatchIgnoringMocksiTags and added new test cases for applyModification method.
packages/reactor/tests/mutation.test.ts Introduced a new test suite for mutation listeners in the Reactor class, validating the handling of document modifications.
packages/reactor/tests/test.utils.ts Added utility function extendExpect to enhance Vitest's assertion library with a custom matcher.
packages/reactor/utils.ts Introduced generateRandomString function for creating random strings.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Reactor
    participant MutationObserver
    participant Element

    User->>Reactor: Apply Modification
    Reactor->>MutationObserver: Detach Observer
    Reactor->>Element: Modify Content
    Reactor->>MutationObserver: Attach Observer
    MutationObserver->>Element: Observe Changes
    MutationObserver->>Reactor: Handle Mutation
    Reactor->>Element: Update State
Loading

🐇 In the meadow, changes bloom,
New IDs and states, dispelling gloom.
Observers watch with keen delight,
Modifications dance, oh what a sight!
With tests that leap and utilities bright,
The Reactor hops into the light! 🌼✨


Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between b002319 and e630dd3.

Files selected for processing (10)
  • packages/reactor/interfaces.ts (2 hunks)
  • packages/reactor/modifications.ts (1 hunks)
  • packages/reactor/modifications/adjacentHTML.ts (2 hunks)
  • packages/reactor/modifications/replaceAll.ts (5 hunks)
  • packages/reactor/mutationObserver.ts (2 hunks)
  • packages/reactor/reactor.ts (5 hunks)
  • packages/reactor/tests/modifications.test.ts (15 hunks)
  • packages/reactor/tests/mutation.test.ts (1 hunks)
  • packages/reactor/tests/test.utils.ts (1 hunks)
  • packages/reactor/utils.ts (1 hunks)
Additional context used
GitHub Check: vitest_run
packages/reactor/tests/modifications.test.ts

[failure] 206-206: tests/modifications.test.ts > Utils > applyModification > should unapply from wikipedia
AssertionError: expected '<p mocksi-id="lybmz6g6" mocksi-modifi…' to be '

The office of the "President of th…' // Object.is equality

  • Expected
  • Received

❯ tests/modifications.test.ts:206:30

Additional comments not posted (59)
packages/reactor/tests/test.utils.ts (2)

1-1: LGTM!

The import statement is correct and necessary for type definitions.

The code changes are approved.


3-17: LGTM!

The extendExpect function is correctly implemented and adds useful functionality for testing by extending the expect object with a custom matcher toMatchIgnoringMocksiTags.

The code changes are approved.

packages/reactor/utils.ts (2)

Line range hint 1-14: LGTM!

The parseRequest function is correctly implemented and handles errors appropriately by logging them and throwing a new error.

The code changes are approved.


15-23: LGTM!

The generateRandomString function is correctly implemented and provides useful functionality for generating random strings of a specified length using lowercase letters and digits.

The code changes are approved.

packages/reactor/modifications/adjacentHTML.ts (4)

4-4: LGTM!

The elementId property replaces the element property and aligns with the new approach of using ID-based references.

The code changes are approved.


15-19: LGTM!

The constructor has been updated to use this.addModifiedElement(element) and set this.elementId, enhancing the encapsulation of element management.

The code changes are approved.


23-27: LGTM!

The apply method has been updated to handle multiple elements and track their old state, enhancing the robustness of the apply operation.

The code changes are approved.


31-36: LGTM!

The unapply method has been updated to handle multiple elements and restore their old state, enhancing the robustness of the unapply operation.

The code changes are approved.

packages/reactor/tests/mutation.test.ts (6)

1-4: LGTM!

The import statements are correct and necessary for the tests.

The code changes are approved.


6-6: LGTM!

The extendExpect function is correctly called to extend the expect function.

The code changes are approved.


8-8: LGTM!

The describe block is correctly used to group related tests.

The code changes are approved.


13-21: LGTM!

The beforeEach block is correctly used to set up the test environment before each test.

The code changes are approved.


23-44: LGTM!

The it block is correctly used to test the handling of an added mutation.

The code changes are approved.


46-67: LGTM!

The it block is correctly used to test the handling of undoing after an added mutation.

The code changes are approved.

packages/reactor/interfaces.ts (11)

1-1: LGTM!

The import statement is correct and necessary for the new functionality.

The code changes are approved.


55-55: LGTM!

The new property uuid is correctly added to the class.

The code changes are approved.


67-77: LGTM!

The addModifiedElement method is correctly implemented to add a modified element.

The code changes are approved.


79-86: LGTM!

The removeModifiedElement method is correctly implemented to remove a modified element.

The code changes are approved.


88-90: LGTM!

The getModifiedElement method is correctly implemented to get a modified element by its mocksi-id.

The code changes are approved.


92-96: LGTM!

The getModifiedElements method is correctly implemented to get all modified elements.

The code changes are approved.


101-104: LGTM!

The modifiedElementRemoved method is correctly implemented to check if a modification is no longer needed.

The code changes are approved.


106-108: LGTM!

The getMocksiId method is correctly implemented to get the mocksi-id of an element.

The code changes are approved.


110-112: LGTM!

The setElementState method is correctly implemented to set the state of an element.

The code changes are approved.


114-116: LGTM!

The getElementState method is correctly implemented to get the state of an element.

The code changes are approved.


118-120: LGTM!

The removeElementState method is correctly implemented to remove the state of an element.

The code changes are approved.

packages/reactor/mutationObserver.ts (7)

1-3: LGTM!

The import statements are correct and necessary for the new functionality.

The code changes are approved.


6-11: LGTM!

The new property reactor and the constructor are correctly implemented.

The code changes are approved.


28-42: LGTM!

The handleMutation method is correctly implemented to handle mutations in the DOM.

The code changes are approved.


44-68: LGTM!

The walkAddedElements method is correctly implemented to walk through added elements.

The code changes are approved.


70-92: LGTM!

The walkRemovedElements method is correctly implemented to walk through removed elements.

The code changes are approved.


94-107: LGTM!

The removeModifiedElement method is correctly implemented to remove a modified element.

The code changes are approved.


110-124: LGTM!

The printNode function is correctly implemented to print a node.

The code changes are approved.

packages/reactor/modifications.ts (2)

Line range hint 140-198: LGTM!

The function is correctly implemented, handling different modification types appropriately.

The code changes are approved.


200-209: LGTM!

The function is correctly implemented, handling both selector and XPath cases appropriately.

The code changes are approved.

packages/reactor/modifications/replaceAll.ts (7)

7-14: LGTM!

The constructor is correctly implemented, initializing the MutationObserver appropriately.

The code changes are approved.


18-29: LGTM!

The function is correctly implemented, applying the modification and starting the observation appropriately.

The code changes are approved.


Line range hint 33-57: LGTM!

The function is correctly implemented, disconnecting the observer and reverting the changes appropriately.

The code changes are approved.


58-80: LGTM!

The function is correctly implemented, handling mutations and updating the changes array appropriately.

The code changes are approved.


82-91: LGTM!

The function is correctly implemented, removing changes related to a specific element appropriately.

The code changes are approved.


95-98: LGTM!

The type is correctly defined, reflecting the structure of a tree change appropriately.

The code changes are approved.


Line range hint 159-204: LGTM!

The function is correctly implemented, replacing text in a node based on a pattern appropriately.

The code changes are approved.

packages/reactor/reactor.ts (3)

23-29: LGTM!

The constructor is correctly implemented, initializing the mutationObserver appropriately.

The code changes are approved.


53-55: LGTM!

The function is correctly implemented, attaching the Reactor to the document and applying modifications appropriately.

The code changes are approved.


157-169: LGTM!

The function is correctly implemented, pushing a modification request to the stack and applying it appropriately.

The code changes are approved.

packages/reactor/tests/modifications.test.ts (15)

2-2: LGTM!

The import statement for extendExpect is correctly added.

The code changes are approved.


7-7: LGTM!

The function call to extendExpect(expect); is correctly added to extend the expect functionality.

The code changes are approved.


Line range hint 51-56: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 66-71: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 81-85: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 95-99: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 112-116: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 129-133: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 147-151: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


178-191: LGTM!

The new test case is well-structured and effectively validates the applyModification method with Wikipedia-style content.

The code changes are approved.


Line range hint 216-221: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 234-239: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 249-254: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 267-272: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.


Line range hint 432-437: LGTM!

The test case is correctly modified to use toMatchIgnoringMocksiTags instead of toBe for more flexible matching.

The code changes are approved.

Comment on lines 193 to 207
it("should unapply from wikipedia", async() => {
const modification: Modification = {
action: "replaceAll",
content: "/Thailand/Russia/",
};

const element = doc.createElement("p");
element.innerHTML = "<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Thailand is not new.</p>"
doc.body.appendChild(element);

const modifications = await applyModification(doc.body, modification, doc);
modifications.unapply();

expect(element.innerHTML).toBe("<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Russia is not new.</p>");
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix the test case failure.

The new test case is well-structured but fails due to additional attributes in the modified content.

Apply this diff to fix the test case failure:

- expect(element.innerHTML).toBe("<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Russia is not new.</p>");
+ expect(element.innerHTML).toMatchIgnoringMocksiTags("<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Russia is not new.</p>");
Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
it("should unapply from wikipedia", async() => {
const modification: Modification = {
action: "replaceAll",
content: "/Thailand/Russia/",
};
const element = doc.createElement("p");
element.innerHTML = "<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Thailand is not new.</p>"
doc.body.appendChild(element);
const modifications = await applyModification(doc.body, modification, doc);
modifications.unapply();
expect(element.innerHTML).toBe("<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Russia is not new.</p>");
});
it("should unapply from wikipedia", async() => {
const modification: Modification = {
action: "replaceAll",
content: "/Thailand/Russia/",
};
const element = doc.createElement("p");
element.innerHTML = "<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Thailand is not new.</p>"
doc.body.appendChild(element);
const modifications = await applyModification(doc.body, modification, doc);
modifications.unapply();
expect(element.innerHTML).toMatchIgnoringMocksiTags("<p>The office of the \"President of the <a href=\"/wiki/People%27s_Committee_of_Siam\" title=\"People's Committee of Siam\">People's Committee</a>\" (<span title=\"Thai-language text\"><span lang=\"th\">ประธานคณะกรรมการราษฎร</span></span>), later changed to \"Prime Minister of Siam\" (<span title=\"Thai-language text\"><span lang=\"th\">นายกรัฐมนตรีสยาม</span></span>), was first created in the <a href=\"/wiki/Constitution_of_Thailand#1932_Temporary_Charter\" title=\"Constitution of Thailand\">Temporary Constitution of 1932</a>. The office was modeled after the <a href=\"/wiki/Prime_Minister_of_the_United_Kingdom\" title=\"Prime Minister of the United Kingdom\">prime minister of the United Kingdom</a>, as Siam became a <a href=\"/wiki/Parliamentary_democracy\" class=\"mw-redirect\" title=\"Parliamentary democracy\">parliamentary democracy</a> in 1932 after a <a href=\"/wiki/Siamese_revolution_of_1932\" title=\"Siamese revolution of 1932\">bloodless revolution</a>. However, the idea of a separate head of government in Russia is not new.</p>");
});
Tools
GitHub Check: vitest_run

[failure] 206-206: tests/modifications.test.ts > Utils > applyModification > should unapply from wikipedia
AssertionError: expected '<p mocksi-id="lybmz6g6" mocksi-modifi…' to be '

The office of the "President of th…' // Object.is equality

  • Expected
  • Received

❯ tests/modifications.test.ts:206:30

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between e630dd3 and 46caca4.

Files selected for processing (3)
  • packages/reactor/modifications/replaceAll.ts (5 hunks)
  • packages/reactor/tests/modifications.test.ts (15 hunks)
  • packages/reactor/tests/test.utils.ts (1 hunks)
Files skipped from review as they are similar to previous changes (3)
  • packages/reactor/modifications/replaceAll.ts
  • packages/reactor/tests/modifications.test.ts
  • packages/reactor/tests/test.utils.ts

Copy link
Contributor

@elg0nz elg0nz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fantastic work! 🙌🔥

Note: I saw some duplication on mutationObserver, but I suggest we hold off on any further refactoring until Drew and Kayla complete their QA. This will help us minimize risks as we approach the beta launch 🚢 :shipit:

this.element.insertAdjacentHTML(this.position, this.newValue);

// TODO - highlighting
for (const element of this.getModifiedElements()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this apply and unapply func look very similar... No idea how to remove the duplication though, so just leaving this as a note, feel free to ignore 😄

this.observer.disconnect();

for (const mutation of mutations) {
if (mutation.type === "childList") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: an early return/continue would make this code a tiny bit neater


constructor(doc: Document, element: Element, content: string) {
super(doc);
this.element = element;
this.content = content;

this.observer = new MutationObserver(this.handleMutation.bind(this));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

@jonathankap jonathankap merged commit fc9ba5e into main Aug 29, 2024
3 checks passed
@jonathankap jonathankap deleted the MOC-150_dom_mutations branch August 29, 2024 16:36
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants