• 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

4.05
/src/autocomplete/overlay/autocomplete.service.ts
1
import { getFlexiblePositions, ThyAbstractOverlayService } from 'ngx-tethys/core';
2
import { of, Subject } from 'rxjs';
3
import { takeUntil } from 'rxjs/operators';
4

5
import { Directionality } from '@angular/cdk/bidi';
6
import { coerceArray, coerceElement } from '@angular/cdk/coercion';
7
import {
8
    ComponentType,
9
    FlexibleConnectedPositionStrategy,
10
    Overlay,
11
    OverlayConfig,
12
    OverlayContainer,
13
    OverlayRef,
14
    PositionStrategy,
15
    ScrollDispatcher
16
} from '@angular/cdk/overlay';
17
import { Platform } from '@angular/cdk/platform';
18
import { ComponentPortal } from '@angular/cdk/portal';
19
import { ViewportRuler } from '@angular/cdk/scrolling';
20
import { DOCUMENT } from '@angular/common';
1✔
21
import { ElementRef, Inject, Injectable, Injector, NgZone, OnDestroy, StaticProvider, TemplateRef } from '@angular/core';
22

×
23
import { ThyAutocompleteContainerComponent } from './autocomplete-container.component';
×
24
import { ThyAutocompleteRef, ThyInternalAutocompleteRef } from './autocomplete-ref';
×
25
import { THY_AUTOCOMPLETE_DEFAULT_CONFIG, ThyAutocompleteConfig } from './autocomplete.config';
×
26
import { autocompleteAbstractOverlayOptions } from './autocomplete.options';
×
27

×
28
/**
29
 * @private
30
 */
×
31
@Injectable()
32
export class ThyAutocompleteService
33
    extends ThyAbstractOverlayService<ThyAutocompleteConfig, ThyAutocompleteContainerComponent>
×
34
    implements OnDestroy
