"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.activate = activate; exports.deactivate = deactivate; const vscode = __importStar(require("vscode")); const formatter_1 = require("./formatter"); const componentIndex_1 = require("./componentIndex"); const definitionProvider_1 = require("./definitionProvider"); const blade_component_provider_1 = require("./blade_component_provider"); const blade_spacer_1 = require("./blade_spacer"); const blade_language_config_1 = require("./blade_language_config"); function activate(context) { console.log('JQHTML extension activated'); // Initialize component index const componentIndex = new componentIndex_1.JqhtmlComponentIndex(); context.subscriptions.push({ dispose: () => componentIndex.dispose() }); // Register the formatter const formatter = new formatter_1.JqhtmlFormattingEditProvider(); const formatterProvider = vscode.languages.registerDocumentFormattingEditProvider('jqhtml', formatter); context.subscriptions.push(formatterProvider); // Register definition provider for goto definition (Ctrl+Click, F12) const definitionProvider = new definitionProvider_1.JqhtmlDefinitionProvider(componentIndex); const definitionProviderDisposable = vscode.languages.registerDefinitionProvider('jqhtml', definitionProvider); context.subscriptions.push(definitionProviderDisposable); // Register hover provider for component information const hoverProvider = new definitionProvider_1.JqhtmlHoverProvider(componentIndex); const hoverProviderDisposable = vscode.languages.registerHoverProvider('jqhtml', hoverProvider); context.subscriptions.push(hoverProviderDisposable); // Register auto-closing tag functionality const autoCloseDisposable = vscode.workspace.onDidChangeTextDocument((event) => { if (event.document.languageId !== 'jqhtml') { return; } // Check if we should auto-close const activeEditor = vscode.window.activeTextEditor; if (!activeEditor || activeEditor.document !== event.document) { return; } // Only process single character changes (typing) if (event.contentChanges.length !== 1) { return; } const change = event.contentChanges[0]; const text = change.text; // Check if user typed '>' if (text === '>') { const position = change.range.start; const line = event.document.lineAt(position.line); const lineText = line.text.substring(0, position.character + 1); // Match opening tags: , , , or regular HTML tags // Look for self-closing indicators /> or existing closing tags const openingTagMatch = lineText.match(/<(\/?)(Define:|Slot:)?([A-Z][A-Za-z0-9_]*|\w+)(?:\s+[^>]*)?>$/); if (openingTagMatch && !openingTagMatch[1]) { // Not a closing tag (no /) const tagPrefix = openingTagMatch[2] || ''; // 'Define:' or 'Slot:' or '' const tagName = openingTagMatch[3]; // Check if it's self-closing or already has a closing tag const beforeTag = lineText.substring(0, lineText.lastIndexOf('<')); if (beforeTag.endsWith('/')) { return; // Self-closing tag } // Check if this is a slot tag (starts with Slot:) const isSlot = tagPrefix === 'Slot:'; // For slots, check if it's self-closing syntax if (isSlot && lineText.match(/$/)) { // Don't auto-close self-closing slots if (lineText.endsWith('/>')) { return; } } // Check if we should auto-close this tag // Component tags (start with capital), Define: tags, and slot tags const shouldAutoClose = tagName[0] === tagName[0].toUpperCase() || tagPrefix === 'Define:' || isSlot || isHtmlTag(tagName); if (shouldAutoClose) { // Build the closing tag let closingTag = ''; if (isSlot) { closingTag = ``; } else { closingTag = ``; } // Insert the closing tag activeEditor.edit((editBuilder) => { const insertPosition = position.translate(0, 1); editBuilder.insert(insertPosition, closingTag); }, { undoStopBefore: false, undoStopAfter: false }).then(() => { // Move cursor between the tags const newPosition = position.translate(0, 1); activeEditor.selection = new vscode.Selection(newPosition, newPosition); }); } } } }); context.subscriptions.push(autoCloseDisposable); // Register format on save if enabled const config = vscode.workspace.getConfiguration('editor'); if (config.get('formatOnSave')) { console.log('JQHTML: Format on save is enabled'); } // ========================================================================= // BLADE SUPPORT (Optional - controlled by jqhtml.enableBladeSupport setting) // ========================================================================= const jqhtmlConfig = vscode.workspace.getConfiguration('jqhtml'); const bladeSupport = jqhtmlConfig.get('enableBladeSupport', true); if (bladeSupport) { // Register Blade component semantic tokens provider // Highlights component tag names and tag="" attributes in .blade.php files const bladeComponentProvider = new blade_component_provider_1.BladeComponentSemanticTokensProvider(); context.subscriptions.push(vscode.languages.registerDocumentSemanticTokensProvider([{ language: 'blade' }, { pattern: '**/*.blade.php' }], bladeComponentProvider, new vscode.SemanticTokensLegend(['class', 'jqhtmlTagAttribute']))); console.log('JQHTML: Blade component highlighting registered'); // Register Blade auto-spacing ({{ -> {{ | }}) const getAutoSpacingEnabled = () => { return vscode.workspace.getConfiguration('jqhtml').get('enableBladeAutoSpacing', true); }; context.subscriptions.push(vscode.workspace.onDidChangeTextDocument((event) => { (0, blade_spacer_1.blade_spacer)(event, vscode.window.activeTextEditor, getAutoSpacingEnabled()); })); console.log('JQHTML: Blade auto-spacing registered'); // Initialize Blade language configuration (indentation rules) (0, blade_language_config_1.init_blade_language_config)(); console.log('JQHTML: Blade language configuration initialized'); } else { console.log('JQHTML: Blade support disabled via settings'); } console.log('JQHTML: All features registered (formatter, auto-close, goto definition, hover)'); // Return public API for other extensions return { findComponent: (name) => componentIndex.findComponent(name), getAllComponentNames: () => componentIndex.getAllComponentNames(), reindexWorkspace: () => componentIndex.reindexWorkspace() }; } // Helper function to check if a tag is a standard HTML tag function isHtmlTag(tagName) { const htmlTags = [ 'div', 'span', 'p', 'a', 'button', 'input', 'form', 'header', 'footer', 'section', 'article', 'nav', 'main', 'aside', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'table', 'tr', 'td', 'th', 'thead', 'tbody', 'tfoot', 'img', 'video', 'audio', 'canvas', 'svg', 'iframe', 'label', 'select', 'option', 'textarea', 'fieldset', 'legend', 'details', 'summary', 'dialog', 'template', 'blockquote', 'pre', 'code', 'em', 'strong', 'small', 'mark', 'del', 'ins', 'sub', 'sup' ]; return htmlTags.includes(tagName.toLowerCase()); } function deactivate() { console.log('JQHTML extension deactivated'); } //# sourceMappingURL=extension.js.map