• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

adobe / spectrum-web-components / 14094674923

26 Mar 2025 10:27PM UTC coverage: 86.218% (-11.8%) from 98.002%
14094674923

Pull #5221

github

web-flow
Merge 2a1ea92e7 into 3184c1e6a
Pull Request #5221: RFC | leverage css module imports in components

1737 of 2032 branches covered (85.48%)

Branch coverage included in aggregate %.

14184 of 16434 relevant lines covered (86.31%)

85.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.5
/tools/shared/src/observe-slot-presence.ts
1
/*
15✔
2
Copyright 2020 Adobe. All rights reserved.
15✔
3
This file is licensed to you under the Apache License, Version 2.0 (the "License");
15✔
4
you may not use this file except in compliance with the License. You may obtain a copy
15✔
5
of the License at http://www.apache.org/licenses/LICENSE-2.0
15✔
6
Unless required by applicable law or agreed to in writing, software distributed under
15✔
7
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
15✔
8
OF ANY KIND, either express or implied. See the License for the specific language
15✔
9
governing permissions and limitations under the License.
15✔
10
*/
15✔
11
import { ReactiveElement } from '@spectrum-web-components/base';
15✔
12
import { MutationController } from '@lit-labs/observers/mutation-controller.js';
15✔
13

15✔
14
const slotContentIsPresent = Symbol('slotContentIsPresent');
15✔
15

15✔
16
type Constructor<T = Record<string, unknown>> = {
15✔
17
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
15✔
18
    new (...args: any[]): T;
15✔
19
    prototype: T;
15✔
20
};
15✔
21

15✔
22
export interface SlotPresenceObservingInterface {
15✔
23
    slotContentIsPresent: boolean;
15✔
24
    getSlotContentPresence(selector: string): boolean;
15✔
25
    managePresenceObservedSlot(): void;
15✔
26
}
15✔
27

15✔
28
export function ObserveSlotPresence<T extends Constructor<ReactiveElement>>(
15✔
29
    constructor: T,
15✔
30
    lightDomSelector: string | string[]
15✔
31
): T & Constructor<SlotPresenceObservingInterface> {
15✔
32
    const lightDomSelectors = Array.isArray(lightDomSelector)
15!
33
        ? lightDomSelector
×
34
        : [lightDomSelector];
15✔
35
    class SlotPresenceObservingElement
15✔
36
        extends constructor
15✔
37
        implements SlotPresenceObservingInterface
15✔
38
    {
15✔
39
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
15✔
40
        constructor(...args: any[]) {
15✔
41
            super(args);
231✔
42

231✔
43
            new MutationController(this, {
231✔
44
                config: {
231✔
45
                    childList: true,
231✔
46
                    subtree: true,
231✔
47
                },
231✔
48
                callback: () => {
231✔
49
                    this.managePresenceObservedSlot();
244✔
50
                },
244✔
51
            });
231✔
52

231✔
53
            this.managePresenceObservedSlot();
231✔
54
        }
231✔
55

15✔
56
        /**
15✔
57
         *  @private
15✔
58
         */
15✔
59
        public get slotContentIsPresent(): boolean {
15✔
60
            if (lightDomSelectors.length === 1) {
179✔
61
                return (
179✔
62
                    this[slotContentIsPresent].get(lightDomSelectors[0]) ||
179✔
63
                    false
178✔
64
                );
179✔
65
            } else {
179✔
66
                throw new Error(
×
67
                    'Multiple selectors provided to `ObserveSlotPresence` use `getSlotContentPresence(selector: string)` instead.'
×
68
                );
×
69
            }
×
70
        }
179✔
71
        private [slotContentIsPresent]: Map<string, boolean> = new Map();
15✔
72

15✔
73
        public getSlotContentPresence(selector: string): boolean {
15✔
74
            if (this[slotContentIsPresent].has(selector)) {
×
75
                return this[slotContentIsPresent].get(selector) || false;
×
76
            }
×
77
            throw new Error(
×
78
                `The provided selector \`${selector}\` is not being observed.`
×
79
            );
×
80
        }
×
81

15✔
82
        public managePresenceObservedSlot = (): void => {
15✔
83
            let changes = false;
478✔
84
            lightDomSelectors.forEach((selector) => {
478✔
85
                const nextValue = !!this.querySelector(`:scope > ${selector}`);
478✔
86
                const previousValue =
478✔
87
                    this[slotContentIsPresent].get(selector) || false;
478✔
88
                changes = changes || previousValue !== nextValue;
478✔
89
                this[slotContentIsPresent].set(
478✔
90
                    selector,
478✔
91
                    !!this.querySelector(`:scope > ${selector}`)
478✔
92
                );
478✔
93
            });
478✔
94
            if (changes) {
478✔
95
                this.updateComplete.then(() => {
4✔
96
                    this.requestUpdate();
4✔
97
                });
4✔
98
            }
4✔
99
        };
478✔
100
    }
15✔
101
    return SlotPresenceObservingElement;
15✔
102
}
15✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc