Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
One theory about how to compute the edit context given a selection in XD
import { Artboard, Group } from 'scenegraph'
// Strictly speaking, promoteArtboards means follow the spec.
// For some usage, we don't want that behavior.
function computeEditContextRoot(selection, promoteArtboards = true) {
// Number of nodes above the given node in the artwork tree.
function computeDepthToRoot(node) {
let depth = 0
while (node.parent != null) {
node = node.parent
++depth
}
return depth
}
// If no selection, no edit context.
if (selection.items.length == 0) return null
// contextNode is the eventual edit context root.
let contextNode, contextDepth
selection.items.forEach((node, idx) => {
if (idx == 0) {
const origNode = node
// Prime the pump on the first iteration.
contextNode = node.parent
contextDepth = computeDepthToRoot(contextNode)
} else {
const origNode = node
node = node.parent
// Pull the deeper one up to the shallower's level,
// and then search up the tree on both sides
// for a common ancestor. We'll eventually hit
// the root together, as a termination guarantee.
let nodeDepth = computeDepthToRoot(node)
while (nodeDepth > contextDepth) {
node = node.parent
--nodeDepth
}
while (nodeDepth < contextDepth) {
contextNode = contextNode.parent
--contextDepth
}
while (contextNode != node) {
contextNode = contextNode.parent
node = node.parent
--contextDepth
--nodeDepth
}
}
})
// Special case: if the edit context root would be an Artboard,
// the result is promoted up to the document root.
if (promoteArtboards && contextNode instanceof Artboard)
contextNode = contextNode.parent
return contextNode
}
export default computeEditContextRoot
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.