Guest User

Untitled

a guest
Jul 18th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.77 KB | None | 0 0
  1. class NodeTree {
  2. insert(node: Node): void {
  3. if (this.has(node)) {
  4. throw new UnexpectedStructure() // TODO
  5. }
  6.  
  7. const getParent = (): Node | undefined => {
  8. const filter: TravelFilter = candidate => candidate.contains(node) ? Travel.ACCEPT : Travel.REJECT
  9. const ancestorPaths = this.DFS(document.body, filter)
  10.  
  11. let parentPath: Array<Node> = []
  12. for (const path of ancestorPaths) {
  13. if (path.length < parentPath.length) {
  14. break
  15. }
  16. parentPath = path
  17. }
  18.  
  19. return parentPath[parentPath.length - 1]
  20. }
  21.  
  22. const parent = getParent()
  23. const children = new Set<Node>()
  24. if (existing(parent)) {
  25. this.parentMap.set(node, parent)
  26. const adjacents = this.childrenMap.get(node)!
  27. new Set(adjacents).forEach(adjacent => {
  28. if (node.contains(adjacent)) {
  29. children.add(adjacent)
  30. adjacents.delete(adjacent)
  31. }
  32. })
  33. }
  34.  
  35. this.childrenMap.set(node, children)
  36. }
  37.  
  38. ancestors(node: Node): Path {
  39. const result = []
  40. for (let parent = this.parentMap.get(node);
  41. existing(parent);
  42. parent = this.parentMap.get(parent)) {
  43. result.unshift(parent)
  44. }
  45. return result
  46. }
  47.  
  48. * DFS(node: Node, filter: TravelFilter = () => Travel.ACCEPT): IterableIterator<Path> {
  49. yield [node]
  50. const children = this.childrenMap.get(node)
  51. if (existing(children)) {
  52. for (const child of children) {
  53. if (filter(child) === Travel.REJECT) {
  54. continue
  55. }
  56. for (const subpath of this.DFS(child)) {
  57. const path = [child, ...subpath]
  58. if (filter(child) === Travel.ACCEPT) {
  59. yield path
  60. }
  61. }
  62. }
  63. }
  64. }
  65.  
  66. children(node: Node): Set<Node> {
  67. let result = this.childrenMap.get(node)
  68. if (notExisting(result)) {
  69. result = new Set<Node>()
  70. this.childrenMap.set(node, result)
  71. }
  72. return result
  73. }
  74.  
  75. has(node: Node): boolean {
  76. return existing(this.childrenMap.get(node))
  77. }
  78.  
  79. clear(): void {
  80. this.parentMap = new Map()
  81. this.childrenMap = new Map([[document.body, new Set()]])
  82. }
  83.  
  84. private parentMap: Map<Node, Node> = new Map()
  85. private childrenMap: Map<Node, Set<Node>> = new Map([[document.body, new Set()]])
  86. }
  87.  
  88. enum Travel {
  89. ACCEPT,
  90. SKIP,
  91. REJECT
  92. }
  93.  
  94. type TravelFilter = (path: Readonly<Node>) => Travel
  95. type Path = Array<Node>
  96.  
  97. class UnexpectedStructure extends Error {}
Add Comment
Please, Sign In to add comment