browser_resources_css_changes.js (6009B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 // Test the ResourceCommand API around CSS_CHANGE. 7 8 add_task(async function () { 9 // Open a test tab 10 const tab = await addTab( 11 "data:text/html,<body style='color: lime;'>CSS Changes</body>" 12 ); 13 14 const { client, resourceCommand, targetCommand } = 15 await initResourceCommand(tab); 16 17 // CSS_CHANGE watcher doesn't record modification made before watching, 18 // so we have to start watching before doing any DOM mutation. 19 await resourceCommand.watchResources([resourceCommand.TYPES.CSS_CHANGE], { 20 onAvailable: () => {}, 21 }); 22 23 const { walker } = await targetCommand.targetFront.getFront("inspector"); 24 const nodeList = await walker.querySelectorAll(walker.rootNode, "body"); 25 const body = (await nodeList.items())[0]; 26 const style = ( 27 await body.inspectorFront.pageStyle.getApplied(body, { 28 skipPseudo: false, 29 }) 30 )[0]; 31 32 info( 33 "Check whether ResourceCommand catches CSS change that fired before starting to watch" 34 ); 35 await setProperty(style.rule, 0, "color", "black"); 36 37 const availableResources = []; 38 await resourceCommand.watchResources([resourceCommand.TYPES.CSS_CHANGE], { 39 onAvailable: resources => availableResources.push(...resources), 40 }); 41 42 // There is no guarantee that the CSS change will be already available when calling watchResources, 43 // so wait for it to be received. 44 info("Wait for CSS change to be received"); 45 await waitFor(() => availableResources.length == 1); 46 47 assertResource( 48 availableResources[0], 49 { index: 0, property: "color", value: "black" }, 50 { index: 0, property: "color", value: "lime" } 51 ); 52 53 info( 54 "Check whether ResourceCommand catches CSS changes after the property was renamed and updated" 55 ); 56 57 // RuleRewriter:apply will not support a simultaneous rename + setProperty. 58 // Doing so would send inconsistent arguments to StyleRuleActor:setRuleText, 59 // the CSS text for the rule will not match the list of modifications, which 60 // would desynchronize the Changes view. Thankfully this scenario should not 61 // happen when using the UI to update the rules. 62 await renameProperty(style.rule, 0, "color", "background-color"); 63 await waitUntil(() => availableResources.length === 2); 64 assertResource( 65 availableResources[1], 66 { index: 0, property: "background-color", value: "black" }, 67 { index: 0, property: "color", value: "black" } 68 ); 69 70 await setProperty(style.rule, 0, "background-color", "pink"); 71 await waitUntil(() => availableResources.length === 3); 72 assertResource( 73 availableResources[2], 74 { index: 0, property: "background-color", value: "pink" }, 75 { index: 0, property: "background-color", value: "black" } 76 ); 77 78 info("Check whether ResourceCommand catches CSS change of disabling"); 79 await setPropertyEnabled(style.rule, 0, "background-color", false); 80 await waitUntil(() => availableResources.length === 4); 81 assertResource(availableResources[3], null, { 82 index: 0, 83 property: "background-color", 84 value: "pink", 85 }); 86 87 info("Check whether ResourceCommand catches CSS change of new property"); 88 await createProperty(style.rule, 1, "font-size", "100px"); 89 await waitUntil(() => availableResources.length === 5); 90 assertResource( 91 availableResources[4], 92 { index: 1, property: "font-size", value: "100px" }, 93 null 94 ); 95 96 info("Check whether ResourceCommand sends all resources added in this test"); 97 const existingResources = []; 98 await resourceCommand.watchResources([resourceCommand.TYPES.CSS_CHANGE], { 99 onAvailable: resources => existingResources.push(...resources), 100 }); 101 await waitUntil(() => existingResources.length === 5); 102 is(availableResources[0], existingResources[0], "1st resource is correct"); 103 is(availableResources[1], existingResources[1], "2nd resource is correct"); 104 is(availableResources[2], existingResources[2], "3rd resource is correct"); 105 is(availableResources[3], existingResources[3], "4th resource is correct"); 106 is(availableResources[4], existingResources[4], "4th resource is correct"); 107 108 targetCommand.destroy(); 109 await client.close(); 110 }); 111 112 function assertResource(resource, expectedAddedChange, expectedRemovedChange) { 113 if (expectedAddedChange) { 114 is(resource.add.length, 1, "The number of added changes is correct"); 115 assertChange(resource.add[0], expectedAddedChange); 116 } else { 117 is(resource.add, null, "There is no added changes"); 118 } 119 120 if (expectedRemovedChange) { 121 is(resource.remove.length, 1, "The number of removed changes is correct"); 122 assertChange(resource.remove[0], expectedRemovedChange); 123 } else { 124 is(resource.remove, null, "There is no removed changes"); 125 } 126 } 127 128 function assertChange(change, expected) { 129 is(change.index, expected.index, "The index of change is correct"); 130 is(change.property, expected.property, "The property of change is correct"); 131 is(change.value, expected.value, "The value of change is correct"); 132 } 133 134 async function setProperty(rule, index, property, value) { 135 const modifications = rule.startModifyingProperties(window, { 136 isKnown: true, 137 }); 138 modifications.setProperty(index, property, value, ""); 139 await modifications.apply(); 140 } 141 142 async function renameProperty(rule, index, oldName, newName) { 143 const modifications = rule.startModifyingProperties(window, { 144 isKnown: true, 145 }); 146 modifications.renameProperty(index, oldName, newName); 147 await modifications.apply(); 148 } 149 150 async function createProperty(rule, index, property, value) { 151 const modifications = rule.startModifyingProperties(window, { 152 isKnown: true, 153 }); 154 modifications.createProperty(index, property, value, "", true); 155 await modifications.apply(); 156 } 157 158 async function setPropertyEnabled(rule, index, property, isEnabled) { 159 const modifications = rule.startModifyingProperties(window, { 160 isKnown: true, 161 }); 162 modifications.setPropertyEnabled(index, property, isEnabled); 163 await modifications.apply(); 164 }