@tldraw/editor 3.11.0-canary.b2098bef0749 → 3.11.0-canary.b65e0ab5933e

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.
package/dist-cjs/index.js CHANGED
@@ -374,7 +374,7 @@ function debugEnableLicensing() {
374
374
  }
375
375
  (0, import_utils.registerTldrawLibraryVersion)(
376
376
  "@tldraw/editor",
377
- "3.11.0-canary.b2098bef0749",
377
+ "3.11.0-canary.b65e0ab5933e",
378
378
  "cjs"
379
379
  );
380
380
  //# sourceMappingURL=index.js.map
@@ -50,7 +50,19 @@ class StyleEmbedder {
50
50
  }
51
51
  readElementStyles(element, { shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }) {
52
52
  const defaultStyles = shouldRespectDefaults ? getDefaultStylesForTagName(element.tagName.toLowerCase()) : NO_STYLES;
53
- const parentStyles = shouldSkipInheritedParentStyles ? this.styles.get(element.parentElement)?.self ?? NO_STYLES : NO_STYLES;
53
+ const parentStyles = Object.assign({}, NO_STYLES);
54
+ if (shouldSkipInheritedParentStyles) {
55
+ let el = element.parentElement;
56
+ while (el) {
57
+ const currentStyles = this.styles.get(el)?.self;
58
+ for (const style in currentStyles) {
59
+ if (!parentStyles[style]) {
60
+ parentStyles[style] = currentStyles[style];
61
+ }
62
+ }
63
+ el = el.parentElement;
64
+ }
65
+ }
54
66
  const info = {
55
67
  self: styleFromElement(element, { defaultStyles, parentStyles }),
56
68
  before: styleFromPseudoElement(element, "::before"),
@@ -177,6 +189,8 @@ function styleFromComputedStyleMap(style, { defaultStyles, parentStyles }) {
177
189
  const value = style.get(property).toString();
178
190
  if (defaultStyles[property] === value) continue;
179
191
  if (parentStyles[property] === value && (0, import_parseCss.isPropertyInherited)(property)) continue;
192
+ if ((0, import_parseCss.isPropertyCoveredByCurrentColor)(style.get("color")?.toString() || "", property, value))
193
+ continue;
180
194
  styles[property] = value;
181
195
  }
182
196
  return styles;
@@ -188,6 +202,7 @@ function styleFromComputedStyle(style, { defaultStyles, parentStyles }) {
188
202
  const value = style.getPropertyValue(property);
189
203
  if (defaultStyles[property] === value) continue;
190
204
  if (parentStyles[property] === value && (0, import_parseCss.isPropertyInherited)(property)) continue;
205
+ if ((0, import_parseCss.isPropertyCoveredByCurrentColor)(style.color, property, value)) continue;
191
206
  styles[property] = value;
192
207
  }
193
208
  return styles;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/StyleEmbedder.ts"],
4
- "sourcesContent": ["import { assertExists, objectMapValues, uniqueId } from '@tldraw/utils'\nimport { FontEmbedder } from './FontEmbedder'\nimport {\n\telementStyle,\n\tgetComputedStyle,\n\tgetRenderedChildNodes,\n\tgetRenderedChildren,\n} from './domUtils'\nimport { resourceToDataUrl } from './fetchCache'\nimport { isPropertyInherited, parseCssValueUrls, shouldIncludeCssProperty } from './parseCss'\n\ntype Styles = { [K in string]?: string }\ntype ReadonlyStyles = { readonly [K in string]?: string }\nconst NO_STYLES = {} as const\n\ninterface ElementStyleInfo {\n\tself: Styles\n\tbefore: Styles | undefined\n\tafter: Styles | undefined\n}\n\nexport class StyleEmbedder {\n\tconstructor(private readonly root: Element) {}\n\tprivate readonly styles = new Map<Element, ElementStyleInfo>()\n\treadonly fonts = new FontEmbedder()\n\n\treadRootElementStyles(rootElement: Element) {\n\t\t// when reading a root, we always apply _all_ the styles, even if they match the defaults\n\t\tthis.readElementStyles(rootElement, {\n\t\t\tshouldRespectDefaults: false,\n\t\t\tshouldSkipInheritedParentStyles: false,\n\t\t})\n\n\t\tconst children = Array.from(getRenderedChildren(rootElement))\n\t\twhile (children.length) {\n\t\t\tconst child = children.pop()!\n\t\t\tchildren.push(...getRenderedChildren(child))\n\n\t\t\t// when reading children, we don't apply styles that match the defaults for that\n\t\t\t// element, or that would be inherited from the parent\n\t\t\tthis.readElementStyles(child, {\n\t\t\t\tshouldRespectDefaults: true,\n\t\t\t\tshouldSkipInheritedParentStyles: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate readElementStyles(\n\t\telement: Element,\n\t\t{ shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }\n\t) {\n\t\tconst defaultStyles = shouldRespectDefaults\n\t\t\t? getDefaultStylesForTagName(element.tagName.toLowerCase())\n\t\t\t: NO_STYLES\n\n\t\tconst parentStyles = shouldSkipInheritedParentStyles\n\t\t\t? (this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES)\n\t\t\t: NO_STYLES\n\n\t\tconst info: ElementStyleInfo = {\n\t\t\tself: styleFromElement(element, { defaultStyles, parentStyles }),\n\t\t\tbefore: styleFromPseudoElement(element, '::before'),\n\t\t\tafter: styleFromPseudoElement(element, '::after'),\n\t\t}\n\t\tthis.styles.set(element, info)\n\t}\n\n\tfetchResources() {\n\t\tconst promises: Promise<void>[] = []\n\n\t\tfor (const info of this.styles.values()) {\n\t\t\tfor (const styles of objectMapValues(info)) {\n\t\t\t\tif (!styles) continue\n\t\t\t\tfor (const [property, value] of Object.entries(styles)) {\n\t\t\t\t\tif (!value) continue\n\t\t\t\t\tif (property === 'font-family') {\n\t\t\t\t\t\tthis.fonts.onFontFamilyValue(value)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst urlMatches = parseCssValueUrls(value)\n\t\t\t\t\tif (urlMatches.length === 0) continue\n\n\t\t\t\t\tpromises.push(\n\t\t\t\t\t\t...urlMatches.map(async ({ url, original }) => {\n\t\t\t\t\t\t\tconst dataUrl = (await resourceToDataUrl(url)) ?? 'data:'\n\t\t\t\t\t\t\tstyles[property] = value.replace(original, `url(\"${dataUrl}\")`)\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.all(promises)\n\t}\n\n\t// custom elements are tricky. if we serialize the dom as-is, the custom elements wont have\n\t// their shadow-dom contents serialized. after we've read all the styles, we need to unwrap the\n\t// contents of each custom elements shadow dom directly into the parent element itself.\n\tunwrapCustomElements() {\n\t\tconst visited = new Set<Node>()\n\n\t\tconst visit = (element: Element, clonedParent: Element | null) => {\n\t\t\tif (visited.has(element)) return\n\t\t\tvisited.add(element)\n\n\t\t\tconst shadowRoot = element.shadowRoot\n\n\t\t\tif (shadowRoot) {\n\t\t\t\tconst clonedCustomEl = document.createElement('div')\n\t\t\t\tthis.styles.set(clonedCustomEl, this.styles.get(element)!)\n\n\t\t\t\tclonedCustomEl.setAttribute('data-tl-custom-element', element.tagName)\n\t\t\t\t;(clonedParent ?? element.parentElement!).appendChild(clonedCustomEl)\n\n\t\t\t\tfor (const child of shadowRoot.childNodes) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedCustomEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedCustomEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telement.remove()\n\t\t\t} else if (clonedParent) {\n\t\t\t\tif (element.tagName.toLowerCase() === 'style') {\n\t\t\t\t\t// we don't clone style tags at that would break the style scoping. instead we\n\t\t\t\t\t// rely on the computed styles we've already read\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst clonedEl = element.cloneNode(false) as Element\n\t\t\t\tthis.styles.set(clonedEl, this.styles.get(element)!)\n\n\t\t\t\tclonedParent.appendChild(clonedEl)\n\n\t\t\t\tfor (const child of getRenderedChildNodes(element)) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const element of this.styles.keys()) {\n\t\t\tvisit(element, null)\n\t\t}\n\t}\n\n\tembedStyles(): string {\n\t\tlet css = ''\n\n\t\tfor (const [element, info] of this.styles) {\n\t\t\tif (info.after || info.before) {\n\t\t\t\tconst className = `pseudo-${uniqueId()}`\n\t\t\t\telement.classList.add(className)\n\n\t\t\t\tif (info.before) {\n\t\t\t\t\tcss += `.${className}::before {${formatCss(info.before)}}\\n`\n\t\t\t\t}\n\t\t\t\tif (info.after) {\n\t\t\t\t\tcss += `.${className}::after {${formatCss(info.after)}}\\n`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst style = elementStyle(element)\n\t\t\tfor (const [property, value] of Object.entries(info.self)) {\n\t\t\t\tif (!value) continue\n\t\t\t\tstyle.setProperty(property, value)\n\t\t\t}\n\n\t\t\t// in HTML, font-kerning: auto is equivalent to font-kerning: normal. But in SVG, it's\n\t\t\t// none. We set it to normal here to match the HTML behavior, as otherwise this can\n\t\t\t// cause rendering differences.\n\t\t\tif (style.fontKerning === 'auto') {\n\t\t\t\tstyle.fontKerning = 'normal'\n\t\t\t}\n\t\t}\n\n\t\treturn css\n\t}\n\n\tasync getFontFaceCss() {\n\t\treturn await this.fonts.createCss()\n\t}\n\n\tdispose() {\n\t\tdestroyDefaultStyleFrame()\n\t}\n}\n\ninterface ReadStyleOpts {\n\tdefaultStyles: ReadonlyStyles\n\tparentStyles: ReadonlyStyles\n}\n\nfunction styleFromElement(element: Element, { defaultStyles, parentStyles }: ReadStyleOpts) {\n\t// `computedStyleMap` produces a more accurate representation of the styles, but it's not\n\t// supported in firefox at the time of writing. So we fall back to `getComputedStyle` if it's\n\t// not available.\n\tif (element.computedStyleMap) {\n\t\treturn styleFromComputedStyleMap(element.computedStyleMap(), { defaultStyles, parentStyles })\n\t}\n\treturn styleFromComputedStyle(getComputedStyle(element), { defaultStyles, parentStyles })\n}\n\nfunction styleFromPseudoElement(element: Element, pseudo: string) {\n\t// the equivalent of `computedStyleMap` for pseudo-elements isn't even fully specced out yet, so\n\t// for those we have to use `getComputedStyle` in all browsers.\n\tconst style = getComputedStyle(element, pseudo)\n\n\tconst content = style.getPropertyValue('content')\n\tif (content === '' || content === 'none') {\n\t\treturn undefined\n\t}\n\n\treturn styleFromComputedStyle(style, { defaultStyles: NO_STYLES, parentStyles: NO_STYLES })\n}\n\nfunction styleFromComputedStyleMap(\n\tstyle: StylePropertyMapReadOnly,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property of style.keys()) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.get(property)!.toString()\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\n\t\tstyles[property] = value\n\t}\n\n\treturn styles\n}\n\nfunction styleFromComputedStyle(\n\tstyle: CSSStyleDeclaration,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property in style) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.getPropertyValue(property)\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\n\t\tstyles[property] = value\n\t}\n\treturn styles\n}\n\nfunction formatCss(style: ReadonlyStyles) {\n\tlet cssText = ''\n\tfor (const [property, value] of Object.entries(style)) {\n\t\tcssText += `${property}: ${value};`\n\t}\n\treturn cssText\n}\n\n// when we're figuring out the default values for a tag, we need read them from a separate document\n// so they're not affected by the current document's styles\nlet defaultStyleFrame:\n\t| { iframe: HTMLIFrameElement; foreignObject: SVGForeignObjectElement; document: Document }\n\t| undefined\nconst defaultStylesByTagName: Record<string, ReadonlyStyles> = {}\nfunction getDefaultStyleFrame() {\n\tif (!defaultStyleFrame) {\n\t\tconst frame = document.createElement('iframe')\n\t\tframe.style.display = 'none'\n\t\tdocument.body.appendChild(frame)\n\t\tconst frameDocument = assertExists(frame.contentDocument, 'frame must have a document')\n\t\tconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\t\tconst foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')\n\t\tsvg.appendChild(foreignObject)\n\t\tframeDocument.body.appendChild(svg)\n\t\tdefaultStyleFrame = { iframe: frame, foreignObject, document: frameDocument }\n\t}\n\treturn defaultStyleFrame\n}\n\nfunction destroyDefaultStyleFrame() {\n\tif (defaultStyleFrame) {\n\t\tdocument.body.removeChild(defaultStyleFrame.iframe)\n\t\tdefaultStyleFrame = undefined\n\t}\n}\n\nconst defaultStyleReadOptions: ReadStyleOpts = { defaultStyles: NO_STYLES, parentStyles: NO_STYLES }\nfunction getDefaultStylesForTagName(tagName: string) {\n\tlet existing = defaultStylesByTagName[tagName]\n\tif (!existing) {\n\t\tconst { foreignObject, document } = getDefaultStyleFrame()\n\t\tconst element = document.createElement(tagName)\n\t\tforeignObject.appendChild(element)\n\t\texisting = element.computedStyleMap\n\t\t\t? styleFromComputedStyleMap(element.computedStyleMap(), defaultStyleReadOptions)\n\t\t\t: styleFromComputedStyle(getComputedStyle(element), defaultStyleReadOptions)\n\t\tforeignObject.removeChild(element)\n\t\tdefaultStylesByTagName[tagName] = existing\n\t}\n\treturn existing\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { assertExists, objectMapValues, uniqueId } from '@tldraw/utils'\nimport { FontEmbedder } from './FontEmbedder'\nimport {\n\telementStyle,\n\tgetComputedStyle,\n\tgetRenderedChildNodes,\n\tgetRenderedChildren,\n} from './domUtils'\nimport { resourceToDataUrl } from './fetchCache'\nimport {\n\tisPropertyCoveredByCurrentColor,\n\tisPropertyInherited,\n\tparseCssValueUrls,\n\tshouldIncludeCssProperty,\n} from './parseCss'\n\ntype Styles = { [K in string]?: string }\ntype ReadonlyStyles = { readonly [K in string]?: string }\nconst NO_STYLES = {} as const\n\ninterface ElementStyleInfo {\n\tself: Styles\n\tbefore: Styles | undefined\n\tafter: Styles | undefined\n}\n\nexport class StyleEmbedder {\n\tconstructor(private readonly root: Element) {}\n\tprivate readonly styles = new Map<Element, ElementStyleInfo>()\n\treadonly fonts = new FontEmbedder()\n\n\treadRootElementStyles(rootElement: Element) {\n\t\t// when reading a root, we always apply _all_ the styles, even if they match the defaults\n\t\tthis.readElementStyles(rootElement, {\n\t\t\tshouldRespectDefaults: false,\n\t\t\tshouldSkipInheritedParentStyles: false,\n\t\t})\n\n\t\tconst children = Array.from(getRenderedChildren(rootElement))\n\t\twhile (children.length) {\n\t\t\tconst child = children.pop()!\n\t\t\tchildren.push(...getRenderedChildren(child))\n\n\t\t\t// when reading children, we don't apply styles that match the defaults for that\n\t\t\t// element, or that would be inherited from the parent\n\t\t\tthis.readElementStyles(child, {\n\t\t\t\tshouldRespectDefaults: true,\n\t\t\t\tshouldSkipInheritedParentStyles: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate readElementStyles(\n\t\telement: Element,\n\t\t{ shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }\n\t) {\n\t\tconst defaultStyles = shouldRespectDefaults\n\t\t\t? getDefaultStylesForTagName(element.tagName.toLowerCase())\n\t\t\t: NO_STYLES\n\n\t\tconst parentStyles = Object.assign({}, NO_STYLES) as Styles\n\t\tif (shouldSkipInheritedParentStyles) {\n\t\t\tlet el = element.parentElement\n\t\t\t// Keep going up the tree to find all the relevant styles\n\t\t\twhile (el) {\n\t\t\t\tconst currentStyles = this.styles.get(el)?.self\n\t\t\t\tfor (const style in currentStyles) {\n\t\t\t\t\tif (!parentStyles[style]) {\n\t\t\t\t\t\tparentStyles[style] = currentStyles[style]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tel = el.parentElement\n\t\t\t}\n\t\t}\n\n\t\tconst info: ElementStyleInfo = {\n\t\t\tself: styleFromElement(element, { defaultStyles, parentStyles }),\n\t\t\tbefore: styleFromPseudoElement(element, '::before'),\n\t\t\tafter: styleFromPseudoElement(element, '::after'),\n\t\t}\n\t\tthis.styles.set(element, info)\n\t}\n\n\tfetchResources() {\n\t\tconst promises: Promise<void>[] = []\n\n\t\tfor (const info of this.styles.values()) {\n\t\t\tfor (const styles of objectMapValues(info)) {\n\t\t\t\tif (!styles) continue\n\t\t\t\tfor (const [property, value] of Object.entries(styles)) {\n\t\t\t\t\tif (!value) continue\n\t\t\t\t\tif (property === 'font-family') {\n\t\t\t\t\t\tthis.fonts.onFontFamilyValue(value)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst urlMatches = parseCssValueUrls(value)\n\t\t\t\t\tif (urlMatches.length === 0) continue\n\n\t\t\t\t\tpromises.push(\n\t\t\t\t\t\t...urlMatches.map(async ({ url, original }) => {\n\t\t\t\t\t\t\tconst dataUrl = (await resourceToDataUrl(url)) ?? 'data:'\n\t\t\t\t\t\t\tstyles[property] = value.replace(original, `url(\"${dataUrl}\")`)\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.all(promises)\n\t}\n\n\t// custom elements are tricky. if we serialize the dom as-is, the custom elements wont have\n\t// their shadow-dom contents serialized. after we've read all the styles, we need to unwrap the\n\t// contents of each custom elements shadow dom directly into the parent element itself.\n\tunwrapCustomElements() {\n\t\tconst visited = new Set<Node>()\n\n\t\tconst visit = (element: Element, clonedParent: Element | null) => {\n\t\t\tif (visited.has(element)) return\n\t\t\tvisited.add(element)\n\n\t\t\tconst shadowRoot = element.shadowRoot\n\n\t\t\tif (shadowRoot) {\n\t\t\t\tconst clonedCustomEl = document.createElement('div')\n\t\t\t\tthis.styles.set(clonedCustomEl, this.styles.get(element)!)\n\n\t\t\t\tclonedCustomEl.setAttribute('data-tl-custom-element', element.tagName)\n\t\t\t\t;(clonedParent ?? element.parentElement!).appendChild(clonedCustomEl)\n\n\t\t\t\tfor (const child of shadowRoot.childNodes) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedCustomEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedCustomEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telement.remove()\n\t\t\t} else if (clonedParent) {\n\t\t\t\tif (element.tagName.toLowerCase() === 'style') {\n\t\t\t\t\t// we don't clone style tags at that would break the style scoping. instead we\n\t\t\t\t\t// rely on the computed styles we've already read\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst clonedEl = element.cloneNode(false) as Element\n\t\t\t\tthis.styles.set(clonedEl, this.styles.get(element)!)\n\n\t\t\t\tclonedParent.appendChild(clonedEl)\n\n\t\t\t\tfor (const child of getRenderedChildNodes(element)) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const element of this.styles.keys()) {\n\t\t\tvisit(element, null)\n\t\t}\n\t}\n\n\tembedStyles(): string {\n\t\tlet css = ''\n\n\t\tfor (const [element, info] of this.styles) {\n\t\t\tif (info.after || info.before) {\n\t\t\t\tconst className = `pseudo-${uniqueId()}`\n\t\t\t\telement.classList.add(className)\n\n\t\t\t\tif (info.before) {\n\t\t\t\t\tcss += `.${className}::before {${formatCss(info.before)}}\\n`\n\t\t\t\t}\n\t\t\t\tif (info.after) {\n\t\t\t\t\tcss += `.${className}::after {${formatCss(info.after)}}\\n`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst style = elementStyle(element)\n\t\t\tfor (const [property, value] of Object.entries(info.self)) {\n\t\t\t\tif (!value) continue\n\t\t\t\tstyle.setProperty(property, value)\n\t\t\t}\n\n\t\t\t// in HTML, font-kerning: auto is equivalent to font-kerning: normal. But in SVG, it's\n\t\t\t// none. We set it to normal here to match the HTML behavior, as otherwise this can\n\t\t\t// cause rendering differences.\n\t\t\tif (style.fontKerning === 'auto') {\n\t\t\t\tstyle.fontKerning = 'normal'\n\t\t\t}\n\t\t}\n\n\t\treturn css\n\t}\n\n\tasync getFontFaceCss() {\n\t\treturn await this.fonts.createCss()\n\t}\n\n\tdispose() {\n\t\tdestroyDefaultStyleFrame()\n\t}\n}\n\ninterface ReadStyleOpts {\n\tdefaultStyles: ReadonlyStyles\n\tparentStyles: ReadonlyStyles\n}\n\nfunction styleFromElement(element: Element, { defaultStyles, parentStyles }: ReadStyleOpts) {\n\t// `computedStyleMap` produces a more accurate representation of the styles, but it's not\n\t// supported in firefox at the time of writing. So we fall back to `getComputedStyle` if it's\n\t// not available.\n\tif (element.computedStyleMap) {\n\t\treturn styleFromComputedStyleMap(element.computedStyleMap(), { defaultStyles, parentStyles })\n\t}\n\treturn styleFromComputedStyle(getComputedStyle(element), { defaultStyles, parentStyles })\n}\n\nfunction styleFromPseudoElement(element: Element, pseudo: string) {\n\t// the equivalent of `computedStyleMap` for pseudo-elements isn't even fully specced out yet, so\n\t// for those we have to use `getComputedStyle` in all browsers.\n\tconst style = getComputedStyle(element, pseudo)\n\n\tconst content = style.getPropertyValue('content')\n\tif (content === '' || content === 'none') {\n\t\treturn undefined\n\t}\n\n\treturn styleFromComputedStyle(style, { defaultStyles: NO_STYLES, parentStyles: NO_STYLES })\n}\n\nfunction styleFromComputedStyleMap(\n\tstyle: StylePropertyMapReadOnly,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property of style.keys()) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.get(property)!.toString()\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\t\tif (isPropertyCoveredByCurrentColor(style.get('color')?.toString() || '', property, value))\n\t\t\tcontinue\n\n\t\tstyles[property] = value\n\t}\n\n\treturn styles\n}\n\nfunction styleFromComputedStyle(\n\tstyle: CSSStyleDeclaration,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property in style) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.getPropertyValue(property)\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\t\tif (isPropertyCoveredByCurrentColor(style.color, property, value)) continue\n\n\t\tstyles[property] = value\n\t}\n\treturn styles\n}\n\nfunction formatCss(style: ReadonlyStyles) {\n\tlet cssText = ''\n\tfor (const [property, value] of Object.entries(style)) {\n\t\tcssText += `${property}: ${value};`\n\t}\n\treturn cssText\n}\n\n// when we're figuring out the default values for a tag, we need read them from a separate document\n// so they're not affected by the current document's styles\nlet defaultStyleFrame:\n\t| { iframe: HTMLIFrameElement; foreignObject: SVGForeignObjectElement; document: Document }\n\t| undefined\nconst defaultStylesByTagName: Record<string, ReadonlyStyles> = {}\nfunction getDefaultStyleFrame() {\n\tif (!defaultStyleFrame) {\n\t\tconst frame = document.createElement('iframe')\n\t\tframe.style.display = 'none'\n\t\tdocument.body.appendChild(frame)\n\t\tconst frameDocument = assertExists(frame.contentDocument, 'frame must have a document')\n\t\tconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\t\tconst foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')\n\t\tsvg.appendChild(foreignObject)\n\t\tframeDocument.body.appendChild(svg)\n\t\tdefaultStyleFrame = { iframe: frame, foreignObject, document: frameDocument }\n\t}\n\treturn defaultStyleFrame\n}\n\nfunction destroyDefaultStyleFrame() {\n\tif (defaultStyleFrame) {\n\t\tdocument.body.removeChild(defaultStyleFrame.iframe)\n\t\tdefaultStyleFrame = undefined\n\t}\n}\n\nconst defaultStyleReadOptions: ReadStyleOpts = { defaultStyles: NO_STYLES, parentStyles: NO_STYLES }\nfunction getDefaultStylesForTagName(tagName: string) {\n\tlet existing = defaultStylesByTagName[tagName]\n\tif (!existing) {\n\t\tconst { foreignObject, document } = getDefaultStyleFrame()\n\t\tconst element = document.createElement(tagName)\n\t\tforeignObject.appendChild(element)\n\t\texisting = element.computedStyleMap\n\t\t\t? styleFromComputedStyleMap(element.computedStyleMap(), defaultStyleReadOptions)\n\t\t\t: styleFromComputedStyle(getComputedStyle(element), defaultStyleReadOptions)\n\t\tforeignObject.removeChild(element)\n\t\tdefaultStylesByTagName[tagName] = existing\n\t}\n\treturn existing\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["document"]
7
7
  }
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var parseCss_exports = {};
20
20
  __export(parseCss_exports, {
21
+ isPropertyCoveredByCurrentColor: () => isPropertyCoveredByCurrentColor,
21
22
  isPropertyInherited: () => isPropertyInherited,
22
23
  parseCss: () => parseCss,
23
24
  parseCssFontFaces: () => parseCssFontFaces,
@@ -96,11 +97,33 @@ function parseCssValueUrls(value) {
96
97
  url: m[1] || m[2] || m[3]
97
98
  }));
98
99
  }
100
+ const currentColorProperties = /* @__PURE__ */ new Set([
101
+ "border-block-end-color",
102
+ "border-block-start-color",
103
+ "border-bottom-color",
104
+ "border-inline-end-color",
105
+ "border-inline-start-color",
106
+ "border-left-color",
107
+ "border-right-color",
108
+ "border-top-color",
109
+ "caret-color",
110
+ "column-rule-color",
111
+ "outline-color",
112
+ "text-decoration",
113
+ "text-decoration-color",
114
+ "text-emphasis-color"
115
+ ]);
116
+ function isPropertyCoveredByCurrentColor(currentColor, property, value) {
117
+ if (currentColorProperties.has(property)) {
118
+ return value === "currentColor" || value === currentColor || property === "text-decoration" && value === `none solid ${currentColor}`;
119
+ }
120
+ }
99
121
  const inheritedProperties = /* @__PURE__ */ new Set([
100
122
  "border-collapse",
101
123
  "border-spacing",
102
124
  "caption-side",
103
- "color",
125
+ // N.B. We shouldn't inherit 'color' because there's some UA styling, e.g. `mark` elements
126
+ // 'color',
104
127
  "cursor",
105
128
  "direction",
106
129
  "empty-cells",
@@ -121,16 +144,18 @@ const inheritedProperties = /* @__PURE__ */ new Set([
121
144
  "orphans",
122
145
  "overflow-wrap",
123
146
  "quotes",
147
+ "stroke-linecap",
148
+ "stroke-linejoin",
124
149
  "tab-size",
125
150
  "text-align",
126
151
  "text-align-last",
127
- "text-decoration-color",
128
152
  "text-indent",
129
153
  "text-justify",
130
154
  "text-shadow",
131
155
  "text-transform",
132
156
  "visibility",
133
157
  "white-space",
158
+ "white-space-collapse",
134
159
  "widows",
135
160
  "word-break",
136
161
  "word-spacing",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/parseCss.ts"],
4
- "sourcesContent": ["import { safeParseUrl } from '@tldraw/utils'\n\nexport interface ParsedFontFace {\n\tfontFace: string\n\turls: { original: string; resolved: string | null; embedded?: Promise<string | null> }[]\n\tfontFamilies: Set<string>\n}\n\n// parsing CSS with regular expressions doesn't really work. There are almost certainly edge cases\n// in the regular expressions we're using here. They're based formal grammars of CSS, but aren't\n// perfect. These were written with https://regexper.com/ - give it a go if you're editing these.\n\n// The regexes themselves would be nicer to work with if we were using named capturing groups\n// (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group).\n// We use a lot of disjunctions (the `|`) to cover different syntaxes though, and at the time of\n// writing, browser support for using named capturing groups across disjunctions is rough.\n\n// Parse @import declarations:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@import#formal_syntax\nconst importsRegex =\n\t/@import\\s+(?:\"([^\"]+)\"|'([^']+)'|url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\))([^;]+);/gi\n\n// Locate @font-face declarations:\nconst fontFaceRegex = /@font-face\\s*{([^}]+)}/gi\n\n// Parse url() calls within a CSS value:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax\nconst urlsRegex = /url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\)/gi\n\n// Locate and parse the value of `font-family` within a @font-face declaration:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family#formal_syntax\nconst fontFamilyRegex =\n\t/(?:^|;)\\s*font-family\\s*:\\s*(?:([^'\"][^;\\n]+)|\"([^\"]+)\"|'([^']+)')\\s*(?:;|$)/gi\n\nexport function parseCssImports(css: string) {\n\treturn Array.from(css.matchAll(importsRegex), (m) => ({\n\t\turl: m[1] || m[2] || m[3] || m[4] || m[5],\n\t\textras: m[6],\n\t}))\n}\n\nexport function parseCssFontFaces(css: string, baseUrl: string) {\n\treturn Array.from(css.matchAll(fontFaceRegex), (m): ParsedFontFace => {\n\t\tconst fontFace = m[1]\n\t\tconst urls = Array.from(fontFace.matchAll(urlsRegex), (m) => {\n\t\t\tconst original = m[1] || m[2] || m[3]\n\t\t\treturn {\n\t\t\t\toriginal,\n\t\t\t\tresolved: safeParseUrl(original, baseUrl)?.href ?? null,\n\t\t\t}\n\t\t})\n\t\tconst fontFamilies = new Set(\n\t\t\tArray.from(fontFace.matchAll(fontFamilyRegex), (m) => (m[1] || m[2] || m[3]).toLowerCase())\n\t\t)\n\n\t\treturn { fontFace, urls, fontFamilies }\n\t})\n}\n\nexport function parseCssFontFamilyValue(value: string) {\n\t// https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#formal_syntax\n\t// we use two regexes here to parse each value in a comma separated list of font families\n\tconst valueRegex = /\\s*(?:([^'\"][^;\\n\\s,]+)|\"([^\"]+)\"|'([^']+)')\\s*/gi\n\tconst separatorRegex = /\\s*,\\s*/gi\n\n\tconst fontFamilies = new Set<string>()\n\n\twhile (true) {\n\t\tconst valueMatch = valueRegex.exec(value)\n\t\tif (!valueMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tconst fontFamily = valueMatch[1] || valueMatch[2] || valueMatch[3]\n\t\tfontFamilies.add(fontFamily.toLowerCase())\n\n\t\tseparatorRegex.lastIndex = valueRegex.lastIndex\n\t\tconst separatorMatch = separatorRegex.exec(value)\n\t\tif (!separatorMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tvalueRegex.lastIndex = separatorRegex.lastIndex\n\t}\n\n\treturn fontFamilies\n}\n\nexport function shouldIncludeCssProperty(property: string) {\n\tif (property.startsWith('-')) return false\n\tif (property.startsWith('animation')) return false\n\tif (property.startsWith('transition')) return false\n\tif (property === 'cursor') return false\n\tif (property === 'pointer-events') return false\n\tif (property === 'user-select') return false\n\tif (property === 'touch-action') return false\n\treturn true\n}\n\nexport function parseCss(css: string, baseUrl: string) {\n\treturn {\n\t\timports: parseCssImports(css),\n\t\tfontFaces: parseCssFontFaces(css, baseUrl),\n\t}\n}\n\nexport function parseCssValueUrls(value: string) {\n\treturn Array.from(value.matchAll(urlsRegex), (m) => ({\n\t\toriginal: m[0],\n\t\turl: m[1] || m[2] || m[3],\n\t}))\n}\n\nconst inheritedProperties = new Set([\n\t'border-collapse',\n\t'border-spacing',\n\t'caption-side',\n\t'color',\n\t'cursor',\n\t'direction',\n\t'empty-cells',\n\t'font-family',\n\t'font-size',\n\t'font-style',\n\t'font-variant',\n\t'font-weight',\n\t'font-size-adjust',\n\t'font-stretch',\n\t'font',\n\t'letter-spacing',\n\t'line-height',\n\t'list-style-image',\n\t'list-style-position',\n\t'list-style-type',\n\t'list-style',\n\t'orphans',\n\t'overflow-wrap',\n\t'quotes',\n\t'tab-size',\n\t'text-align',\n\t'text-align-last',\n\t'text-decoration-color',\n\t'text-indent',\n\t'text-justify',\n\t'text-shadow',\n\t'text-transform',\n\t'visibility',\n\t'white-space',\n\t'widows',\n\t'word-break',\n\t'word-spacing',\n\t'word-wrap',\n])\n\nexport function isPropertyInherited(property: string) {\n\treturn inheritedProperties.has(property)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { safeParseUrl } from '@tldraw/utils'\n\nexport interface ParsedFontFace {\n\tfontFace: string\n\turls: { original: string; resolved: string | null; embedded?: Promise<string | null> }[]\n\tfontFamilies: Set<string>\n}\n\n// parsing CSS with regular expressions doesn't really work. There are almost certainly edge cases\n// in the regular expressions we're using here. They're based formal grammars of CSS, but aren't\n// perfect. These were written with https://regexper.com/ - give it a go if you're editing these.\n\n// The regexes themselves would be nicer to work with if we were using named capturing groups\n// (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group).\n// We use a lot of disjunctions (the `|`) to cover different syntaxes though, and at the time of\n// writing, browser support for using named capturing groups across disjunctions is rough.\n\n// Parse @import declarations:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@import#formal_syntax\nconst importsRegex =\n\t/@import\\s+(?:\"([^\"]+)\"|'([^']+)'|url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\))([^;]+);/gi\n\n// Locate @font-face declarations:\nconst fontFaceRegex = /@font-face\\s*{([^}]+)}/gi\n\n// Parse url() calls within a CSS value:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax\nconst urlsRegex = /url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\)/gi\n\n// Locate and parse the value of `font-family` within a @font-face declaration:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family#formal_syntax\nconst fontFamilyRegex =\n\t/(?:^|;)\\s*font-family\\s*:\\s*(?:([^'\"][^;\\n]+)|\"([^\"]+)\"|'([^']+)')\\s*(?:;|$)/gi\n\nexport function parseCssImports(css: string) {\n\treturn Array.from(css.matchAll(importsRegex), (m) => ({\n\t\turl: m[1] || m[2] || m[3] || m[4] || m[5],\n\t\textras: m[6],\n\t}))\n}\n\nexport function parseCssFontFaces(css: string, baseUrl: string) {\n\treturn Array.from(css.matchAll(fontFaceRegex), (m): ParsedFontFace => {\n\t\tconst fontFace = m[1]\n\t\tconst urls = Array.from(fontFace.matchAll(urlsRegex), (m) => {\n\t\t\tconst original = m[1] || m[2] || m[3]\n\t\t\treturn {\n\t\t\t\toriginal,\n\t\t\t\tresolved: safeParseUrl(original, baseUrl)?.href ?? null,\n\t\t\t}\n\t\t})\n\t\tconst fontFamilies = new Set(\n\t\t\tArray.from(fontFace.matchAll(fontFamilyRegex), (m) => (m[1] || m[2] || m[3]).toLowerCase())\n\t\t)\n\n\t\treturn { fontFace, urls, fontFamilies }\n\t})\n}\n\nexport function parseCssFontFamilyValue(value: string) {\n\t// https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#formal_syntax\n\t// we use two regexes here to parse each value in a comma separated list of font families\n\tconst valueRegex = /\\s*(?:([^'\"][^;\\n\\s,]+)|\"([^\"]+)\"|'([^']+)')\\s*/gi\n\tconst separatorRegex = /\\s*,\\s*/gi\n\n\tconst fontFamilies = new Set<string>()\n\n\twhile (true) {\n\t\tconst valueMatch = valueRegex.exec(value)\n\t\tif (!valueMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tconst fontFamily = valueMatch[1] || valueMatch[2] || valueMatch[3]\n\t\tfontFamilies.add(fontFamily.toLowerCase())\n\n\t\tseparatorRegex.lastIndex = valueRegex.lastIndex\n\t\tconst separatorMatch = separatorRegex.exec(value)\n\t\tif (!separatorMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tvalueRegex.lastIndex = separatorRegex.lastIndex\n\t}\n\n\treturn fontFamilies\n}\n\nexport function shouldIncludeCssProperty(property: string) {\n\tif (property.startsWith('-')) return false\n\tif (property.startsWith('animation')) return false\n\tif (property.startsWith('transition')) return false\n\tif (property === 'cursor') return false\n\tif (property === 'pointer-events') return false\n\tif (property === 'user-select') return false\n\tif (property === 'touch-action') return false\n\treturn true\n}\n\nexport function parseCss(css: string, baseUrl: string) {\n\treturn {\n\t\timports: parseCssImports(css),\n\t\tfontFaces: parseCssFontFaces(css, baseUrl),\n\t}\n}\n\nexport function parseCssValueUrls(value: string) {\n\treturn Array.from(value.matchAll(urlsRegex), (m) => ({\n\t\toriginal: m[0],\n\t\turl: m[1] || m[2] || m[3],\n\t}))\n}\n\nconst currentColorProperties = new Set([\n\t'border-block-end-color',\n\t'border-block-start-color',\n\t'border-bottom-color',\n\t'border-inline-end-color',\n\t'border-inline-start-color',\n\t'border-left-color',\n\t'border-right-color',\n\t'border-top-color',\n\t'caret-color',\n\t'column-rule-color',\n\t'outline-color',\n\t'text-decoration',\n\t'text-decoration-color',\n\t'text-emphasis-color',\n])\n\nexport function isPropertyCoveredByCurrentColor(\n\tcurrentColor: string,\n\tproperty: string,\n\tvalue: string\n) {\n\tif (currentColorProperties.has(property)) {\n\t\treturn (\n\t\t\tvalue === 'currentColor' ||\n\t\t\tvalue === currentColor ||\n\t\t\t(property === 'text-decoration' && value === `none solid ${currentColor}`)\n\t\t)\n\t}\n}\n\nconst inheritedProperties = new Set([\n\t'border-collapse',\n\t'border-spacing',\n\t'caption-side',\n\t// N.B. We shouldn't inherit 'color' because there's some UA styling, e.g. `mark` elements\n\t// 'color',\n\t'cursor',\n\t'direction',\n\t'empty-cells',\n\t'font-family',\n\t'font-size',\n\t'font-style',\n\t'font-variant',\n\t'font-weight',\n\t'font-size-adjust',\n\t'font-stretch',\n\t'font',\n\t'letter-spacing',\n\t'line-height',\n\t'list-style-image',\n\t'list-style-position',\n\t'list-style-type',\n\t'list-style',\n\t'orphans',\n\t'overflow-wrap',\n\t'quotes',\n\t'stroke-linecap',\n\t'stroke-linejoin',\n\t'tab-size',\n\t'text-align',\n\t'text-align-last',\n\t'text-indent',\n\t'text-justify',\n\t'text-shadow',\n\t'text-transform',\n\t'visibility',\n\t'white-space',\n\t'white-space-collapse',\n\t'widows',\n\t'word-break',\n\t'word-spacing',\n\t'word-wrap',\n])\n\nexport function isPropertyInherited(property: string) {\n\treturn inheritedProperties.has(property)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["m"]
7
7
  }
@@ -22,10 +22,10 @@ __export(version_exports, {
22
22
  version: () => version
23
23
  });
24
24
  module.exports = __toCommonJS(version_exports);
25
- const version = "3.11.0-canary.b2098bef0749";
25
+ const version = "3.11.0-canary.b65e0ab5933e";
26
26
  const publishDates = {
27
27
  major: "2024-09-13T14:36:29.063Z",
28
- minor: "2025-03-18T13:49:35.230Z",
29
- patch: "2025-03-18T13:49:35.230Z"
28
+ minor: "2025-03-18T15:30:30.987Z",
29
+ patch: "2025-03-18T15:30:30.987Z"
30
30
  };
31
31
  //# sourceMappingURL=version.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.11.0-canary.b2098bef0749'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-18T13:49:35.230Z',\n\tpatch: '2025-03-18T13:49:35.230Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.11.0-canary.b65e0ab5933e'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-18T15:30:30.987Z',\n\tpatch: '2025-03-18T15:30:30.987Z',\n}\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
@@ -299,7 +299,7 @@ function debugEnableLicensing() {
299
299
  }
300
300
  registerTldrawLibraryVersion(
301
301
  "@tldraw/editor",
302
- "3.11.0-canary.b2098bef0749",
302
+ "3.11.0-canary.b65e0ab5933e",
303
303
  "esm"
304
304
  );
305
305
  export {
@@ -7,7 +7,12 @@ import {
7
7
  getRenderedChildren
8
8
  } from "./domUtils.mjs";
9
9
  import { resourceToDataUrl } from "./fetchCache.mjs";
10
- import { isPropertyInherited, parseCssValueUrls, shouldIncludeCssProperty } from "./parseCss.mjs";
10
+ import {
11
+ isPropertyCoveredByCurrentColor,
12
+ isPropertyInherited,
13
+ parseCssValueUrls,
14
+ shouldIncludeCssProperty
15
+ } from "./parseCss.mjs";
11
16
  const NO_STYLES = {};
12
17
  class StyleEmbedder {
13
18
  constructor(root) {
@@ -32,7 +37,19 @@ class StyleEmbedder {
32
37
  }
33
38
  readElementStyles(element, { shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }) {
34
39
  const defaultStyles = shouldRespectDefaults ? getDefaultStylesForTagName(element.tagName.toLowerCase()) : NO_STYLES;
35
- const parentStyles = shouldSkipInheritedParentStyles ? this.styles.get(element.parentElement)?.self ?? NO_STYLES : NO_STYLES;
40
+ const parentStyles = Object.assign({}, NO_STYLES);
41
+ if (shouldSkipInheritedParentStyles) {
42
+ let el = element.parentElement;
43
+ while (el) {
44
+ const currentStyles = this.styles.get(el)?.self;
45
+ for (const style in currentStyles) {
46
+ if (!parentStyles[style]) {
47
+ parentStyles[style] = currentStyles[style];
48
+ }
49
+ }
50
+ el = el.parentElement;
51
+ }
52
+ }
36
53
  const info = {
37
54
  self: styleFromElement(element, { defaultStyles, parentStyles }),
38
55
  before: styleFromPseudoElement(element, "::before"),
@@ -159,6 +176,8 @@ function styleFromComputedStyleMap(style, { defaultStyles, parentStyles }) {
159
176
  const value = style.get(property).toString();
160
177
  if (defaultStyles[property] === value) continue;
161
178
  if (parentStyles[property] === value && isPropertyInherited(property)) continue;
179
+ if (isPropertyCoveredByCurrentColor(style.get("color")?.toString() || "", property, value))
180
+ continue;
162
181
  styles[property] = value;
163
182
  }
164
183
  return styles;
@@ -170,6 +189,7 @@ function styleFromComputedStyle(style, { defaultStyles, parentStyles }) {
170
189
  const value = style.getPropertyValue(property);
171
190
  if (defaultStyles[property] === value) continue;
172
191
  if (parentStyles[property] === value && isPropertyInherited(property)) continue;
192
+ if (isPropertyCoveredByCurrentColor(style.color, property, value)) continue;
173
193
  styles[property] = value;
174
194
  }
175
195
  return styles;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/StyleEmbedder.ts"],
4
- "sourcesContent": ["import { assertExists, objectMapValues, uniqueId } from '@tldraw/utils'\nimport { FontEmbedder } from './FontEmbedder'\nimport {\n\telementStyle,\n\tgetComputedStyle,\n\tgetRenderedChildNodes,\n\tgetRenderedChildren,\n} from './domUtils'\nimport { resourceToDataUrl } from './fetchCache'\nimport { isPropertyInherited, parseCssValueUrls, shouldIncludeCssProperty } from './parseCss'\n\ntype Styles = { [K in string]?: string }\ntype ReadonlyStyles = { readonly [K in string]?: string }\nconst NO_STYLES = {} as const\n\ninterface ElementStyleInfo {\n\tself: Styles\n\tbefore: Styles | undefined\n\tafter: Styles | undefined\n}\n\nexport class StyleEmbedder {\n\tconstructor(private readonly root: Element) {}\n\tprivate readonly styles = new Map<Element, ElementStyleInfo>()\n\treadonly fonts = new FontEmbedder()\n\n\treadRootElementStyles(rootElement: Element) {\n\t\t// when reading a root, we always apply _all_ the styles, even if they match the defaults\n\t\tthis.readElementStyles(rootElement, {\n\t\t\tshouldRespectDefaults: false,\n\t\t\tshouldSkipInheritedParentStyles: false,\n\t\t})\n\n\t\tconst children = Array.from(getRenderedChildren(rootElement))\n\t\twhile (children.length) {\n\t\t\tconst child = children.pop()!\n\t\t\tchildren.push(...getRenderedChildren(child))\n\n\t\t\t// when reading children, we don't apply styles that match the defaults for that\n\t\t\t// element, or that would be inherited from the parent\n\t\t\tthis.readElementStyles(child, {\n\t\t\t\tshouldRespectDefaults: true,\n\t\t\t\tshouldSkipInheritedParentStyles: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate readElementStyles(\n\t\telement: Element,\n\t\t{ shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }\n\t) {\n\t\tconst defaultStyles = shouldRespectDefaults\n\t\t\t? getDefaultStylesForTagName(element.tagName.toLowerCase())\n\t\t\t: NO_STYLES\n\n\t\tconst parentStyles = shouldSkipInheritedParentStyles\n\t\t\t? (this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES)\n\t\t\t: NO_STYLES\n\n\t\tconst info: ElementStyleInfo = {\n\t\t\tself: styleFromElement(element, { defaultStyles, parentStyles }),\n\t\t\tbefore: styleFromPseudoElement(element, '::before'),\n\t\t\tafter: styleFromPseudoElement(element, '::after'),\n\t\t}\n\t\tthis.styles.set(element, info)\n\t}\n\n\tfetchResources() {\n\t\tconst promises: Promise<void>[] = []\n\n\t\tfor (const info of this.styles.values()) {\n\t\t\tfor (const styles of objectMapValues(info)) {\n\t\t\t\tif (!styles) continue\n\t\t\t\tfor (const [property, value] of Object.entries(styles)) {\n\t\t\t\t\tif (!value) continue\n\t\t\t\t\tif (property === 'font-family') {\n\t\t\t\t\t\tthis.fonts.onFontFamilyValue(value)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst urlMatches = parseCssValueUrls(value)\n\t\t\t\t\tif (urlMatches.length === 0) continue\n\n\t\t\t\t\tpromises.push(\n\t\t\t\t\t\t...urlMatches.map(async ({ url, original }) => {\n\t\t\t\t\t\t\tconst dataUrl = (await resourceToDataUrl(url)) ?? 'data:'\n\t\t\t\t\t\t\tstyles[property] = value.replace(original, `url(\"${dataUrl}\")`)\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.all(promises)\n\t}\n\n\t// custom elements are tricky. if we serialize the dom as-is, the custom elements wont have\n\t// their shadow-dom contents serialized. after we've read all the styles, we need to unwrap the\n\t// contents of each custom elements shadow dom directly into the parent element itself.\n\tunwrapCustomElements() {\n\t\tconst visited = new Set<Node>()\n\n\t\tconst visit = (element: Element, clonedParent: Element | null) => {\n\t\t\tif (visited.has(element)) return\n\t\t\tvisited.add(element)\n\n\t\t\tconst shadowRoot = element.shadowRoot\n\n\t\t\tif (shadowRoot) {\n\t\t\t\tconst clonedCustomEl = document.createElement('div')\n\t\t\t\tthis.styles.set(clonedCustomEl, this.styles.get(element)!)\n\n\t\t\t\tclonedCustomEl.setAttribute('data-tl-custom-element', element.tagName)\n\t\t\t\t;(clonedParent ?? element.parentElement!).appendChild(clonedCustomEl)\n\n\t\t\t\tfor (const child of shadowRoot.childNodes) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedCustomEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedCustomEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telement.remove()\n\t\t\t} else if (clonedParent) {\n\t\t\t\tif (element.tagName.toLowerCase() === 'style') {\n\t\t\t\t\t// we don't clone style tags at that would break the style scoping. instead we\n\t\t\t\t\t// rely on the computed styles we've already read\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst clonedEl = element.cloneNode(false) as Element\n\t\t\t\tthis.styles.set(clonedEl, this.styles.get(element)!)\n\n\t\t\t\tclonedParent.appendChild(clonedEl)\n\n\t\t\t\tfor (const child of getRenderedChildNodes(element)) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const element of this.styles.keys()) {\n\t\t\tvisit(element, null)\n\t\t}\n\t}\n\n\tembedStyles(): string {\n\t\tlet css = ''\n\n\t\tfor (const [element, info] of this.styles) {\n\t\t\tif (info.after || info.before) {\n\t\t\t\tconst className = `pseudo-${uniqueId()}`\n\t\t\t\telement.classList.add(className)\n\n\t\t\t\tif (info.before) {\n\t\t\t\t\tcss += `.${className}::before {${formatCss(info.before)}}\\n`\n\t\t\t\t}\n\t\t\t\tif (info.after) {\n\t\t\t\t\tcss += `.${className}::after {${formatCss(info.after)}}\\n`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst style = elementStyle(element)\n\t\t\tfor (const [property, value] of Object.entries(info.self)) {\n\t\t\t\tif (!value) continue\n\t\t\t\tstyle.setProperty(property, value)\n\t\t\t}\n\n\t\t\t// in HTML, font-kerning: auto is equivalent to font-kerning: normal. But in SVG, it's\n\t\t\t// none. We set it to normal here to match the HTML behavior, as otherwise this can\n\t\t\t// cause rendering differences.\n\t\t\tif (style.fontKerning === 'auto') {\n\t\t\t\tstyle.fontKerning = 'normal'\n\t\t\t}\n\t\t}\n\n\t\treturn css\n\t}\n\n\tasync getFontFaceCss() {\n\t\treturn await this.fonts.createCss()\n\t}\n\n\tdispose() {\n\t\tdestroyDefaultStyleFrame()\n\t}\n}\n\ninterface ReadStyleOpts {\n\tdefaultStyles: ReadonlyStyles\n\tparentStyles: ReadonlyStyles\n}\n\nfunction styleFromElement(element: Element, { defaultStyles, parentStyles }: ReadStyleOpts) {\n\t// `computedStyleMap` produces a more accurate representation of the styles, but it's not\n\t// supported in firefox at the time of writing. So we fall back to `getComputedStyle` if it's\n\t// not available.\n\tif (element.computedStyleMap) {\n\t\treturn styleFromComputedStyleMap(element.computedStyleMap(), { defaultStyles, parentStyles })\n\t}\n\treturn styleFromComputedStyle(getComputedStyle(element), { defaultStyles, parentStyles })\n}\n\nfunction styleFromPseudoElement(element: Element, pseudo: string) {\n\t// the equivalent of `computedStyleMap` for pseudo-elements isn't even fully specced out yet, so\n\t// for those we have to use `getComputedStyle` in all browsers.\n\tconst style = getComputedStyle(element, pseudo)\n\n\tconst content = style.getPropertyValue('content')\n\tif (content === '' || content === 'none') {\n\t\treturn undefined\n\t}\n\n\treturn styleFromComputedStyle(style, { defaultStyles: NO_STYLES, parentStyles: NO_STYLES })\n}\n\nfunction styleFromComputedStyleMap(\n\tstyle: StylePropertyMapReadOnly,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property of style.keys()) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.get(property)!.toString()\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\n\t\tstyles[property] = value\n\t}\n\n\treturn styles\n}\n\nfunction styleFromComputedStyle(\n\tstyle: CSSStyleDeclaration,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property in style) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.getPropertyValue(property)\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\n\t\tstyles[property] = value\n\t}\n\treturn styles\n}\n\nfunction formatCss(style: ReadonlyStyles) {\n\tlet cssText = ''\n\tfor (const [property, value] of Object.entries(style)) {\n\t\tcssText += `${property}: ${value};`\n\t}\n\treturn cssText\n}\n\n// when we're figuring out the default values for a tag, we need read them from a separate document\n// so they're not affected by the current document's styles\nlet defaultStyleFrame:\n\t| { iframe: HTMLIFrameElement; foreignObject: SVGForeignObjectElement; document: Document }\n\t| undefined\nconst defaultStylesByTagName: Record<string, ReadonlyStyles> = {}\nfunction getDefaultStyleFrame() {\n\tif (!defaultStyleFrame) {\n\t\tconst frame = document.createElement('iframe')\n\t\tframe.style.display = 'none'\n\t\tdocument.body.appendChild(frame)\n\t\tconst frameDocument = assertExists(frame.contentDocument, 'frame must have a document')\n\t\tconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\t\tconst foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')\n\t\tsvg.appendChild(foreignObject)\n\t\tframeDocument.body.appendChild(svg)\n\t\tdefaultStyleFrame = { iframe: frame, foreignObject, document: frameDocument }\n\t}\n\treturn defaultStyleFrame\n}\n\nfunction destroyDefaultStyleFrame() {\n\tif (defaultStyleFrame) {\n\t\tdocument.body.removeChild(defaultStyleFrame.iframe)\n\t\tdefaultStyleFrame = undefined\n\t}\n}\n\nconst defaultStyleReadOptions: ReadStyleOpts = { defaultStyles: NO_STYLES, parentStyles: NO_STYLES }\nfunction getDefaultStylesForTagName(tagName: string) {\n\tlet existing = defaultStylesByTagName[tagName]\n\tif (!existing) {\n\t\tconst { foreignObject, document } = getDefaultStyleFrame()\n\t\tconst element = document.createElement(tagName)\n\t\tforeignObject.appendChild(element)\n\t\texisting = element.computedStyleMap\n\t\t\t? styleFromComputedStyleMap(element.computedStyleMap(), defaultStyleReadOptions)\n\t\t\t: styleFromComputedStyle(getComputedStyle(element), defaultStyleReadOptions)\n\t\tforeignObject.removeChild(element)\n\t\tdefaultStylesByTagName[tagName] = existing\n\t}\n\treturn existing\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { assertExists, objectMapValues, uniqueId } from '@tldraw/utils'\nimport { FontEmbedder } from './FontEmbedder'\nimport {\n\telementStyle,\n\tgetComputedStyle,\n\tgetRenderedChildNodes,\n\tgetRenderedChildren,\n} from './domUtils'\nimport { resourceToDataUrl } from './fetchCache'\nimport {\n\tisPropertyCoveredByCurrentColor,\n\tisPropertyInherited,\n\tparseCssValueUrls,\n\tshouldIncludeCssProperty,\n} from './parseCss'\n\ntype Styles = { [K in string]?: string }\ntype ReadonlyStyles = { readonly [K in string]?: string }\nconst NO_STYLES = {} as const\n\ninterface ElementStyleInfo {\n\tself: Styles\n\tbefore: Styles | undefined\n\tafter: Styles | undefined\n}\n\nexport class StyleEmbedder {\n\tconstructor(private readonly root: Element) {}\n\tprivate readonly styles = new Map<Element, ElementStyleInfo>()\n\treadonly fonts = new FontEmbedder()\n\n\treadRootElementStyles(rootElement: Element) {\n\t\t// when reading a root, we always apply _all_ the styles, even if they match the defaults\n\t\tthis.readElementStyles(rootElement, {\n\t\t\tshouldRespectDefaults: false,\n\t\t\tshouldSkipInheritedParentStyles: false,\n\t\t})\n\n\t\tconst children = Array.from(getRenderedChildren(rootElement))\n\t\twhile (children.length) {\n\t\t\tconst child = children.pop()!\n\t\t\tchildren.push(...getRenderedChildren(child))\n\n\t\t\t// when reading children, we don't apply styles that match the defaults for that\n\t\t\t// element, or that would be inherited from the parent\n\t\t\tthis.readElementStyles(child, {\n\t\t\t\tshouldRespectDefaults: true,\n\t\t\t\tshouldSkipInheritedParentStyles: true,\n\t\t\t})\n\t\t}\n\t}\n\n\tprivate readElementStyles(\n\t\telement: Element,\n\t\t{ shouldRespectDefaults = true, shouldSkipInheritedParentStyles = true }\n\t) {\n\t\tconst defaultStyles = shouldRespectDefaults\n\t\t\t? getDefaultStylesForTagName(element.tagName.toLowerCase())\n\t\t\t: NO_STYLES\n\n\t\tconst parentStyles = Object.assign({}, NO_STYLES) as Styles\n\t\tif (shouldSkipInheritedParentStyles) {\n\t\t\tlet el = element.parentElement\n\t\t\t// Keep going up the tree to find all the relevant styles\n\t\t\twhile (el) {\n\t\t\t\tconst currentStyles = this.styles.get(el)?.self\n\t\t\t\tfor (const style in currentStyles) {\n\t\t\t\t\tif (!parentStyles[style]) {\n\t\t\t\t\t\tparentStyles[style] = currentStyles[style]\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tel = el.parentElement\n\t\t\t}\n\t\t}\n\n\t\tconst info: ElementStyleInfo = {\n\t\t\tself: styleFromElement(element, { defaultStyles, parentStyles }),\n\t\t\tbefore: styleFromPseudoElement(element, '::before'),\n\t\t\tafter: styleFromPseudoElement(element, '::after'),\n\t\t}\n\t\tthis.styles.set(element, info)\n\t}\n\n\tfetchResources() {\n\t\tconst promises: Promise<void>[] = []\n\n\t\tfor (const info of this.styles.values()) {\n\t\t\tfor (const styles of objectMapValues(info)) {\n\t\t\t\tif (!styles) continue\n\t\t\t\tfor (const [property, value] of Object.entries(styles)) {\n\t\t\t\t\tif (!value) continue\n\t\t\t\t\tif (property === 'font-family') {\n\t\t\t\t\t\tthis.fonts.onFontFamilyValue(value)\n\t\t\t\t\t}\n\n\t\t\t\t\tconst urlMatches = parseCssValueUrls(value)\n\t\t\t\t\tif (urlMatches.length === 0) continue\n\n\t\t\t\t\tpromises.push(\n\t\t\t\t\t\t...urlMatches.map(async ({ url, original }) => {\n\t\t\t\t\t\t\tconst dataUrl = (await resourceToDataUrl(url)) ?? 'data:'\n\t\t\t\t\t\t\tstyles[property] = value.replace(original, `url(\"${dataUrl}\")`)\n\t\t\t\t\t\t})\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Promise.all(promises)\n\t}\n\n\t// custom elements are tricky. if we serialize the dom as-is, the custom elements wont have\n\t// their shadow-dom contents serialized. after we've read all the styles, we need to unwrap the\n\t// contents of each custom elements shadow dom directly into the parent element itself.\n\tunwrapCustomElements() {\n\t\tconst visited = new Set<Node>()\n\n\t\tconst visit = (element: Element, clonedParent: Element | null) => {\n\t\t\tif (visited.has(element)) return\n\t\t\tvisited.add(element)\n\n\t\t\tconst shadowRoot = element.shadowRoot\n\n\t\t\tif (shadowRoot) {\n\t\t\t\tconst clonedCustomEl = document.createElement('div')\n\t\t\t\tthis.styles.set(clonedCustomEl, this.styles.get(element)!)\n\n\t\t\t\tclonedCustomEl.setAttribute('data-tl-custom-element', element.tagName)\n\t\t\t\t;(clonedParent ?? element.parentElement!).appendChild(clonedCustomEl)\n\n\t\t\t\tfor (const child of shadowRoot.childNodes) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedCustomEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedCustomEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telement.remove()\n\t\t\t} else if (clonedParent) {\n\t\t\t\tif (element.tagName.toLowerCase() === 'style') {\n\t\t\t\t\t// we don't clone style tags at that would break the style scoping. instead we\n\t\t\t\t\t// rely on the computed styles we've already read\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst clonedEl = element.cloneNode(false) as Element\n\t\t\t\tthis.styles.set(clonedEl, this.styles.get(element)!)\n\n\t\t\t\tclonedParent.appendChild(clonedEl)\n\n\t\t\t\tfor (const child of getRenderedChildNodes(element)) {\n\t\t\t\t\tif (child instanceof Element) {\n\t\t\t\t\t\tvisit(child, clonedEl)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclonedEl.appendChild(child.cloneNode(true))\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (const element of this.styles.keys()) {\n\t\t\tvisit(element, null)\n\t\t}\n\t}\n\n\tembedStyles(): string {\n\t\tlet css = ''\n\n\t\tfor (const [element, info] of this.styles) {\n\t\t\tif (info.after || info.before) {\n\t\t\t\tconst className = `pseudo-${uniqueId()}`\n\t\t\t\telement.classList.add(className)\n\n\t\t\t\tif (info.before) {\n\t\t\t\t\tcss += `.${className}::before {${formatCss(info.before)}}\\n`\n\t\t\t\t}\n\t\t\t\tif (info.after) {\n\t\t\t\t\tcss += `.${className}::after {${formatCss(info.after)}}\\n`\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst style = elementStyle(element)\n\t\t\tfor (const [property, value] of Object.entries(info.self)) {\n\t\t\t\tif (!value) continue\n\t\t\t\tstyle.setProperty(property, value)\n\t\t\t}\n\n\t\t\t// in HTML, font-kerning: auto is equivalent to font-kerning: normal. But in SVG, it's\n\t\t\t// none. We set it to normal here to match the HTML behavior, as otherwise this can\n\t\t\t// cause rendering differences.\n\t\t\tif (style.fontKerning === 'auto') {\n\t\t\t\tstyle.fontKerning = 'normal'\n\t\t\t}\n\t\t}\n\n\t\treturn css\n\t}\n\n\tasync getFontFaceCss() {\n\t\treturn await this.fonts.createCss()\n\t}\n\n\tdispose() {\n\t\tdestroyDefaultStyleFrame()\n\t}\n}\n\ninterface ReadStyleOpts {\n\tdefaultStyles: ReadonlyStyles\n\tparentStyles: ReadonlyStyles\n}\n\nfunction styleFromElement(element: Element, { defaultStyles, parentStyles }: ReadStyleOpts) {\n\t// `computedStyleMap` produces a more accurate representation of the styles, but it's not\n\t// supported in firefox at the time of writing. So we fall back to `getComputedStyle` if it's\n\t// not available.\n\tif (element.computedStyleMap) {\n\t\treturn styleFromComputedStyleMap(element.computedStyleMap(), { defaultStyles, parentStyles })\n\t}\n\treturn styleFromComputedStyle(getComputedStyle(element), { defaultStyles, parentStyles })\n}\n\nfunction styleFromPseudoElement(element: Element, pseudo: string) {\n\t// the equivalent of `computedStyleMap` for pseudo-elements isn't even fully specced out yet, so\n\t// for those we have to use `getComputedStyle` in all browsers.\n\tconst style = getComputedStyle(element, pseudo)\n\n\tconst content = style.getPropertyValue('content')\n\tif (content === '' || content === 'none') {\n\t\treturn undefined\n\t}\n\n\treturn styleFromComputedStyle(style, { defaultStyles: NO_STYLES, parentStyles: NO_STYLES })\n}\n\nfunction styleFromComputedStyleMap(\n\tstyle: StylePropertyMapReadOnly,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property of style.keys()) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.get(property)!.toString()\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\t\tif (isPropertyCoveredByCurrentColor(style.get('color')?.toString() || '', property, value))\n\t\t\tcontinue\n\n\t\tstyles[property] = value\n\t}\n\n\treturn styles\n}\n\nfunction styleFromComputedStyle(\n\tstyle: CSSStyleDeclaration,\n\t{ defaultStyles, parentStyles }: ReadStyleOpts\n) {\n\tconst styles: Record<string, string> = {}\n\tfor (const property in style) {\n\t\tif (!shouldIncludeCssProperty(property)) continue\n\n\t\tconst value = style.getPropertyValue(property)\n\n\t\tif (defaultStyles[property] === value) continue\n\t\tif (parentStyles[property] === value && isPropertyInherited(property)) continue\n\t\tif (isPropertyCoveredByCurrentColor(style.color, property, value)) continue\n\n\t\tstyles[property] = value\n\t}\n\treturn styles\n}\n\nfunction formatCss(style: ReadonlyStyles) {\n\tlet cssText = ''\n\tfor (const [property, value] of Object.entries(style)) {\n\t\tcssText += `${property}: ${value};`\n\t}\n\treturn cssText\n}\n\n// when we're figuring out the default values for a tag, we need read them from a separate document\n// so they're not affected by the current document's styles\nlet defaultStyleFrame:\n\t| { iframe: HTMLIFrameElement; foreignObject: SVGForeignObjectElement; document: Document }\n\t| undefined\nconst defaultStylesByTagName: Record<string, ReadonlyStyles> = {}\nfunction getDefaultStyleFrame() {\n\tif (!defaultStyleFrame) {\n\t\tconst frame = document.createElement('iframe')\n\t\tframe.style.display = 'none'\n\t\tdocument.body.appendChild(frame)\n\t\tconst frameDocument = assertExists(frame.contentDocument, 'frame must have a document')\n\t\tconst svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')\n\t\tconst foreignObject = document.createElementNS('http://www.w3.org/2000/svg', 'foreignObject')\n\t\tsvg.appendChild(foreignObject)\n\t\tframeDocument.body.appendChild(svg)\n\t\tdefaultStyleFrame = { iframe: frame, foreignObject, document: frameDocument }\n\t}\n\treturn defaultStyleFrame\n}\n\nfunction destroyDefaultStyleFrame() {\n\tif (defaultStyleFrame) {\n\t\tdocument.body.removeChild(defaultStyleFrame.iframe)\n\t\tdefaultStyleFrame = undefined\n\t}\n}\n\nconst defaultStyleReadOptions: ReadStyleOpts = { defaultStyles: NO_STYLES, parentStyles: NO_STYLES }\nfunction getDefaultStylesForTagName(tagName: string) {\n\tlet existing = defaultStylesByTagName[tagName]\n\tif (!existing) {\n\t\tconst { foreignObject, document } = getDefaultStyleFrame()\n\t\tconst element = document.createElement(tagName)\n\t\tforeignObject.appendChild(element)\n\t\texisting = element.computedStyleMap\n\t\t\t? styleFromComputedStyleMap(element.computedStyleMap(), defaultStyleReadOptions)\n\t\t\t: styleFromComputedStyle(getComputedStyle(element), defaultStyleReadOptions)\n\t\tforeignObject.removeChild(element)\n\t\tdefaultStylesByTagName[tagName] = existing\n\t}\n\treturn existing\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["document"]
7
7
  }
@@ -67,11 +67,33 @@ function parseCssValueUrls(value) {
67
67
  url: m[1] || m[2] || m[3]
68
68
  }));
69
69
  }
70
+ const currentColorProperties = /* @__PURE__ */ new Set([
71
+ "border-block-end-color",
72
+ "border-block-start-color",
73
+ "border-bottom-color",
74
+ "border-inline-end-color",
75
+ "border-inline-start-color",
76
+ "border-left-color",
77
+ "border-right-color",
78
+ "border-top-color",
79
+ "caret-color",
80
+ "column-rule-color",
81
+ "outline-color",
82
+ "text-decoration",
83
+ "text-decoration-color",
84
+ "text-emphasis-color"
85
+ ]);
86
+ function isPropertyCoveredByCurrentColor(currentColor, property, value) {
87
+ if (currentColorProperties.has(property)) {
88
+ return value === "currentColor" || value === currentColor || property === "text-decoration" && value === `none solid ${currentColor}`;
89
+ }
90
+ }
70
91
  const inheritedProperties = /* @__PURE__ */ new Set([
71
92
  "border-collapse",
72
93
  "border-spacing",
73
94
  "caption-side",
74
- "color",
95
+ // N.B. We shouldn't inherit 'color' because there's some UA styling, e.g. `mark` elements
96
+ // 'color',
75
97
  "cursor",
76
98
  "direction",
77
99
  "empty-cells",
@@ -92,16 +114,18 @@ const inheritedProperties = /* @__PURE__ */ new Set([
92
114
  "orphans",
93
115
  "overflow-wrap",
94
116
  "quotes",
117
+ "stroke-linecap",
118
+ "stroke-linejoin",
95
119
  "tab-size",
96
120
  "text-align",
97
121
  "text-align-last",
98
- "text-decoration-color",
99
122
  "text-indent",
100
123
  "text-justify",
101
124
  "text-shadow",
102
125
  "text-transform",
103
126
  "visibility",
104
127
  "white-space",
128
+ "white-space-collapse",
105
129
  "widows",
106
130
  "word-break",
107
131
  "word-spacing",
@@ -111,6 +135,7 @@ function isPropertyInherited(property) {
111
135
  return inheritedProperties.has(property);
112
136
  }
113
137
  export {
138
+ isPropertyCoveredByCurrentColor,
114
139
  isPropertyInherited,
115
140
  parseCss,
116
141
  parseCssFontFaces,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/lib/exports/parseCss.ts"],
4
- "sourcesContent": ["import { safeParseUrl } from '@tldraw/utils'\n\nexport interface ParsedFontFace {\n\tfontFace: string\n\turls: { original: string; resolved: string | null; embedded?: Promise<string | null> }[]\n\tfontFamilies: Set<string>\n}\n\n// parsing CSS with regular expressions doesn't really work. There are almost certainly edge cases\n// in the regular expressions we're using here. They're based formal grammars of CSS, but aren't\n// perfect. These were written with https://regexper.com/ - give it a go if you're editing these.\n\n// The regexes themselves would be nicer to work with if we were using named capturing groups\n// (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group).\n// We use a lot of disjunctions (the `|`) to cover different syntaxes though, and at the time of\n// writing, browser support for using named capturing groups across disjunctions is rough.\n\n// Parse @import declarations:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@import#formal_syntax\nconst importsRegex =\n\t/@import\\s+(?:\"([^\"]+)\"|'([^']+)'|url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\))([^;]+);/gi\n\n// Locate @font-face declarations:\nconst fontFaceRegex = /@font-face\\s*{([^}]+)}/gi\n\n// Parse url() calls within a CSS value:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax\nconst urlsRegex = /url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\)/gi\n\n// Locate and parse the value of `font-family` within a @font-face declaration:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family#formal_syntax\nconst fontFamilyRegex =\n\t/(?:^|;)\\s*font-family\\s*:\\s*(?:([^'\"][^;\\n]+)|\"([^\"]+)\"|'([^']+)')\\s*(?:;|$)/gi\n\nexport function parseCssImports(css: string) {\n\treturn Array.from(css.matchAll(importsRegex), (m) => ({\n\t\turl: m[1] || m[2] || m[3] || m[4] || m[5],\n\t\textras: m[6],\n\t}))\n}\n\nexport function parseCssFontFaces(css: string, baseUrl: string) {\n\treturn Array.from(css.matchAll(fontFaceRegex), (m): ParsedFontFace => {\n\t\tconst fontFace = m[1]\n\t\tconst urls = Array.from(fontFace.matchAll(urlsRegex), (m) => {\n\t\t\tconst original = m[1] || m[2] || m[3]\n\t\t\treturn {\n\t\t\t\toriginal,\n\t\t\t\tresolved: safeParseUrl(original, baseUrl)?.href ?? null,\n\t\t\t}\n\t\t})\n\t\tconst fontFamilies = new Set(\n\t\t\tArray.from(fontFace.matchAll(fontFamilyRegex), (m) => (m[1] || m[2] || m[3]).toLowerCase())\n\t\t)\n\n\t\treturn { fontFace, urls, fontFamilies }\n\t})\n}\n\nexport function parseCssFontFamilyValue(value: string) {\n\t// https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#formal_syntax\n\t// we use two regexes here to parse each value in a comma separated list of font families\n\tconst valueRegex = /\\s*(?:([^'\"][^;\\n\\s,]+)|\"([^\"]+)\"|'([^']+)')\\s*/gi\n\tconst separatorRegex = /\\s*,\\s*/gi\n\n\tconst fontFamilies = new Set<string>()\n\n\twhile (true) {\n\t\tconst valueMatch = valueRegex.exec(value)\n\t\tif (!valueMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tconst fontFamily = valueMatch[1] || valueMatch[2] || valueMatch[3]\n\t\tfontFamilies.add(fontFamily.toLowerCase())\n\n\t\tseparatorRegex.lastIndex = valueRegex.lastIndex\n\t\tconst separatorMatch = separatorRegex.exec(value)\n\t\tif (!separatorMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tvalueRegex.lastIndex = separatorRegex.lastIndex\n\t}\n\n\treturn fontFamilies\n}\n\nexport function shouldIncludeCssProperty(property: string) {\n\tif (property.startsWith('-')) return false\n\tif (property.startsWith('animation')) return false\n\tif (property.startsWith('transition')) return false\n\tif (property === 'cursor') return false\n\tif (property === 'pointer-events') return false\n\tif (property === 'user-select') return false\n\tif (property === 'touch-action') return false\n\treturn true\n}\n\nexport function parseCss(css: string, baseUrl: string) {\n\treturn {\n\t\timports: parseCssImports(css),\n\t\tfontFaces: parseCssFontFaces(css, baseUrl),\n\t}\n}\n\nexport function parseCssValueUrls(value: string) {\n\treturn Array.from(value.matchAll(urlsRegex), (m) => ({\n\t\toriginal: m[0],\n\t\turl: m[1] || m[2] || m[3],\n\t}))\n}\n\nconst inheritedProperties = new Set([\n\t'border-collapse',\n\t'border-spacing',\n\t'caption-side',\n\t'color',\n\t'cursor',\n\t'direction',\n\t'empty-cells',\n\t'font-family',\n\t'font-size',\n\t'font-style',\n\t'font-variant',\n\t'font-weight',\n\t'font-size-adjust',\n\t'font-stretch',\n\t'font',\n\t'letter-spacing',\n\t'line-height',\n\t'list-style-image',\n\t'list-style-position',\n\t'list-style-type',\n\t'list-style',\n\t'orphans',\n\t'overflow-wrap',\n\t'quotes',\n\t'tab-size',\n\t'text-align',\n\t'text-align-last',\n\t'text-decoration-color',\n\t'text-indent',\n\t'text-justify',\n\t'text-shadow',\n\t'text-transform',\n\t'visibility',\n\t'white-space',\n\t'widows',\n\t'word-break',\n\t'word-spacing',\n\t'word-wrap',\n])\n\nexport function isPropertyInherited(property: string) {\n\treturn inheritedProperties.has(property)\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { safeParseUrl } from '@tldraw/utils'\n\nexport interface ParsedFontFace {\n\tfontFace: string\n\turls: { original: string; resolved: string | null; embedded?: Promise<string | null> }[]\n\tfontFamilies: Set<string>\n}\n\n// parsing CSS with regular expressions doesn't really work. There are almost certainly edge cases\n// in the regular expressions we're using here. They're based formal grammars of CSS, but aren't\n// perfect. These were written with https://regexper.com/ - give it a go if you're editing these.\n\n// The regexes themselves would be nicer to work with if we were using named capturing groups\n// (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group).\n// We use a lot of disjunctions (the `|`) to cover different syntaxes though, and at the time of\n// writing, browser support for using named capturing groups across disjunctions is rough.\n\n// Parse @import declarations:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@import#formal_syntax\nconst importsRegex =\n\t/@import\\s+(?:\"([^\"]+)\"|'([^']+)'|url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\))([^;]+);/gi\n\n// Locate @font-face declarations:\nconst fontFaceRegex = /@font-face\\s*{([^}]+)}/gi\n\n// Parse url() calls within a CSS value:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/url#syntax\nconst urlsRegex = /url\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)'|([^'\")]+))\\s*\\)/gi\n\n// Locate and parse the value of `font-family` within a @font-face declaration:\n// https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-family#formal_syntax\nconst fontFamilyRegex =\n\t/(?:^|;)\\s*font-family\\s*:\\s*(?:([^'\"][^;\\n]+)|\"([^\"]+)\"|'([^']+)')\\s*(?:;|$)/gi\n\nexport function parseCssImports(css: string) {\n\treturn Array.from(css.matchAll(importsRegex), (m) => ({\n\t\turl: m[1] || m[2] || m[3] || m[4] || m[5],\n\t\textras: m[6],\n\t}))\n}\n\nexport function parseCssFontFaces(css: string, baseUrl: string) {\n\treturn Array.from(css.matchAll(fontFaceRegex), (m): ParsedFontFace => {\n\t\tconst fontFace = m[1]\n\t\tconst urls = Array.from(fontFace.matchAll(urlsRegex), (m) => {\n\t\t\tconst original = m[1] || m[2] || m[3]\n\t\t\treturn {\n\t\t\t\toriginal,\n\t\t\t\tresolved: safeParseUrl(original, baseUrl)?.href ?? null,\n\t\t\t}\n\t\t})\n\t\tconst fontFamilies = new Set(\n\t\t\tArray.from(fontFace.matchAll(fontFamilyRegex), (m) => (m[1] || m[2] || m[3]).toLowerCase())\n\t\t)\n\n\t\treturn { fontFace, urls, fontFamilies }\n\t})\n}\n\nexport function parseCssFontFamilyValue(value: string) {\n\t// https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#formal_syntax\n\t// we use two regexes here to parse each value in a comma separated list of font families\n\tconst valueRegex = /\\s*(?:([^'\"][^;\\n\\s,]+)|\"([^\"]+)\"|'([^']+)')\\s*/gi\n\tconst separatorRegex = /\\s*,\\s*/gi\n\n\tconst fontFamilies = new Set<string>()\n\n\twhile (true) {\n\t\tconst valueMatch = valueRegex.exec(value)\n\t\tif (!valueMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tconst fontFamily = valueMatch[1] || valueMatch[2] || valueMatch[3]\n\t\tfontFamilies.add(fontFamily.toLowerCase())\n\n\t\tseparatorRegex.lastIndex = valueRegex.lastIndex\n\t\tconst separatorMatch = separatorRegex.exec(value)\n\t\tif (!separatorMatch) {\n\t\t\tbreak\n\t\t}\n\n\t\tvalueRegex.lastIndex = separatorRegex.lastIndex\n\t}\n\n\treturn fontFamilies\n}\n\nexport function shouldIncludeCssProperty(property: string) {\n\tif (property.startsWith('-')) return false\n\tif (property.startsWith('animation')) return false\n\tif (property.startsWith('transition')) return false\n\tif (property === 'cursor') return false\n\tif (property === 'pointer-events') return false\n\tif (property === 'user-select') return false\n\tif (property === 'touch-action') return false\n\treturn true\n}\n\nexport function parseCss(css: string, baseUrl: string) {\n\treturn {\n\t\timports: parseCssImports(css),\n\t\tfontFaces: parseCssFontFaces(css, baseUrl),\n\t}\n}\n\nexport function parseCssValueUrls(value: string) {\n\treturn Array.from(value.matchAll(urlsRegex), (m) => ({\n\t\toriginal: m[0],\n\t\turl: m[1] || m[2] || m[3],\n\t}))\n}\n\nconst currentColorProperties = new Set([\n\t'border-block-end-color',\n\t'border-block-start-color',\n\t'border-bottom-color',\n\t'border-inline-end-color',\n\t'border-inline-start-color',\n\t'border-left-color',\n\t'border-right-color',\n\t'border-top-color',\n\t'caret-color',\n\t'column-rule-color',\n\t'outline-color',\n\t'text-decoration',\n\t'text-decoration-color',\n\t'text-emphasis-color',\n])\n\nexport function isPropertyCoveredByCurrentColor(\n\tcurrentColor: string,\n\tproperty: string,\n\tvalue: string\n) {\n\tif (currentColorProperties.has(property)) {\n\t\treturn (\n\t\t\tvalue === 'currentColor' ||\n\t\t\tvalue === currentColor ||\n\t\t\t(property === 'text-decoration' && value === `none solid ${currentColor}`)\n\t\t)\n\t}\n}\n\nconst inheritedProperties = new Set([\n\t'border-collapse',\n\t'border-spacing',\n\t'caption-side',\n\t// N.B. We shouldn't inherit 'color' because there's some UA styling, e.g. `mark` elements\n\t// 'color',\n\t'cursor',\n\t'direction',\n\t'empty-cells',\n\t'font-family',\n\t'font-size',\n\t'font-style',\n\t'font-variant',\n\t'font-weight',\n\t'font-size-adjust',\n\t'font-stretch',\n\t'font',\n\t'letter-spacing',\n\t'line-height',\n\t'list-style-image',\n\t'list-style-position',\n\t'list-style-type',\n\t'list-style',\n\t'orphans',\n\t'overflow-wrap',\n\t'quotes',\n\t'stroke-linecap',\n\t'stroke-linejoin',\n\t'tab-size',\n\t'text-align',\n\t'text-align-last',\n\t'text-indent',\n\t'text-justify',\n\t'text-shadow',\n\t'text-transform',\n\t'visibility',\n\t'white-space',\n\t'white-space-collapse',\n\t'widows',\n\t'word-break',\n\t'word-spacing',\n\t'word-wrap',\n])\n\nexport function isPropertyInherited(property: string) {\n\treturn inheritedProperties.has(property)\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["m"]
7
7
  }
@@ -1,8 +1,8 @@
1
- const version = "3.11.0-canary.b2098bef0749";
1
+ const version = "3.11.0-canary.b65e0ab5933e";
2
2
  const publishDates = {
3
3
  major: "2024-09-13T14:36:29.063Z",
4
- minor: "2025-03-18T13:49:35.230Z",
5
- patch: "2025-03-18T13:49:35.230Z"
4
+ minor: "2025-03-18T15:30:30.987Z",
5
+ patch: "2025-03-18T15:30:30.987Z"
6
6
  };
7
7
  export {
8
8
  publishDates,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/version.ts"],
4
- "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.11.0-canary.b2098bef0749'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-18T13:49:35.230Z',\n\tpatch: '2025-03-18T13:49:35.230Z',\n}\n"],
4
+ "sourcesContent": ["// This file is automatically generated by internal/scripts/refresh-assets.ts.\n// Do not edit manually. Or do, I'm a comment, not a cop.\n\nexport const version = '3.11.0-canary.b65e0ab5933e'\nexport const publishDates = {\n\tmajor: '2024-09-13T14:36:29.063Z',\n\tminor: '2025-03-18T15:30:30.987Z',\n\tpatch: '2025-03-18T15:30:30.987Z',\n}\n"],
5
5
  "mappings": "AAGO,MAAM,UAAU;AAChB,MAAM,eAAe;AAAA,EAC3B,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AACR;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tldraw/editor",
3
3
  "description": "A tiny little drawing app (editor).",
4
- "version": "3.11.0-canary.b2098bef0749",
4
+ "version": "3.11.0-canary.b65e0ab5933e",
5
5
  "author": {
6
6
  "name": "tldraw Inc.",
7
7
  "email": "hello@tldraw.com"
@@ -48,12 +48,12 @@
48
48
  "@tiptap/core": "^2.9.1",
49
49
  "@tiptap/pm": "^2.9.1",
50
50
  "@tiptap/react": "^2.9.1",
51
- "@tldraw/state": "3.11.0-canary.b2098bef0749",
52
- "@tldraw/state-react": "3.11.0-canary.b2098bef0749",
53
- "@tldraw/store": "3.11.0-canary.b2098bef0749",
54
- "@tldraw/tlschema": "3.11.0-canary.b2098bef0749",
55
- "@tldraw/utils": "3.11.0-canary.b2098bef0749",
56
- "@tldraw/validate": "3.11.0-canary.b2098bef0749",
51
+ "@tldraw/state": "3.11.0-canary.b65e0ab5933e",
52
+ "@tldraw/state-react": "3.11.0-canary.b65e0ab5933e",
53
+ "@tldraw/store": "3.11.0-canary.b65e0ab5933e",
54
+ "@tldraw/tlschema": "3.11.0-canary.b65e0ab5933e",
55
+ "@tldraw/utils": "3.11.0-canary.b65e0ab5933e",
56
+ "@tldraw/validate": "3.11.0-canary.b65e0ab5933e",
57
57
  "@types/core-js": "^2.5.8",
58
58
  "@use-gesture/react": "^10.3.1",
59
59
  "classnames": "^2.5.1",
@@ -7,7 +7,12 @@ import {
7
7
  getRenderedChildren,
8
8
  } from './domUtils'
9
9
  import { resourceToDataUrl } from './fetchCache'
10
- import { isPropertyInherited, parseCssValueUrls, shouldIncludeCssProperty } from './parseCss'
10
+ import {
11
+ isPropertyCoveredByCurrentColor,
12
+ isPropertyInherited,
13
+ parseCssValueUrls,
14
+ shouldIncludeCssProperty,
15
+ } from './parseCss'
11
16
 
12
17
  type Styles = { [K in string]?: string }
13
18
  type ReadonlyStyles = { readonly [K in string]?: string }
@@ -53,9 +58,20 @@ export class StyleEmbedder {
53
58
  ? getDefaultStylesForTagName(element.tagName.toLowerCase())
54
59
  : NO_STYLES
55
60
 
56
- const parentStyles = shouldSkipInheritedParentStyles
57
- ? (this.styles.get(element.parentElement as Element)?.self ?? NO_STYLES)
58
- : NO_STYLES
61
+ const parentStyles = Object.assign({}, NO_STYLES) as Styles
62
+ if (shouldSkipInheritedParentStyles) {
63
+ let el = element.parentElement
64
+ // Keep going up the tree to find all the relevant styles
65
+ while (el) {
66
+ const currentStyles = this.styles.get(el)?.self
67
+ for (const style in currentStyles) {
68
+ if (!parentStyles[style]) {
69
+ parentStyles[style] = currentStyles[style]
70
+ }
71
+ }
72
+ el = el.parentElement
73
+ }
74
+ }
59
75
 
60
76
  const info: ElementStyleInfo = {
61
77
  self: styleFromElement(element, { defaultStyles, parentStyles }),
@@ -230,6 +246,8 @@ function styleFromComputedStyleMap(
230
246
 
231
247
  if (defaultStyles[property] === value) continue
232
248
  if (parentStyles[property] === value && isPropertyInherited(property)) continue
249
+ if (isPropertyCoveredByCurrentColor(style.get('color')?.toString() || '', property, value))
250
+ continue
233
251
 
234
252
  styles[property] = value
235
253
  }
@@ -249,6 +267,7 @@ function styleFromComputedStyle(
249
267
 
250
268
  if (defaultStyles[property] === value) continue
251
269
  if (parentStyles[property] === value && isPropertyInherited(property)) continue
270
+ if (isPropertyCoveredByCurrentColor(style.color, property, value)) continue
252
271
 
253
272
  styles[property] = value
254
273
  }
@@ -111,11 +111,43 @@ export function parseCssValueUrls(value: string) {
111
111
  }))
112
112
  }
113
113
 
114
+ const currentColorProperties = new Set([
115
+ 'border-block-end-color',
116
+ 'border-block-start-color',
117
+ 'border-bottom-color',
118
+ 'border-inline-end-color',
119
+ 'border-inline-start-color',
120
+ 'border-left-color',
121
+ 'border-right-color',
122
+ 'border-top-color',
123
+ 'caret-color',
124
+ 'column-rule-color',
125
+ 'outline-color',
126
+ 'text-decoration',
127
+ 'text-decoration-color',
128
+ 'text-emphasis-color',
129
+ ])
130
+
131
+ export function isPropertyCoveredByCurrentColor(
132
+ currentColor: string,
133
+ property: string,
134
+ value: string
135
+ ) {
136
+ if (currentColorProperties.has(property)) {
137
+ return (
138
+ value === 'currentColor' ||
139
+ value === currentColor ||
140
+ (property === 'text-decoration' && value === `none solid ${currentColor}`)
141
+ )
142
+ }
143
+ }
144
+
114
145
  const inheritedProperties = new Set([
115
146
  'border-collapse',
116
147
  'border-spacing',
117
148
  'caption-side',
118
- 'color',
149
+ // N.B. We shouldn't inherit 'color' because there's some UA styling, e.g. `mark` elements
150
+ // 'color',
119
151
  'cursor',
120
152
  'direction',
121
153
  'empty-cells',
@@ -136,16 +168,18 @@ const inheritedProperties = new Set([
136
168
  'orphans',
137
169
  'overflow-wrap',
138
170
  'quotes',
171
+ 'stroke-linecap',
172
+ 'stroke-linejoin',
139
173
  'tab-size',
140
174
  'text-align',
141
175
  'text-align-last',
142
- 'text-decoration-color',
143
176
  'text-indent',
144
177
  'text-justify',
145
178
  'text-shadow',
146
179
  'text-transform',
147
180
  'visibility',
148
181
  'white-space',
182
+ 'white-space-collapse',
149
183
  'widows',
150
184
  'word-break',
151
185
  'word-spacing',
package/src/version.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // This file is automatically generated by internal/scripts/refresh-assets.ts.
2
2
  // Do not edit manually. Or do, I'm a comment, not a cop.
3
3
 
4
- export const version = '3.11.0-canary.b2098bef0749'
4
+ export const version = '3.11.0-canary.b65e0ab5933e'
5
5
  export const publishDates = {
6
6
  major: '2024-09-13T14:36:29.063Z',
7
- minor: '2025-03-18T13:49:35.230Z',
8
- patch: '2025-03-18T13:49:35.230Z',
7
+ minor: '2025-03-18T15:30:30.987Z',
8
+ patch: '2025-03-18T15:30:30.987Z',
9
9
  }