diff --git a/public/assets/css/pagedjs-interface.css b/public/assets/css/pagedjs-interface.css
index c03eeb7..bcef24a 100644
--- a/public/assets/css/pagedjs-interface.css
+++ b/public/assets/css/pagedjs-interface.css
@@ -144,54 +144,6 @@
/*--------------------------------------------------------------------------------------*/
}
-/* Hover and selection states for pages and elements */
-.page-hovered {
- outline: 2px solid #ff8a5050 !important;
- cursor: pointer !important;
-}
-
-.page-selected {
- outline: 2px solid #ff8a50 !important;
-}
-
-.element-hovered {
- outline: 2px solid #7136ff50 !important;
- cursor: pointer !important;
-}
-
-.element-selected {
- outline: 2px dashed #7136ff !important;
- background-color: #7136ff1a !important;
-}
-
-.element-hover-label {
- position: absolute;
- background: #7136ff;
- color: white;
- padding: 0.25rem 0.5rem;
- border-radius: 4px;
- font-size: 0.875rem;
- font-weight: 600;
- opacity: 0.3;
- pointer-events: none;
- z-index: 9999;
- font-family: sans-serif;
-}
-
-.page-hover-label {
- position: absolute;
- background: #ff8a50;
- color: white;
- padding: 0.25rem 0.5rem;
- border-radius: 4px;
- font-size: 0.875rem;
- font-weight: 600;
- opacity: 0.3;
- pointer-events: none;
- z-index: 9999;
- font-family: sans-serif;
-}
-
/* Marks (to delete when merge in paged.js) */
.pagedjs_marks-crop {
diff --git a/src/App.vue b/src/App.vue
index 5d129f6..44ce2a6 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -41,11 +41,9 @@ const isNearPageEdge = (pageElement, mouseX, mouseY) => {
const rect = pageElement.getBoundingClientRect();
const nearLeft = mouseX >= rect.left && mouseX <= rect.left + EDGE_THRESHOLD;
- const nearRight =
- mouseX >= rect.right - EDGE_THRESHOLD && mouseX <= rect.right;
+ const nearRight = mouseX >= rect.right - EDGE_THRESHOLD && mouseX <= rect.right;
const nearTop = mouseY >= rect.top && mouseY <= rect.top + EDGE_THRESHOLD;
- const nearBottom =
- mouseY >= rect.bottom - EDGE_THRESHOLD && mouseY <= rect.bottom;
+ const nearBottom = mouseY >= rect.bottom - EDGE_THRESHOLD && mouseY <= rect.bottom;
const inHorizontalRange = mouseY >= rect.top && mouseY <= rect.bottom;
const inVerticalRange = mouseX >= rect.left && mouseX <= rect.right;
@@ -67,90 +65,6 @@ const getPagesWithSameTemplate = (page, doc) => {
);
};
-// Get selector for element (same logic as ElementPopup)
-const getSelectorFromElement = (element) => {
- if (element.id) {
- return `#${element.id}`;
- }
- const tagName = element.tagName.toLowerCase();
- // Filter out state classes (element-hovered, element-selected, page-hovered, page-selected)
- const classes = Array.from(element.classList).filter(
- (cls) =>
- ![
- 'element-hovered',
- 'element-selected',
- 'page-hovered',
- 'page-selected',
- ].includes(cls)
- );
- if (classes.length > 0) {
- return `${tagName}.${classes[0]}`;
- }
- return tagName;
-};
-
-// Create and position element label on hover
-const createElementLabel = (element) => {
- const doc = element.ownerDocument;
- const existingLabel = doc.querySelector('.element-hover-label');
- if (existingLabel) {
- existingLabel.remove();
- }
-
- const rect = element.getBoundingClientRect();
- const scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop;
- const scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft;
-
- const label = doc.createElement('div');
- label.className = 'element-hover-label';
- label.textContent = getSelectorFromElement(element);
- label.style.top = `${rect.top + scrollTop - 32}px`;
- label.style.left = `${rect.left + scrollLeft}px`;
-
- doc.body.appendChild(label);
- return label;
-};
-
-// Remove element label
-const removeElementLabel = (doc) => {
- const label = doc.querySelector('.element-hover-label');
- if (label) {
- label.remove();
- }
-};
-
-// Create and position page label on hover
-const createPageLabel = (page) => {
- const doc = page.ownerDocument;
- const existingLabel = doc.querySelector('.page-hover-label');
- if (existingLabel) {
- existingLabel.remove();
- }
-
- const rect = page.getBoundingClientRect();
- const scrollTop = doc.documentElement.scrollTop || doc.body.scrollTop;
- const scrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft;
-
- const templateName = page.getAttribute('data-page-type') || 'default';
-
- const label = doc.createElement('div');
- label.className = 'page-hover-label';
- label.textContent = `@page ${templateName}`;
- label.style.top = `${rect.top + scrollTop - 32}px`;
- label.style.left = `${rect.left + scrollLeft}px`;
-
- doc.body.appendChild(label);
- return label;
-};
-
-// Remove page label
-const removePageLabel = (doc) => {
- const label = doc.querySelector('.page-hover-label');
- if (label) {
- label.remove();
- }
-};
-
// Handle mouse movement in iframe
const handleIframeMouseMove = (event) => {
const pages = event.target.ownerDocument.querySelectorAll('.pagedjs_page');
@@ -168,16 +82,12 @@ const handleIframeMouseMove = (event) => {
if (foundPage !== hoveredPage.value) {
// Remove highlight from previous page (only if not in selectedPages)
if (hoveredPage.value && !selectedPages.value.includes(hoveredPage.value)) {
- hoveredPage.value.classList.remove('page-hovered');
+ hoveredPage.value.style.outline = '';
}
- // Remove previous page label
- removePageLabel(event.target.ownerDocument);
-
// Add highlight to new page (only if not already selected)
if (foundPage && !selectedPages.value.includes(foundPage)) {
- foundPage.classList.add('page-hovered');
- createPageLabel(foundPage);
+ foundPage.style.outline = `2px solid ${PAGE_HIGHLIGHT_COLOR}50`;
}
hoveredPage.value = foundPage;
@@ -186,88 +96,46 @@ const handleIframeMouseMove = (event) => {
// If not near page edge, check for content element hover
if (!foundPage) {
const contentElement = getContentElement(event.target);
- const doc = event.target.ownerDocument;
if (contentElement !== hoveredElement.value) {
// Remove highlight from previous element (only if not selected)
- if (
- hoveredElement.value &&
- hoveredElement.value !== selectedElement.value
- ) {
- hoveredElement.value.classList.remove('element-hovered');
+ if (hoveredElement.value && hoveredElement.value !== selectedElement.value) {
+ hoveredElement.value.style.outline = '';
}
- // Remove previous labels
- removeElementLabel(doc);
- removePageLabel(doc);
-
// Add highlight to new element (only if not already selected)
if (contentElement && contentElement !== selectedElement.value) {
- contentElement.classList.add('element-hovered');
- createElementLabel(contentElement);
+ contentElement.style.outline = `2px dashed ${ELEMENT_HIGHLIGHT_COLOR}`;
}
hoveredElement.value = contentElement;
}
} else {
// Clear element hover when hovering page edge
- if (
- hoveredElement.value &&
- hoveredElement.value !== selectedElement.value
- ) {
- hoveredElement.value.classList.remove('element-hovered');
+ if (hoveredElement.value && hoveredElement.value !== selectedElement.value) {
+ hoveredElement.value.style.outline = '';
hoveredElement.value = null;
}
- // Remove element label when hovering page edge
- removeElementLabel(event.target.ownerDocument);
}
};
// Clear selection highlight from all selected pages
const clearSelectedPages = () => {
selectedPages.value.forEach((page) => {
- page.classList.remove('page-selected');
+ page.style.outline = '';
});
selectedPages.value = [];
};
// Content elements that can trigger ElementPopup
const CONTENT_ELEMENTS = [
- 'P',
- 'H1',
- 'H2',
- 'H3',
- 'H4',
- 'H5',
- 'H6',
- 'IMG',
- 'FIGURE',
- 'FIGCAPTION',
- 'UL',
- 'OL',
- 'LI',
- 'BLOCKQUOTE',
- 'PRE',
- 'CODE',
- 'TABLE',
- 'THEAD',
- 'TBODY',
- 'TR',
- 'TH',
- 'TD',
- 'A',
- 'SPAN',
- 'STRONG',
- 'EM',
- 'B',
- 'I',
- 'U',
- 'ARTICLE',
- 'SECTION',
- 'ASIDE',
- 'HEADER',
- 'FOOTER',
- 'NAV',
+ 'P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6',
+ 'IMG', 'FIGURE', 'FIGCAPTION',
+ 'UL', 'OL', 'LI',
+ 'BLOCKQUOTE', 'PRE', 'CODE',
+ 'TABLE', 'THEAD', 'TBODY', 'TR', 'TH', 'TD',
+ 'A', 'SPAN', 'STRONG', 'EM', 'B', 'I', 'U',
+ 'ARTICLE', 'SECTION', 'ASIDE', 'HEADER', 'FOOTER', 'NAV'
];
// Check if element is a content element (or find closest content parent)
@@ -285,9 +153,8 @@ const getContentElement = (element) => {
// Clear selected element highlight
const clearSelectedElement = () => {
if (selectedElement.value) {
- selectedElement.value.classList.remove('element-selected');
- const doc = selectedElement.value.ownerDocument;
- removeElementLabel(doc);
+ selectedElement.value.style.outline = '';
+ selectedElement.value.style.backgroundColor = '';
selectedElement.value = null;
}
};
@@ -315,14 +182,10 @@ const handleIframeClick = (event) => {
const doc = event.target.ownerDocument;
const sameTemplatePages = getPagesWithSameTemplate(hoveredPage.value, doc);
sameTemplatePages.forEach((page) => {
- page.classList.add('page-selected');
+ page.style.outline = `2px solid ${PAGE_HIGHLIGHT_COLOR}`;
});
selectedPages.value = sameTemplatePages;
- // Remove labels when opening popup
- removePageLabel(doc);
- removeElementLabel(doc);
-
pagePopup.value.open(hoveredPage.value, event, sameTemplatePages.length);
elementPopup.value.close();
return;
@@ -351,35 +214,16 @@ const handleIframeClick = (event) => {
// Clear page selections
clearSelectedPages();
- // If popup is already open and we're clicking another element, close it
- if (elementPopup.value.visible) {
- clearSelectedElement();
- elementPopup.value.close();
- pagePopup.value.close();
- return;
- }
-
// Clear previous element selection
clearSelectedElement();
- // Remove hovered class from the element we're about to select
- contentElement.classList.remove('element-hovered');
-
- // Clear the hoveredElement ref if it's the same as what we're selecting
- if (hoveredElement.value === contentElement) {
- hoveredElement.value = null;
- }
-
- // Get document and remove labels when opening popup
- const doc = event.target.ownerDocument;
- removeElementLabel(doc);
- removePageLabel(doc);
-
// Select the new element
selectedElement.value = contentElement;
- contentElement.classList.add('element-selected');
+ contentElement.style.outline = '';
+ contentElement.style.backgroundColor = `${ELEMENT_HIGHLIGHT_COLOR}4D`; // 30% opacity
// Get count of similar elements
+ const doc = event.target.ownerDocument;
const count = getSimilarElementsCount(contentElement, doc);
elementPopup.value.handleIframeClick(event, contentElement, count);
@@ -445,10 +289,7 @@ const renderPreview = async (shouldReloadFromFile = false) => {
hiddenFrame.onload = () => {
// Add event listeners for page and element interactions
- hiddenFrame.contentDocument.addEventListener(
- 'mousemove',
- handleIframeMouseMove
- );
+ hiddenFrame.contentDocument.addEventListener('mousemove', handleIframeMouseMove);
hiddenFrame.contentDocument.addEventListener('click', handleIframeClick);
// Close Coloris when clicking in the iframe
@@ -582,26 +423,12 @@ onMounted(() => renderPreview(true));
-
-
+
+
@@ -651,9 +478,7 @@ onMounted(() => renderPreview(true));
align-items: center;
justify-content: center;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
- transition:
- transform 0.2s ease,
- box-shadow 0.2s ease;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
z-index: 1000;
}
diff --git a/src/components/ElementPopup.vue b/src/components/ElementPopup.vue
index a8d9a73..a6ebd79 100644
--- a/src/components/ElementPopup.vue
+++ b/src/components/ElementPopup.vue
@@ -337,10 +337,8 @@ const getSelectorFromElement = (element) => {
// Get tag name
const tagName = element.tagName.toLowerCase();
- // Get first class if available (filter out state classes)
- const classes = Array.from(element.classList).filter(
- (cls) => !['element-hovered', 'element-selected', 'page-hovered', 'page-selected'].includes(cls)
- );
+ // Get first class if available
+ const classes = Array.from(element.classList);
if (classes.length > 0) {
return `${tagName}.${classes[0]}`;
}