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

atinc / ngx-tethys / d9ae709b-3c27-4b69-b125-b8b80b54f90b

pending completion
d9ae709b-3c27-4b69-b125-b8b80b54f90b

Pull #2757

circleci

mengshuicmq
fix: fix code review
Pull Request #2757: feat(color-picker): color-picker support disabled (#INFR-8645)

98 of 6315 branches covered (1.55%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

2392 of 13661 relevant lines covered (17.51%)

83.12 hits per line

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

0.96
/src/core/overlay/abstract-overlay-ref.ts
1
import { ESCAPE, helpers } from 'ngx-tethys/util';
2
import { Observable, of, Subject } from 'rxjs';
3
import { filter, take } from 'rxjs/operators';
4

5
import { GlobalPositionStrategy, OverlayRef, PositionStrategy } from '@angular/cdk/overlay';
6

7
import { ThyAbstractOverlayContainer } from './abstract-overlay-container';
8
import { ThyAbstractOverlayConfig, ThyAbstractOverlayOptions, ThyAbstractOverlayPosition } from './abstract-overlay.config';
1✔
9

10
export abstract class ThyAbstractOverlayRef<
×
11
    TComponent = unknown,
×
12
    TContainer extends ThyAbstractOverlayContainer = ThyAbstractOverlayContainer,
13
    TResult = unknown
14
> {
×
15
    id: string;
16
    componentInstance: TComponent;
×
17
    backdropClosable: boolean;
18
    disableClose: boolean;
19
    containerInstance: TContainer;
20

21
    /**
×
22
     * 获取 OverlayRef
23
     */
24
    abstract getOverlayRef(): OverlayRef;
×
25

×
26
    /**
×
27
     * 关闭当前模态框,若force为true,则canClose无效,强制关闭
×
28
     * @param dialogResult
29
     * @param force
×
30
     */
31
    abstract close(dialogResult?: TResult, force?: boolean): void;
×
32

33
    /**
×
34
     * 模态框打开后的回调
35
     */
×
36
    abstract afterOpened(): Observable<void>;
37

×
38
    /**
×
39
     * 模态框关闭后的回调
40
     */
×
41
    abstract afterClosed(): Observable<TResult | undefined>;
42

×
43
    /**
×
44
     * 模态框关闭前的回调
×
45
     */
×
46
    abstract beforeClosed(): Observable<TResult | undefined>;
47

48
    abstract keydownEvents(): Observable<KeyboardEvent>;
49

×
50
    /**
×
51
     * 点击模态框遮罩层的回调
×
52
     */
53
    abstract backdropClick(): Observable<MouseEvent>;
54

55
    /**
×
56
     * 更新模态框的位置
×
57
     * @param position
58
     */
×
59
    abstract updatePosition(position?: ThyAbstractOverlayPosition): this;
×
60
}
61

62
// Counter for unique overlay ids.
63
const uniqueIdMap: { [key: string]: number } = {};
×
64

×
65
function getUniqueId(name: string) {
×
66
    if (uniqueIdMap[name] !== undefined) {
×
67
        uniqueIdMap[name] = uniqueIdMap[name] + 1;
×
68
    } else {
×
69
        uniqueIdMap[name] = 0;
×
70
    }
71
    return uniqueIdMap[name];
72
}
×
73

74
export abstract class ThyAbstractInternalOverlayRef<
×
75
    T,
76
    TContainer extends ThyAbstractOverlayContainer,
×
77
    TResult = undefined
×
78
> extends ThyAbstractOverlayRef<T, TContainer, TResult> {
79
    /** The instance of component opened into the dialog. */
80
    componentInstance: T;
81

82
    /** Whether the user is allowed to close the dialog. */
83
    backdropClosable: boolean = this.config.backdropClosable;
84

85
    /** Whether the user is not allowed to close the dialog. */
86
    disableClose: boolean = this.config.disableClose;
×
87

×
88
    /** Subject for notifying the user that the dialog has finished opening. */
89
    private readonly _afterOpened = new Subject<void>();
×
90

×
91
    /** Subject for notifying the user that the dialog has finished closing. */
×
92
    private readonly _afterClosed = new Subject<TResult | undefined>();
93

×
94
    /** Subject for notifying the user that the dialog has started closing. */
×
95
    private readonly _beforeClosed = new Subject<TResult | undefined>();
96

97
    /** Result to be passed to afterClosed. */
98
    private _result: TResult | undefined;
99

100
    /** Fetches the position strategy object from the overlay ref. */
101
    protected getPositionStrategy(): PositionStrategy {
×
102
        return this.overlayRef.getConfig().positionStrategy;
103
    }
104

105
    constructor(
106
        private options: ThyAbstractOverlayOptions,
107
        protected overlayRef: OverlayRef,
×
108
        containerInstance: TContainer,
109
        protected config: ThyAbstractOverlayConfig
110
    ) {
111
        super();
112
        this.containerInstance = containerInstance;
113
        // Pass the id along to the container.
×
114
        this.id = containerInstance.id = config.id ? config.id : `thy-${this.options.name}-${getUniqueId(this.options.name)}`;
115
        // Emit when opening animation completes
116
        containerInstance.animationOpeningDone.pipe(take(1)).subscribe(() => {
117
            this._afterOpened.next();
118
            if (this.options.disposeWhenClose) {
119
                this._afterOpened.complete();
×
120
            }
121
        });
122

123
        // Dispose overlay when closing animation is complete
124
        containerInstance.animationClosingDone.pipe(take(1)).subscribe(() => {
125
            if (this.options.disposeWhenClose) {
×
126
                this.overlayRef.dispose();
127
            }
128
        });
129

×
130
        // Dispose overlay when container after destroy
131
        containerInstance.containerDestroy.pipe(take(1)).subscribe(() => {
132
            if (this.options.disposeWhenClose) {
133
                // component element has not been deleted when the component destroy, so use promise wait for component element destroyed
134
                Promise.resolve().then(() => {
135
                    this.overlayRef.dispose();
136
                });
×
137
            }
×
138
        });
×
139

140
        overlayRef.detachments().subscribe(() => {
×
141
            this._beforeClosed.next(this._result);
×
142
            this._beforeClosed.complete();
143
            this._afterClosed.next(this._result);
144
            this._afterClosed.complete();
×
145
            this.componentInstance = null;
146
            this.overlayRef.dispose();
×
147
        });
×
148

149
        // ESC close
150
        overlayRef
×
151
            .keydownEvents()
152
            .pipe(filter(event => event.keyCode === ESCAPE))
×
153
            .subscribe(() => {
×
154
                if ((this.disableClose !== undefined && !this.disableClose) || this.backdropClosable) {
155
                    this.close();
156
                }
157
            });
158
    }
159

160
    /**
161
     * Close the overlay.
162
     * @param overlayResult Optional result to return to the dialog opener.
163
     */
164
    close(overlayResult?: TResult, force?: boolean): void {
165
        if (force || !this.config.canClose || !!this.config.canClose(overlayResult)) {
166
            this._result = overlayResult;
167
            // Transition the backdrop in parallel to the overlay.
168
            this._beforeClosed.next(overlayResult);
169
            if (this.options.disposeWhenClose) {
170
                this._beforeClosed.complete();
171
            }
172

173
            this.overlayRef.detachBackdrop();
174
            this.containerInstance.startExitAnimation();
175
        }
176
    }
177

178
    /**
179
     * Gets an observable that is notified when the dialog is finished opening.
180
     */
181
    afterOpened(): Observable<void> {
182
        return this._afterOpened.asObservable();
183
    }
184

185
    /**
186
     * Gets an observable that is notified when the dialog is finished closing.
187
     */
188
    afterClosed(): Observable<TResult | undefined> {
189
        return this._afterClosed.asObservable();
190
    }
191

192
    /**
193
     * Gets an observable that is notified when the dialog has started closing.
194
     */
195
    beforeClosed(): Observable<TResult | undefined> {
196
        return this._beforeClosed.asObservable();
197
    }
198

199
    /**
200
     * Gets an observable that emits when the overlay's backdrop has been clicked.
201
     */
202
    backdropClick(): Observable<MouseEvent> {
203
        return this.overlayRef.backdropClick();
204
    }
205

206
    /**
207
     * Gets an observable that emits when keydown events are targeted on the overlay.
208
     */
209
    keydownEvents(): Observable<KeyboardEvent> {
210
        return this.overlayRef.keydownEvents();
211
    }
212

213
    /** Get overlay ref */
214
    getOverlayRef() {
215
        return this.overlayRef;
216
    }
217

218
    /**
219
     * Updates the overlay's position when is GlobalPositionStrategy
220
     * @param position New overlay position.
221
     */
222
    updateGlobalPosition(position?: ThyAbstractOverlayPosition): this {
223
        const strategy = this.getPositionStrategy() as GlobalPositionStrategy;
224

225
        if ((typeof ngDevMode === 'undefined' || ngDevMode) && !(strategy instanceof GlobalPositionStrategy)) {
226
            throw new Error(`current strategy is not GlobalPositionStrategy`);
227
        }
228

229
        if (position && (position.left || position.right)) {
230
            position.left ? strategy.left(position.left) : strategy.right(position.right);
231
        } else {
232
            strategy.centerHorizontally();
233
        }
234

235
        if (position && (position.top || position.bottom)) {
236
            position.top ? strategy.top(position.top) : strategy.bottom(position.bottom);
237
        } else {
238
            strategy.centerVertically();
239
        }
240

241
        this.overlayRef.updatePosition();
242

243
        return this;
244
    }
245
}
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