Changeset 240946 in webkit
- Timestamp:
- Feb 4, 2019 3:30:49 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r240941 r240946 1 2019-02-04 Nikita Vasilyev <nvasilyev@apple.com> 2 3 Web Inspector: Styles: fix race conditions when editing 4 https://bugs.webkit.org/show_bug.cgi?id=192739 5 <rdar://problem/46752925> 6 7 Reviewed by Devin Rousso. 8 9 * inspector/css/modify-css-property-expected.txt: 10 * inspector/css/modify-css-property-race-expected.txt: Added. 11 * inspector/css/modify-css-property-race.html: Added. 12 * inspector/css/modify-css-property.html: 13 1 14 2019-02-04 Simon Fraser <simon.fraser@apple.com> 2 15 -
trunk/LayoutTests/inspector/css/modify-css-property-expected.txt
r239251 r240946 5 5 -- Running test case: Update value when CSSStyleDeclaration is not locked 6 6 PASS: "font-size" property value should update immediately. 7 PASS: Style declaration text should stay unchanged.7 PASS: Style declaration text should update immediately. 8 8 9 9 -- Running test case: Update value when CSSStyleDeclaration is locked … … 11 11 PASS: Style declaration text should update immediately. 12 12 13 -- Running test case: ModifyCSSProperty.PropertiesChangedEvent 14 PASS: Style declaration is unlocked. 15 PASS: "width" property value should update to "200px". 16 PASS: Inline style declaration text should update when not locked. 17 13 18 -- Running test case: Update inline style value when CSSStyleDeclaration locked and not locked 14 19 PASS: Style declaration text should update immediately. 15 PASS: Style declaration text should stay "width: 64px". 16 PASS: "width" property value should update to "200px". 20 PASS: Style declaration text should update immediately. 21 PASS: Style declaration is unlocked. 22 PASS: "width" property value should update to "128px". 17 23 PASS: Inline style declaration text should update when not locked. 24 25 -- Running test case: ModifyCSSProperty.ConsequentValueChanges 26 PASS: Style declaration text should contain most recent value. 18 27 19 28 -- Running test case: ModifyCSSProperty.CommentOutAndUncommentPropertyWithNewlines -
trunk/LayoutTests/inspector/css/modify-css-property.html
r240314 r240946 45 45 InspectorTest.expectEqual(getProperty("font-size").rawValue, "10px", `"font-size" property value should update immediately.`); 46 46 47 InspectorTest.expectEqual(styleDeclaration.text, `font-size: 1 2px; color: antiquewhite`, `Style declaration text should stay unchanged.`);47 InspectorTest.expectEqual(styleDeclaration.text, `font-size: 10px; color: antiquewhite`, `Style declaration text should update immediately.`); 48 48 49 49 resolve(); … … 95 95 96 96 suite.addTestCase({ 97 name: " Update inline style value when CSSStyleDeclaration locked and not locked",97 name: "ModifyCSSProperty.PropertiesChangedEvent", 98 98 test(resolve, reject) { 99 99 let getInlineStyleDeclaration = () => { … … 108 108 let getProperty = (propertyName) => { 109 109 let styleDeclaration = getInlineStyleDeclaration(); 110 for (let property of styleDeclaration.properties) { 111 if (property.name === propertyName) 112 return property; 113 } 114 InspectorTest.fail("No property found."); 115 resolve(); 116 }; 117 118 let styleDeclaration = getInlineStyleDeclaration(); 119 120 styleDeclaration.awaitEvent(WI.CSSStyleDeclaration.Event.PropertiesChanged).then((event) => { 121 InspectorTest.expectThat(!styleDeclaration.locked, `Style declaration is unlocked.`); 122 InspectorTest.expectEqual(getProperty("width").rawValue, "200px", `"width" property value should update to "200px".`); 123 InspectorTest.expectEqual(styleDeclaration.text, `width: 200px;`, `Inline style declaration text should update when not locked.`); 124 resolve(); 125 }); 126 127 styleDeclaration.locked = true; 128 // WI.CSSStyleDeclaration.Event.PropertiesChanged event should not fire when the style declaration is locked. 129 InspectorTest.evaluateInPage(`makeNarrow()`); 130 131 styleDeclaration.locked = false; 132 InspectorTest.evaluateInPage(`makeWide()`); 133 } 134 }); 135 136 suite.addTestCase({ 137 name: "Update inline style value when CSSStyleDeclaration locked and not locked", 138 test(resolve, reject) { 139 let getInlineStyleDeclaration = () => { 140 for (let styleDeclaration of nodeStyles.orderedStyles) { 141 if (styleDeclaration.type === styleDeclaration.constructor.Type.Inline) 142 return styleDeclaration; 143 } 144 InspectorTest.fail("No declaration found."); 145 resolve(); 146 }; 147 148 let getProperty = (propertyName) => { 149 let styleDeclaration = getInlineStyleDeclaration(); 110 150 for (let property of styleDeclaration.enabledProperties) { 111 151 if (property.name === propertyName) … … 118 158 let styleDeclaration = getInlineStyleDeclaration(); 119 159 120 styleDeclaration.awaitEvent(WI.CSSStyleDeclaration.Event.PropertiesChanged)121 .then((event) => {122 InspectorTest.expectEqual(getProperty("width").rawValue, "200px", `"width" property value should update to "200px".`);123 InspectorTest.expectEqual(styleDeclaration.text, `width: 200px;`, `Inline style declaration text should update when not locked.`);124 })125 .then(resolve, reject);160 WI.CSSStyleDeclaration.awaitEvent(WI.CSSStyleDeclaration.Event.PropertiesChanged).then((event) => { 161 InspectorTest.expectThat(!styleDeclaration.locked, `Style declaration is unlocked.`); 162 InspectorTest.expectEqual(getProperty("width").rawValue, "128px", `"width" property value should update to "128px".`); 163 InspectorTest.expectEqual(styleDeclaration.text, `width: 128px;`, `Inline style declaration text should update when not locked.`); 164 resolve(); 165 }); 126 166 127 167 styleDeclaration.locked = true; … … 134 174 styleDeclaration.locked = false; 135 175 getProperty("width").rawValue = "128px"; 136 InspectorTest.expectEqual(styleDeclaration.text, `width: 64px;`, `Style declaration text should stay "width: 64px".`);176 InspectorTest.expectEqual(styleDeclaration.text, `width: 128px;`, `Style declaration text should update immediately.`); 137 177 138 178 InspectorTest.evaluateInPage(`makeWide()`); 179 } 180 }); 181 182 suite.addTestCase({ 183 name: "ModifyCSSProperty.ConsequentValueChanges", 184 test(resolve, reject) { 185 let getInlineStyleDeclaration = () => { 186 for (let styleDeclaration of nodeStyles.orderedStyles) { 187 if (styleDeclaration.type === styleDeclaration.constructor.Type.Inline) 188 return styleDeclaration; 189 } 190 InspectorTest.fail("No declaration found."); 191 resolve(); 192 }; 193 194 let getProperty = (propertyName) => { 195 let styleDeclaration = getInlineStyleDeclaration(); 196 for (let property of styleDeclaration.properties) { 197 if (property.name === propertyName) 198 return property; 199 } 200 InspectorTest.fail("No property found."); 201 resolve(); 202 }; 203 204 let styleDeclaration = getInlineStyleDeclaration(); 205 styleDeclaration.locked = false; 206 207 for (let i = 0; i <= 20; ++i) 208 getProperty("width").rawValue = i + "px"; 209 210 InspectorTest.expectEqual(styleDeclaration.text, `width: 20px;`, `Style declaration text should contain most recent value.`); 211 212 resolve(); 139 213 } 140 214 }); -
trunk/Source/WebInspectorUI/ChangeLog
r240884 r240946 1 2019-02-04 Nikita Vasilyev <nvasilyev@apple.com> 2 3 Web Inspector: Styles: fix race conditions when editing 4 https://bugs.webkit.org/show_bug.cgi?id=192739 5 <rdar://problem/46752925> 6 7 Reviewed by Devin Rousso. 8 9 Editing CSS property in the style editor syncronously updates CSSStyleDeclaration on the front-end 10 and asyncronously updates the backend by calling CSSAgent.setStyleText. After the new style text is applied 11 on the backend, CSSStyleDeclaration (on the front-end) gets updated. 12 13 Unsure there's no race conditions by introducing `_updatesInProgressCount`: 14 15 - Increment it before calling CSSAgent.setStyleText. 16 - Decrement it after CSSAgent.setStyleText is finished. 17 18 Prevent updates of CSSStyleDeclaration when _updatesInProgressCount isn't 0. 19 20 * UserInterface/Models/CSSProperty.js: 21 (WI.CSSProperty.prototype._updateOwnerStyleText): 22 * UserInterface/Models/CSSStyleDeclaration.js: 23 (WI.CSSStyleDeclaration): 24 (WI.CSSStyleDeclaration.prototype.set text): Removed. 25 (WI.CSSStyleDeclaration.prototype.setText): Added. 26 Change the setter to a method since it has side effects including an asynchronous backend call. 27 28 * UserInterface/Models/DOMNodeStyles.js: 29 (WI.DOMNodeStyles.prototype.changeStyleText): 30 31 * UserInterface/Views/SpreadsheetStyleProperty.js: 32 (WI.SpreadsheetStyleProperty.prototype.get nameTextField): Removed. 33 (WI.SpreadsheetStyleProperty.prototype.get valueTextField): Removed. 34 Drive-by: remove unused code. 35 1 36 2019-02-01 Devin Rousso <drousso@apple.com> 2 37 -
trunk/Source/WebInspectorUI/UserInterface/Models/CSSProperty.js
r240559 r240946 381 381 } 382 382 383 console.assert(this._ownerStyle); 384 if (!this._ownerStyle) 385 return; 386 383 387 this._prependSemicolonIfNeeded(); 384 388 -
trunk/Source/WebInspectorUI/UserInterface/Models/CSSStyleDeclaration.js
r240559 r240946 42 42 43 43 this._initialState = null; 44 this._updatesInProgressCount = 0; 44 45 this._locked = false; 45 46 this._pendingProperties = []; … … 107 108 { 108 109 let dontFireEvents = options.dontFireEvents || false; 109 let suppressLock = options.suppressLock || false; 110 111 if (this._locked && !suppressLock && text !== this._text) 110 111 // When two consequent setText calls happen (A and B), only update when the last call (B) is finished. 112 // Front-end: A B 113 // Back-end: A B 114 // _updatesInProgressCount: 0 1 2 1 0 115 // ^ 116 // update only happens here 117 if (this._updatesInProgressCount > 0 && !options.forceUpdate) { 118 if (WI.settings.enableStyleEditingDebugMode.value && text !== this._text) 119 console.warn("Style modified while editing:", text); 120 121 return; 122 } 123 124 // Allow updates from the backend when text matches because `properties` may contain warnings that need to be shown. 125 if (this._locked && !options.forceUpdate && text !== this._text) 112 126 return; 113 127 … … 200 214 text = trimmedText; 201 215 202 // Update text immediately when it was modified via the styles sidebar. 203 if (this._locked) 204 this._text = text; 205 206 this._nodeStyles.changeStyleText(this, text); 216 this._text = text; 217 ++this._updatesInProgressCount; 218 219 let timeoutId = setTimeout(() => { 220 console.error("Timed out when setting style text:", text); 221 styleTextDidChange(); 222 }, 2000); 223 224 let styleTextDidChange = () => { 225 if (!timeoutId) 226 return; 227 228 clearTimeout(timeoutId); 229 timeoutId = null; 230 this._updatesInProgressCount = Math.max(0, this._updatesInProgressCount - 1); 231 }; 232 233 this._nodeStyles.changeStyleText(this, text, styleTextDidChange); 207 234 } 208 235 … … 323 350 this._properties[index].index = index; 324 351 325 this.update(this._text, this._properties, this._styleSheetTextRange, {dontFireEvents: true, suppressLock: true});352 this.update(this._text, this._properties, this._styleSheetTextRange, {dontFireEvents: true, forceUpdate: true}); 326 353 327 354 return property; -
trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js
r240314 r240946 450 450 } 451 451 452 changeStyleText(style, text) 453 { 454 if (!style.ownerStyleSheet || !style.styleSheetTextRange) 452 changeStyleText(style, text, callback) 453 { 454 if (!style.ownerStyleSheet || !style.styleSheetTextRange) { 455 callback(); 455 456 return; 457 } 456 458 457 459 text = text || ""; 458 460 459 function styleChanged(error, stylePayload)460 {461 if (error)461 let didSetStyleText = (error, stylePayload) => { 462 if (error) { 463 callback(error); 462 464 return; 463 this.refresh(); 464 } 465 466 CSSAgent.setStyleText(style.id, text, styleChanged.bind(this)); 465 } 466 467 this.refresh().then(callback); 468 }; 469 470 CSSAgent.setStyleText(style.id, text, didSetStyleText); 467 471 } 468 472 -
trunk/Source/WebInspectorUI/UserInterface/Views/SpreadsheetStyleProperty.js
r240741 r240946 76 76 get element() { return this._element; } 77 77 get property() { return this._property; } 78 get nameTextField() { return this._nameTextField; }79 get valueTextField() { return this._valueTextField; }80 78 get enabled() { return this._property.enabled; } 81 79
Note: See TracChangeset
for help on using the changeset viewer.