From d5b019ef2f6ce79dd40e0ee291b80f3174eecbb0 Mon Sep 17 00:00:00 2001 From: Simon Kalt Date: Wed, 26 Apr 2023 16:17:06 +0200 Subject: [PATCH] Keep priorities when updating individual sub-properties --- lib/CSSStyleDeclaration.test.js | 39 ++++++++++++++++++++++++++++++++- lib/parsers.js | 19 +++++++++++----- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/lib/CSSStyleDeclaration.test.js b/lib/CSSStyleDeclaration.test.js index 3127770..bed5047 100644 --- a/lib/CSSStyleDeclaration.test.js +++ b/lib/CSSStyleDeclaration.test.js @@ -415,7 +415,44 @@ describe('CSSStyleDeclaration', () => { } } } - }); + } + ); + + test.each(['margin', 'padding'])( + 'setting additional %s properties keeps important status of others', + (property) => { + var style = new CSSStyleDeclaration(); + var importantProperty = property + '-top: 3px !important;'; + style.cssText = importantProperty; + expect(style.cssText).toContain(importantProperty); + + style[property + 'Right'] = '4px'; + style[property + 'Bottom'] = '5px'; + style[property + 'Left'] = '6px'; + + expect(style.cssText).toContain(importantProperty); + expect(style.cssText).toContain(property + '-right: 4px;'); + expect(style.cssText).toContain(property + '-bottom: 5px;'); + expect(style.cssText).toContain(property + '-left: 6px;'); + expect(style.cssText).not.toContain('margin:'); + } + ); + + test.each(['margin', 'padding'])( + 'setting individual %s keeps important status of others', + (property) => { + var style = new CSSStyleDeclaration(); + style.cssText = property + ': 3px !important;'; + + style[property + 'Top'] = '4px'; + + expect(style.cssText).toContain(property + '-top: 4px;'); + expect(style.cssText).toContain(property + '-right: 3px !important;'); + expect(style.cssText).toContain(property + '-bottom: 3px !important;'); + expect(style.cssText).toContain(property + '-left: 3px !important;'); + expect(style.cssText).not.toContain('margin:'); + } + ); test('setting a value to 0 should return the string value', () => { var style = new CSSStyleDeclaration(); diff --git a/lib/parsers.js b/lib/parsers.js index 13bd751..887bd51 100644 --- a/lib/parsers.js +++ b/lib/parsers.js @@ -695,17 +695,26 @@ exports.subImplicitSetter = function (prefix, part, isValid, parser) { v = parser(v); this._setProperty(property, v); - var parts = subparts.map(subpart => this._values[subpart]); - if (parts.every(p => p !== '' && p != null)) { + var combinedPriority = this.getPropertyPriority(prefix); + var parts = subparts.map((subpart) => this._values[subpart]); + var priorities = subparts.map((subpart) => this.getPropertyPriority(subpart)); + // Combine into a single property if all values are set and have the same priority + if ( + parts.every((p) => p !== '' && p != null) && + priorities.every((p) => p === priorities[0]) && + priorities[0] === combinedPriority + ) { for (var i = 0; i < subparts.length; i++) { this.removeProperty(subparts[i]); this._values[subparts[i]] = parts[i]; } - this._setProperty(prefix, parts.join(' ')); + this._setProperty(prefix, parts.join(' '), priorities[0]); } else { this.removeProperty(prefix); - for (var i = 0; i < subparts.length; i++) { - this._setProperty(subparts[i], parts[i]); + for (var j = 0; j < subparts.length; j++) { + // The property we're setting won't be important, the rest will either keep their priority or inherit it from the combined property + var priority = subparts[j] === property ? '' : priorities[j] || combinedPriority; + this._setProperty(subparts[j], parts[j], priority); } } return v;