@trops/dash-core 0.1.178 → 0.1.180

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.
@@ -39234,6 +39234,28 @@ function extractComputedColors(computedStyles) {
39234
39234
  return results;
39235
39235
  }
39236
39236
 
39237
+ /**
39238
+ * Extract colors from broad DOM color scan (frequency-based).
39239
+ * @param {Array<{color: string, count: number}>} domColors - Sorted by frequency
39240
+ * @returns {Array<{hex: string, source: string, confidence: number, count: number}>}
39241
+ */
39242
+ function extractDomColors(domColors) {
39243
+ if (!Array.isArray(domColors) || domColors.length === 0) return [];
39244
+ const results = [];
39245
+ for (const entry of domColors) {
39246
+ if (!entry.color || !entry.count) continue;
39247
+ const rgb = parseColor(entry.color);
39248
+ if (!rgb) continue;
39249
+ results.push({
39250
+ hex: rgbToHex(rgb),
39251
+ source: "dom",
39252
+ confidence: 0.7,
39253
+ count: entry.count,
39254
+ });
39255
+ }
39256
+ return results;
39257
+ }
39258
+
39237
39259
  // ─── Favicon extraction ──────────────────────────────────────────────────────
39238
39260
 
39239
39261
  /**
@@ -39462,7 +39484,7 @@ function mergeAndRank(allColors, maxColors = 6) {
39462
39484
  for (const cluster of clusters) {
39463
39485
  if (deltaE$1(cluster.lab, lab) < THRESHOLD) {
39464
39486
  // Merge into existing cluster — keep the highest-confidence color as representative
39465
- cluster.count++;
39487
+ cluster.count += color.count || 1;
39466
39488
  cluster.sources.add(color.source);
39467
39489
  if (color.confidence > cluster.confidence) {
39468
39490
  cluster.hex = color.hex;
@@ -39481,7 +39503,7 @@ function mergeAndRank(allColors, maxColors = 6) {
39481
39503
  rgb,
39482
39504
  lab,
39483
39505
  confidence: color.confidence,
39484
- count: 1,
39506
+ count: color.count || 1,
39485
39507
  sources: new Set([color.source]),
39486
39508
  });
39487
39509
  }
@@ -39563,6 +39585,7 @@ function mergeAndRank(allColors, maxColors = 6) {
39563
39585
  * @param {string} params.htmlContent - Raw HTML of the page
39564
39586
  * @param {string} params.cssContent - Concatenated CSS content
39565
39587
  * @param {Object} params.computedStyles - Map of selector → { color, backgroundColor, borderColor }
39588
+ * @param {Array<{color: string, count: number}>} [params.domColors] - Frequency-sorted DOM colors from broad scan
39566
39589
  * @param {string} [params.baseUrl] - Page URL for resolving favicon paths (enables image extraction)
39567
39590
  * @returns {Promise<{ palette: Array, rawCount: number }>}
39568
39591
  */
