@symbo.ls/connect 3.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/build.js +205 -0
  2. package/dist/assets/1024x1024.png +0 -0
  3. package/dist/assets/128x128.png +0 -0
  4. package/dist/assets/144x144.png +0 -0
  5. package/dist/assets/192x192.png +0 -0
  6. package/dist/assets/48x48.png +0 -0
  7. package/dist/assets/512x512.png +0 -0
  8. package/dist/assets/72x72.png +0 -0
  9. package/dist/assets/96x96.png +0 -0
  10. package/dist/assets/active_cursor.png +0 -0
  11. package/dist/assets/favicon.svg +6 -0
  12. package/dist/assets/old/144x144.png +0 -0
  13. package/dist/assets/old/192x192.png +0 -0
  14. package/dist/assets/old/48x48.png +0 -0
  15. package/dist/assets/old/48x48_faint.png +0 -0
  16. package/dist/assets/old/512x512.png +0 -0
  17. package/dist/assets/old/72x72.png +0 -0
  18. package/dist/assets/old/96x96.png +0 -0
  19. package/dist/auth.js +373 -0
  20. package/dist/content.css +46 -0
  21. package/dist/content.js +1171 -0
  22. package/dist/content.js.map +7 -0
  23. package/dist/devtools.html +7 -0
  24. package/dist/devtools.js +5 -0
  25. package/dist/manifest.json +87 -0
  26. package/dist/page-agent.js +727 -0
  27. package/dist/panel.css +2239 -0
  28. package/dist/panel.html +235 -0
  29. package/dist/panel.js +4973 -0
  30. package/dist/picker.html +111 -0
  31. package/dist/picker.js +300 -0
  32. package/dist/service_worker.js +219 -0
  33. package/dist/service_worker.js.map +7 -0
  34. package/dist/settings.css +128 -0
  35. package/dist/settings.html +26 -0
  36. package/dist/settings_ui.js +57 -0
  37. package/dist/settings_ui.js.map +7 -0
  38. package/package.json +20 -0
  39. package/src/content.js +104 -0
  40. package/src/grabber/clean.js +605 -0
  41. package/src/grabber/computed.js +78 -0
  42. package/src/grabber/parse.js +268 -0
  43. package/src/grabber/stylesheets.js +117 -0
  44. package/src/grabber/utils.js +238 -0
  45. package/src/service_worker.js +246 -0
  46. package/src/settings/settings_ui.js +52 -0
  47. package/src/settings/settings_utils.js +70 -0
  48. package/static/assets/1024x1024.png +0 -0
  49. package/static/assets/128x128.png +0 -0
  50. package/static/assets/144x144.png +0 -0
  51. package/static/assets/192x192.png +0 -0
  52. package/static/assets/48x48.png +0 -0
  53. package/static/assets/512x512.png +0 -0
  54. package/static/assets/72x72.png +0 -0
  55. package/static/assets/96x96.png +0 -0
  56. package/static/assets/active_cursor.png +0 -0
  57. package/static/assets/favicon.svg +6 -0
  58. package/static/assets/old/144x144.png +0 -0
  59. package/static/assets/old/192x192.png +0 -0
  60. package/static/assets/old/48x48.png +0 -0
  61. package/static/assets/old/48x48_faint.png +0 -0
  62. package/static/assets/old/512x512.png +0 -0
  63. package/static/assets/old/72x72.png +0 -0
  64. package/static/assets/old/96x96.png +0 -0
  65. package/static/auth.js +373 -0
  66. package/static/content.css +46 -0
  67. package/static/devtools.html +7 -0
  68. package/static/devtools.js +5 -0
  69. package/static/manifest.json +56 -0
  70. package/static/page-agent.js +727 -0
  71. package/static/panel.css +2239 -0
  72. package/static/panel.html +235 -0
  73. package/static/panel.js +4973 -0
  74. package/static/picker.html +111 -0
  75. package/static/picker.js +300 -0
  76. package/static/settings.css +128 -0
  77. package/static/settings.html +26 -0
