diff --git a/package-lock.json b/package-lock.json index 4ade679..ac33119 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "js-beautify": "^1.15.1", "json5": "^2.2.3", "live-server": "^1.2.2", + "lodash": "^4.17.21", "normalize-diacritics-es": "^1.0.8", "npm": "^10.9.2", "postcss-sass": "^0.5.0" @@ -3842,7 +3843,6 @@ "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, "license": "MIT" }, "node_modules/lodash.debounce": { diff --git a/package.json b/package.json index b9cacd9..e8f5338 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "js-beautify": "^1.15.1", "json5": "^2.2.3", "live-server": "^1.2.2", + "lodash": "^4.17.21", "normalize-diacritics-es": "^1.0.8", "npm": "^10.9.2", "postcss-sass": "^0.5.0" diff --git a/src/mock.js b/src/mock.js index ca4da65..7d8c62a 100644 --- a/src/mock.js +++ b/src/mock.js @@ -1 +1,34 @@ -import "./script.js" \ No newline at end of file +import "./script.js" +function m_pointer() { + document.body.classList.add("mock-pointer") + if (document.querySelector("div#m_pointer_0000HELLYEAH")) return document.querySelector("div#m_pointer_0000HELLYEAH") + const p = document.createElement("div") + p.id = "m_pointer_0000HELLYEAH" + p.style.cssText = ` + position: fixed; + transform: translate(-50%, -50%); + z-index: 999999999; + width: 30px; + height: 30px; + border-radius: 50%; + pointer-events: none; + background: rgb(255, 255, 255, .5); + box-shadow: inset 0px 0px 0px 2px rgb(255, 255, 255, .5; + ` + document.body.append(p) + return p +} +document.body.addEventListener("pointerenter", (e) => { + const p = m_pointer() + p.style.left = e.pageX + "px" + p.style.top = e.pageY + "px" +}) +window.addEventListener("pointermove", (e) => { + const p = m_pointer() + p.style.left = e.pageX + "px" + p.style.top = e.pageY + "px" +}) +document.body.addEventListener("pointerleave", (e) => { + const p = m_pointer() + p.remove() +}) \ No newline at end of file diff --git a/src/styles/selectorMode.scss b/src/styles/selectorMode.scss index 43da9cf..ddb7fa0 100644 --- a/src/styles/selectorMode.scss +++ b/src/styles/selectorMode.scss @@ -11,4 +11,12 @@ body.selector-mode { .groove-app-tile-imageicon { pointer-events: all !important; } +} + +body.mock-pointer { + + &, + * { + cursor: none !important; + } } \ No newline at end of file diff --git a/src/themeEditor.js b/src/themeEditor.js index 21725a4..30ce7c1 100644 --- a/src/themeEditor.js +++ b/src/themeEditor.js @@ -1,5 +1,6 @@ import { css as beautifyCss } from 'js-beautify'; import * as sass from "sass"; +import { debounce } from 'lodash'; window.sass = sass window.beautifyCss = beautifyCss const editor = CodeMirror.fromTextArea(document.getElementById('cssEditor'), { @@ -39,9 +40,7 @@ function rescale() { const scaleWidth = previewWidth / deviceWidth; const scaleHeight = previewHeight / deviceHeight; scale = Math.min(.75, Math.min(scaleWidth, scaleHeight)); - device.style.transform = `scale(${scale})`; - console.log(scale) } window.addEventListener('resize', rescale); @@ -57,7 +56,6 @@ document.querySelector("div.CodeMirror-gutter").addEventListener("pointerdown", var editorSize = 50 window.addEventListener("pointermove", (e) => { if (resizing) { - console.log(e.pageX - resizing) const sc = (e.pageX - resizing) / window.innerWidth * 100 editorSize = (lastSize - sc) || 0 editorSize = (editorSize || 0) @@ -126,9 +124,7 @@ window.addEventListener('keydown', (e) => { (e.ctrlKey && e.shiftKey && e.code === 'KeyI')) { e.preventDefault(); // editor.setValue(editor.getValue().trim()); - const cursor = editor.getCursor(); - editor.setValue(beautifyCss(editor.getValue(), { indent_size: 4, space_in_empty_paren: true })); - editor.setCursor(cursor); + beautify() //editor.setValue(formatted); showToast('Style formatted'); } @@ -173,7 +169,6 @@ function compile() { }; const showWarning = lastcsstext != cssText lastcsstext = cssText - console.log("metadata", titleMatch, metadata) if (titleMatch == null) { const cursor = editor.getCursor() cursor.line += 2 @@ -223,7 +218,6 @@ async function preview() { currentBlobUrl = iframeWindow.URL.createObjectURL(blob); showToast('CSS blob URL created: ' + currentBlobUrl); - console.log(currentBlobUrl); iframeWindow.Groove.launchApp(`groove.internal.tweaks?installStyle=${currentBlobUrl}`) } async function run(css) { @@ -411,10 +405,9 @@ function elementFromPoint(x, y) { return false; } var lastEl -document.querySelector("#selector-frame").addEventListener("pointermove", (e) => { - const rect = e.currentTarget.getBoundingClientRect(); +document.querySelector("#selector-frame").addEventListener("pointermove", debounce((e) => { + const rect = document.querySelector("#selector-frame").getBoundingClientRect(); const [x, y] = [e.clientX - rect.left, e.clientY - rect.top]; - console.log('Relative position:', { x, y }); const el = elementFromPoint(x / scale, y / scale) if (el) { const iframeWindow = document.querySelector("iframe").contentWindow; @@ -430,10 +423,9 @@ document.querySelector("#selector-frame").addEventListener("pointermove", (e) => selectorBox.classList.add("alt") } else { selectorBox.classList.remove("alt") - } } -}) +}, 16)); // 16ms debounce for smooth 60fps const blacklistedClasses = [ 'ng-star-inserted', @@ -486,7 +478,7 @@ function getElementSelector(element, group = false) { // Check static selectors first for (const selector of static_selectors) { - if (element.matches(selector)) { + if (element.matches(selector.replaceAll(" &", ""))) { return selector; } } @@ -525,7 +517,11 @@ function getElementSelector(element, group = false) { } function beautify() { const cursor = editor.getCursor(); - editor.setValue(beautifyCss(editor.getValue(), { indent_size: 4, space_in_empty_paren: true })); + editor.setValue(beautifyCss(editor.getValue(), { + indent_size: 4, + space_in_empty_paren: true, + brace_style: "end-expand" + })); editor.setCursor(cursor); } document.querySelector("#selector-frame").addEventListener("click", (e) => { @@ -536,7 +532,6 @@ document.querySelector("#selector-frame").addEventListener("click", (e) => { let currentContent = editor.getValue(); const selectorParts = selector.split(/\s*>\s*|\s+/); - // Function to find existing selector in content function findSelectorPosition(content, selector) { const regex = new RegExp(`${selector}\\s*{[^}]*}`, 'g'); const matches = [...content.matchAll(regex)]; @@ -546,14 +541,13 @@ document.querySelector("#selector-frame").addEventListener("click", (e) => { let currentPosition = 0; let nestedContent = ''; let remainingParts = [...selectorParts]; + let finalLine = 0; - // Process each selector part while (remainingParts.length > 0) { const currentSelector = remainingParts[0]; const position = findSelectorPosition(currentContent, currentSelector); if (position !== -1) { - // Selector exists, find its closing brace let bracketCount = 1; let i = currentContent.indexOf('{', position) + 1; @@ -563,14 +557,14 @@ document.querySelector("#selector-frame").addEventListener("click", (e) => { i++; } - currentPosition = i - 1; // Position before closing brace + currentPosition = i - 1; + finalLine = currentContent.substr(0, currentPosition).split('\n').length; remainingParts.shift(); } else { break; } } - // Build remaining nested structure if (remainingParts.length > 0) { let indentation = ' '.repeat(selectorParts.length - remainingParts.length); @@ -579,25 +573,29 @@ document.querySelector("#selector-frame").addEventListener("click", (e) => { indentation += ' '; }); - // Add closing braces remainingParts.forEach(() => { indentation = indentation.slice(4); nestedContent += `${indentation}}\n`; }); - // Insert the new content at the appropriate position if (currentPosition > 0) { currentContent = currentContent.slice(0, currentPosition) + '\n' + nestedContent + currentContent.slice(currentPosition); + finalLine += 1; } else { currentContent += '\n' + nestedContent; + finalLine = currentContent.split('\n').length - remainingParts.length; } } editor.setValue(currentContent); beautify(); + // Set cursor position and focus + editor.setCursor(finalLine - 1, 4); + editor.focus(); + showToast('Selector copied and nested structure added'); document.querySelector("#selectorBtn").style.removeProperty("background-color"); document.querySelector("div.preview").classList.remove("selector-mode");