|
1 | 1 | import addOverlayLayer from "./addOverlayLayer";
|
2 |
| -import cloneObject from "../util/cloneObject"; |
3 |
| -import forEach from "../util/forEach"; |
4 | 2 | import DOMEvent from "./DOMEvent";
|
5 | 3 | import { nextStep } from "./steps";
|
6 | 4 | import onKeyDown from "./onKeyDown";
|
7 | 5 | import onResize from "./onResize";
|
8 |
| -import createElement from "../util/createElement"; |
| 6 | +import fetchIntroSteps from "./fetchIntroSteps"; |
9 | 7 |
|
10 | 8 | /**
|
11 | 9 | * Initiate a new introduction/guide from an element in the page
|
12 | 10 | *
|
13 | 11 | * @api private
|
14 |
| - * @method _introForElement |
| 12 | + * @method introForElement |
15 | 13 | * @param {Object} targetElm
|
16 |
| - * @param {String} group |
17 | 14 | * @returns {Boolean} Success or not?
|
18 | 15 | */
|
19 |
| -export default function introForElement(targetElm, group) { |
20 |
| - const allIntroSteps = targetElm.querySelectorAll("*[data-intro]"); |
21 |
| - let introItems = []; |
22 |
| - |
23 |
| - if (this._options.steps) { |
24 |
| - //use steps passed programmatically |
25 |
| - forEach(this._options.steps, (step) => { |
26 |
| - const currentItem = cloneObject(step); |
27 |
| - |
28 |
| - //set the step |
29 |
| - currentItem.step = introItems.length + 1; |
30 |
| - |
31 |
| - currentItem.title = currentItem.title || ""; |
32 |
| - |
33 |
| - //use querySelector function only when developer used CSS selector |
34 |
| - if (typeof currentItem.element === "string") { |
35 |
| - //grab the element with given selector from the page |
36 |
| - currentItem.element = document.querySelector(currentItem.element); |
37 |
| - } |
38 |
| - |
39 |
| - //intro without element |
40 |
| - if ( |
41 |
| - typeof currentItem.element === "undefined" || |
42 |
| - currentItem.element === null |
43 |
| - ) { |
44 |
| - let floatingElementQuery = document.querySelector( |
45 |
| - ".introjsFloatingElement" |
46 |
| - ); |
47 |
| - |
48 |
| - if (floatingElementQuery === null) { |
49 |
| - floatingElementQuery = createElement("div", { |
50 |
| - className: "introjsFloatingElement", |
51 |
| - }); |
52 |
| - |
53 |
| - document.body.appendChild(floatingElementQuery); |
54 |
| - } |
55 |
| - |
56 |
| - currentItem.element = floatingElementQuery; |
57 |
| - currentItem.position = "floating"; |
58 |
| - } |
59 |
| - |
60 |
| - currentItem.scrollTo = currentItem.scrollTo || this._options.scrollTo; |
61 |
| - |
62 |
| - if (typeof currentItem.disableInteraction === "undefined") { |
63 |
| - currentItem.disableInteraction = this._options.disableInteraction; |
64 |
| - } |
65 |
| - |
66 |
| - if (currentItem.element !== null) { |
67 |
| - introItems.push(currentItem); |
68 |
| - } |
69 |
| - }); |
70 |
| - } else { |
71 |
| - //use steps from data-* annotations |
72 |
| - const elmsLength = allIntroSteps.length; |
73 |
| - let disableInteraction; |
74 |
| - |
75 |
| - //if there's no element to intro |
76 |
| - if (elmsLength < 1) { |
77 |
| - return false; |
78 |
| - } |
79 |
| - |
80 |
| - forEach(allIntroSteps, (currentElement) => { |
81 |
| - // PR #80 |
82 |
| - // start intro for groups of elements |
83 |
| - if (group && currentElement.getAttribute("data-intro-group") !== group) { |
84 |
| - return; |
85 |
| - } |
86 |
| - |
87 |
| - // skip hidden elements |
88 |
| - if (currentElement.style.display === "none") { |
89 |
| - return; |
90 |
| - } |
91 |
| - |
92 |
| - const step = parseInt(currentElement.getAttribute("data-step"), 10); |
93 |
| - |
94 |
| - if (currentElement.hasAttribute("data-disable-interaction")) { |
95 |
| - disableInteraction = !!currentElement.getAttribute( |
96 |
| - "data-disable-interaction" |
97 |
| - ); |
98 |
| - } else { |
99 |
| - disableInteraction = this._options.disableInteraction; |
100 |
| - } |
101 |
| - |
102 |
| - if (step > 0) { |
103 |
| - introItems[step - 1] = { |
104 |
| - element: currentElement, |
105 |
| - title: currentElement.getAttribute("data-title") || "", |
106 |
| - intro: currentElement.getAttribute("data-intro"), |
107 |
| - step: parseInt(currentElement.getAttribute("data-step"), 10), |
108 |
| - tooltipClass: currentElement.getAttribute("data-tooltipclass"), |
109 |
| - highlightClass: currentElement.getAttribute("data-highlightclass"), |
110 |
| - position: |
111 |
| - currentElement.getAttribute("data-position") || |
112 |
| - this._options.tooltipPosition, |
113 |
| - scrollTo: |
114 |
| - currentElement.getAttribute("data-scrollto") || |
115 |
| - this._options.scrollTo, |
116 |
| - disableInteraction, |
117 |
| - }; |
118 |
| - } |
119 |
| - }); |
120 |
| - |
121 |
| - //next add intro items without data-step |
122 |
| - //todo: we need a cleanup here, two loops are redundant |
123 |
| - let nextStep = 0; |
124 |
| - |
125 |
| - forEach(allIntroSteps, (currentElement) => { |
126 |
| - // PR #80 |
127 |
| - // start intro for groups of elements |
128 |
| - if (group && currentElement.getAttribute("data-intro-group") !== group) { |
129 |
| - return; |
130 |
| - } |
131 |
| - |
132 |
| - if (currentElement.getAttribute("data-step") === null) { |
133 |
| - while (true) { |
134 |
| - if (typeof introItems[nextStep] === "undefined") { |
135 |
| - break; |
136 |
| - } else { |
137 |
| - nextStep++; |
138 |
| - } |
139 |
| - } |
140 |
| - |
141 |
| - if (currentElement.hasAttribute("data-disable-interaction")) { |
142 |
| - disableInteraction = !!currentElement.getAttribute( |
143 |
| - "data-disable-interaction" |
144 |
| - ); |
145 |
| - } else { |
146 |
| - disableInteraction = this._options.disableInteraction; |
147 |
| - } |
148 |
| - |
149 |
| - introItems[nextStep] = { |
150 |
| - element: currentElement, |
151 |
| - title: currentElement.getAttribute("data-title") || "", |
152 |
| - intro: currentElement.getAttribute("data-intro"), |
153 |
| - step: nextStep + 1, |
154 |
| - tooltipClass: currentElement.getAttribute("data-tooltipclass"), |
155 |
| - highlightClass: currentElement.getAttribute("data-highlightclass"), |
156 |
| - position: |
157 |
| - currentElement.getAttribute("data-position") || |
158 |
| - this._options.tooltipPosition, |
159 |
| - scrollTo: |
160 |
| - currentElement.getAttribute("data-scrollto") || |
161 |
| - this._options.scrollTo, |
162 |
| - disableInteraction, |
163 |
| - }; |
164 |
| - } |
165 |
| - }); |
166 |
| - } |
| 16 | +export default function introForElement(targetElm ) { |
| 17 | + //set it to the introJs object |
| 18 | + const steps = fetchIntroSteps.call(this, targetElm); |
167 | 19 |
|
168 |
| - //removing undefined/null elements |
169 |
| - const tempIntroItems = []; |
170 |
| - for (let z = 0; z < introItems.length; z++) { |
171 |
| - if (introItems[z]) { |
172 |
| - // copy non-falsy values to the end of the array |
173 |
| - tempIntroItems.push(introItems[z]); |
174 |
| - } |
| 20 | + if (steps.length === 0) { |
| 21 | + return false; |
175 | 22 | }
|
176 | 23 |
|
177 |
| - introItems = tempIntroItems; |
178 |
| - |
179 |
| - //Ok, sort all items with given steps |
180 |
| - introItems.sort((a, b) => a.step - b.step); |
181 |
| - |
182 |
| - //set it to the introJs object |
183 |
| - this._introItems = introItems; |
| 24 | + this._introItems = steps; |
184 | 25 |
|
185 | 26 | //add overlay layer to the page
|
186 | 27 | if (addOverlayLayer.call(this, targetElm)) {
|
|
0 commit comments