@@ -0,0 +1,128 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ :root {
8
+ --bg: #141416;
9
+ --bg-alt: #242428;
10
+ --bg-hover: #34343a;
11
+ --border: #34343a;
12
+ --text: #bcbcc2;
13
+ --text-dim: #65656f;
14
+ --text-bright: #e0e0e2;
15
+ --accent: #0085FF;
16
+ }
17
+
18
+ body {
19
+ background: var(--bg);
20
+ color: var(--text);
21
+ font-family: 'DmSansVariable', 'Helvetica Neue', 'Helvetica', system-ui, sans-serif;
22
+ font-size: 14px;
23
+ line-height: 1.5;
24
+ }
25
+
26
+ .main-container {
27
+ margin: 0 auto;
28
+ max-width: 700px;
29
+ padding: 40px 24px;
30
+ }
31
+
32
+ header {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 12px;
36
+ margin-bottom: 8px;
37
+ }
38
+
39
+ .logo {
40
+ width: 32px;
41
+ height: 32px;
42
+ fill: var(--accent);
43
+ flex-shrink: 0;
44
+ }
45
+
46
+ h1 {
47
+ font-size: 20px;
48
+ font-weight: 600;
49
+ color: var(--text-bright);
50
+ }
51
+
52
+ section p {
53
+ color: var(--text-dim);
54
+ font-size: 13px;
55
+ margin-bottom: 24px;
56
+ }
57
+
58
+ .separator {
59
+ margin: 0 0 24px;
60
+ width: 100%;
61
+ height: 1px;
62
+ background: var(--border);
63
+ }
64
+
65
+ #settings-container {
66
+ display: flex;
67
+ flex-direction: column;
68
+ gap: 12px;
69
+ }
70
+
71
+ .setting {
72
+ position: relative;
73
+ background: var(--bg-alt);
74
+ border: 1px solid var(--border);
75
+ border-radius: 10px;
76
+ transition: border-color 0.15s;
77
+ }
78
+
79
+ .setting:hover {
80
+ border-color: var(--accent);
81
+ }
82
+
83
+ .setting label {
84
+ color: var(--text-bright);
85
+ cursor: pointer;
86
+ display: flex;
87
+ align-items: center;
88
+ justify-content: space-between;
89
+ font-size: 14px;
90
+ line-height: 1;
91
+ padding: 16px 20px;
92
+ border-radius: 10px;
93
+ }
94
+
95
+ .setting input[type='checkbox'] {
96
+ appearance: none;
97
+ -webkit-appearance: none;
98
+ width: 40px;
99
+ height: 22px;
100
+ background: var(--bg-hover);
101
+ border-radius: 11px;
102
+ position: relative;
103
+ cursor: pointer;
104
+ flex-shrink: 0;
105
+ margin: 0;
106
+ transition: background 0.2s;
107
+ }
108
+
109
+ .setting input[type='checkbox']::after {
110
+ content: '';
111
+ position: absolute;
112
+ top: 3px;
113
+ left: 3px;
114
+ width: 16px;
115
+ height: 16px;
116
+ background: var(--text-dim);
117
+ border-radius: 50%;
118
+ transition: transform 0.2s, background 0.2s;
119
+ }
120
+
121
+ .setting input[type='checkbox']:checked {
122
+ background: var(--accent);
123
+ }
124
+
125
+ .setting input[type='checkbox']:checked::after {
126
+ transform: translateX(18px);
127
+ background: #fff;
128
+ }
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Symbols Connect — Settings</title>
7
+ <link rel="icon" href="assets/favicon.svg" />
8
+ <link rel="stylesheet" href="settings.css" />
9
+ <script type="module" src="settings_ui.js" defer></script>
10
+ </head>
11
+ <body>
12
+ <div class="main-container">
13
+ <header>
14
+ <svg class="logo" viewBox="0 0 24 24"><path d="M13.843 2.7C19.063 2.7 23 6.366 23 11.228c0 3.754-2.862 6.584-6.658 6.584-3.287 0-5.007-2.318-5.007-4.609 0-2.395 1.923-4.344 4.287-4.344.566 0 1.023.12 1.309.223a.212.212 0 01.137.229l-.016.058-.514 1.18a.223.223 0 01-.245.13 2.965 2.965 0 00-.506-.046c-1.245 0-2.258 1.027-2.258 2.288 0 1.33 1.165 2.373 2.651 2.373 2.195 0 3.913-1.777 3.913-4.046 0-3.024-2.294-5.135-5.58-5.135-4.076 0-7.393 3.36-7.393 7.491a7.519 7.519 0 002.871 5.924l-4.96 3.18A12.042 12.042 0 012 14.7c0-6.617 5.313-12 11.843-12z" fill-rule="evenodd"/></svg>
15
+ <h1>Symbols Connect — Settings</h1>
16
+ </header>
17
+ <main>
18
+ <section>
19
+ <p>Adjust preferences for the Symbols extension. Changes take effect immediately.</p>
20
+ <div class="separator"></div>
21
+ <div id="settings-container"></div>
22
+ </section>
23
+ </main>
24
+ </div>
25
+ </body>
26
+ </html>
@@ -0,0 +1,57 @@
1
+ // src/settings/settings_utils.js
2
+ var storageKey = "settings";
3
+ var settingsDefinitions = [
4
+ {
5
+ key: "useStylesheets",
6
+ name: "Use Stylesheets",
7
+ type: "checkbox",
8
+ default: true
9
+ },
10
+ {
11
+ key: "useComputed",
12
+ name: "Use Computed",
13
+ type: "checkbox",
14
+ default: false
15
+ }
16
+ ];
17
+ var getSettings = async () => (await chrome.storage.local.get(storageKey)).settings;
18
+ async function updateSettings(updates) {
19
+ const cur = await getSettings();
20
+ chrome.storage.local.set({ [storageKey]: { ...cur, ...updates } }).catch((reason) => console.error(`failed to update settings : ${reason}`));
21
+ }
22
+
23
+ // src/settings/settings_ui.js
24
+ var container = document.getElementById("settings-container");
25
+ var curSettings = await getSettings();
26
+ settingsDefinitions.forEach(({ key, name, type, default: defValue }) => {
27
+ const input = document.createElement("input");
28
+ input.id = key;
29
+ input.type = type;
30
+ if (!(key in curSettings)) {
31
+ console.error(`Setting ${key} missing value`, curSettings);
32
+ }
33
+ const value = curSettings[key] ?? defValue ?? null;
34
+ if ((defValue ?? null) !== null) {
35
+ input.defaultValue = defValue;
36
+ }
37
+ if ((value ?? null) !== null) {
38
+ if (type === "checkbox") {
39
+ input.checked = value;
40
+ } else {
41
+ input.value = value;
42
+ }
43
+ }
44
+ const label = document.createElement("label");
45
+ label.htmlFor = key;
46
+ label.textContent = name;
47
+ const wrapper = document.createElement("div");
48
+ wrapper.classList.add("setting");
49
+ wrapper.append(label);
50
+ wrapper.append(input);
51
+ container.append(wrapper);
52
+ input.addEventListener("change", (event) => {
53
+ const val = type === "checkbox" ? event.target.checked : event.target.value;
54
+ updateSettings({ [key]: val });
55
+ });
56
+ });
57
+ //# sourceMappingURL=settings_ui.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/settings/settings_utils.js", "../src/settings/settings_ui.js"],
4
+ "sourcesContent": ["/**\n * @typedef {Object} Settings\n * @property {boolean} useComputed\n * @property {boolean} useStylesheets\n */\n\nconst storageKey = 'settings'\n\n/**\n * @typedef {Object} SettingDefinition\n * @property {string} type\n * @property {String} name\n * @property {string} [key]\n * @property {any} [default]\n * @property {value} [any]\n */\n\n/**\n * @type {SettingDefinition[]}\n */\nexport const settingsDefinitions = [\n {\n key: 'useStylesheets',\n name: 'Use Stylesheets',\n type: 'checkbox',\n default: true\n },\n {\n key: 'useComputed',\n name: 'Use Computed',\n type: 'checkbox',\n default: false\n }\n]\n\n/**\n * @returns {Promise<Settings>}\n */\nexport const getSettings = async () =>\n (await chrome.storage.local.get(storageKey)).settings\n\n/**\n * @param {Partial<Settings>} updates\n */\nexport async function updateSettings(updates) {\n const cur = await getSettings()\n chrome.storage.local\n .set({ [storageKey]: { ...cur, ...updates } })\n .catch((reason) => console.error(`failed to update settings : ${reason}`))\n}\n\nexport async function initSettings() {\n const curSettings = (await getSettings()) ?? {}\n\n // construct default settings from definitions\n const defaultSettings = {}\n settingsDefinitions.forEach(({ key, default: defValue }) => {\n defaultSettings[key] = defValue\n })\n\n // override defaults with any existing settings\n Object.keys(curSettings).forEach((key) => {\n // only include settings within the current defined set\n if (key in defaultSettings) {\n defaultSettings[key] = curSettings[key]\n }\n })\n\n updateSettings(defaultSettings)\n}\n", "import {\n getSettings,\n updateSettings,\n settingsDefinitions\n} from './settings_utils'\n\nconst container = document.getElementById('settings-container')\n\nconst curSettings = await getSettings()\n\n// Build settings UI from definitions\nsettingsDefinitions.forEach(({ key, name, type, default: defValue }) => {\n const input = document.createElement('input')\n input.id = key\n input.type = type\n\n if (!(key in curSettings)) {\n console.error(`Setting ${key} missing value`, curSettings)\n }\n\n const value = curSettings[key] ?? defValue ?? null\n\n if ((defValue ?? null) !== null) {\n input.defaultValue = defValue\n }\n\n if ((value ?? null) !== null) {\n if (type === 'checkbox') {\n input.checked = value\n } else {\n input.value = value\n }\n }\n\n const label = document.createElement('label')\n label.htmlFor = key\n label.textContent = name\n\n const wrapper = document.createElement('div')\n wrapper.classList.add('setting')\n\n wrapper.append(label)\n wrapper.append(input)\n\n container.append(wrapper)\n\n input.addEventListener('change', (event) => {\n const val = type === 'checkbox' ? event.target.checked : event.target.value\n\n updateSettings({ [key]: val })\n })\n})\n"],
5
+ "mappings": ";AAMA,IAAM,aAAa;AAcZ,IAAM,sBAAsB;AAAA,EACjC;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AAAA,EACA;AAAA,IACE,KAAK;AAAA,IACL,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,EACX;AACF;AAKO,IAAM,cAAc,aACxB,MAAM,OAAO,QAAQ,MAAM,IAAI,UAAU,GAAG;AAK/C,eAAsB,eAAe,SAAS;AAC5C,QAAM,MAAM,MAAM,YAAY;AAC9B,SAAO,QAAQ,MACZ,IAAI,EAAE,CAAC,UAAU,GAAG,EAAE,GAAG,KAAK,GAAG,QAAQ,EAAE,CAAC,EAC5C,MAAM,CAAC,WAAW,QAAQ,MAAM,+BAA+B,MAAM,EAAE,CAAC;AAC7E;;;AC3CA,IAAM,YAAY,SAAS,eAAe,oBAAoB;AAE9D,IAAM,cAAc,MAAM,YAAY;AAGtC,oBAAoB,QAAQ,CAAC,EAAE,KAAK,MAAM,MAAM,SAAS,SAAS,MAAM;AACtE,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,KAAK;AACX,QAAM,OAAO;AAEb,MAAI,EAAE,OAAO,cAAc;AACzB,YAAQ,MAAM,WAAW,GAAG,kBAAkB,WAAW;AAAA,EAC3D;AAEA,QAAM,QAAQ,YAAY,GAAG,KAAK,YAAY;AAE9C,OAAK,YAAY,UAAU,MAAM;AAC/B,UAAM,eAAe;AAAA,EACvB;AAEA,OAAK,SAAS,UAAU,MAAM;AAC5B,QAAI,SAAS,YAAY;AACvB,YAAM,UAAU;AAAA,IAClB,OAAO;AACL,YAAM,QAAQ;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,UAAU;AAChB,QAAM,cAAc;AAEpB,QAAM,UAAU,SAAS,cAAc,KAAK;AAC5C,UAAQ,UAAU,IAAI,SAAS;AAE/B,UAAQ,OAAO,KAAK;AACpB,UAAQ,OAAO,KAAK;AAEpB,YAAU,OAAO,OAAO;AAExB,QAAM,iBAAiB,UAAU,CAAC,UAAU;AAC1C,UAAM,MAAM,SAAS,aAAa,MAAM,OAAO,UAAU,MAAM,OAAO;AAEtE,mBAAe,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC;AAAA,EAC/B,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@symbo.ls/connect",
3
+ "version": "3.2.7",
4
+ "description": "Symbols Connect — Chrome extension for DOMQL inspection and element grabbing",
5
+ "main": "dist/content.js",
6
+ "scripts": {
7
+ "build": "node ./build.js",
8
+ "build:watch": "node ./build.js --watch",
9
+ "build:local": "node ./build.js --local",
10
+ "build:watch:local": "node ./build.js --watch --local",
11
+ "build:prod": "node ./build.js --prod"
12
+ },
13
+ "devDependencies": {
14
+ "esbuild": "^0.25.0",
15
+ "chokidar": "^3.5.3"
16
+ },
17
+ "dependencies": {
18
+ "@domql/utils": "^2.29.81"
19
+ }
20
+ }
package/src/content.js ADDED
@@ -0,0 +1,104 @@
1
+ import { parseElement } from './grabber/parse'
2
+
3
+ // ============================================================
4
+ // DOMQL Inspector: inject page-agent for DevTools panel access
5
+ // ============================================================
6
+ function injectPageAgent () {
7
+ const script = document.createElement('script')
8
+ script.src = chrome.runtime.getURL('page-agent.js')
9
+ script.onload = () => script.remove()
10
+ ;(document.head || document.documentElement).appendChild(script)
11
+ }
12
+
13
+ injectPageAgent()
14
+
15
+ // ============================================================
16
+ // Symbols Grabber: click-to-capture element mode
17
+ // ============================================================
18
+ async function addToLibrary (node) {
19
+ const rootStyles = window.getComputedStyle(document.documentElement)
20
+ const obj = await parseElement(node, rootStyles)
21
+
22
+ const store = { domqlStr: JSON.stringify(obj) }
23
+ console.log('%c[Symbols] saving domql', 'color: green', store)
24
+
25
+ chrome.storage.local.set(store)
26
+ chrome.runtime.sendMessage({ type: 'open_platform' })
27
+
28
+ return obj
29
+ }
30
+
31
+ const focusNodeClass = 'symbols-grabber-hovered'
32
+ let isListenerActive = false
33
+ let focusedNode = null
34
+
35
+ document.body.addEventListener(
36
+ 'mouseover',
37
+ (event) => {
38
+ const { target } = event
39
+ if (target && isListenerActive) {
40
+ if (focusedNode && focusedNode !== target) {
41
+ focusedNode.classList.remove(focusNodeClass)
42
+ }
43
+ focusedNode = target
44
+ focusedNode.classList.add(focusNodeClass)
45
+ }
46
+ },
47
+ true
48
+ )
49
+
50
+ chrome.runtime.onMessage.addListener((msg, sender, respond) => {
51
+ if (sender.id === chrome.runtime.id) {
52
+ const { type, state } = msg
53
+
54
+ if (type === 'toggle' && typeof state === 'number') {
55
+ console.log(
56
+ `%c[Symbols] grabber ${state ? 'enabled' : 'disabled'}`,
57
+ `color: ${state ? 'green' : 'red'}`
58
+ )
59
+
60
+ isListenerActive = Boolean(state)
61
+ document.body.classList.toggle('symbols-grabber-active', isListenerActive)
62
+
63
+ if (!state) {
64
+ document.querySelectorAll(`.${focusNodeClass}`).forEach((el) => {
65
+ el.classList.remove(focusNodeClass)
66
+ })
67
+ focusedNode = null
68
+ }
69
+
70
+ document.body.addEventListener(
71
+ 'click',
72
+ (event) => {
73
+ const { target } = event
74
+ if (target && isListenerActive) {
75
+ event.preventDefault()
76
+ event.stopImmediatePropagation()
77
+
78
+ if (target.classList.contains(focusNodeClass)) {
79
+ target.classList.remove(focusNodeClass)
80
+ }
81
+
82
+ addToLibrary(target).then(
83
+ (domql) => {
84
+ target.classList.add(focusNodeClass)
85
+ respond({ success: true, domql })
86
+ },
87
+ (error) => {
88
+ console.error('[Symbols] error adding to library', error)
89
+ respond({ success: false, error: error.message || error })
90
+ }
91
+ )
92
+
93
+ isListenerActive = false
94
+ }
95
+ },
96
+ { capture: true, once: true }
97
+ )
98
+ }
99
+ }
100
+
101
+ return true
102
+ })
103
+
104
+ console.log('[Symbols] Content script loaded (inspector + grabber)')