posthog-js 1.316.1 → 1.317.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/dist/array.full.es5.js +1 -1
- package/dist/array.full.js +1 -1
- package/dist/array.full.no-external.js +1 -1
- package/dist/array.js +1 -1
- package/dist/array.no-external.js +1 -1
- package/dist/customizations.full.js +1 -1
- package/dist/element-inference.d.ts +21 -0
- package/dist/element-inference.js +2 -0
- package/dist/element-inference.js.map +1 -0
- package/dist/lazy-recorder.js +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/module.d.ts +12 -0
- package/dist/module.full.d.ts +12 -0
- package/dist/module.full.js +1 -1
- package/dist/module.full.js.map +1 -1
- package/dist/module.full.no-external.d.ts +12 -0
- package/dist/module.full.no-external.js +1 -1
- package/dist/module.full.no-external.js.map +1 -1
- package/dist/module.js +1 -1
- package/dist/module.js.map +1 -1
- package/dist/module.no-external.d.ts +12 -0
- package/dist/module.no-external.js +1 -1
- package/dist/module.no-external.js.map +1 -1
- package/dist/posthog-recorder.js +1 -1
- package/dist/product-tours-preview.d.ts +12 -0
- package/dist/product-tours-preview.js +1 -1
- package/dist/product-tours-preview.js.map +1 -1
- package/dist/product-tours.js +1 -1
- package/dist/product-tours.js.map +1 -1
- package/dist/src/entrypoints/element-inference.es.d.ts +1 -0
- package/dist/src/entrypoints/product-tours.d.ts +2 -0
- package/dist/src/extensions/product-tours/element-inference.d.ts +30 -0
- package/dist/src/extensions/product-tours/index.d.ts +2 -0
- package/dist/src/extensions/product-tours/product-tours-utils.d.ts +2 -1
- package/dist/src/posthog-product-tours-types.d.ts +7 -0
- package/dist/surveys-preview.d.ts +12 -0
- package/lib/package.json +5 -1
- package/lib/src/entrypoints/element-inference.es.d.ts +1 -0
- package/lib/src/entrypoints/element-inference.es.js +8 -0
- package/lib/src/entrypoints/element-inference.es.js.map +1 -0
- package/lib/src/entrypoints/product-tours.d.ts +2 -0
- package/lib/src/entrypoints/product-tours.js +5 -0
- package/lib/src/entrypoints/product-tours.js.map +1 -1
- package/lib/src/extensions/product-tours/components/ProductTourTooltip.js +5 -2
- package/lib/src/extensions/product-tours/components/ProductTourTooltip.js.map +1 -1
- package/lib/src/extensions/product-tours/components/ProductTourTooltipInner.js +1 -1
- package/lib/src/extensions/product-tours/components/ProductTourTooltipInner.js.map +1 -1
- package/lib/src/extensions/product-tours/element-inference.d.ts +30 -0
- package/lib/src/extensions/product-tours/element-inference.js +296 -0
- package/lib/src/extensions/product-tours/element-inference.js.map +1 -0
- package/lib/src/extensions/product-tours/index.d.ts +2 -0
- package/lib/src/extensions/product-tours/index.js +4 -1
- package/lib/src/extensions/product-tours/index.js.map +1 -1
- package/lib/src/extensions/product-tours/preview.js +1 -1
- package/lib/src/extensions/product-tours/preview.js.map +1 -1
- package/lib/src/extensions/product-tours/product-tours-utils.d.ts +2 -1
- package/lib/src/extensions/product-tours/product-tours-utils.js +12 -0
- package/lib/src/extensions/product-tours/product-tours-utils.js.map +1 -1
- package/lib/src/extensions/product-tours/product-tours.js +15 -31
- package/lib/src/extensions/product-tours/product-tours.js.map +1 -1
- package/lib/src/posthog-product-tours-types.d.ts +7 -0
- package/lib/src/posthog-product-tours-types.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { findElement, getElementPath, elementIsVisible } from '../extensions/product-tours/element-inference';
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { generateProductTours } from '../extensions/product-tours';
|
|
2
|
+
export { findElement, getElementPath, elementIsVisible } from '../extensions/product-tours/element-inference';
|
|
3
|
+
export type { InferredSelector, AutoData, SelectorGroup } from '../extensions/product-tours/element-inference';
|
|
2
4
|
export default generateProductTours;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare function elementIsVisible(element: HTMLElement, cache: WeakMap<HTMLElement, boolean>): boolean;
|
|
2
|
+
export interface SelectorGroup {
|
|
3
|
+
cardinality: number;
|
|
4
|
+
cssSelectors: Array<{
|
|
5
|
+
css: string;
|
|
6
|
+
offset: number;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
9
|
+
export interface AutoData {
|
|
10
|
+
notextGroups: SelectorGroup[];
|
|
11
|
+
textGroups: SelectorGroup[];
|
|
12
|
+
}
|
|
13
|
+
export interface InferredSelector {
|
|
14
|
+
autoData: string;
|
|
15
|
+
text: string | null;
|
|
16
|
+
excludeText?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* if inferSelector is the sauce, this is the nugget
|
|
20
|
+
*
|
|
21
|
+
* find an element in the dom using the element inference data
|
|
22
|
+
*
|
|
23
|
+
* 1. try each group of selectors, starting with most specific (lowest cardinality)
|
|
24
|
+
* 2. try each selector in the group - run the css query, go to offset
|
|
25
|
+
* 3. "vote" for the element if it was found
|
|
26
|
+
* 4. return early if any element gets majority votes
|
|
27
|
+
* 5. return element w/ most votes
|
|
28
|
+
*/
|
|
29
|
+
export declare function findElement(selector: InferredSelector): HTMLElement | null;
|
|
30
|
+
export declare function getElementPath(el: HTMLElement | null, depth?: number): string | null;
|
|
@@ -2,4 +2,6 @@ import { PostHog } from '../../posthog-core';
|
|
|
2
2
|
import { ProductTourManager } from './product-tours';
|
|
3
3
|
export { ProductTourManager } from './product-tours';
|
|
4
4
|
export { findElementBySelector, getElementMetadata, getProductTourStylesheet } from './product-tours-utils';
|
|
5
|
+
export { findElement, getElementPath } from './element-inference';
|
|
6
|
+
export type { InferredSelector, AutoData, SelectorGroup } from './element-inference';
|
|
5
7
|
export declare function generateProductTours(posthog: PostHog, isEnabled: boolean): ProductTourManager | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ProductTourAppearance, ProductTourSelectorError } from '../../posthog-product-tours-types';
|
|
1
|
+
import { ProductTourAppearance, ProductTourSelectorError, ProductTourStep } from '../../posthog-product-tours-types';
|
|
2
2
|
export declare function getProductTourStylesheet(): HTMLStyleElement | null;
|
|
3
3
|
export interface ElementFindResult {
|
|
4
4
|
element: HTMLElement | null;
|
|
@@ -24,3 +24,4 @@ export declare function getSpotlightStyle(targetRect: DOMRect, padding?: number)
|
|
|
24
24
|
export declare function addProductTourCSSVariablesToElement(element: HTMLElement, appearance?: ProductTourAppearance): void;
|
|
25
25
|
export declare function renderTipTapContent(content: any): string;
|
|
26
26
|
export declare function normalizeUrl(url: string): string;
|
|
27
|
+
export declare function getStepHtml(step: ProductTourStep): string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PropertyMatchType } from './types';
|
|
2
2
|
import { SurveyActionType, SurveyEventWithFilters } from './posthog-surveys-types';
|
|
3
|
+
import type { InferredSelector } from './extensions/product-tours/element-inference';
|
|
3
4
|
export interface JSONContent {
|
|
4
5
|
type?: string;
|
|
5
6
|
attrs?: Record<string, any>;
|
|
@@ -30,12 +31,18 @@ export interface ProductTourStep {
|
|
|
30
31
|
selector?: string;
|
|
31
32
|
progressionTrigger: 'button' | 'click';
|
|
32
33
|
content: JSONContent | null;
|
|
34
|
+
/** Pre-rendered HTML content from the editor. If present, SDK should use this instead of rendering from JSONContent. */
|
|
35
|
+
contentHtml?: string;
|
|
33
36
|
/** Inline survey question config - if present, this is a survey step */
|
|
34
37
|
survey?: ProductTourSurveyQuestion;
|
|
35
38
|
/** ID of the auto-created survey for this step (set by backend) */
|
|
36
39
|
linkedSurveyId?: string;
|
|
37
40
|
/** ID of the survey question (set by backend, used for event tracking) */
|
|
38
41
|
linkedSurveyQuestionId?: string;
|
|
42
|
+
/** Enhanced element data for more reliable lookup at runtime */
|
|
43
|
+
inferenceData?: InferredSelector;
|
|
44
|
+
/** Maximum tooltip width in pixels (defaults to 320px) */
|
|
45
|
+
maxWidth?: number;
|
|
39
46
|
}
|
|
40
47
|
export interface ProductTourConditions {
|
|
41
48
|
url?: string;
|
|
@@ -1623,6 +1623,12 @@ declare class PostHogFeatureFlags {
|
|
|
1623
1623
|
reset(): void;
|
|
1624
1624
|
}
|
|
1625
1625
|
|
|
1626
|
+
interface InferredSelector {
|
|
1627
|
+
autoData: string;
|
|
1628
|
+
text: string | null;
|
|
1629
|
+
excludeText?: boolean;
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1626
1632
|
interface JSONContent {
|
|
1627
1633
|
type?: string;
|
|
1628
1634
|
attrs?: Record<string, any>;
|
|
@@ -1653,12 +1659,18 @@ interface ProductTourStep {
|
|
|
1653
1659
|
selector?: string;
|
|
1654
1660
|
progressionTrigger: 'button' | 'click';
|
|
1655
1661
|
content: JSONContent | null;
|
|
1662
|
+
/** Pre-rendered HTML content from the editor. If present, SDK should use this instead of rendering from JSONContent. */
|
|
1663
|
+
contentHtml?: string;
|
|
1656
1664
|
/** Inline survey question config - if present, this is a survey step */
|
|
1657
1665
|
survey?: ProductTourSurveyQuestion;
|
|
1658
1666
|
/** ID of the auto-created survey for this step (set by backend) */
|
|
1659
1667
|
linkedSurveyId?: string;
|
|
1660
1668
|
/** ID of the survey question (set by backend, used for event tracking) */
|
|
1661
1669
|
linkedSurveyQuestionId?: string;
|
|
1670
|
+
/** Enhanced element data for more reliable lookup at runtime */
|
|
1671
|
+
inferenceData?: InferredSelector;
|
|
1672
|
+
/** Maximum tooltip width in pixels (defaults to 320px) */
|
|
1673
|
+
maxWidth?: number;
|
|
1662
1674
|
}
|
|
1663
1675
|
interface ProductTourConditions {
|
|
1664
1676
|
url?: string;
|
package/lib/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "posthog-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.317.0",
|
|
4
4
|
"description": "Posthog-js allows you to automatically capture usage and send events to PostHog.",
|
|
5
5
|
"repository": "https://github.com/PostHog/posthog-js",
|
|
6
6
|
"author": "hey@posthog.com",
|
|
@@ -52,8 +52,10 @@
|
|
|
52
52
|
"@posthog/core": "workspace:*",
|
|
53
53
|
"@posthog/types": "workspace:*",
|
|
54
54
|
"core-js": "^3.38.1",
|
|
55
|
+
"dompurify": "^3.3.1",
|
|
55
56
|
"fflate": "^0.4.8",
|
|
56
57
|
"preact": "^10.19.3",
|
|
58
|
+
"query-selector-shadow-dom": "^1.0.1",
|
|
57
59
|
"web-vitals": "^4.2.4"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
@@ -83,9 +85,11 @@
|
|
|
83
85
|
"@testing-library/dom": "catalog:",
|
|
84
86
|
"@testing-library/jest-dom": "catalog:",
|
|
85
87
|
"@testing-library/preact": "catalog:",
|
|
88
|
+
"@types/dompurify": "^3.2.0",
|
|
86
89
|
"@types/dotenv": "^8.2.3",
|
|
87
90
|
"@types/jest": "catalog:",
|
|
88
91
|
"@types/node": "^22.5.0",
|
|
92
|
+
"@types/query-selector-shadow-dom": "^1.0.4",
|
|
89
93
|
"@types/sinon": "^17.0.1",
|
|
90
94
|
"@types/web": "^0.0.222",
|
|
91
95
|
"babel-jest": "^29.7.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { findElement, getElementPath, elementIsVisible } from '../extensions/product-tours/element-inference';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.elementIsVisible = exports.getElementPath = exports.findElement = void 0;
|
|
4
|
+
var element_inference_1 = require("../extensions/product-tours/element-inference");
|
|
5
|
+
Object.defineProperty(exports, "findElement", { enumerable: true, get: function () { return element_inference_1.findElement; } });
|
|
6
|
+
Object.defineProperty(exports, "getElementPath", { enumerable: true, get: function () { return element_inference_1.getElementPath; } });
|
|
7
|
+
Object.defineProperty(exports, "elementIsVisible", { enumerable: true, get: function () { return element_inference_1.elementIsVisible; } });
|
|
8
|
+
//# sourceMappingURL=element-inference.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element-inference.es.js","sourceRoot":"","sources":["../../../src/entrypoints/element-inference.es.ts"],"names":[],"mappings":";;;AAAA,mFAA6G;AAApG,gHAAA,WAAW,OAAA;AAAE,mHAAA,cAAc,OAAA;AAAE,qHAAA,gBAAgB,OAAA","sourcesContent":["export { findElement, getElementPath, elementIsVisible } from '../extensions/product-tours/element-inference'\n"]}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import { generateProductTours } from '../extensions/product-tours';
|
|
2
|
+
export { findElement, getElementPath, elementIsVisible } from '../extensions/product-tours/element-inference';
|
|
3
|
+
export type { InferredSelector, AutoData, SelectorGroup } from '../extensions/product-tours/element-inference';
|
|
2
4
|
export default generateProductTours;
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.elementIsVisible = exports.getElementPath = exports.findElement = void 0;
|
|
3
4
|
var product_tours_1 = require("../extensions/product-tours");
|
|
4
5
|
var globals_1 = require("../utils/globals");
|
|
5
6
|
globals_1.assignableWindow.__PosthogExtensions__ = globals_1.assignableWindow.__PosthogExtensions__ || {};
|
|
6
7
|
globals_1.assignableWindow.__PosthogExtensions__.generateProductTours = product_tours_1.generateProductTours;
|
|
8
|
+
var element_inference_1 = require("../extensions/product-tours/element-inference");
|
|
9
|
+
Object.defineProperty(exports, "findElement", { enumerable: true, get: function () { return element_inference_1.findElement; } });
|
|
10
|
+
Object.defineProperty(exports, "getElementPath", { enumerable: true, get: function () { return element_inference_1.getElementPath; } });
|
|
11
|
+
Object.defineProperty(exports, "elementIsVisible", { enumerable: true, get: function () { return element_inference_1.elementIsVisible; } });
|
|
7
12
|
exports.default = product_tours_1.generateProductTours;
|
|
8
13
|
//# sourceMappingURL=product-tours.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-tours.js","sourceRoot":"","sources":["../../../src/entrypoints/product-tours.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"product-tours.js","sourceRoot":"","sources":["../../../src/entrypoints/product-tours.ts"],"names":[],"mappings":";;;AAAA,6DAAkE;AAClE,4CAAmD;AAEnD,0BAAgB,CAAC,qBAAqB,GAAG,0BAAgB,CAAC,qBAAqB,IAAI,EAAE,CAAA;AACrF,0BAAgB,CAAC,qBAAqB,CAAC,oBAAoB,GAAG,oCAAoB,CAAA;AAElF,mFAA6G;AAApG,gHAAA,WAAW,OAAA;AAAE,mHAAA,cAAc,OAAA;AAAE,qHAAA,gBAAgB,OAAA;AAGtD,kBAAe,oCAAoB,CAAA","sourcesContent":["import { generateProductTours } from '../extensions/product-tours'\nimport { assignableWindow } from '../utils/globals'\n\nassignableWindow.__PosthogExtensions__ = assignableWindow.__PosthogExtensions__ || {}\nassignableWindow.__PosthogExtensions__.generateProductTours = generateProductTours\n\nexport { findElement, getElementPath, elementIsVisible } from '../extensions/product-tours/element-inference'\nexport type { InferredSelector, AutoData, SelectorGroup } from '../extensions/product-tours/element-inference'\n\nexport default generateProductTours\n"]}
|
|
@@ -199,7 +199,10 @@ function ProductTourTooltip(_a) {
|
|
|
199
199
|
var isSurvey = displayedStep.type === 'survey';
|
|
200
200
|
// For element steps, don't render until position is calculated
|
|
201
201
|
var isPositionReady = isCentered || !(0, core_1.isNull)(position);
|
|
202
|
-
var tooltipStyle =
|
|
202
|
+
var tooltipStyle = __assign(__assign({}, (displayedStep.maxWidth && {
|
|
203
|
+
width: "".concat(displayedStep.maxWidth, "px"),
|
|
204
|
+
maxWidth: "".concat(displayedStep.maxWidth, "px"),
|
|
205
|
+
})), (isCentered
|
|
203
206
|
? {
|
|
204
207
|
top: '50%',
|
|
205
208
|
left: '50%',
|
|
@@ -208,7 +211,7 @@ function ProductTourTooltip(_a) {
|
|
|
208
211
|
: {
|
|
209
212
|
top: position ? "".concat(position.top, "px") : '0',
|
|
210
213
|
left: position ? "".concat(position.left, "px") : '0',
|
|
211
|
-
};
|
|
214
|
+
}));
|
|
212
215
|
return ((0, jsx_runtime_1.jsxs)("div", { class: "ph-tour-container", children: [(0, jsx_runtime_1.jsx)("div", { class: "ph-tour-click-overlay", onClick: handleOverlayClick }), (0, jsx_runtime_1.jsx)("div", { class: "ph-tour-modal-overlay", style: {
|
|
213
216
|
opacity: isCentered && isVisible ? 1 : 0,
|
|
214
217
|
transition: "opacity ".concat(TRANSITION_DURATION, "ms ease-out"),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductTourTooltip.js","sourceRoot":"","sources":["../../../../../src/extensions/product-tours/components/ProductTourTooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h } from 'preact'\nimport { useEffect, useState, useCallback, useRef } from 'preact/hooks'\nimport { ProductTour, ProductTourStep, ProductTourDismissReason } from '../../../posthog-product-tours-types'\nimport { calculateTooltipPosition, getSpotlightStyle, TooltipPosition } from '../product-tours-utils'\nimport { addEventListener } from '../../../utils'\nimport { window as _window } from '../../../utils/globals'\nimport { ProductTourTooltipInner } from './ProductTourTooltipInner'\nimport { ProductTourSurveyStepInner } from './ProductTourSurveyStepInner'\nimport { isNull } from '@posthog/core'\n\nconst window = _window as Window & typeof globalThis\n\ntype TransitionState = 'entering' | 'visible' | 'exiting'\n\nexport interface ProductTourTooltipProps {\n tour: ProductTour\n step: ProductTourStep\n stepIndex: number\n totalSteps: number\n targetElement: HTMLElement | null\n onNext: () => void\n onPrevious: () => void\n onDismiss: (reason: ProductTourDismissReason) => void\n onSurveySubmit?: (response: string | number | null) => void\n}\n\nfunction getOppositePosition(position: TooltipPosition): TooltipPosition {\n const opposites: Record<TooltipPosition, TooltipPosition> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n }\n return opposites[position]\n}\n\nfunction scrollToElement(element: HTMLElement, resolve: () => void): void {\n const initialRect = element.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const viewportWidth = window.innerWidth\n\n const safeMarginY = viewportHeight / 6\n const safeMarginX = viewportWidth / 6\n\n const isInSafeZone =\n initialRect.top >= safeMarginY &&\n initialRect.bottom <= viewportHeight - safeMarginY &&\n initialRect.left >= safeMarginX &&\n initialRect.right <= viewportWidth - safeMarginX\n\n if (isInSafeZone) {\n resolve()\n return\n }\n\n element.scrollIntoView({ behavior: 'smooth', block: 'center' })\n\n let lastTop = initialRect.top\n let stableCount = 0\n let resolved = false\n\n const checkStability = () => {\n if (resolved) return\n\n const currentRect = element.getBoundingClientRect()\n if (Math.abs(currentRect.top - lastTop) < 1) {\n stableCount++\n if (stableCount >= 3) {\n resolved = true\n resolve()\n return\n }\n } else {\n stableCount = 0\n }\n lastTop = currentRect.top\n setTimeout(checkStability, 50)\n }\n\n setTimeout(checkStability, 30)\n\n setTimeout(() => {\n if (!resolved) {\n resolved = true\n resolve()\n }\n }, 500)\n}\n\nconst TRANSITION_DURATION = 150\n\nexport function ProductTourTooltip({\n tour,\n step,\n stepIndex,\n totalSteps,\n targetElement,\n onNext,\n onPrevious,\n onDismiss,\n onSurveySubmit,\n}: ProductTourTooltipProps): h.JSX.Element {\n const [transitionState, setTransitionState] = useState<TransitionState>('entering')\n const [position, setPosition] = useState<ReturnType<typeof calculateTooltipPosition> | null>(null)\n const [spotlightStyle, setSpotlightStyle] = useState<ReturnType<typeof getSpotlightStyle> | null>(null)\n\n const [displayedStep, setDisplayedStep] = useState(step)\n const [displayedStepIndex, setDisplayedStepIndex] = useState(stepIndex)\n\n const previousStepRef = useRef(stepIndex)\n const isTransitioningRef = useRef(false)\n\n // Modal and survey steps are both centered on screen\n const isCentered = displayedStep.type === 'modal' || displayedStep.type === 'survey'\n\n const updatePosition = useCallback(() => {\n if (!targetElement) return\n const rect = targetElement.getBoundingClientRect()\n setPosition(calculateTooltipPosition(rect))\n setSpotlightStyle(getSpotlightStyle(rect))\n }, [targetElement])\n\n useEffect(() => {\n const currentStepIndex = stepIndex\n const isStepChange = previousStepRef.current !== stepIndex\n\n const finishEntering = () => {\n if (previousStepRef.current !== currentStepIndex) return\n setTransitionState('visible')\n isTransitioningRef.current = false\n }\n\n const enterStep = () => {\n // Only scroll/position for element steps\n if (targetElement && step.type === 'element') {\n scrollToElement(targetElement, () => {\n if (previousStepRef.current !== currentStepIndex) return\n updatePosition()\n setTimeout(finishEntering, 50)\n })\n } else {\n setTimeout(finishEntering, 50)\n }\n }\n\n if (!isStepChange) {\n previousStepRef.current = stepIndex\n isTransitioningRef.current = true\n enterStep()\n return\n }\n\n previousStepRef.current = stepIndex\n isTransitioningRef.current = true\n setTransitionState('exiting')\n\n setTimeout(() => {\n if (previousStepRef.current !== currentStepIndex) return\n\n // Reset position for element steps to prevent flash at old position\n if (step.type === 'element') {\n setPosition(null)\n setSpotlightStyle(null)\n }\n\n setDisplayedStep(step)\n setDisplayedStepIndex(stepIndex)\n setTransitionState('entering')\n\n enterStep()\n }, TRANSITION_DURATION)\n }, [targetElement, stepIndex, step, updatePosition])\n\n useEffect(() => {\n if (transitionState !== 'visible' || isCentered) return\n\n const handleUpdate = () => {\n if (!isTransitioningRef.current) {\n updatePosition()\n }\n }\n\n addEventListener(window, 'scroll', handleUpdate as EventListener, { capture: true })\n addEventListener(window, 'resize', handleUpdate as EventListener)\n\n return () => {\n window?.removeEventListener('scroll', handleUpdate, true)\n window?.removeEventListener('resize', handleUpdate)\n }\n }, [updatePosition, transitionState, isCentered])\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onDismiss('escape_key')\n }\n }\n addEventListener(window, 'keydown', handleKeyDown as EventListener)\n return () => {\n window?.removeEventListener('keydown', handleKeyDown)\n }\n }, [onDismiss])\n\n const handleOverlayClick = (e: MouseEvent) => {\n e.stopPropagation()\n onDismiss('user_clicked_outside')\n }\n\n const handleTooltipClick = (e: MouseEvent) => {\n e.stopPropagation()\n }\n\n const handleSpotlightClick = (e: MouseEvent) => {\n e.stopPropagation()\n if (targetElement) {\n targetElement.click()\n }\n onNext()\n }\n\n const isVisible = transitionState === 'visible'\n const isSurvey = displayedStep.type === 'survey'\n\n // For element steps, don't render until position is calculated\n const isPositionReady = isCentered || !isNull(position)\n\n const tooltipStyle = isCentered\n ? {\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n }\n : {\n top: position ? `${position.top}px` : '0',\n left: position ? `${position.left}px` : '0',\n }\n\n return (\n <div class=\"ph-tour-container\">\n <div class=\"ph-tour-click-overlay\" onClick={handleOverlayClick} />\n\n {/* Modal overlay - visible for centered steps */}\n <div\n class=\"ph-tour-modal-overlay\"\n style={{\n opacity: isCentered && isVisible ? 1 : 0,\n transition: `opacity ${TRANSITION_DURATION}ms ease-out`,\n pointerEvents: isCentered ? 'auto' : 'none',\n }}\n />\n\n {/* Spotlight - visible for element steps */}\n <div\n class=\"ph-tour-spotlight\"\n style={{\n ...(isVisible && isPositionReady && spotlightStyle\n ? spotlightStyle\n : { top: '50%', left: '50%', width: '0px', height: '0px' }),\n opacity: !isCentered && isVisible && isPositionReady ? 1 : 0,\n transition: `opacity ${TRANSITION_DURATION}ms ease-out`,\n ...(displayedStep.progressionTrigger === 'click' &&\n !isCentered && {\n pointerEvents: 'auto',\n cursor: 'pointer',\n }),\n }}\n onClick={displayedStep.progressionTrigger === 'click' && !isCentered ? handleSpotlightClick : undefined}\n />\n\n <div\n class={`ph-tour-tooltip ${isCentered ? 'ph-tour-tooltip--modal' : ''} ${isSurvey ? 'ph-tour-survey-step' : ''}`}\n style={{\n ...tooltipStyle,\n opacity: isVisible && isPositionReady ? 1 : 0,\n transition: `opacity ${TRANSITION_DURATION}ms ease-out`,\n }}\n onClick={handleTooltipClick}\n >\n {!isCentered && position && (\n <div class={`ph-tour-arrow ph-tour-arrow--${getOppositePosition(position.position)}`} />\n )}\n\n {isSurvey ? (\n <ProductTourSurveyStepInner\n step={displayedStep}\n appearance={tour.appearance}\n stepIndex={displayedStepIndex}\n totalSteps={totalSteps}\n onSubmit={onSurveySubmit}\n onPrevious={onPrevious}\n onDismiss={() => onDismiss('user_clicked_skip')}\n />\n ) : (\n <ProductTourTooltipInner\n step={displayedStep}\n appearance={tour.appearance}\n stepIndex={displayedStepIndex}\n totalSteps={totalSteps}\n onNext={onNext}\n onPrevious={onPrevious}\n onDismiss={() => onDismiss('user_clicked_skip')}\n />\n )}\n </div>\n </div>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ProductTourTooltip.js","sourceRoot":"","sources":["../../../../../src/extensions/product-tours/components/ProductTourTooltip.tsx"],"names":[],"mappings":"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","sourcesContent":["import { h } from 'preact'\nimport { useEffect, useState, useCallback, useRef } from 'preact/hooks'\nimport { ProductTour, ProductTourStep, ProductTourDismissReason } from '../../../posthog-product-tours-types'\nimport { calculateTooltipPosition, getSpotlightStyle, TooltipPosition } from '../product-tours-utils'\nimport { addEventListener } from '../../../utils'\nimport { window as _window } from '../../../utils/globals'\nimport { ProductTourTooltipInner } from './ProductTourTooltipInner'\nimport { ProductTourSurveyStepInner } from './ProductTourSurveyStepInner'\nimport { isNull } from '@posthog/core'\n\nconst window = _window as Window & typeof globalThis\n\ntype TransitionState = 'entering' | 'visible' | 'exiting'\n\nexport interface ProductTourTooltipProps {\n tour: ProductTour\n step: ProductTourStep\n stepIndex: number\n totalSteps: number\n targetElement: HTMLElement | null\n onNext: () => void\n onPrevious: () => void\n onDismiss: (reason: ProductTourDismissReason) => void\n onSurveySubmit?: (response: string | number | null) => void\n}\n\nfunction getOppositePosition(position: TooltipPosition): TooltipPosition {\n const opposites: Record<TooltipPosition, TooltipPosition> = {\n top: 'bottom',\n bottom: 'top',\n left: 'right',\n right: 'left',\n }\n return opposites[position]\n}\n\nfunction scrollToElement(element: HTMLElement, resolve: () => void): void {\n const initialRect = element.getBoundingClientRect()\n const viewportHeight = window.innerHeight\n const viewportWidth = window.innerWidth\n\n const safeMarginY = viewportHeight / 6\n const safeMarginX = viewportWidth / 6\n\n const isInSafeZone =\n initialRect.top >= safeMarginY &&\n initialRect.bottom <= viewportHeight - safeMarginY &&\n initialRect.left >= safeMarginX &&\n initialRect.right <= viewportWidth - safeMarginX\n\n if (isInSafeZone) {\n resolve()\n return\n }\n\n element.scrollIntoView({ behavior: 'smooth', block: 'center' })\n\n let lastTop = initialRect.top\n let stableCount = 0\n let resolved = false\n\n const checkStability = () => {\n if (resolved) return\n\n const currentRect = element.getBoundingClientRect()\n if (Math.abs(currentRect.top - lastTop) < 1) {\n stableCount++\n if (stableCount >= 3) {\n resolved = true\n resolve()\n return\n }\n } else {\n stableCount = 0\n }\n lastTop = currentRect.top\n setTimeout(checkStability, 50)\n }\n\n setTimeout(checkStability, 30)\n\n setTimeout(() => {\n if (!resolved) {\n resolved = true\n resolve()\n }\n }, 500)\n}\n\nconst TRANSITION_DURATION = 150\n\nexport function ProductTourTooltip({\n tour,\n step,\n stepIndex,\n totalSteps,\n targetElement,\n onNext,\n onPrevious,\n onDismiss,\n onSurveySubmit,\n}: ProductTourTooltipProps): h.JSX.Element {\n const [transitionState, setTransitionState] = useState<TransitionState>('entering')\n const [position, setPosition] = useState<ReturnType<typeof calculateTooltipPosition> | null>(null)\n const [spotlightStyle, setSpotlightStyle] = useState<ReturnType<typeof getSpotlightStyle> | null>(null)\n\n const [displayedStep, setDisplayedStep] = useState(step)\n const [displayedStepIndex, setDisplayedStepIndex] = useState(stepIndex)\n\n const previousStepRef = useRef(stepIndex)\n const isTransitioningRef = useRef(false)\n\n // Modal and survey steps are both centered on screen\n const isCentered = displayedStep.type === 'modal' || displayedStep.type === 'survey'\n\n const updatePosition = useCallback(() => {\n if (!targetElement) return\n const rect = targetElement.getBoundingClientRect()\n setPosition(calculateTooltipPosition(rect))\n setSpotlightStyle(getSpotlightStyle(rect))\n }, [targetElement])\n\n useEffect(() => {\n const currentStepIndex = stepIndex\n const isStepChange = previousStepRef.current !== stepIndex\n\n const finishEntering = () => {\n if (previousStepRef.current !== currentStepIndex) return\n setTransitionState('visible')\n isTransitioningRef.current = false\n }\n\n const enterStep = () => {\n // Only scroll/position for element steps\n if (targetElement && step.type === 'element') {\n scrollToElement(targetElement, () => {\n if (previousStepRef.current !== currentStepIndex) return\n updatePosition()\n setTimeout(finishEntering, 50)\n })\n } else {\n setTimeout(finishEntering, 50)\n }\n }\n\n if (!isStepChange) {\n previousStepRef.current = stepIndex\n isTransitioningRef.current = true\n enterStep()\n return\n }\n\n previousStepRef.current = stepIndex\n isTransitioningRef.current = true\n setTransitionState('exiting')\n\n setTimeout(() => {\n if (previousStepRef.current !== currentStepIndex) return\n\n // Reset position for element steps to prevent flash at old position\n if (step.type === 'element') {\n setPosition(null)\n setSpotlightStyle(null)\n }\n\n setDisplayedStep(step)\n setDisplayedStepIndex(stepIndex)\n setTransitionState('entering')\n\n enterStep()\n }, TRANSITION_DURATION)\n }, [targetElement, stepIndex, step, updatePosition])\n\n useEffect(() => {\n if (transitionState !== 'visible' || isCentered) return\n\n const handleUpdate = () => {\n if (!isTransitioningRef.current) {\n updatePosition()\n }\n }\n\n addEventListener(window, 'scroll', handleUpdate as EventListener, { capture: true })\n addEventListener(window, 'resize', handleUpdate as EventListener)\n\n return () => {\n window?.removeEventListener('scroll', handleUpdate, true)\n window?.removeEventListener('resize', handleUpdate)\n }\n }, [updatePosition, transitionState, isCentered])\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n onDismiss('escape_key')\n }\n }\n addEventListener(window, 'keydown', handleKeyDown as EventListener)\n return () => {\n window?.removeEventListener('keydown', handleKeyDown)\n }\n }, [onDismiss])\n\n const handleOverlayClick = (e: MouseEvent) => {\n e.stopPropagation()\n onDismiss('user_clicked_outside')\n }\n\n const handleTooltipClick = (e: MouseEvent) => {\n e.stopPropagation()\n }\n\n const handleSpotlightClick = (e: MouseEvent) => {\n e.stopPropagation()\n if (targetElement) {\n targetElement.click()\n }\n onNext()\n }\n\n const isVisible = transitionState === 'visible'\n const isSurvey = displayedStep.type === 'survey'\n\n // For element steps, don't render until position is calculated\n const isPositionReady = isCentered || !isNull(position)\n\n const tooltipStyle = {\n ...(displayedStep.maxWidth && {\n width: `${displayedStep.maxWidth}px`,\n maxWidth: `${displayedStep.maxWidth}px`,\n }),\n ...(isCentered\n ? {\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n }\n : {\n top: position ? `${position.top}px` : '0',\n left: position ? `${position.left}px` : '0',\n }),\n }\n\n return (\n <div class=\"ph-tour-container\">\n <div class=\"ph-tour-click-overlay\" onClick={handleOverlayClick} />\n\n {/* Modal overlay - visible for centered steps */}\n <div\n class=\"ph-tour-modal-overlay\"\n style={{\n opacity: isCentered && isVisible ? 1 : 0,\n transition: `opacity ${TRANSITION_DURATION}ms ease-out`,\n pointerEvents: isCentered ? 'auto' : 'none',\n }}\n />\n\n {/* Spotlight - visible for element steps */}\n <div\n class=\"ph-tour-spotlight\"\n style={{\n ...(isVisible && isPositionReady && spotlightStyle\n ? spotlightStyle\n : { top: '50%', left: '50%', width: '0px', height: '0px' }),\n opacity: !isCentered && isVisible && isPositionReady ? 1 : 0,\n transition: `opacity ${TRANSITION_DURATION}ms ease-out`,\n ...(displayedStep.progressionTrigger === 'click' &&\n !isCentered && {\n pointerEvents: 'auto',\n cursor: 'pointer',\n }),\n }}\n onClick={displayedStep.progressionTrigger === 'click' && !isCentered ? handleSpotlightClick : undefined}\n />\n\n <div\n class={`ph-tour-tooltip ${isCentered ? 'ph-tour-tooltip--modal' : ''} ${isSurvey ? 'ph-tour-survey-step' : ''}`}\n style={{\n ...tooltipStyle,\n opacity: isVisible && isPositionReady ? 1 : 0,\n transition: `opacity ${TRANSITION_DURATION}ms ease-out`,\n }}\n onClick={handleTooltipClick}\n >\n {!isCentered && position && (\n <div class={`ph-tour-arrow ph-tour-arrow--${getOppositePosition(position.position)}`} />\n )}\n\n {isSurvey ? (\n <ProductTourSurveyStepInner\n step={displayedStep}\n appearance={tour.appearance}\n stepIndex={displayedStepIndex}\n totalSteps={totalSteps}\n onSubmit={onSurveySubmit}\n onPrevious={onPrevious}\n onDismiss={() => onDismiss('user_clicked_skip')}\n />\n ) : (\n <ProductTourTooltipInner\n step={displayedStep}\n appearance={tour.appearance}\n stepIndex={displayedStepIndex}\n totalSteps={totalSteps}\n onNext={onNext}\n onPrevious={onPrevious}\n onDismiss={() => onDismiss('user_clicked_skip')}\n />\n )}\n </div>\n </div>\n )\n}\n"]}
|
|
@@ -13,6 +13,6 @@ function ProductTourTooltipInner(_a) {
|
|
|
13
13
|
var showNextButton = step.progressionTrigger === 'button' || step.type === 'modal';
|
|
14
14
|
var isInteractive = !!(onNext || onPrevious || onDismiss);
|
|
15
15
|
var cursorStyle = isInteractive ? undefined : { cursor: 'default' };
|
|
16
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { class: "ph-tour-dismiss", onClick: onDismiss, "aria-label": "Close tour", style: cursorStyle, children: icons_1.cancelSVG }), (0, jsx_runtime_1.jsx)("div", { class: "ph-tour-content", dangerouslySetInnerHTML: { __html: (0, product_tours_utils_1.
|
|
16
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("button", { class: "ph-tour-dismiss", onClick: onDismiss, "aria-label": "Close tour", style: cursorStyle, children: icons_1.cancelSVG }), (0, jsx_runtime_1.jsx)("div", { class: "ph-tour-content", dangerouslySetInnerHTML: { __html: (0, product_tours_utils_1.getStepHtml)(step) } }), (0, jsx_runtime_1.jsxs)("div", { class: "ph-tour-footer", children: [(0, jsx_runtime_1.jsxs)("span", { class: "ph-tour-progress", children: [stepIndex + 1, " of ", totalSteps] }), (0, jsx_runtime_1.jsxs)("div", { class: "ph-tour-buttons", children: [!isFirstStep && ((0, jsx_runtime_1.jsx)("button", { class: "ph-tour-button ph-tour-button--secondary", onClick: onPrevious, style: cursorStyle, children: "Back" })), showNextButton && ((0, jsx_runtime_1.jsx)("button", { class: "ph-tour-button ph-tour-button--primary", onClick: onNext, style: cursorStyle, children: isLastStep ? 'Done' : 'Next' }))] })] }), !whiteLabel && ((0, jsx_runtime_1.jsxs)("a", { href: isInteractive ? 'https://posthog.com/product-tours' : undefined, target: isInteractive ? '_blank' : undefined, rel: isInteractive ? 'noopener noreferrer' : undefined, class: "ph-tour-branding", style: isInteractive ? undefined : { cursor: 'default', pointerEvents: 'none' }, children: ["Tour by ", icons_1.IconPosthogLogo] }))] }));
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=ProductTourTooltipInner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProductTourTooltipInner.js","sourceRoot":"","sources":["../../../../../src/extensions/product-tours/components/ProductTourTooltipInner.tsx"],"names":[],"mappings":";;AAeA,0DA6DC;;AA1ED,
|
|
1
|
+
{"version":3,"file":"ProductTourTooltipInner.js","sourceRoot":"","sources":["../../../../../src/extensions/product-tours/components/ProductTourTooltipInner.tsx"],"names":[],"mappings":";;AAeA,0DA6DC;;AA1ED,8DAAoD;AACpD,6CAAgE;AAYhE,SAAgB,uBAAuB,CAAC,EAQT;;QAP3B,IAAI,UAAA,EACJ,UAAU,gBAAA,EACV,SAAS,eAAA,EACT,UAAU,gBAAA,EACV,MAAM,YAAA,EACN,UAAU,gBAAA,EACV,SAAS,eAAA;IAET,IAAM,UAAU,GAAG,MAAA,UAAU,aAAV,UAAU,uBAAV,UAAU,CAAE,UAAU,mCAAI,KAAK,CAAA;IAClD,IAAM,UAAU,GAAG,SAAS,IAAI,UAAU,GAAG,CAAC,CAAA;IAC9C,IAAM,WAAW,GAAG,SAAS,KAAK,CAAC,CAAA;IACnC,IAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,CAAA;IAEpF,IAAM,aAAa,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,UAAU,IAAI,SAAS,CAAC,CAAA;IAC3D,IAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAA;IAErE,OAAO,CACH,6DACI,mCAAQ,KAAK,EAAC,iBAAiB,EAAC,OAAO,EAAE,SAAS,gBAAa,YAAY,EAAC,KAAK,EAAE,WAAW,YACzF,iBAAS,GACL,EAET,gCAAK,KAAK,EAAC,iBAAiB,EAAC,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAA,iCAAW,EAAC,IAAI,CAAC,EAAE,GAAI,EAEvF,iCAAK,KAAK,EAAC,gBAAgB,aACvB,kCAAM,KAAK,EAAC,kBAAkB,aACzB,SAAS,GAAG,CAAC,UAAM,UAAU,IAC3B,EAEP,iCAAK,KAAK,EAAC,iBAAiB,aACvB,CAAC,WAAW,IAAI,CACb,mCACI,KAAK,EAAC,0CAA0C,EAChD,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,WAAW,qBAGb,CACZ,EACA,cAAc,IAAI,CACf,mCAAQ,KAAK,EAAC,wCAAwC,EAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,YACrF,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GACxB,CACZ,IACC,IACJ,EAEL,CAAC,UAAU,IAAI,CACZ,+BACI,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,SAAS,EACrE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAC5C,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,EACtD,KAAK,EAAC,kBAAkB,EACxB,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,yBAEtE,uBAAe,IACxB,CACP,IACF,CACN,CAAA;AACL,CAAC","sourcesContent":["import { h } from 'preact'\nimport { ProductTourStep, ProductTourAppearance } from '../../../posthog-product-tours-types'\nimport { getStepHtml } from '../product-tours-utils'\nimport { IconPosthogLogo, cancelSVG } from '../../surveys/icons'\n\nexport interface ProductTourTooltipInnerProps {\n step: ProductTourStep\n appearance?: ProductTourAppearance\n stepIndex: number\n totalSteps: number\n onNext?: () => void\n onPrevious?: () => void\n onDismiss?: () => void\n}\n\nexport function ProductTourTooltipInner({\n step,\n appearance,\n stepIndex,\n totalSteps,\n onNext,\n onPrevious,\n onDismiss,\n}: ProductTourTooltipInnerProps): h.JSX.Element {\n const whiteLabel = appearance?.whiteLabel ?? false\n const isLastStep = stepIndex >= totalSteps - 1\n const isFirstStep = stepIndex === 0\n const showNextButton = step.progressionTrigger === 'button' || step.type === 'modal'\n\n const isInteractive = !!(onNext || onPrevious || onDismiss)\n const cursorStyle = isInteractive ? undefined : { cursor: 'default' }\n\n return (\n <>\n <button class=\"ph-tour-dismiss\" onClick={onDismiss} aria-label=\"Close tour\" style={cursorStyle}>\n {cancelSVG}\n </button>\n\n <div class=\"ph-tour-content\" dangerouslySetInnerHTML={{ __html: getStepHtml(step) }} />\n\n <div class=\"ph-tour-footer\">\n <span class=\"ph-tour-progress\">\n {stepIndex + 1} of {totalSteps}\n </span>\n\n <div class=\"ph-tour-buttons\">\n {!isFirstStep && (\n <button\n class=\"ph-tour-button ph-tour-button--secondary\"\n onClick={onPrevious}\n style={cursorStyle}\n >\n Back\n </button>\n )}\n {showNextButton && (\n <button class=\"ph-tour-button ph-tour-button--primary\" onClick={onNext} style={cursorStyle}>\n {isLastStep ? 'Done' : 'Next'}\n </button>\n )}\n </div>\n </div>\n\n {!whiteLabel && (\n <a\n href={isInteractive ? 'https://posthog.com/product-tours' : undefined}\n target={isInteractive ? '_blank' : undefined}\n rel={isInteractive ? 'noopener noreferrer' : undefined}\n class=\"ph-tour-branding\"\n style={isInteractive ? undefined : { cursor: 'default', pointerEvents: 'none' }}\n >\n Tour by {IconPosthogLogo}\n </a>\n )}\n </>\n )\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export declare function elementIsVisible(element: HTMLElement, cache: WeakMap<HTMLElement, boolean>): boolean;
|
|
2
|
+
export interface SelectorGroup {
|
|
3
|
+
cardinality: number;
|
|
4
|
+
cssSelectors: Array<{
|
|
5
|
+
css: string;
|
|
6
|
+
offset: number;
|
|
7
|
+
}>;
|
|
8
|
+
}
|
|
9
|
+
export interface AutoData {
|
|
10
|
+
notextGroups: SelectorGroup[];
|
|
11
|
+
textGroups: SelectorGroup[];
|
|
12
|
+
}
|
|
13
|
+
export interface InferredSelector {
|
|
14
|
+
autoData: string;
|
|
15
|
+
text: string | null;
|
|
16
|
+
excludeText?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* if inferSelector is the sauce, this is the nugget
|
|
20
|
+
*
|
|
21
|
+
* find an element in the dom using the element inference data
|
|
22
|
+
*
|
|
23
|
+
* 1. try each group of selectors, starting with most specific (lowest cardinality)
|
|
24
|
+
* 2. try each selector in the group - run the css query, go to offset
|
|
25
|
+
* 3. "vote" for the element if it was found
|
|
26
|
+
* 4. return early if any element gets majority votes
|
|
27
|
+
* 5. return element w/ most votes
|
|
28
|
+
*/
|
|
29
|
+
export declare function findElement(selector: InferredSelector): HTMLElement | null;
|
|
30
|
+
export declare function getElementPath(el: HTMLElement | null, depth?: number): string | null;
|