(tutorialId)
| 198 | |
| 199 | // Start a tutorial by ID - using confirm() dialogs |
| 200 | export async function startTutorial(tutorialId) { |
| 201 | CarrotDebug.ui(`🎓 startTutorial called with ID: ${tutorialId}`); |
| 202 | const tutorial = tutorials[tutorialId]; |
| 203 | if (!tutorial) { |
| 204 | alert(`Tutorial "${tutorialId}" not found`); |
| 205 | return; |
| 206 | } |
| 207 | |
| 208 | const steps = tutorial.steps; |
| 209 | |
| 210 | // Show each step with browser confirm dialog |
| 211 | for (let i = 0; i < steps.length; i++) { |
| 212 | const step = steps[i]; |
| 213 | |
| 214 | // Highlight the target element |
| 215 | const target = document.querySelector(step.target); |
| 216 | if (target) { |
| 217 | // Remove previous highlights |
| 218 | document.querySelectorAll('.carrot-tutorial-highlight') |
| 219 | .forEach(el => el.classList.remove('carrot-tutorial-highlight')); |
| 220 | |
| 221 | // Add highlight to current target |
| 222 | target.classList.add('carrot-tutorial-highlight'); |
| 223 | |
| 224 | // Scroll to target |
| 225 | const isMobile = window.innerWidth <= 768 || 'ontouchstart' in window; |
| 226 | const scrollOptions = { |
| 227 | behavior: 'smooth', |
| 228 | block: isMobile ? 'start' : 'center', |
| 229 | inline: 'nearest' |
| 230 | }; |
| 231 | |
| 232 | target.scrollIntoView(scrollOptions); |
| 233 | |
| 234 | // Wait for scroll to complete |
| 235 | await new Promise(resolve => setTimeout(resolve, isMobile ? 800 : 500)); |
| 236 | } |
| 237 | |
| 238 | // Clean up HTML tags and format text nicely |
| 239 | const cleanContent = step.content |
| 240 | .replace(/<[^>]*>/g, '') // Remove HTML tags |
| 241 | .replace(/\s+/g, ' ') // Normalize whitespace |
| 242 | .replace(/</g, '<').replace(/>/g, '>') // Fix HTML entities |
| 243 | .replace(/&/g, '&') // Fix ampersands |
| 244 | .trim(); |
| 245 | |
| 246 | // Format text with proper line breaks for readability |
| 247 | const formattedContent = cleanContent |
| 248 | .replace(/([.!?])\s+([A-Z])/g, '$1\n\n$2') // Add breaks after sentences |
| 249 | .replace(/([:])\s*([A-Z•])/g, '$1\n$2') // Add breaks after colons |
| 250 | .replace(/•\s/g, '\n• ') // Put bullets on new lines |
| 251 | .replace(/(\d+\.)\s/g, '\n$1 ') // Put numbered items on new lines |
| 252 | .replace(/\n\n\n+/g, '\n\n') // Clean up multiple line breaks |
| 253 | .trim(); |
| 254 | |
| 255 | // Show step as confirm dialog |
| 256 | const continueClicked = confirm( |
| 257 | `Step ${i + 1} of ${steps.length}: ${step.title}\n\n${formattedContent}\n\nClick OK for next step, Cancel to exit tutorial.` |
no test coverage detected