codeplay-common 4.7.4 → 4.7.6

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.
@@ -1211,12 +1211,33 @@ async function capturePageSnapshot(client) {
1211
1211
  };
1212
1212
 
1213
1213
  const serializeDocument = async (sourceDocument) => {
1214
- const clonedRoot = sourceDocument.documentElement.cloneNode(true);
1215
- const originalElements = [
1216
- sourceDocument.documentElement,
1217
- ...sourceDocument.documentElement.querySelectorAll('*'),
1218
- ];
1219
- const clonedElements = [clonedRoot, ...clonedRoot.querySelectorAll('*')];
1214
+ const originalElements = [];
1215
+ const clonedElements = [];
1216
+ const cloneWithShadowRoots = (original) => {
1217
+ const clone = original.cloneNode(false);
1218
+ if (original.nodeType === Node.ELEMENT_NODE) {
1219
+ originalElements.push(original);
1220
+ clonedElements.push(clone);
1221
+ }
1222
+ for (const child of original.childNodes) {
1223
+ clone.appendChild(cloneWithShadowRoots(child));
1224
+ }
1225
+ if (original.shadowRoot) {
1226
+ const template = sourceDocument.createElement('template');
1227
+ template.setAttribute('shadowrootmode', 'open');
1228
+ for (const stylesheet of original.shadowRoot.adoptedStyleSheets || []) {
1229
+ const style = sourceDocument.createElement('style');
1230
+ style.textContent = [...stylesheet.cssRules].map((rule) => rule.cssText).join('\\n');
1231
+ template.content.appendChild(style);
1232
+ }
1233
+ for (const child of original.shadowRoot.childNodes) {
1234
+ template.content.appendChild(cloneWithShadowRoots(child));
1235
+ }
1236
+ clone.prepend(template);
1237
+ }
1238
+ return clone;
1239
+ };
1240
+ const clonedRoot = cloneWithShadowRoots(sourceDocument.documentElement);
1220
1241
 
1221
1242
  clonedRoot.setAttribute(
1222
1243
  'data-responsive-window-scroll-y',
@@ -1234,9 +1255,13 @@ async function capturePageSnapshot(client) {
1234
1255
  clone.setAttribute('data-responsive-scroll-left', String(original.scrollLeft));
1235
1256
  }
1236
1257
 
1237
- if (original.classList.contains('swiper-initialized')) {
1258
+ if (original.classList.contains('swiper-initialized') || original.swiper) {
1238
1259
  clone.setAttribute('data-responsive-swiper-width', String(original.clientWidth));
1239
1260
  clone.setAttribute('data-responsive-swiper-height', String(original.clientHeight));
1261
+ if (original.swiper) {
1262
+ clone.setAttribute('data-responsive-swiper-active-index', String(original.swiper.activeIndex));
1263
+ clone.setAttribute('data-responsive-swiper-direction', original.swiper.params.direction);
1264
+ }
1240
1265
  }
1241
1266
 
1242
1267
  const tagName = original.tagName?.toLowerCase();
@@ -1321,7 +1346,7 @@ async function capturePageSnapshot(client) {
1321
1346
  }
1322
1347
  }));
1323
1348
 