@@ -39570,6 +39593,7 @@ async function extractColorsFromUrl({
39570
39593
  htmlContent,
39571
39594
  cssContent,
39572
39595
  computedStyles,
39596
+ domColors,
39573
39597
  baseUrl,
39574
39598
  }) {
39575
39599
  console.log("[themeFromUrlController] Starting color extraction pipeline");
@@ -39594,6 +39618,11 @@ async function extractColorsFromUrl({
39594
39618
  `[themeFromUrlController] Computed styles: ${computedColors.length} colors`,
39595
39619
  );
39596
39620
 
39621
+ const domColorResults = extractDomColors(domColors);
39622
+ console.log(
39623
+ `[themeFromUrlController] DOM scan: ${domColorResults.length} colors`,
39624
+ );
39625
+
39597
39626
  // Favicon extraction (async, requires baseUrl)
39598
39627
  let faviconColors = [];
39599
39628
  if (baseUrl) {
@@ -39613,6 +39642,7 @@ async function extractColorsFromUrl({
39613
39642
  ...metaColors,
39614
39643
  ...cssVarColors,
39615
39644
  ...computedColors,
39645
+ ...domColorResults,
39616
39646
  ...faviconColors,
39617
39647
  ].filter((c) => {
39618
39648
  if (!c.hex) {
@@ -39714,7 +39744,7 @@ function pick(arr) {
39714
39744
  /**
39715
39745
  * Generate a fun theme name based on color families.
39716
39746
  */
39717
- function generateThemeName(primary, secondary) {
39747
+ function generateThemeName$1(primary, secondary) {
39718
39748
  const adjectives = {
39719
39749
  red: "Crimson",
39720
39750
  orange: "Sunset",
@@ -39825,7 +39855,7 @@ function generateRandomTheme() {
39825
39855
  const tertiary = nearestColor(tertiaryHue);
39826
39856
 
39827
39857
  const neutral = pick(NEUTRAL_COLORS);
39828
- const name = generateThemeName(primary, secondary);
39858
+ const name = generateThemeName$1(primary, secondary);
39829
39859
 
39830
39860
  return buildRawTheme(name, primary, secondary, tertiary, neutral);
39831
39861
  }
@@ -39871,7 +39901,7 @@ function generateHarmonyTheme(baseColor, strategy = "complementary") {
39871
39901
  const secondary = nearestColor(secondaryHue);
39872
39902
  const tertiary = nearestColor(tertiaryHue);
39873
39903
  const neutral = pick(NEUTRAL_COLORS);
39874
- const name = generateThemeName(primary, secondary);
39904
+ const name = generateThemeName$1(primary, secondary);
39875
39905
 
39876
39906
  return buildRawTheme(name, primary, secondary, tertiary, neutral);
39877
39907
  }
@@ -39884,7 +39914,7 @@ function generateHarmonyTheme(baseColor, strategy = "complementary") {
39884
39914
  */
39885
39915
  function generateCustomTheme(primary, secondary, tertiary) {
39886
39916
  const neutral = pick(NEUTRAL_COLORS);
39887
- const name = generateThemeName(primary, secondary);
39917
+ const name = generateThemeName$1(primary, secondary);
39888
39918
  return buildRawTheme(name, primary, secondary, tertiary, neutral);
39889
39919
  }
39890
39920
 
@@ -39911,7 +39941,7 @@ var themeGenerator = /*#__PURE__*/Object.freeze({
39911
39941
  generateCustomTheme: generateCustomTheme,
39912
39942
  generateHarmonyTheme: generateHarmonyTheme,
39913
39943
  generateRandomTheme: generateRandomTheme,
39914
- generateThemeName: generateThemeName,
39944
+ generateThemeName: generateThemeName$1,
39915
39945
  getThemePresets: getThemePresets
39916
39946
  });
39917
39947
 
@@ -39926,6 +39956,7 @@ var require$$1 = /*@__PURE__*/getAugmentedNamespace(themeGenerator);
39926
39956
  */
39927
39957
 
39928
39958
  const { TAILWIND_COLORS } = require$$0;
39959
+ const { generateThemeName } = require$$1;
39929
39960
 
39930
39961
  const VALID_HEX_RE = /^#[0-9a-fA-F]{6}$/;
39931
39962
 
@@ -40258,7 +40289,6 @@ function generateThemeFromPalette$1(palette, overrides = {}) {
40258
40289
  }
40259
40290
 
40260
40291
  // Step 3: Generate theme name from families
40261
- const { generateThemeName } = require$$1;
40262
40292
  const themeName = generateThemeName(
40263
40293
  primaryMatch.family,
40264
40294
  secondaryMatch.family,
@@ -70426,30 +70456,54 @@ async function handleCreateThemeFromUrl$1({ url, name }) {
70426
70456
  const extracted = await scanWindow.webContents.executeJavaScript(`
70427
70457
  (function() {
70428
70458
  try {
70429
- const htmlContent = document.documentElement.outerHTML;
70430
- let cssContent = '';
70459
+ var htmlContent = document.documentElement.outerHTML;
70460
+ var cssContent = '';
70431
70461
  try {
70432
- for (const sheet of document.styleSheets) {
70462
+ for (var s = 0; s < document.styleSheets.length; s++) {
70433
70463
  try {
70434
- for (const rule of sheet.cssRules) {
70435
- cssContent += rule.cssText + '\\n';
70464
+ var rules = document.styleSheets[s].cssRules;
70465
+ for (var r = 0; r < rules.length; r++) {
70466
+ cssContent += rules[r].cssText + '\\n';
70436
70467
  }
70437
- } catch (e) { /* cross-origin stylesheet */ }
70468
+ } catch (e) {}
70438
70469
  }
70439
70470
  } catch (e) {}
70440
- const selectors = ['body', 'header', 'nav', 'main', 'footer', 'a', 'button', 'h1', 'h2'];
70441
- const computedStyles = {};
70442
- for (const sel of selectors) {
70443
- const el = document.querySelector(sel);
70444
- if (!el) continue;
70445
- const cs = window.getComputedStyle(el);
70446
- computedStyles[sel] = {
70447
- color: cs.color,
70448
- backgroundColor: cs.backgroundColor,
70449
- borderColor: cs.borderColor,
70450
- };
70471
+
70472
+ var DEFAULT_COLORS = {
70473
+ 'rgba(0, 0, 0, 0)': 1, 'transparent': 1,
70474
+ 'rgb(0, 0, 0)': 1, 'rgb(255, 255, 255)': 1
70475
+ };
70476
+ var colorFreq = {};
70477
+ var elements = document.body ? document.body.querySelectorAll('*') : [];
70478
+ var limit = Math.min(elements.length, 500);
70479
+ for (var i = 0; i < limit; i++) {
70480
+ var el = elements[i];
70481
+ if (el.offsetWidth === 0 && el.offsetHeight === 0) continue;
70482
+ var cs = window.getComputedStyle(el);
70483
+ var props = ['color', 'backgroundColor', 'borderColor'];
70484
+ for (var p = 0; p < props.length; p++) {
70485
+ var val = cs[props[p]];
70486
+ if (val && !DEFAULT_COLORS[val]) {
70487
+ colorFreq[val] = (colorFreq[val] || 0) + 1;
70488
+ }
70489
+ }
70490
+ if (el instanceof SVGElement) {
70491
+ var fill = cs.fill;
70492
+ var stroke = cs.stroke;
70493
+ if (fill && fill !== 'none' && !DEFAULT_COLORS[fill]) {
70494
+ colorFreq[fill] = (colorFreq[fill] || 0) + 1;
70495
+ }
70496
+ if (stroke && stroke !== 'none' && !DEFAULT_COLORS[stroke]) {
70497
+ colorFreq[stroke] = (colorFreq[stroke] || 0) + 1;
70498
+ }
70499
+ }
70451
70500
  }
70452
- return { success: true, htmlContent, cssContent, computedStyles };
70501
+ var domColors = Object.keys(colorFreq)
70502
+ .map(function(key) { return { color: key, count: colorFreq[key] }; })
70503
+ .sort(function(a, b) { return b.count - a.count; })
70504
+ .slice(0, 50);
70505
+
70506
+ return { success: true, htmlContent: htmlContent, cssContent: cssContent, domColors: domColors };
70453
70507
  } catch (e) {
70454
70508
  return { success: false, error: { type: 'EXTRACTION_FAILED', message: e.message } };
70455
70509
  }
@@ -70465,7 +70519,7 @@ async function handleCreateThemeFromUrl$1({ url, name }) {
70465
70519
  return themeFromUrlController$1.extractColorsFromUrl({
70466
70520
  htmlContent: extracted.htmlContent,
70467
70521
  cssContent: extracted.cssContent,
70468
- computedStyles: extracted.computedStyles,
70522
+ domColors: extracted.domColors,
70469
70523
  baseUrl: trimmedUrl,
70470
70524
  });
70471
70525
  } finally {