@plohoj/html-editor 0.0.7 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +137 -123
- package/dist/index.js +256 -99
- package/dist/index.js.map +1 -1
- package/package.json +25 -25
- package/src/index.ts +25 -23
- package/src/observable/await-element.ts +47 -29
- package/src/observable/await-elements.ts +38 -20
- package/src/observable/await-random-element.ts +40 -22
- package/src/observable/observe-mutation.ts +10 -12
- package/src/observable/observe-pressed-keyboard-buttons.ts +29 -30
- package/src/observable/observe-query-selector-all.ts +154 -101
- package/src/observable/observe-query-selector.ts +176 -112
- package/src/observable/observe-url-changes.ts +23 -0
- package/src/observable/url-change.ts +37 -38
- package/src/operators/blur-element.ts +21 -0
- package/src/operators/click-element.ts +20 -21
- package/src/operators/focus-element.ts +21 -22
- package/src/operators/merge-map-added-elements.ts +120 -77
- package/src/operators/merge-map-by-condition.ts +124 -0
- package/src/operators/merge-map-by-string-condition.ts +57 -0
- package/src/operators/remove-element.ts +8 -9
- package/src/operators/restore-history.ts +53 -51
- package/src/operators/set-input-value.ts +20 -21
- package/src/utils/compose-restore-history.ts +61 -61
- package/src/utils/find-recursively.ts +203 -203
- package/src/utils/random-from-array.ts +6 -6
- package/src/utils/stubs.ts +7 -7
- package/src/operators/merge-map-string-toggle.ts +0 -36
|
@@ -1,77 +1,120 @@
|
|
|
1
|
-
import { EMPTY,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
import { connect, EMPTY, filter, merge, mergeMap, Observable, OperatorFunction, takeUntil } from "rxjs";
|
|
2
|
+
import type { observeQuerySelector, IObservedElementChange, IObserveQuerySelectorOptions } from "../observable/observe-query-selector";
|
|
3
|
+
import type { observeQuerySelectorAll, IObservedElementsChanges } from "../observable/observe-query-selector-all";
|
|
4
|
+
|
|
5
|
+
export interface IMergeMapElementChangeOptions<E extends Element = Element, O = unknown> {
|
|
6
|
+
/**
|
|
7
|
+
* The function that will be called to generate a new stream
|
|
8
|
+
* for each element discovered the first time after it is added.
|
|
9
|
+
*/
|
|
10
|
+
project: (element: E) => Observable<O>;
|
|
11
|
+
/**
|
|
12
|
+
* Determines when a stream from the {@link project} function should be terminated:
|
|
13
|
+
* * `'removed'`: As soon as the element is removed.
|
|
14
|
+
* * `'added'`: After the element is removed and (new one will discovered or have already been discovered before).
|
|
15
|
+
* * `'always'`: streams will not be interrupted, after the element is removed.
|
|
16
|
+
*
|
|
17
|
+
* @default 'removed'
|
|
18
|
+
*/
|
|
19
|
+
takeUntil?: 'removed' | 'added' | 'always';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function assuredArray<T>(values?: T | T[]): T[] {
|
|
23
|
+
if (values instanceof Array) {
|
|
24
|
+
return values
|
|
25
|
+
}
|
|
26
|
+
if (values) {
|
|
27
|
+
return [values];
|
|
28
|
+
}
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Conversion operator to a new stream for each new added element.
|
|
34
|
+
*
|
|
35
|
+
* It can be more convenient to use the {@link IObserveQuerySelectorOptions.project | project} option in
|
|
36
|
+
* {@link observeQuerySelectorAll} and {@link observeQuerySelector} functions.
|
|
37
|
+
*/
|
|
38
|
+
export function mergeMapAddedElements<E extends Element, O = unknown>(
|
|
39
|
+
options: IMergeMapElementChangeOptions<E, O>,
|
|
40
|
+
): OperatorFunction<IObservedElementsChanges<E> | IObservedElementChange<E>, O>;
|
|
41
|
+
export function mergeMapAddedElements<E extends Element, O = unknown>(
|
|
42
|
+
project: (element: E) => Observable<O>,
|
|
43
|
+
options?: Omit<IMergeMapElementChangeOptions, 'project'>,
|
|
44
|
+
): OperatorFunction<IObservedElementsChanges<E> | IObservedElementChange<E>, O>;
|
|
45
|
+
export function mergeMapAddedElements<E extends Element, O = unknown>(
|
|
46
|
+
projectOrOptions: ((element: E) => Observable<O>) | IMergeMapElementChangeOptions<E, O>,
|
|
47
|
+
options?: Omit<IMergeMapElementChangeOptions, 'project'>,
|
|
48
|
+
): OperatorFunction<IObservedElementsChanges<E> | IObservedElementChange<E>, O> {
|
|
49
|
+
// #region Options parsing
|
|
50
|
+
let project: (element: E) => Observable<O>;
|
|
51
|
+
let stableOptions: Omit<IMergeMapElementChangeOptions, 'project'>;
|
|
52
|
+
if (typeof projectOrOptions === 'function') {
|
|
53
|
+
project = projectOrOptions;
|
|
54
|
+
stableOptions = options || {};
|
|
55
|
+
} else {
|
|
56
|
+
project = projectOrOptions.project;
|
|
57
|
+
stableOptions = projectOrOptions;
|
|
58
|
+
}
|
|
59
|
+
const { takeUntil: takeUntilOption = 'removed' } = stableOptions;
|
|
60
|
+
// #endregion
|
|
61
|
+
|
|
62
|
+
if (takeUntilOption === 'always') {
|
|
63
|
+
return source$ => source$.pipe(
|
|
64
|
+
mergeMap(changes => {
|
|
65
|
+
const added = assuredArray(changes.added);
|
|
66
|
+
if (added.length === 0) {
|
|
67
|
+
return EMPTY;
|
|
68
|
+
}
|
|
69
|
+
const addedObservers = added.map(project);
|
|
70
|
+
return merge(...addedObservers);
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
return source$ => source$.pipe(
|
|
75
|
+
connect(connectedSource$ =>connectedSource$.pipe(
|
|
76
|
+
mergeMap(changes => {
|
|
77
|
+
const added = assuredArray(changes.added);
|
|
78
|
+
if (added.length === 0) {
|
|
79
|
+
return EMPTY;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const addedObservers = added.map(addedElement => {
|
|
83
|
+
let takeUntil$: Observable<unknown> | undefined;
|
|
84
|
+
if (takeUntilOption === 'removed') {
|
|
85
|
+
takeUntil$ = connectedSource$.pipe(
|
|
86
|
+
filter(connectedChanges => connectedChanges.removed instanceof Array
|
|
87
|
+
? connectedChanges.removed.indexOf(addedElement) !== -1
|
|
88
|
+
: connectedChanges.removed === addedElement
|
|
89
|
+
),
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
let wasRemoved = false
|
|
93
|
+
takeUntil$ = connectedSource$.pipe(
|
|
94
|
+
filter(connectedChanges => {
|
|
95
|
+
if (!wasRemoved) {
|
|
96
|
+
wasRemoved = connectedChanges.removed instanceof Array
|
|
97
|
+
? connectedChanges.removed.indexOf(addedElement) !== -1
|
|
98
|
+
: connectedChanges.removed === addedElement;
|
|
99
|
+
}
|
|
100
|
+
if (wasRemoved) {
|
|
101
|
+
const hasTarget = connectedChanges.target instanceof Array
|
|
102
|
+
? connectedChanges.target.indexOf(addedElement) !== -1
|
|
103
|
+
: connectedChanges.target === addedElement;
|
|
104
|
+
return hasTarget;
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return project(addedElement).pipe(
|
|
112
|
+
takeUntil(takeUntil$),
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
return merge(...addedObservers);
|
|
117
|
+
})
|
|
118
|
+
)),
|
|
119
|
+
);
|
|
120
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { connect, EMPTY, filter, map, mergeMap, Observable, of, OperatorFunction, takeUntil } from "rxjs";
|
|
2
|
+
|
|
3
|
+
export interface IMergeMapByConditionOptions<I = unknown, O = unknown> {
|
|
4
|
+
/** The condition that the source must satisfy */
|
|
5
|
+
condition: (value: I) => boolean;
|
|
6
|
+
/**
|
|
7
|
+
* The function that will be called to generate a new stream
|
|
8
|
+
* if the source changes and satisfies the {@link condition}.
|
|
9
|
+
*/
|
|
10
|
+
project?: (source: I) => Observable<O>;
|
|
11
|
+
/**
|
|
12
|
+
* Determines when the {@link project} function will be called to create a new stream:
|
|
13
|
+
* * `'all'`: For each source changes that satisfies the {@link condition}.
|
|
14
|
+
* * `'new'`: Only if the previous source failed the {@link condition} check.
|
|
15
|
+
*
|
|
16
|
+
* @default 'new'
|
|
17
|
+
*/
|
|
18
|
+
takeFor?: 'all' | 'new';
|
|
19
|
+
/**
|
|
20
|
+
* Determines when a stream from the {@link project} function should be terminated:
|
|
21
|
+
* * `'fail'`: As soon as the source failed the {@link condition} check.
|
|
22
|
+
* * `'pass'`: After the source failed the {@link condition} check and then successfully passes again.
|
|
23
|
+
* * `'always'`: It does not depend on whether the source passes the {@link condition} check or not.
|
|
24
|
+
*
|
|
25
|
+
* @default 'fail'
|
|
26
|
+
*/
|
|
27
|
+
takeUntil?: 'fail' | 'pass' | 'always';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** The operator creates a separate stream when the source is validated. */
|
|
31
|
+
export function mergeMapByCondition<I>(
|
|
32
|
+
options: IMergeMapByConditionOptions<I> & { project?: undefined },
|
|
33
|
+
): OperatorFunction<I, I>;
|
|
34
|
+
export function mergeMapByCondition<I, O>(
|
|
35
|
+
options: IMergeMapByConditionOptions<I, O>,
|
|
36
|
+
): OperatorFunction<I, O>;
|
|
37
|
+
export function mergeMapByCondition<I>(
|
|
38
|
+
condition: (value: I) => boolean,
|
|
39
|
+
project?: undefined,
|
|
40
|
+
options?: Omit<IMergeMapByConditionOptions, 'condition' | 'project'>,
|
|
41
|
+
): OperatorFunction<I, I>;
|
|
42
|
+
export function mergeMapByCondition<I, O>(
|
|
43
|
+
condition: (value: I) => boolean,
|
|
44
|
+
project: (source: I) => Observable<O>,
|
|
45
|
+
options?: Omit<IMergeMapByConditionOptions, 'condition' | 'project'>,
|
|
46
|
+
): OperatorFunction<I, O>;
|
|
47
|
+
export function mergeMapByCondition<I, O>(
|
|
48
|
+
conditionOrOptions: ((value: I) => boolean) | IMergeMapByConditionOptions<I, O>,
|
|
49
|
+
project?: ((source: I) => Observable<O>),
|
|
50
|
+
options?: Omit<IMergeMapByConditionOptions, 'condition' | 'project'>,
|
|
51
|
+
): OperatorFunction<I, I | O> {
|
|
52
|
+
// #region Options parsing
|
|
53
|
+
let stableOptions: Omit<IMergeMapByConditionOptions, 'condition' | 'project'>;
|
|
54
|
+
let conditionFn: (value: I) => boolean;
|
|
55
|
+
let stableProject: ((source: I) => Observable<O>) | undefined;
|
|
56
|
+
if ('condition' in conditionOrOptions) {
|
|
57
|
+
stableOptions = conditionOrOptions;
|
|
58
|
+
conditionFn = conditionOrOptions.condition;
|
|
59
|
+
stableProject = conditionOrOptions.project;
|
|
60
|
+
} else {
|
|
61
|
+
conditionFn = conditionOrOptions;
|
|
62
|
+
stableOptions = options || {};
|
|
63
|
+
stableProject = project;
|
|
64
|
+
}
|
|
65
|
+
const {
|
|
66
|
+
takeFor = 'new',
|
|
67
|
+
takeUntil: takeUntilOption = 'fail',
|
|
68
|
+
} = stableOptions;
|
|
69
|
+
// #endregion
|
|
70
|
+
|
|
71
|
+
let isPrevConditionPass = false;
|
|
72
|
+
|
|
73
|
+
return source$ => source$.pipe(
|
|
74
|
+
map(source => ({ source, isConditionPassed: conditionFn(source) })),
|
|
75
|
+
connect(connectedSource$ => {
|
|
76
|
+
let takeUntil$: Observable<unknown> | undefined;
|
|
77
|
+
if (takeUntilOption === 'fail') {
|
|
78
|
+
takeUntil$ = connectedSource$.pipe(
|
|
79
|
+
filter(({ isConditionPassed }) => isConditionPassed)
|
|
80
|
+
);
|
|
81
|
+
} else if (takeUntilOption === 'pass') {
|
|
82
|
+
let wasFailed = false
|
|
83
|
+
takeUntil$ = connectedSource$.pipe(
|
|
84
|
+
filter(({ isConditionPassed }) => {
|
|
85
|
+
if (isConditionPassed) {
|
|
86
|
+
if (wasFailed) {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
wasFailed = true;
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
})
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return connectedSource$.pipe(
|
|
98
|
+
mergeMap(({ source, isConditionPassed }) => {
|
|
99
|
+
if (isConditionPassed) {
|
|
100
|
+
const isCreateNewProject = takeFor === 'all' || !isPrevConditionPass;
|
|
101
|
+
isPrevConditionPass = true;
|
|
102
|
+
|
|
103
|
+
if (isCreateNewProject) {
|
|
104
|
+
if (!stableProject) {
|
|
105
|
+
return of(source);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let project$ = stableProject(source);
|
|
109
|
+
if (takeUntil$) {
|
|
110
|
+
project$ = project$.pipe(
|
|
111
|
+
takeUntil(takeUntil$)
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
return project$;
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
isPrevConditionPass = false;
|
|
118
|
+
}
|
|
119
|
+
return EMPTY;
|
|
120
|
+
}),
|
|
121
|
+
);
|
|
122
|
+
}),
|
|
123
|
+
);
|
|
124
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Observable, OperatorFunction } from "rxjs";
|
|
2
|
+
import { IMergeMapByConditionOptions, mergeMapByCondition } from './merge-map-by-condition';
|
|
3
|
+
import type { IObserveUrlChangesOptions, observeUrlChanges } from '../observable/observe-url-changes';
|
|
4
|
+
|
|
5
|
+
export interface IMergeMapByStringConditionOptions<O = unknown>
|
|
6
|
+
extends Omit<IMergeMapByConditionOptions<string, O>, 'condition'> {
|
|
7
|
+
|
|
8
|
+
/** The condition that the source string must satisfy */
|
|
9
|
+
condition: RegExp | ((value: string) => boolean);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function getStringConditionFunction(
|
|
13
|
+
condition: RegExp | ((value: string) => boolean)
|
|
14
|
+
): (value: string) => boolean {
|
|
15
|
+
return typeof condition === 'function' ? condition : (value: string) => condition.test(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The operator creates a separate stream when the source string is validated.
|
|
20
|
+
*
|
|
21
|
+
* It can be more convenient to use the {@link IObserveUrlChangesOptions.project | project} option in
|
|
22
|
+
* {@link observeUrlChanges} function.
|
|
23
|
+
*/
|
|
24
|
+
export function mergeMapStringCondition(
|
|
25
|
+
options: IMergeMapByStringConditionOptions & { project?: undefined },
|
|
26
|
+
): OperatorFunction<string, string>;
|
|
27
|
+
export function mergeMapStringCondition<O>(
|
|
28
|
+
options: IMergeMapByStringConditionOptions<O>,
|
|
29
|
+
): OperatorFunction<string, O>;
|
|
30
|
+
export function mergeMapStringCondition(
|
|
31
|
+
condition: RegExp | ((value: string) => boolean),
|
|
32
|
+
project?: undefined,
|
|
33
|
+
options?: Omit<IMergeMapByStringConditionOptions, 'condition' | 'project'>,
|
|
34
|
+
): OperatorFunction<string, string>;
|
|
35
|
+
export function mergeMapStringCondition<O>(
|
|
36
|
+
condition: RegExp | ((value: string) => boolean),
|
|
37
|
+
project: (url: string) => Observable<O>,
|
|
38
|
+
options?: Omit<IMergeMapByStringConditionOptions, 'condition' | 'project'>,
|
|
39
|
+
): OperatorFunction<string, O>;
|
|
40
|
+
export function mergeMapStringCondition<O>(
|
|
41
|
+
conditionOrOptions: RegExp | ((value: string) => boolean) | IMergeMapByStringConditionOptions<O>,
|
|
42
|
+
project?: ((url: string) => Observable<O>),
|
|
43
|
+
options?: Omit<IMergeMapByStringConditionOptions, 'condition' | 'project'>,
|
|
44
|
+
): OperatorFunction<string, O | string> {
|
|
45
|
+
if ('condition' in conditionOrOptions) {
|
|
46
|
+
return mergeMapByCondition({
|
|
47
|
+
...conditionOrOptions,
|
|
48
|
+
condition: getStringConditionFunction(conditionOrOptions.condition),
|
|
49
|
+
});
|
|
50
|
+
} else {
|
|
51
|
+
return mergeMapByCondition({
|
|
52
|
+
...options,
|
|
53
|
+
condition: getStringConditionFunction(conditionOrOptions),
|
|
54
|
+
project,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { MonoTypeOperatorFunction } from "rxjs";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
1
|
+
import { MonoTypeOperatorFunction, tap } from "rxjs";
|
|
2
|
+
|
|
3
|
+
export function removeElement<T extends Element>(): MonoTypeOperatorFunction<T> {
|
|
4
|
+
return tap((element) => {
|
|
5
|
+
element.remove();
|
|
6
|
+
console.log(`Remove: `, element);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
@@ -1,51 +1,53 @@
|
|
|
1
|
-
import { concat, defer, EMPTY, ignoreElements, merge, MonoTypeOperatorFunction, NEVER, Observable, ObservableInput, of, share, takeUntil, tap } from 'rxjs';
|
|
2
|
-
|
|
3
|
-
export interface IRestoredHistoryOption<T = unknown> {
|
|
4
|
-
getStory(): T | undefined;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
cancelRestore
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
1
|
+
import { concat, defer, EMPTY, ignoreElements, merge, MonoTypeOperatorFunction, NEVER, Observable, ObservableInput, of, share, takeUntil, tap } from 'rxjs';
|
|
2
|
+
|
|
3
|
+
export interface IRestoredHistoryOption<T = unknown> {
|
|
4
|
+
getStory(): T | undefined;
|
|
5
|
+
/** Setting a new value that was thrown by the thread */
|
|
6
|
+
setStory(value: T): void;
|
|
7
|
+
/** Called if {@link cancelRestore} threw an event */
|
|
8
|
+
removeStory(): void;
|
|
9
|
+
cancelRestore?: () => ObservableInput<unknown>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function restoreHistory<T>(
|
|
13
|
+
options: IRestoredHistoryOption<T>
|
|
14
|
+
): MonoTypeOperatorFunction<T> {
|
|
15
|
+
return (source$: Observable<T>) => {
|
|
16
|
+
let hasStory = false;
|
|
17
|
+
const observeCancel$ = options.cancelRestore
|
|
18
|
+
? defer(() => options.cancelRestore!())
|
|
19
|
+
.pipe(
|
|
20
|
+
tap(() => {
|
|
21
|
+
if (hasStory) {
|
|
22
|
+
options.removeStory();
|
|
23
|
+
}
|
|
24
|
+
}),
|
|
25
|
+
share(),
|
|
26
|
+
)
|
|
27
|
+
: NEVER;
|
|
28
|
+
const story$ = concat(
|
|
29
|
+
defer(() => {
|
|
30
|
+
const story = options.getStory();
|
|
31
|
+
if (story === undefined) {
|
|
32
|
+
return EMPTY;
|
|
33
|
+
}
|
|
34
|
+
hasStory = true;
|
|
35
|
+
let rested$ = of(story);
|
|
36
|
+
if (options.cancelRestore) {
|
|
37
|
+
rested$ = rested$.pipe(takeUntil(observeCancel$))
|
|
38
|
+
}
|
|
39
|
+
return rested$;
|
|
40
|
+
}),
|
|
41
|
+
source$.pipe(
|
|
42
|
+
tap((data: T) => {
|
|
43
|
+
options.setStory(data);
|
|
44
|
+
hasStory = true;
|
|
45
|
+
}),
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
return merge(
|
|
49
|
+
story$,
|
|
50
|
+
observeCancel$.pipe(ignoreElements())
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { MonoTypeOperatorFunction } from "rxjs";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
element.
|
|
6
|
-
element.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export function setInputValue(value: string):
|
|
12
|
-
export function setInputValue(
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
1
|
+
import { MonoTypeOperatorFunction, tap } from "rxjs";
|
|
2
|
+
|
|
3
|
+
function setInputValueImmediately(element: HTMLInputElement, value: string): void {
|
|
4
|
+
element.value = value;
|
|
5
|
+
element.focus();
|
|
6
|
+
element.dispatchEvent(new Event('input'));
|
|
7
|
+
console.log(`Set value: `, { element, value });
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function setInputValue(value: string): MonoTypeOperatorFunction<HTMLInputElement>;
|
|
11
|
+
export function setInputValue(element: HTMLInputElement, value: string): void;
|
|
12
|
+
export function setInputValue(
|
|
13
|
+
elementOrValue: HTMLInputElement | string, value?: string
|
|
14
|
+
): MonoTypeOperatorFunction<HTMLInputElement> | void {
|
|
15
|
+
if (typeof elementOrValue === 'string') {
|
|
16
|
+
return tap((element: HTMLInputElement) => setInputValueImmediately(element, elementOrValue));
|
|
17
|
+
} else {
|
|
18
|
+
setInputValueImmediately(elementOrValue, value!);
|
|
19
|
+
}
|
|
20
|
+
}
|