35
{
36
    private readonly ngUnsubscribe$ = new Subject();
×
37

×
38
    private originInstancesMap = new Map<
×
39
        ElementRef | HTMLElement,
×
40
        {
×
41
            config: ThyAutocompleteConfig;
×
42
            autocompleteRef: ThyAutocompleteRef<any, any>;
43
        }
44
    >();
×
45

×
46
    private buildPositionStrategy<TData>(config: ThyAutocompleteConfig<TData>): PositionStrategy {
×
47
        const positionStrategy = new FlexibleConnectedPositionStrategy(
48
            config.origin,
49
            this._viewportRuler,
×
50
            this._document,
×
51
            this._platform,
×
52
            this._overlayContainer
53
        );
54
        const positions = getFlexiblePositions(config.placement, config.offset, 'thy-autocomplete');
×
55
        positionStrategy.withPositions(positions);
56
        positionStrategy.withGrowAfterOpen(true);
57
        positionStrategy.positionChanges.pipe(takeUntil(this.ngUnsubscribe$)).subscribe(change => {
×
58
            if (change.scrollableViewProperties.isOverlayClipped) {
×
59
                // After position changes occur and the overlay is clipped by
60
                // a parent scrollable then close the tooltip.
61
                this.ngZone.run(() => this.close());
62
            }
63
        });
64
        return positionStrategy;
65
    }
66

67
    protected buildOverlayConfig<TData>(config: ThyAutocompleteConfig<TData>): OverlayConfig {
68
        const strategy = this.buildPositionStrategy(config);
×
69
        const overlayConfig = this.buildBaseOverlayConfig(config);
×
70
        overlayConfig.positionStrategy = strategy;
71
        overlayConfig.scrollStrategy = config.scrollStrategy || this.overlay.scrollStrategies.block();
72
        overlayConfig.width = config.width;
73
        return overlayConfig;
74
    }
75

76
    protected attachOverlayContainer(overlay: OverlayRef, config: ThyAutocompleteConfig<any>): ThyAutocompleteContainerComponent {
77
        const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
×
78
        const injector = Injector.create({
79
            parent: userInjector || this.injector,
80
            providers: [{ provide: ThyAutocompleteConfig, useValue: config }]
×
81
        });
×
82
        const containerPortal = new ComponentPortal(ThyAutocompleteContainerComponent, config.viewContainerRef, injector);
83
        const containerRef = overlay.attach<ThyAutocompleteContainerComponent>(containerPortal);
84
        return containerRef.instance;
85
    }
×
86

×
87
    protected createAbstractOverlayRef<T>(
88
        overlayRef: OverlayRef,
89
        containerInstance: ThyAutocompleteContainerComponent,
90
        config: ThyAutocompleteConfig<any>
×
91
    ): ThyInternalAutocompleteRef<T> {
×
92
        return new ThyInternalAutocompleteRef<T>(overlayRef, containerInstance, config);
×
93
    }
×
94

×
95
    protected createInjector<T>(
×
96
        config: ThyAutocompleteConfig,
×
97
        autocompleteRef: ThyAutocompleteRef<T>,
×
98
        autocompleteContainer: ThyAutocompleteContainerComponent
×
99
    ): Injector {
100
        const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
101
        const injectionTokens: StaticProvider[] = [
×
102
            {
×
103
                provide: ThyAutocompleteContainerComponent,
×
104
                useValue: autocompleteContainer
×
105
            },
×
106
            {
×
107
                provide: ThyAutocompleteRef,
108
                useValue: autocompleteRef
×
109
            }
×
110
        ];
111

112
        if (config.direction && (!userInjector || !userInjector.get<Directionality | null>(Directionality, null))) {
113
            injectionTokens.push({
×
114
                provide: Directionality,
115
                useValue: {
116
                    value: config.direction,
×
117
                    change: of()
118
                }
1✔
119
            });
120
        }
121

122
        return Injector.create({ parent: userInjector || this.injector, providers: injectionTokens });
123
    }
124

125
    private originElementAddActiveClass(config: ThyAutocompleteConfig) {
126
        if (config.originActiveClass) {
127
            coerceElement<HTMLElement>(config.origin).classList.add(...coerceArray(config.originActiveClass));
128
        }
129
    }
130

1✔
131
    private originElementRemoveActiveClass(config: ThyAutocompleteConfig) {
132
        if (config.originActiveClass) {
133
            coerceElement<HTMLElement>(config.origin).classList.remove(...coerceArray(config.originActiveClass));
134
        }
135
    }
136

137
    constructor(
138
        overlay: Overlay,
139
        injector: Injector,
140
        @Inject(THY_AUTOCOMPLETE_DEFAULT_CONFIG) defaultConfig: ThyAutocompleteConfig,
141
        private scrollDispatcher: ScrollDispatcher,
142
        private ngZone: NgZone,
143
        private _viewportRuler: ViewportRuler,
144
        @Inject(DOCUMENT) private _document: any,
145
        private _platform: Platform,
146
        private _overlayContainer: OverlayContainer
147
    ) {
148
        super(autocompleteAbstractOverlayOptions, overlay, injector, defaultConfig);
149
    }
150

151
    open<T, TData = any, TResult = any>(
152
        componentOrTemplateRef: ComponentType<T> | TemplateRef<T>,
153
        config?: ThyAutocompleteConfig<TData>
154
    ): ThyAutocompleteRef<T, TResult> {
155
        const originElement = coerceElement(config.origin);
156
        const autocompleteRef = this.openOverlay(componentOrTemplateRef, config) as ThyAutocompleteRef<T>;
157
        config = autocompleteRef.containerInstance.config;
158
        autocompleteRef.afterClosed().subscribe(() => {
159
            this.originElementRemoveActiveClass(config);
160
            this.originInstancesMap.delete(originElement);
161
        });
162

163
        this.originElementAddActiveClass(config);
164
        this.originInstancesMap.set(originElement, {
165
            config,
166
            autocompleteRef
167
        });
168

169
        return autocompleteRef;
170
    }
171

172
    ngOnDestroy() {
173
        this.dispose();
174
    }
175
}
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