Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added parameter to avoid using ranges when creating tspans for mobilesafari; Added support for CSS transforms. #66

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,25 @@ export function handleElement(element: Element, context: Readonly<TraversalConte
svgContainer.setAttribute('opacity', styles.opacity)
}

// CSS Transforms to SVG transforms
if (styles.transform && styles.transform !== 'none') {
const htmlelement: HTMLElement = element as HTMLElement
const left: number = context.options.captureArea.left ? context.options.captureArea.left : 0
const offsetLeft: number = htmlelement.offsetLeft
const offsetWidth: number = htmlelement.offsetWidth
const centerx = left + offsetLeft + offsetWidth / 2

const top: number = context.options.captureArea.top ? context.options.captureArea.top : 0
const offsetTop: number = htmlelement.offsetTop
const offsetHeight: number = htmlelement.offsetHeight
const centery = top + offsetTop + offsetHeight / 2

const strtransform = `translate(${centerx} ${centery}) ${
styles.transform
} translate(${-centerx} ${-centery})`
svgContainer.setAttribute('transform', strtransform)
}

// Accessibility
for (const [name, value] of getAccessibilityAttributes(element, context)) {
svgContainer.setAttribute(name, value)
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export function elementToSVG(element: Element, options?: DomToSvgOptions): XMLDo
options: {
captureArea: options?.captureArea ?? element.getBoundingClientRect(),
keepLinks: options?.keepLinks !== false,
avoidTextSelection: options ? !!options.avoidTextSelection : false
},
})

Expand Down
1 change: 1 addition & 0 deletions src/inline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export async function inlineResources(element: Element): Promise<void> {
// SVGs embedded through <img> are never interactive.
keepLinks: false,
captureArea: svgRoot.viewBox.baseVal,
avoidTextSelection: false
},
})

Expand Down
18 changes: 12 additions & 6 deletions src/text.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,18 @@ export function handleTextNode(textNode: Text, context: TraversalContext): void
try {
selection.removeAllRanges()
selection.addRange(lineRange)
textSpan.textContent = selection
.toString()
// SVG does not support tabs in text. Tabs get rendered as one space character. Convert the
// tabs to spaces according to tab-size instead.
// Ideally we would keep the tab and create offset tspans.
.replace(/\t/g, ' '.repeat(tabSize))
if (context.options.avoidTextSelection) {
textSpan.textContent = textNode.textContent
? textNode.textContent.slice(lineRange.startOffset, lineRange.endOffset)
: textNode.textContent
} else {
textSpan.textContent = selection
.toString()
// SVG does not support tabs in text. Tabs get rendered as one space character. Convert the
// tabs to spaces according to tab-size instead.
// Ideally we would keep the tab and create offset tspans.
.replace(/\t/g, ' '.repeat(tabSize))
}
} finally {
parentElement.style.userSelect = previousUserSelect
selection.removeAllRanges()
Expand Down
8 changes: 8 additions & 0 deletions src/traversal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ export interface DomToSvgOptions {
* @default true
*/
keepLinks?: boolean

/**
* Whether to use text selection to fill tspans or use textContent (different whitespace handling).
* textContent works in mobile iOS browsers
*
* @default false
*/
avoidTextSelection?: boolean
}

export interface TraversalContext {
Expand Down