Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
import "./.next/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
Original file line number Diff line number Diff line change
Expand Up @@ -65,27 +65,40 @@ export function iframeSelectionScript(storeDomain) {
const compatibility = createCompatibilityCode();
const init = createInitCode();

// Combinar todos los módulos en un IIFE
// El módulo de compatibilidad se ejecuta primero para agregar atributos antes de la inicialización
// Agregar verificación para evitar ejecución múltiple
return `(function() {
if (window.__FASTTIFY_THEME_STUDIO_SCRIPT_LOADED__) {
'use strict';
var NS_KEY = '__FASTTIFY_THEME_STUDIO_NS__';
if (window[NS_KEY]) {
return;
}
window.__FASTTIFY_THEME_STUDIO_SCRIPT_LOADED__ = true;
var $ = window[NS_KEY] = {};

(function() {
${constants}
})();

(function() {
${utils}
})();

(function() {
${selection}
})();

(function() {
${eventHandlers}
})();

(function() {
${domainLinks}
})();

(function() {
${compatibility}
})();

(function() {
${init}
})();
})();`;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

// @ts-ignore - Importing JS file directly
// @ts-ignore
import { iframeSelectionScript as iframeSelectionScriptImpl } from './iframe-selection-script.js';

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,12 @@ function compatibilityModule() {
}
}

