UNPKG

6.66 kBJavaScriptView Raw
1import * as i0 from '@angular/core';
2import { InjectionToken, inject, EventEmitter, Injectable, Optional, Inject, Directive, Output, Input, NgModule } from '@angular/core';
3import { DOCUMENT } from '@angular/common';
4
5/**
6 * Injection token used to inject the document into Directionality.
7 * This is used so that the value can be faked in tests.
8 *
9 * We can't use the real document in tests because changing the real `dir` causes geometry-based
10 * tests in Safari to fail.
11 *
12 * We also can't re-provide the DOCUMENT token from platform-browser because the unit tests
13 * themselves use things like `querySelector` in test code.
14 *
15 * This token is defined in a separate file from Directionality as a workaround for
16 * https://github.com/angular/angular/issues/22559
17 *
18 * @docs-private
19 */
20const DIR_DOCUMENT = new InjectionToken('cdk-dir-doc', {
21 providedIn: 'root',
22 factory: DIR_DOCUMENT_FACTORY,
23});
24/** @docs-private */
25function DIR_DOCUMENT_FACTORY() {
26 return inject(DOCUMENT);
27}
28
29/** Regex that matches locales with an RTL script. Taken from `goog.i18n.bidi.isRtlLanguage`. */
30const RTL_LOCALE_PATTERN = /^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_](Adlm|Arab|Hebr|Nkoo|Rohg|Thaa))(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)/i;
31/** Resolves a string value to a specific direction. */
32function _resolveDirectionality(rawValue) {
33 const value = rawValue?.toLowerCase() || '';
34 if (value === 'auto' && typeof navigator !== 'undefined' && navigator?.language) {
35 return RTL_LOCALE_PATTERN.test(navigator.language) ? 'rtl' : 'ltr';
36 }
37 return value === 'rtl' ? 'rtl' : 'ltr';
38}
39/**
40 * The directionality (LTR / RTL) context for the application (or a subtree of it).
41 * Exposes the current direction and a stream of direction changes.
42 */
43class Directionality {
44 constructor(_document) {
45 /** The current 'ltr' or 'rtl' value. */
46 this.value = 'ltr';
47 /** Stream that emits whenever the 'ltr' / 'rtl' state changes. */
48 this.change = new EventEmitter();
49 if (_document) {
50 const bodyDir = _document.body ? _document.body.dir : null;
51 const htmlDir = _document.documentElement ? _document.documentElement.dir : null;
52 this.value = _resolveDirectionality(bodyDir || htmlDir || 'ltr');
53 }
54 }
55 ngOnDestroy() {
56 this.change.complete();
57 }
58 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: Directionality, deps: [{ token: DIR_DOCUMENT, optional: true }], target: i0.ɵɵFactoryTarget.Injectable }); }
59 static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: Directionality, providedIn: 'root' }); }
60}
61i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: Directionality, decorators: [{
62 type: Injectable,
63 args: [{ providedIn: 'root' }]
64 }], ctorParameters: function () { return [{ type: undefined, decorators: [{
65 type: Optional
66 }, {
67 type: Inject,
68 args: [DIR_DOCUMENT]
69 }] }]; } });
70
71/**
72 * Directive to listen for changes of direction of part of the DOM.
73 *
74 * Provides itself as Directionality such that descendant directives only need to ever inject
75 * Directionality to get the closest direction.
76 */
77class Dir {
78 constructor() {
79 /** Normalized direction that accounts for invalid/unsupported values. */
80 this._dir = 'ltr';
81 /** Whether the `value` has been set to its initial value. */
82 this._isInitialized = false;
83 /** Event emitted when the direction changes. */
84 this.change = new EventEmitter();
85 }
86 /** @docs-private */
87 get dir() {
88 return this._dir;
89 }
90 set dir(value) {
91 const previousValue = this._dir;
92 // Note: `_resolveDirectionality` resolves the language based on the browser's language,
93 // whereas the browser does it based on the content of the element. Since doing so based
94 // on the content can be expensive, for now we're doing the simpler matching.
95 this._dir = _resolveDirectionality(value);
96 this._rawDir = value;
97 if (previousValue !== this._dir && this._isInitialized) {
98 this.change.emit(this._dir);
99 }
100 }
101 /** Current layout direction of the element. */
102 get value() {
103 return this.dir;
104 }
105 /** Initialize once default value has been set. */
106 ngAfterContentInit() {
107 this._isInitialized = true;
108 }
109 ngOnDestroy() {
110 this.change.complete();
111 }
112 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: Dir, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
113 static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: Dir, selector: "[dir]", inputs: { dir: "dir" }, outputs: { change: "dirChange" }, host: { properties: { "attr.dir": "_rawDir" } }, providers: [{ provide: Directionality, useExisting: Dir }], exportAs: ["dir"], ngImport: i0 }); }
114}
115i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: Dir, decorators: [{
116 type: Directive,
117 args: [{
118 selector: '[dir]',
119 providers: [{ provide: Directionality, useExisting: Dir }],
120 host: { '[attr.dir]': '_rawDir' },
121 exportAs: 'dir',
122 }]
123 }], propDecorators: { change: [{
124 type: Output,
125 args: ['dirChange']
126 }], dir: [{
127 type: Input
128 }] } });
129
130class BidiModule {
131 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: BidiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
132 static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.0.0", ngImport: i0, type: BidiModule, declarations: [Dir], exports: [Dir] }); }
133 static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: BidiModule }); }
134}
135i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: BidiModule, decorators: [{
136 type: NgModule,
137 args: [{
138 exports: [Dir],
139 declarations: [Dir],
140 }]
141 }] });
142
143/**
144 * Generated bundle index. Do not edit.
145 */
146
147export { BidiModule, DIR_DOCUMENT, Dir, Directionality };
148//# sourceMappingURL=bidi.mjs.map