1324
- clonedRoot.querySelectorAll('script, link[rel="modulepreload"]').forEach(
1349
+ clonedElements.filter((element) => element.matches('script, link[rel="modulepreload"]')).forEach(
1325
1350
  (element) => element.remove(),
1326
1351
  );
1327
1352
  clonedRoot.querySelectorAll('meta[http-equiv="Content-Security-Policy"]').forEach(
@@ -1560,25 +1585,34 @@ async function waitForReplayLayout(client, snapshot) {
1560
1585
  new Promise((resolve) => setTimeout(resolve, 5000)),
1561
1586
  ]);
1562
1587
 
1563
- const replayElements = (selector) => replayDocuments.flatMap((replayDocument) => (
1564
- [...replayDocument.querySelectorAll(selector)]
1588
+ const replayRoots = [];
1589
+ const collectRoots = (root) => {
1590
+ replayRoots.push(root);
1591
+ root.querySelectorAll('*').forEach((element) => {
1592
+ if (element.shadowRoot) collectRoots(element.shadowRoot);
1593
+ });
1594
+ };
1595
+ replayDocuments.forEach(collectRoots);
1596
+ const replayElements = (selector) => replayRoots.flatMap((root) => (
1597
+ [...root.querySelectorAll(selector)]
1565
1598
  ));
1566
1599
 
1567
1600
  replayElements('[data-responsive-swiper-width]').forEach((swiper) => {
1568
- const wrapper = [...swiper.children].find((element) => (
1601
+ const wrapper = swiper.shadowRoot?.querySelector('.swiper-wrapper') || [...swiper.children].find((element) => (
1569
1602
  element.classList.contains('swiper-wrapper')
1570
1603
  ));
1571
1604
 
1572
1605
  if (!wrapper) return;
1573
1606
 
1574
- const slides = [...wrapper.children].filter((element) => (
1575
- element.classList.contains('swiper-slide')
1607
+ const slides = [...(swiper.shadowRoot ? swiper.children : wrapper.children)].filter((element) => (
1608
+ element.matches('.swiper-slide, swiper-slide')
1576
1609
  ));
1577
1610
  const sourceWidth = Number(swiper.dataset.responsiveSwiperWidth);
1578
1611
  const sourceHeight = Number(swiper.dataset.responsiveSwiperHeight);
1579
1612
  const widthScale = sourceWidth > 0 ? swiper.clientWidth / sourceWidth : 1;
1580
1613
  const heightScale = sourceHeight > 0 ? swiper.clientHeight / sourceHeight : 1;
1581
- const isVertical = swiper.classList.contains('swiper-vertical');
1614
+ const isVertical = swiper.dataset.responsiveSwiperDirection === 'vertical'
1615
+ || swiper.classList.contains('swiper-vertical');
1582
1616
 
1583
1617
  slides.forEach((slide) => {
1584
1618
  if (!slide.dataset.responsiveSwiperWidth && slide.style.width) {
@@ -1601,7 +1635,7 @@ async function waitForReplayLayout(client, snapshot) {
1601
1635
  }
1602
1636
  });
1603
1637
 
1604
- const activeSlide = slides.find((slide) => (
1638
+ const activeSlide = slides[Number(swiper.dataset.responsiveSwiperActiveIndex)] || slides.find((slide) => (
1605
1639
  slide.classList.contains('swiper-slide-active')
1606
1640
  )) || slides[0];
1607
1641
 
@@ -1773,19 +1807,26 @@ function rgbToHsl(red, green, blue) {
1773
1807
  async function getPromotionalPalette(screenshotBuffer, screenshotFileName) {
1774
1808
  const { data, info } = await sharp(screenshotBuffer)
1775
1809
  .resize(36, 36, { fit: 'fill' })
1810
+ .toColourspace('srgb')
1776
1811
  .removeAlpha()
1777
1812
  .raw()
1778
1813
  .toBuffer({ resolveWithObject: true });
1779
1814
  const colorBuckets = new Map();
1815
+ const neutralBuckets = new Map();
1780
1816
 
1781
1817
  for (let index = 0; index < data.length; index += info.channels) {
1782
1818
  const red = data[index];
1783
1819
  const green = data[index + 1];
1784
1820
  const blue = data[index + 2];
1785
1821
  const hsl = rgbToHsl(red, green, blue);
1786
- if (hsl.lightness < 0.1 || hsl.lightness > 0.94 || hsl.saturation < 0.12) continue;
1787
- const key = `${Math.round(red / 24)},${Math.round(green / 24)},${Math.round(blue / 24)}`;
1788
- const bucket = colorBuckets.get(key) || {
1822
+ const isColorful = hsl.lightness >= 0.1 && hsl.lightness <= 0.94
1823
+ && hsl.saturation >= 0.12 && Math.max(red, green, blue) - Math.min(red, green, blue) >= 12;
1824
+ const buckets = isColorful ? colorBuckets : neutralBuckets;
1825
+ // Combine shades of the same hue so large tinted surfaces and their controls count together.
1826
+ const key = isColorful
1827
+ ? Math.round(hsl.hue / 15) % 24
1828
+ : `${Math.round(red / 24)},${Math.round(green / 24)},${Math.round(blue / 24)}`;
1829
+ const bucket = buckets.get(key) || {
1789
1830
  count: 0, red: 0, green: 0, blue: 0, saturation: 0, lightness: 0,
1790
1831
  };
1791
1832
  bucket.count += 1;
@@ -1794,16 +1835,18 @@ async function getPromotionalPalette(screenshotBuffer, screenshotFileName) {
1794
1835
  bucket.blue += blue;
1795
1836
  bucket.saturation += hsl.saturation;
1796
1837
  bucket.lightness += hsl.lightness;
1797
- colorBuckets.set(key, bucket);
1838
+ buckets.set(key, bucket);
1798
1839
  }
1799
1840
 
1800
- let selectedColor = { red: 85, green: 70, blue: 232 };
1841
+ let selectedColor;
1801
1842
  let selectedScore = -1;
1802
- for (const bucket of colorBuckets.values()) {
1843
+ for (const bucket of (colorBuckets.size ? colorBuckets : neutralBuckets).values()) {
1803
1844
  const saturation = bucket.saturation / bucket.count;
1804
1845
  const lightness = bucket.lightness / bucket.count;
1805
- const score = bucket.count * (0.55 + saturation * 1.8)
1806
- * (1 - Math.abs(lightness - 0.55) * 0.7);
1846
+ const score = colorBuckets.size
1847
+ ? bucket.count * (0.55 + saturation * 1.8)
1848
+ * (1 - Math.abs(lightness - 0.55) * 0.7)
1849
+ : bucket.count;
1807
1850
  if (score <= selectedScore) continue;
1808
1851
  selectedScore = score;
1809
1852
  selectedColor = {
@@ -1815,21 +1858,24 @@ async function getPromotionalPalette(screenshotBuffer, screenshotFileName) {
1815
1858
 
1816
1859
  const seed = getDecorationSeed(path.parse(screenshotFileName).name);
1817
1860
  const sourceHsl = rgbToHsl(selectedColor.red, selectedColor.green, selectedColor.blue);
1818
- const hue = Math.round((sourceHsl.hue + (seed % 25) - 12 + 360) % 360);
1819
- const secondaryHue = (hue + [38, 56, 142, 205][seed % 4]) % 360;
1820
- const saturation = Math.max(58, Math.min(82, Math.round(sourceHsl.saturation * 100)));
1861
+ const hue = Math.round(sourceHsl.hue) % 360;
1862
+ const secondaryHue = (hue + 18) % 360;
1863
+ const saturation = colorBuckets.size
1864
+ ? Math.min(75, Math.round(sourceHsl.saturation * 100))
1865
+ : 0;
1866
+ const backgroundSaturation = Math.round(saturation * 0.75);
1821
1867
 
1822
1868
  return {
1823
1869
  seed,
1824
1870
  accent: `hsl(${hue} ${saturation}% 46%)`,
1825
1871
  accentSoft: `hsla(${hue} ${saturation}% 55% / 0.2)`,
1826
- secondary: `hsl(${secondaryHue} 70% 54%)`,
1827
- secondarySoft: `hsla(${secondaryHue} 72% 58% / 0.18)`,
1828
- backgroundStart: `hsl(${hue} 68% 97%)`,
1829
- backgroundMiddle: `hsl(${(hue + 14) % 360} 58% 93%)`,
1830
- backgroundEnd: `hsl(${secondaryHue} 62% 88%)`,
1831
- text: `hsl(${hue} 35% 17%)`,
1832
- mutedText: `hsl(${hue} 18% 38%)`,
1872
+ secondary: `hsl(${secondaryHue} ${saturation}% 54%)`,
1873
+ secondarySoft: `hsla(${secondaryHue} ${saturation}% 58% / 0.18)`,
1874
+ backgroundStart: `hsl(${hue} ${backgroundSaturation}% 97%)`,
1875
+ backgroundMiddle: `hsl(${hue} ${backgroundSaturation}% 93%)`,
1876
+ backgroundEnd: `hsl(${secondaryHue} ${backgroundSaturation}% 88%)`,
1877
+ text: `hsl(${hue} ${Math.min(35, saturation)}% 17%)`,
1878
+ mutedText: `hsl(${hue} ${Math.min(18, saturation)}% 38%)`,
1833
1879
  };
1834
1880
  }
1835
1881
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeplay-common",
3
- "version": "4.7.4",
3
+ "version": "4.7.6",
4
4
  "description": "Common build scripts and files",
5
5
  "scripts": {
6
6
  "postinstall": "node scripts/sync-files.js",