// Detectar comentario de inicio de bloque (para futura implementación)
const blockStartMatch = commentText.match(/^FASTTIFY_BLOCK_START:(.+)$/);
if (blockStartMatch) {
const blockId = blockStartMatch[1];
const blockElement = findNextVisibleElement(comment);

if (blockElement && !blockElement.hasAttribute('data-block-id')) {
// Necesitamos obtener el sectionId del contexto
// Por ahora, buscar el sectionId más cercano subiendo en el árbol
let blockParent = blockElement.parentElement;
let sectionId = null;

Expand All @@ -177,19 +174,15 @@ function compatibilityModule() {
* Se ejecuta después de que el DOM esté completamente cargado
*/
function initCompatibility() {
// Ejecutar inmediatamente si el DOM ya está listo
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', processCompatibilityMarkers);
} else {
// Usar setTimeout para asegurar que el contenido renderizado esté disponible
setTimeout(processCompatibilityMarkers, 0);
}

// También procesar después de un pequeño delay para capturar contenido dinámico
setTimeout(processCompatibilityMarkers, 100);
}

// Inicializar cuando el módulo se carga
initCompatibility();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,27 @@ function constantsModule(storeDomain) {
if (window.self === window.top) {
return;
}
const SELECTED_CLASS = 'fasttify-theme-studio-selected';
const HOVER_CLASS = 'fasttify-theme-studio-hover';
const STORE_DOMAIN = storeDomain;
const IS_LOCALHOST = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
const style = document.createElement('style');
style.textContent =
var $ = window.__FASTTIFY_THEME_STUDIO_NS__;
$.SELECTED_CLASS = 'fasttify-theme-studio-selected';
$.HOVER_CLASS = 'fasttify-theme-studio-hover';
$.STORE_DOMAIN = storeDomain;
$.IS_LOCALHOST = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1';
$.style = document.createElement('style');
$.style.textContent =
'[data-section-id].' +
SELECTED_CLASS +
$.SELECTED_CLASS +
',' +
'[data-block-id].' +
SELECTED_CLASS +
$.SELECTED_CLASS +
' {' +
' position: relative !important;' +
' box-shadow: inset 0 0 0 2px #006fbb !important;' +
'}' +
'[data-section-id].' +
HOVER_CLASS +
$.HOVER_CLASS +
',' +
'[data-block-id].' +
HOVER_CLASS +
$.HOVER_CLASS +
' {' +
' position: relative !important;' +
' box-shadow: inset 0 0 0 2px rgba(0, 111, 187, 0.6) !important;' +
Expand All @@ -68,39 +69,116 @@ function constantsModule(storeDomain) {
' pointer-events: none;' +
' border-radius: 4px;' +
'}';
document.head.appendChild(style);
let inspectorEnabled = true;
let currentSelectedElement = null;
let hoveredElement = null;
let currentLabelElement = null;
let hoverLabelElement = null;
let lastSelectionTimestamp = 0;
let scrollAnimationFrame = null;
document.head.appendChild($.style);

/**
* Aplica estilos directamente al elemento como fallback si el CSS no funciona
* @param {Element} element - El elemento al que aplicar los estilos
* @param {string} type - Tipo de estilo: 'hover' o 'selected'
*/
$.applyStyles = function (element, type) {
if (!element) return;

// Guardar estilos originales solo la primera vez
if (!element._fasttifyOriginalStyles) {
element._fasttifyOriginalStyles = {
boxShadow: element.style.boxShadow || '',
position: element.style.position || '',
};
}

if (type === 'hover') {
element.style.setProperty('box-shadow', 'inset 0 0 0 2px rgba(0, 111, 187, 0.6)', 'important');
element.style.setProperty('position', 'relative', 'important');
} else if (type === 'selected') {
element.style.setProperty('box-shadow', 'inset 0 0 0 2px #006fbb', 'important');
element.style.setProperty('position', 'relative', 'important');
}
};

/**
* Remueve los estilos aplicados y restaura los originales
* @param {Element} element - El elemento del que remover los estilos
*/
$.removeStyles = function (element) {
if (!element) return;

if (element._fasttifyOriginalStyles) {
// Restaurar estilos originales
if (element._fasttifyOriginalStyles.boxShadow) {
element.style.boxShadow = element._fasttifyOriginalStyles.boxShadow;
} else {
element.style.removeProperty('box-shadow');
}

if (element._fasttifyOriginalStyles.position) {
element.style.position = element._fasttifyOriginalStyles.position;
} else {
element.style.removeProperty('position');
}

delete element._fasttifyOriginalStyles;
} else {
// Si no hay estilos originales guardados, remover los que agregamos
element.style.removeProperty('box-shadow');
element.style.removeProperty('position');
}
};

/**
* Verifica si los estilos CSS se están aplicando correctamente
* @param {Element} element - El elemento a verificar
* @param {string} type - Tipo de estilo: 'hover' o 'selected'
* @returns {boolean} true si los estilos se están aplicando, false si no
*/
$.verifyStylesApplied = function (element, type) {
if (!element) return false;

var computedStyle = window.getComputedStyle(element);
var boxShadow = computedStyle.boxShadow;
var hasBoxShadow = boxShadow && boxShadow !== 'none' && boxShadow.indexOf('inset') !== -1;

return hasBoxShadow;
};

$.inspectorEnabled = true;
$.currentSelectedElement = null;
$.hoveredElement = null;
$.currentLabelElement = null;
$.hoverLabelElement = null;
$.lastSelectionTimestamp = 0;
$.scrollAnimationFrame = null;

/**
* Función global para toggle el inspector
* @param {boolean} enabled - Si el inspector está habilitado
*/
window.toggleInspector = function (enabled) {
inspectorEnabled = enabled !== undefined ? enabled : !inspectorEnabled;
if (style) {
style.disabled = !inspectorEnabled;
$.inspectorEnabled = enabled !== undefined ? enabled : !$.inspectorEnabled;
if ($.style) {
$.style.disabled = !$.inspectorEnabled;
}
// Limpiar selección cuando se desactiva
if (!inspectorEnabled) {
if (currentSelectedElement) {
currentSelectedElement.classList.remove(SELECTED_CLASS);
if (!$.inspectorEnabled) {
if ($.currentSelectedElement) {
$.currentSelectedElement.classList.remove($.SELECTED_CLASS);
if (typeof $.removeStyles === 'function') {
$.removeStyles($.currentSelectedElement);
}
if (typeof window.removeLabel === 'function') {
window.removeLabel(false);
}
currentSelectedElement = null;
$.currentSelectedElement = null;
}
if (hoveredElement) {
hoveredElement.classList.remove(HOVER_CLASS);
if ($.hoveredElement) {
$.hoveredElement.classList.remove($.HOVER_CLASS);
if (typeof $.removeStyles === 'function') {
$.removeStyles($.hoveredElement);
}
if (typeof window.removeLabel === 'function') {
window.removeLabel(true);
}
hoveredElement = null;
$.hoveredElement = null;
}
}
};
Expand All @@ -114,6 +192,17 @@ function constantsModule(storeDomain) {
export function createConstantsCode(storeDomain) {
let functionBody = extractFunctionBody(constantsModule, 'constants');
const domainValue = storeDomain ? JSON.stringify(storeDomain) : 'null';
functionBody = functionBody.replace(/const STORE_DOMAIN = storeDomain;/, `const STORE_DOMAIN = ${domainValue};`);

functionBody = functionBody.replace(
/[a-zA-Z_$][a-zA-Z0-9_$]*\.STORE_DOMAIN\s*=\s*[a-zA-Z_$][a-zA-Z0-9_$]*\s*[;,]/g,
(match) => {
const varMatch = match.match(/^([a-zA-Z_$][a-zA-Z0-9_$]*)\.STORE_DOMAIN/);
if (varMatch) {
return `${varMatch[1]}.STORE_DOMAIN = ${domainValue};`;
}
return match;
}
);

return functionBody;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,21 @@ import { extractFunctionBody } from './extract-function-body.js';
* Esta función no se ejecuta directamente, se convierte a string para inyectar en el iframe
*/
function domainLinksModule() {
var $ = window.__FASTTIFY_THEME_STUDIO_NS__;
/**
* Configura los enlaces relativos para mostrar el dominio completo de la tienda
* En localhost solo agrega tooltips, en producción modifica los hrefs
*/
function setupDomainLinks() {
if (!STORE_DOMAIN) return;
$.setupDomainLinks = function () {
if (!$.STORE_DOMAIN) return;

// Modificar todos los enlaces para que muestren el dominio de la tienda en el tooltip
// En localhost, los enlaces relativos funcionan bien, solo agregamos el tooltip
// En producción, modificamos el href pero interceptamos los clicks
const updateLinks = function () {
const links = document.querySelectorAll('a[href]');
var updateLinks = function () {
var links = document.querySelectorAll('a[href]');
links.forEach(function (link) {
const href = link.getAttribute('href');
var href = link.getAttribute('href');
if (
href &&
!href.startsWith('http://') &&
Expand All @@ -54,11 +55,11 @@ function domainLinksModule() {
}

// Construir la URL completa con el dominio de la tienda para el tooltip
const fullUrl = 'https://' + STORE_DOMAIN + (href.startsWith('/') ? href : '/' + href);
var fullUrl = 'https://' + $.STORE_DOMAIN + (href.startsWith('/') ? href : '/' + href);

// En localhost, solo agregar title para el tooltip sin modificar href
// En producción, modificar href para que el navegador muestre la URL completa
if (IS_LOCALHOST) {
if ($.IS_LOCALHOST) {
// Solo agregar title si no tiene uno personalizado
if (!link.hasAttribute('title')) {
link.setAttribute('title', fullUrl);
Expand All @@ -76,15 +77,15 @@ function domainLinksModule() {

// Observar cambios en el DOM para actualizar nuevos enlaces
if (typeof MutationObserver !== 'undefined') {
const observer = new MutationObserver(function (mutations) {
var observer = new MutationObserver(function (mutations) {
updateLinks();
});
observer.observe(document.body, {
childList: true,
subtree: true,
});
}
}
};
}

/**
Expand Down
Loading
Loading