tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

reactions.js (26545B)


      1 let testNumber = 1;
      2 
      3 function testNodeConnector(testFunction, name) {
      4    let container = document.createElement('div');
      5    container.appendChild(document.createElement('div'));
      6    document.body.appendChild(container);
      7 
      8    test(function () {
      9        var element = define_new_custom_element();
     10        var instance = document.createElement(element.name);
     11        assert_array_equals(element.takeLog().types(), ['constructed']);
     12        testFunction(container, instance);
     13        assert_array_equals(element.takeLog().types(), ['connected']);
     14    }, name + ' must enqueue a connected reaction');
     15 
     16    test(function () {
     17        var element = define_new_custom_element();
     18        var instance = document.createElement(element.name);
     19        assert_array_equals(element.takeLog().types(), ['constructed']);
     20        var newDoc = document.implementation.createHTMLDocument();
     21        testFunction(container, instance);
     22        assert_array_equals(element.takeLog().types(), ['connected']);
     23        testFunction(newDoc.documentElement, instance);
     24        assert_array_equals(element.takeLog().types(), ['disconnected', 'adopted', 'connected']);
     25    }, name + ' must enqueue a disconnected reaction, an adopted reaction, and a connected reaction when the custom element was in another document');
     26 
     27    container.parentNode.removeChild(container);
     28 }
     29 
     30 function testNodeDisconnector(testFunction, name) {
     31    let container = document.createElement('div');
     32    container.appendChild(document.createElement('div'));
     33    document.body.appendChild(container);
     34 
     35    test(function () {
     36        var element = define_new_custom_element();
     37        var instance = document.createElement(element.name);
     38        assert_array_equals(element.takeLog().types(), ['constructed']);
     39        container.appendChild(instance);
     40        assert_array_equals(element.takeLog().types(), ['connected']);
     41        testFunction(instance, window);
     42        assert_array_equals(element.takeLog().types(), ['disconnected']);
     43    }, name + ' must enqueue a disconnected reaction');
     44 
     45    container.parentNode.removeChild(container);
     46 }
     47 
     48 function testInsertingMarkup(testFunction, name) {
     49    let container = document.createElement('div');
     50    container.appendChild(document.createElement('div'));
     51    document.body.appendChild(container);
     52 
     53    test(function () {
     54        var element = define_new_custom_element();
     55        testFunction(container, `<${element.name}></${element.name}>`);
     56        assert_array_equals(element.takeLog().types(), ['constructed', 'connected']);
     57    }, name + ' must enqueue a connected reaction for a newly constructed custom element');
     58 
     59    test(function () {
     60        var element = define_new_custom_element(['title']);
     61        testFunction(container, `<${element.name} id="hello" title="hi"></${element.name}>`);
     62        var logEntries = element.takeLog();
     63        assert_array_equals(logEntries.types(), ['constructed', 'attributeChanged', 'connected']);
     64        assert_attribute_log_entry(logEntries[1], {name: 'title', oldValue: null, newValue: 'hi', namespace: null});
     65    }, name + ' must enqueue a attributeChanged reaction for a newly constructed custom element');
     66 
     67    container.parentNode.removeChild(container);
     68 }
     69 
     70 function testParsingMarkup(testFunction, name) {
     71    test(function () {
     72        var element = define_new_custom_element(['id']);
     73        assert_array_equals(element.takeLog().types(), []);
     74        var instance = testFunction(document, `<${element.name} id="hello" class="foo"></${element.name}>`);
     75        assert_equals(Object.getPrototypeOf(instance.querySelector(element.name)), element.class.prototype);
     76        var logEntries = element.takeLog();
     77        assert_array_equals(logEntries.types(), ['constructed', 'attributeChanged']);
     78        assert_attribute_log_entry(logEntries[1], {name: 'id', oldValue: null, newValue: 'hello', namespace: null});
     79    }, name + ' must construct a custom element');
     80 }
     81 
     82 function testCloner(testFunction, name) {
     83    let container = document.createElement('div');
     84    container.appendChild(document.createElement('div'));
     85    document.body.appendChild(container);
     86 
     87    test(function () {
     88        var element = define_new_custom_element(['id']);
     89        var instance = document.createElement(element.name);
     90        container.appendChild(instance);
     91 
     92        instance.setAttribute('id', 'foo');
     93        assert_array_equals(element.takeLog().types(), ['constructed', 'connected', 'attributeChanged']);
     94        var newInstance = testFunction(instance);
     95        var logEntries = element.takeLog();
     96        assert_array_equals(logEntries.types(), ['constructed', 'attributeChanged']);
     97        assert_attribute_log_entry(logEntries.last(), {name: 'id', oldValue: null, newValue: 'foo', namespace: null});
     98    }, name + ' must enqueue an attributeChanged reaction when cloning an element with an observed attribute');
     99 
    100    test(function () {
    101        var element = define_new_custom_element(['id']);
    102        var instance = document.createElement(element.name);
    103        container.appendChild(instance);
    104 
    105        instance.setAttribute('lang', 'en');
    106        assert_array_equals(element.takeLog().types(), ['constructed', 'connected']);
    107        var newInstance = testFunction(instance);
    108        assert_array_equals(element.takeLog().types(), ['constructed']);
    109    }, name + ' must not enqueue an attributeChanged reaction when cloning an element with an unobserved attribute');
    110 
    111    test(function () {
    112        var element = define_new_custom_element(['title', 'class']);
    113        var instance = document.createElement(element.name);
    114        container.appendChild(instance);
    115 
    116        instance.setAttribute('lang', 'en');
    117        instance.className = 'foo';
    118        instance.setAttribute('title', 'hello world');
    119        assert_array_equals(element.takeLog().types(), ['constructed', 'connected', 'attributeChanged', 'attributeChanged']);
    120        var newInstance = testFunction(instance);
    121        var logEntries = element.takeLog();
    122        assert_array_equals(logEntries.types(), ['constructed', 'attributeChanged', 'attributeChanged']);
    123        assert_attribute_log_entry(logEntries[1], {name: 'class', oldValue: null, newValue: 'foo', namespace: null});
    124        assert_attribute_log_entry(logEntries[2], {name: 'title', oldValue: null, newValue: 'hello world', namespace: null});
    125    }, name + ' must enqueue an attributeChanged reaction when cloning an element only for observed attributes');
    126 }
    127 
    128 function testReflectAttributeWithContentValues(jsAttributeName, contentAttributeName, validValue1, contentValue1, validValue2, contentValue2, name, elementName, interfaceName, optionalSupportPredicate) {
    129    test(function () {
    130        if (optionalSupportPredicate) {
    131            assert_implements_optional(optionalSupportPredicate());
    132        }
    133        if (elementName === undefined) {
    134            var element = define_new_custom_element([contentAttributeName]);
    135            var instance = document.createElement(element.name);
    136        } else {
    137            var element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
    138            var instance = document.createElement(elementName, { is: element.name });
    139        }
    140        assert_array_equals(element.takeLog().types(), ['constructed']);
    141        instance[jsAttributeName] = validValue1;
    142        var logEntries = element.takeLog();
    143        assert_array_equals(logEntries.types(), ['attributeChanged']);
    144 
    145        assert_attribute_log_entry(logEntries.last(), {name: contentAttributeName, oldValue: null, newValue: contentValue1, namespace: null});
    146    }, name + ' must enqueue an attributeChanged reaction when adding ' + contentAttributeName + ' content attribute');
    147 
    148    test(function () {
    149        if (optionalSupportPredicate) {
    150            assert_implements_optional(optionalSupportPredicate());
    151        }
    152        if (elementName === undefined) {
    153            var element = define_new_custom_element([contentAttributeName]);
    154            var instance = document.createElement(element.name);
    155        } else {
    156            var element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
    157            var instance = document.createElement(elementName, { is: element.name });
    158        }
    159        instance[jsAttributeName] = validValue1;
    160        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    161        instance[jsAttributeName] = validValue2;
    162        var logEntries = element.takeLog();
    163        assert_array_equals(logEntries.types(), ['attributeChanged']);
    164        assert_attribute_log_entry(logEntries.last(), {name: contentAttributeName, oldValue: contentValue1, newValue: contentValue2, namespace: null});
    165    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
    166 }
    167 
    168 function testReflectAttribute(jsAttributeName, contentAttributeName, validValue1, validValue2, name, elementName, interfaceName, optionalSupportPredicate) {
    169    testReflectAttributeWithContentValues(jsAttributeName, contentAttributeName, validValue1, validValue1, validValue2, validValue2, name, elementName, interfaceName, optionalSupportPredicate);
    170 }
    171 
    172 function testReflectBooleanAttribute(jsAttributeName, contentAttributeName, name, elementName, interfaceName) {
    173    testReflectAttributeWithContentValues(jsAttributeName, contentAttributeName, true, '', false, null, name, elementName, interfaceName);
    174 }
    175 
    176 function testReflectAttributeWithContentValuesAndDependentAttributes(jsAttributeName, contentAttributeName, validValue1, contentValue1, validValue2, contentValue2, name, elementName, getParentElement, setAttributes, interfaceName) {
    177    let parentElement = getParentElement();
    178 
    179    test(() => {
    180        let element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
    181        let instance = document.createElement(elementName, { is: element.name });
    182 
    183        assert_array_equals(element.takeLog().types(), ['constructed']);
    184        parentElement.appendChild(instance);
    185        assert_array_equals(element.takeLog().types(), ['connected']);
    186        setAttributes(instance);
    187        instance[jsAttributeName] = validValue1;
    188        let logEntries = element.takeLog();
    189        assert_array_equals(logEntries.types(), ['attributeChanged']);
    190        assert_attribute_log_entry(logEntries.last(), { name: contentAttributeName, oldValue: null, newValue: contentValue1, namespace: null });
    191 
    192    }, name + ' must enqueue an attributeChanged reaction when adding a new attribute');
    193 
    194    test(() => {
    195        let element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
    196        let instance = document.createElement(elementName, { is: element.name });
    197        parentElement.appendChild(instance);
    198        setAttributes(instance);
    199        instance[jsAttributeName] = validValue1;
    200 
    201        assert_array_equals(element.takeLog().types(), ['constructed', 'connected', 'attributeChanged']);
    202        instance[jsAttributeName] = validValue2;
    203        let logEntries = element.takeLog();
    204        assert_array_equals(logEntries.types(), ['attributeChanged']);
    205        assert_attribute_log_entry(logEntries.last(), { name: contentAttributeName, oldValue: contentValue1, newValue: contentValue2, namespace: null });
    206 
    207    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
    208 }
    209 
    210 function testReflectAttributeWithDependentAttributes(jsAttributeName, contentAttributeName, validValue1, validValue2, name, elementName, getParentElement, setAttributes, interfaceName) {
    211    testReflectAttributeWithContentValuesAndDependentAttributes(jsAttributeName, contentAttributeName, validValue1, validValue1, validValue2, validValue2, name, elementName, getParentElement, setAttributes, interfaceName);
    212 }
    213 
    214 function testReflectBooleanAttributeWithDependentAttributes(jsAttributeName, contentAttributeName, name, elementName, getParentElement, setAttributes, interfaceName) {
    215    testReflectAttributeWithContentValuesAndDependentAttributes(jsAttributeName, contentAttributeName, true, '', false, null, name, elementName, getParentElement, setAttributes, interfaceName);
    216 }
    217 
    218 function testReflectAttributeWithContentValuesAndParentNode(jsAttributeName, contentAttributeName, validValue1, contentValue1, validValue2, contentValue2, name, elementName, getParentElement, interfaceName) {
    219    let parentElement = getParentElement();
    220 
    221    test(() => {
    222        let element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
    223        let instance = document.createElement(elementName, { is: element.name });
    224 
    225        assert_array_equals(element.takeLog().types(), ['constructed']);
    226        parentElement.appendChild(instance);
    227        assert_array_equals(element.takeLog().types(), ['connected']);
    228        instance[jsAttributeName] = validValue1;
    229        let logEntries = element.takeLog();
    230        assert_array_equals(logEntries.types(), ['attributeChanged']);
    231        assert_attribute_log_entry(logEntries.last(), { name: contentAttributeName, oldValue: null, newValue: contentValue1, namespace: null });
    232 }, name + ' must enqueue an attributeChanged reaction when adding a new attribute');
    233 
    234    test(() => {
    235        let element = define_build_in_custom_element([contentAttributeName], interfaceName, elementName);
    236        let instance = document.createElement(elementName, { is: element.name });
    237        parentElement.appendChild(instance);
    238 
    239        assert_array_equals(element.takeLog().types(), ['constructed', 'connected']);
    240        instance[jsAttributeName] = validValue1;
    241        assert_array_equals(element.takeLog().types(), ['attributeChanged']);
    242        instance[jsAttributeName] = validValue2;
    243        let logEntries = element.takeLog();
    244        assert_array_equals(logEntries.types(), ['attributeChanged']);
    245        assert_attribute_log_entry(logEntries.last(), { name: contentAttributeName, oldValue: contentValue1, newValue: contentValue2, namespace: null });
    246    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
    247 }
    248 
    249 function testReflectAttributeWithParentNode(jsAttributeName, contentAttributeName, validValue1, validValue2, name, elementName, getParentElement, interfaceName) {
    250    testReflectAttributeWithContentValuesAndParentNode(jsAttributeName, contentAttributeName, validValue1, validValue1, validValue2, validValue2, name, elementName, getParentElement, interfaceName);
    251 }
    252 
    253 function testReflectBooleanAttributeWithParentNode(jsAttributeName, contentAttributeName, name, elementName, getParentElement, interfaceName) {
    254    testReflectAttributeWithContentValuesAndParentNode(jsAttributeName, contentAttributeName, true, '', false, null, name, elementName, getParentElement, interfaceName);
    255 }
    256 
    257 function testAttributeAdder(testFunction, name) {
    258    test(function () {
    259        var element = define_new_custom_element(['id']);
    260        var instance = document.createElement(element.name);
    261        assert_array_equals(element.takeLog().types(), ['constructed']);
    262        testFunction(instance, 'id', 'foo');
    263        var logEntries = element.takeLog();
    264        assert_array_equals(logEntries.types(), ['attributeChanged']);
    265        assert_attribute_log_entry(logEntries.last(), {name: 'id', oldValue: null, newValue: 'foo', namespace: null});
    266    }, name + ' must enqueue an attributeChanged reaction when adding an attribute');
    267 
    268    test(function () {
    269        var element = define_new_custom_element(['class']);
    270        var instance = document.createElement(element.name);
    271        assert_array_equals(element.takeLog().types(), ['constructed']);
    272        testFunction(instance, 'data-lang', 'en');
    273        assert_array_equals(element.takeLog().types(), []);
    274    }, name + ' must not enqueue an attributeChanged reaction when adding an unobserved attribute');
    275 
    276    test(function () {
    277        var element = define_new_custom_element(['title']);
    278        var instance = document.createElement(element.name);
    279        instance.setAttribute('title', 'hello');
    280        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    281        testFunction(instance, 'title', 'world');
    282        var logEntries = element.takeLog();
    283        assert_array_equals(logEntries.types(), ['attributeChanged']);
    284        assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: 'hello', newValue: 'world', namespace: null});
    285    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
    286 
    287    test(function () {
    288        var element = define_new_custom_element([]);
    289        var instance = document.createElement(element.name);
    290        instance.setAttribute('data-lang', 'zh');
    291        assert_array_equals(element.takeLog().types(), ['constructed']);
    292        testFunction(instance, 'data-lang', 'en');
    293        assert_array_equals(element.takeLog().types(), []);
    294    }, name + ' must enqueue an attributeChanged reaction when replacing an existing unobserved attribute');
    295 }
    296 
    297 function testAttributeMutator(testFunction, name) {
    298    test(function () {
    299        var element = define_new_custom_element(['title']);
    300        var instance = document.createElement(element.name);
    301        instance.setAttribute('title', 'hello');
    302        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    303        testFunction(instance, 'title', 'world');
    304        var logEntries = element.takeLog();
    305        assert_array_equals(logEntries.types(), ['attributeChanged']);
    306        assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: 'hello', newValue: 'world', namespace: null});
    307    }, name + ' must enqueue an attributeChanged reaction when replacing an existing attribute');
    308 
    309    test(function () {
    310        var element = define_new_custom_element(['class']);
    311        var instance = document.createElement(element.name);
    312        instance.setAttribute('data-lang', 'zh');
    313        assert_array_equals(element.takeLog().types(), ['constructed']);
    314        testFunction(instance, 'data-lang', 'en');
    315        assert_array_equals(element.takeLog().types(), []);
    316    }, name + ' must not enqueue an attributeChanged reaction when replacing an existing unobserved attribute');
    317 }
    318 
    319 function testAttributeRemover(testFunction, name, options) {
    320    if (options && !options.onlyExistingAttribute) {
    321        test(function () {
    322            var element = define_new_custom_element(['title']);
    323            var instance = document.createElement(element.name);
    324            assert_array_equals(element.takeLog().types(), ['constructed']);
    325            testFunction(instance, 'title');
    326            assert_array_equals(element.takeLog().types(), []);
    327        }, name + ' must not enqueue an attributeChanged reaction when removing an attribute that does not exist');
    328    }
    329 
    330    test(function () {
    331        var element = define_new_custom_element([]);
    332        var instance = document.createElement(element.name);
    333        instance.setAttribute('data-lang', 'hello');
    334        assert_array_equals(element.takeLog().types(), ['constructed']);
    335        testFunction(instance, 'data-lang');
    336        assert_array_equals(element.takeLog().types(), []);
    337    }, name + ' must not enqueue an attributeChanged reaction when removing an unobserved attribute');
    338 
    339    test(function () {
    340        var element = define_new_custom_element(['title']);
    341        var instance = document.createElement(element.name);
    342        instance.setAttribute('title', 'hello');
    343        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    344        testFunction(instance, 'title');
    345        var logEntries = element.takeLog();
    346        assert_array_equals(logEntries.types(), ['attributeChanged']);
    347        assert_attribute_log_entry(logEntries.last(), {name: 'title', oldValue: 'hello', newValue: null, namespace: null});
    348    }, name + ' must enqueue an attributeChanged reaction when removing an existing attribute');
    349 
    350    test(function () {
    351        var element = define_new_custom_element([]);
    352        var instance = document.createElement(element.name);
    353        instance.setAttribute('data-lang', 'ja');
    354        assert_array_equals(element.takeLog().types(), ['constructed']);
    355        testFunction(instance, 'data-lang');
    356        assert_array_equals(element.takeLog().types(), []);
    357    }, name + ' must not enqueue an attributeChanged reaction when removing an existing unobserved attribute');
    358 }
    359 
    360 function test_mutating_style_property_value(testFunction, name, options) {
    361    const propertyName = (options || {}).propertyName || 'color';
    362    const idlName = (options || {}).idlName || 'color';
    363    const value1 = (options || {}).value1 || 'blue';
    364    const rule1 = `${propertyName}: ${value1};`;
    365    const value2 = (options || {}).value2 || 'red';
    366    const rule2 = `${propertyName}: ${value2};`;
    367 
    368    test(function () {
    369        var element = define_new_custom_element(['style']);
    370        var instance = document.createElement(element.name);
    371        assert_array_equals(element.takeLog().types(), ['constructed']);
    372        testFunction(instance, propertyName, idlName, value1);
    373        assert_equals(instance.getAttribute('style'), rule1);
    374        var logEntries = element.takeLog();
    375        assert_array_equals(logEntries.types(), ['attributeChanged']);
    376        assert_attribute_log_entry(logEntries.last(), {name: 'style', oldValue: null, newValue: rule1, namespace: null});
    377    }, name + ' must enqueue an attributeChanged reaction when it adds the observed style attribute');
    378 
    379    test(function () {
    380        var element = define_new_custom_element(['title']);
    381        var instance = document.createElement(element.name);
    382        assert_array_equals(element.takeLog().types(), ['constructed']);
    383        testFunction(instance, propertyName, idlName, value1);
    384        assert_equals(instance.getAttribute('style'), rule1);
    385        assert_array_equals(element.takeLog().types(), []);
    386    }, name + ' must not enqueue an attributeChanged reaction when it adds the style attribute but the style attribute is not observed');
    387 
    388    test(function () {
    389        var element = define_new_custom_element(['style']);
    390        var instance = document.createElement(element.name);
    391        testFunction(instance, propertyName, idlName, value1);
    392        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    393        testFunction(instance, propertyName, idlName, value2);
    394        assert_equals(instance.getAttribute('style'), rule2);
    395        var logEntries = element.takeLog();
    396        assert_array_equals(logEntries.types(), ['attributeChanged']);
    397        assert_attribute_log_entry(logEntries.last(), {name: 'style', oldValue: rule1, newValue: rule2, namespace: null});
    398    }, name + ' must enqueue an attributeChanged reaction when it mutates the observed style attribute');
    399 
    400    test(function () {
    401        var element = define_new_custom_element([]);
    402        var instance = document.createElement(element.name);
    403        testFunction(instance, propertyName, idlName, value1);
    404        assert_array_equals(element.takeLog().types(), ['constructed']);
    405        testFunction(instance, propertyName, idlName, value2);
    406        assert_equals(instance.getAttribute('style'), rule2);
    407        assert_array_equals(element.takeLog().types(), []);
    408    }, name + ' must not enqueue an attributeChanged reaction when it mutates the style attribute but the style attribute is not observed');
    409 }
    410 
    411 function test_removing_style_property_value(testFunction, name) {
    412    test(function () {
    413        var element = define_new_custom_element(['style']);
    414        var instance = document.createElement(element.name);
    415        instance.setAttribute('style', 'color: red; display: none;');
    416        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    417        testFunction(instance, 'color', 'color');
    418        assert_equals(instance.getAttribute('style'), 'display: none;'); // Don't make this empty since browser behaviors are inconsistent now.
    419        var logEntries = element.takeLog();
    420        assert_array_equals(logEntries.types(), ['attributeChanged']);
    421        assert_attribute_log_entry(logEntries.last(), {name: 'style', oldValue: 'color: red; display: none;', newValue: 'display: none;', namespace: null});
    422    }, name + ' must enqueue an attributeChanged reaction when it removes a property from the observed style attribute');
    423 
    424    test(function () {
    425        var element = define_new_custom_element(['class']);
    426        var instance = document.createElement(element.name);
    427        instance.setAttribute('style', 'color: red; display: none;');
    428        assert_array_equals(element.takeLog().types(), ['constructed']);
    429        testFunction(instance, 'color', 'color');
    430        assert_equals(instance.getAttribute('style'), 'display: none;'); // Don't make this empty since browser behaviors are inconsistent now.
    431        assert_array_equals(element.takeLog().types(), []);
    432    }, name + ' must not enqueue an attributeChanged reaction when it removes a property from the style attribute but the style attribute is not observed');
    433 }
    434 
    435 function test_mutating_style_property_priority(testFunction, name) {
    436    test(function () {
    437        var element = define_new_custom_element(['style']);
    438        var instance = document.createElement(element.name);
    439        instance.setAttribute('style', 'color: red');
    440        assert_array_equals(element.takeLog().types(), ['constructed', 'attributeChanged']);
    441        testFunction(instance, 'color', 'color', true);
    442        assert_equals(instance.getAttribute('style'), 'color: red !important;');
    443        var logEntries = element.takeLog();
    444        assert_array_equals(logEntries.types(), ['attributeChanged']);
    445        assert_attribute_log_entry(logEntries.last(), {name: 'style', oldValue: 'color: red', newValue: 'color: red !important;', namespace: null});
    446    }, name + ' must enqueue an attributeChanged reaction when it makes a property important and the style attribute is observed');
    447 
    448    test(function () {
    449        var element = define_new_custom_element(['id']);
    450        var instance = document.createElement(element.name);
    451        instance.setAttribute('style', 'color: red');
    452        assert_array_equals(element.takeLog().types(), ['constructed']);
    453        testFunction(instance, 'color', 'color', true);
    454        assert_equals(instance.getAttribute('style'), 'color: red !important;');
    455        assert_array_equals(element.takeLog().types(), []);
    456    }, name + ' must enqueue an attributeChanged reaction when it makes a property important but the style attribute is not observed');
    457 }