@leafer/selector 1.0.0-rc.5 → 1.0.0-rc.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer/selector",
3
- "version": "1.0.0-rc.5",
3
+ "version": "1.0.0-rc.7",
4
4
  "description": "@leafer/selector",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -22,9 +22,9 @@
22
22
  "leaferjs"
23
23
  ],
24
24
  "dependencies": {
25
- "@leafer/core": "1.0.0-rc.5"
25
+ "@leafer/core": "1.0.0-rc.7"
26
26
  },
27
27
  "devDependencies": {
28
- "@leafer/interface": "1.0.0-rc.5"
28
+ "@leafer/interface": "1.0.0-rc.7"
29
29
  }
30
30
  }
@@ -4,7 +4,7 @@ import { BoundsHelper, LeafList, LeafHelper } from '@leafer/core'
4
4
 
5
5
  const { hitRadiusPoint } = BoundsHelper
6
6
 
7
- export class FindPath {
7
+ export class Pather {
8
8
 
9
9
  protected target: ILeaf
10
10
  protected selector: ISelector
@@ -63,10 +63,10 @@ export class FindPath {
63
63
  public getPath(leaf: ILeaf): LeafList {
64
64
  const path = new LeafList()
65
65
  while (leaf) {
66
- path.push(leaf)
66
+ path.add(leaf)
67
67
  leaf = leaf.parent
68
68
  }
69
- path.push(this.target)
69
+ path.add(this.target)
70
70
  return path
71
71
  }
72
72
 
@@ -76,7 +76,7 @@ export class FindPath {
76
76
  for (let i = path.list.length - 1; i > -1; i--) {
77
77
  item = path.list[i]
78
78
  if (!item.__.hittable) break
79
- hittablePath.unshift(item)
79
+ hittablePath.addAt(item, 0)
80
80
  if (!item.__.hitChildren) break
81
81
  }
82
82
  return hittablePath
@@ -96,7 +96,7 @@ export class FindPath {
96
96
  for (let j = 0, jLen = path.length; j < jLen; j++) {
97
97
  leaf = path.list[j]
98
98
  if (nextPath && nextPath.has(leaf)) break
99
- throughPath.push(leaf)
99
+ throughPath.add(leaf)
100
100
  }
101
101
  }
102
102
 
@@ -104,7 +104,7 @@ export class FindPath {
104
104
  }
105
105
 
106
106
 
107
- protected eachFind(children: Array<ILeaf>, hitMask: boolean): void {
107
+ protected eachFind(children: ILeaf[], hitMask: boolean): void {
108
108
  let child: ILeaf, hit: boolean
109
109
  const { point } = this, len = children.length
110
110
  for (let i = len - 1; i > -1; i--) {
package/src/Selector.ts CHANGED
@@ -1,128 +1,138 @@
1
- import { ILeaf, ILeafArrayMap, ILeafMap, ILeafList, ISelector, ISelectPathResult, ISelectPathOptions, IPointData, IEventListenerId, ISelectorConfig } from '@leafer/interface'
2
- import { ChildEvent, LayoutEvent, DataHelper, Platform } from '@leafer/core'
1
+ import { ILeaf, ILeafMap, ISelector, ISelectorProxy, ISelectPathResult, ISelectPathOptions, IPointData, IEventListenerId, ISelectorConfig, IFindMethod, AnswerType } from '@leafer/interface'
2
+ import { ChildEvent, LayoutEvent, DataHelper, Platform, PropertyEvent, LeafHelper } from '@leafer/core'
3
3
 
4
- import { FindPath } from './FindPath'
4
+ import { Pather } from './Pather'
5
5
 
6
- interface IFind {
7
- (leaf: ILeaf): boolean
8
- }
9
6
 
7
+ const { Yes, NoAndSkip, YesAndSkip } = AnswerType
10
8
 
11
9
  export class Selector implements ISelector {
12
10
 
13
11
  public target: ILeaf
14
12
 
15
- public list: ILeafList
13
+ public proxy?: ISelectorProxy // editor
16
14
 
17
15
  public config: ISelectorConfig = {}
18
16
 
19
- protected findPath: FindPath
17
+ protected pather: Pather
20
18
 
21
- protected innerIdList: ILeafMap = {}
22
- protected idList: ILeafMap = {}
23
- protected classNameList: ILeafArrayMap = {}
24
- protected tagNameList: ILeafArrayMap = {}
19
+ protected innerIdMap: ILeafMap = {}
20
+ protected idMap: ILeafMap = {}
21
+
22
+ protected findLeaf: ILeaf
23
+
24
+ protected methods = {
25
+ id: (leaf: ILeaf, name: string) => leaf.id === name ? (this.idMap[name] = leaf, 1) : 0,
26
+ innerId: (leaf: ILeaf, innerId: number) => leaf.innerId === innerId ? (this.innerIdMap[innerId] = leaf, 1) : 0,
27
+ className: (leaf: ILeaf, name: string) => leaf.className === name ? 1 : 0,
28
+ tag: (leaf: ILeaf, name: string) => leaf.__tag === name ? 1 : 0
29
+ }
25
30
 
26
31
  protected __eventIds: IEventListenerId[]
27
32
 
33
+
28
34
  constructor(target: ILeaf, userConfig?: ISelectorConfig) {
29
35
  this.target = target
30
36
  if (userConfig) this.config = DataHelper.default(userConfig, this.config)
31
- this.findPath = new FindPath(target, this)
37
+ this.pather = new Pather(target, this)
32
38
  this.__listenEvents()
33
39
  }
34
40
 
41
+ public getBy(condition: number | string | IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf | ILeaf[] {
42
+ switch (typeof condition) {
43
+ case 'number':
44
+ const leaf = this.getByInnerId(condition, branch)
45
+ return one ? leaf : (leaf ? [leaf] : [])
46
+ case 'string':
47
+ switch (condition[0]) {
48
+ case '#':
49
+ const leaf = this.getById(condition.substring(1), branch)
50
+ return one ? leaf : (leaf ? [leaf] : [])
51
+ case '.':
52
+ return this.getByMethod(this.methods.className, branch, one, condition.substring(1)) // className
53
+ default:
54
+ return this.getByMethod(this.methods.tag, branch, one, condition) // tagName
55
+ }
56
+ case 'function':
57
+ return this.getByMethod(condition as IFindMethod, branch, one, options)
58
+ }
59
+ }
60
+
35
61
  public getByPoint(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult {
36
62
  if (Platform.name === 'node') this.target.emit(LayoutEvent.CHECK_UPDATE)
37
- return this.findPath.getByPoint(hitPoint, hitRadius, options)
38
- }
39
-
40
- public find(name: number | string, branch?: ILeaf): ILeaf | ILeaf[] {
41
- if (typeof name === 'number') {
42
- return this.getByInnerId(name, branch)
43
- } else if (name.startsWith('#')) {
44
- return this.getById(name.substring(1), branch)
45
- } else if (name.startsWith('.')) {
46
- return this.getByClassName(name.substring(1), branch)
47
- } else {
48
- return this.getByTagName(name, branch)
49
- }
63
+ return this.pather.getByPoint(hitPoint, hitRadius, options)
50
64
  }
51
65
 
52
- public getByInnerId(name: number, branch?: ILeaf): ILeaf {
53
- let cache = this.innerIdList[name]
66
+ public getByInnerId(innerId: number, branch?: ILeaf): ILeaf {
67
+ const cache = this.innerIdMap[innerId]
54
68
  if (cache) return cache
55
- if (!branch) branch = this.target
56
- let find: ILeaf
57
- this.loopFind(branch, (leaf) => {
58
- if (leaf.innerId === name) {
59
- find = leaf
60
- this.innerIdList[name] = find
61
- return true
62
- } else {
63
- return false
64
- }
65
- })
66
- return find
69
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId)
70
+ return this.findLeaf
67
71
  }
68
72
 
69
- public getById(name: string, branch?: ILeaf): ILeaf {
70
- let cache = this.idList[name]
71
- if (cache) return cache
72
- if (!branch) branch = this.target
73
- let find: ILeaf
74
- this.loopFind(branch, (leaf) => {
75
- if (leaf.id === name) {
76
- find = leaf
77
- this.idList[name] = find
78
- return true
79
- } else {
80
- return false
81
- }
82
- })
83
- return find
73
+ public getById(id: string, branch?: ILeaf): ILeaf {
74
+ const cache = this.idMap[id]
75
+ if (cache && LeafHelper.hasParent(cache, branch || this.target)) return cache
76
+ this.eachFind(this.toChildren(branch), this.methods.id, null, id)
77
+ return this.findLeaf
84
78
  }
85
79
 
86
- public getByClassName(name: string, branch?: ILeaf): ILeaf[] {
87
- if (!branch) branch = this.target
88
- let find: Array<ILeaf | ILeaf> = []
89
- this.loopFind(branch, (leaf) => {
90
- if (leaf.className === name) find.push(leaf)
91
- return false
92
- })
93
- return find
80
+ public getByClassName(className: string, branch?: ILeaf): ILeaf[] {
81
+ return this.getByMethod(this.methods.className, branch, false, className) as ILeaf[]
94
82
  }
95
83
 
96
- public getByTagName(name: string, branch?: ILeaf): ILeaf[] {
97
- if (!branch) branch = this.target
98
- let find: Array<ILeaf | ILeaf> = []
99
- this.loopFind(branch, (leaf) => {
100
- if (leaf.__tag === name) find.push(leaf)
101
- return false
102
- })
103
- return find
84
+ public getByTag(tag: string, branch?: ILeaf): ILeaf[] {
85
+ return this.getByMethod(this.methods.tag, branch, false, tag) as ILeaf[]
104
86
  }
105
87
 
106
- protected loopFind(branch: ILeaf, find: IFind): void {
107
- if (find(branch)) return
108
- const { children } = branch
88
+ public getByMethod(method: IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf[] | ILeaf {
89
+ const list: ILeaf[] = one ? null : []
90
+ this.eachFind(this.toChildren(branch), method, list, options)
91
+ return list || this.findLeaf
92
+ }
93
+
94
+
95
+ protected eachFind(children: ILeaf[], method: IFindMethod, list?: ILeaf[], options?: any): void {
96
+ let child: ILeaf, result: AnswerType
109
97
  for (let i = 0, len = children.length; i < len; i++) {
110
- branch = children[i] as ILeaf
111
- if (find(branch)) return
112
- if (branch.isBranch) this.loopFind(branch, find)
98
+ child = children[i]
99
+ result = method(child, options)
100
+ if (result === Yes || result === YesAndSkip) {
101
+ if (list) {
102
+ list.push(child)
103
+ } else {
104
+ this.findLeaf = child
105
+ return
106
+ }
107
+ }
108
+ if (child.isBranch && result < NoAndSkip) this.eachFind(child.children, method, list, options)
113
109
  }
114
110
  }
115
111
 
112
+ protected toChildren(branch: ILeaf): ILeaf[] {
113
+ this.findLeaf = null
114
+ return [branch || this.target]
115
+ }
116
+
117
+
116
118
  protected __onRemoveChild(event: ChildEvent): void {
117
- const target = event.target as ILeaf
118
- if (this.idList[target.id]) this.idList[target.id] = null
119
- if (this.innerIdList[target.id]) this.innerIdList[target.innerId] = null
119
+ const { id, innerId } = event.child
120
+ if (this.idMap[id]) delete this.idMap[id]
121
+ if (this.innerIdMap[innerId]) delete this.innerIdMap[innerId]
122
+ }
123
+
124
+ protected __checkIdChange(event: PropertyEvent): void {
125
+ if (event.attrName === 'id') {
126
+ const id = event.oldValue as string
127
+ if (this.idMap[id]) delete this.idMap[id]
128
+ }
120
129
  }
121
130
 
122
131
 
123
132
  protected __listenEvents(): void {
124
133
  this.__eventIds = [
125
- this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this)
134
+ this.target.on_(ChildEvent.REMOVE, this.__onRemoveChild, this),
135
+ this.target.on_(PropertyEvent.CHANGE, this.__checkIdChange, this)
126
136
  ]
127
137
  }
128
138
 
@@ -134,11 +144,10 @@ export class Selector implements ISelector {
134
144
  public destroy(): void {
135
145
  if (this.__eventIds.length) {
136
146
  this.__removeListenEvents()
137
- this.findPath.destroy()
138
- this.innerIdList = {}
139
- this.idList = {}
140
- this.classNameList = {}
141
- this.tagNameList = {}
147
+ this.pather.destroy()
148
+ this.findLeaf = null
149
+ this.innerIdMap = {}
150
+ this.idMap = {}
142
151
  }
143
152
  }
144
153
 
package/types/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { ILeaf, ISelector, ILeafList, IRadiusPointData, IPointData, ISelectPathOptions, ISelectPathResult, ISelectorConfig, ILeafMap, ILeafArrayMap, IEventListenerId } from '@leafer/interface';
2
- import { LeafList, ChildEvent } from '@leafer/core';
1
+ import { ILeaf, ISelector, ILeafList, IRadiusPointData, IPointData, ISelectPathOptions, ISelectPathResult, ISelectorProxy, ISelectorConfig, ILeafMap, IEventListenerId, IFindMethod } from '@leafer/interface';
2
+ import { LeafList, ChildEvent, PropertyEvent } from '@leafer/core';
3
3
 
4
- declare class FindPath {
4
+ declare class Pather {
5
5
  protected target: ILeaf;
6
6
  protected selector: ISelector;
7
7
  protected findList: ILeaf[];
@@ -13,34 +13,39 @@ declare class FindPath {
13
13
  getPath(leaf: ILeaf): LeafList;
14
14
  getHitablePath(leaf: ILeaf): LeafList;
15
15
  getThroughPath(list: ILeaf[]): LeafList;
16
- protected eachFind(children: Array<ILeaf>, hitMask: boolean): void;
16
+ protected eachFind(children: ILeaf[], hitMask: boolean): void;
17
17
  protected hitChild(child: ILeaf, point: IRadiusPointData): void;
18
18
  protected clear(): void;
19
19
  destroy(): void;
20
20
  }
21
21
 
22
- interface IFind {
23
- (leaf: ILeaf): boolean;
24
- }
25
22
  declare class Selector implements ISelector {
26
23
  target: ILeaf;
27
- list: ILeafList;
24
+ proxy?: ISelectorProxy;
28
25
  config: ISelectorConfig;
29
- protected findPath: FindPath;
30
- protected innerIdList: ILeafMap;
31
- protected idList: ILeafMap;
32
- protected classNameList: ILeafArrayMap;
33
- protected tagNameList: ILeafArrayMap;
26
+ protected pather: Pather;
27
+ protected innerIdMap: ILeafMap;
28
+ protected idMap: ILeafMap;
29
+ protected findLeaf: ILeaf;
30
+ protected methods: {
31
+ id: (leaf: ILeaf, name: string) => 1 | 0;
32
+ innerId: (leaf: ILeaf, innerId: number) => 1 | 0;
33
+ className: (leaf: ILeaf, name: string) => 1 | 0;
34
+ tag: (leaf: ILeaf, name: string) => 1 | 0;
35
+ };
34
36
  protected __eventIds: IEventListenerId[];
35
37
  constructor(target: ILeaf, userConfig?: ISelectorConfig);
38
+ getBy(condition: number | string | IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf | ILeaf[];
36
39
  getByPoint(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult;
37
- find(name: number | string, branch?: ILeaf): ILeaf | ILeaf[];
38
- getByInnerId(name: number, branch?: ILeaf): ILeaf;
39
- getById(name: string, branch?: ILeaf): ILeaf;
40
- getByClassName(name: string, branch?: ILeaf): ILeaf[];
41
- getByTagName(name: string, branch?: ILeaf): ILeaf[];
42
- protected loopFind(branch: ILeaf, find: IFind): void;
40
+ getByInnerId(innerId: number, branch?: ILeaf): ILeaf;
41
+ getById(id: string, branch?: ILeaf): ILeaf;
42
+ getByClassName(className: string, branch?: ILeaf): ILeaf[];
43
+ getByTag(tag: string, branch?: ILeaf): ILeaf[];
44
+ getByMethod(method: IFindMethod, branch?: ILeaf, one?: boolean, options?: any): ILeaf[] | ILeaf;
45
+ protected eachFind(children: ILeaf[], method: IFindMethod, list?: ILeaf[], options?: any): void;
46
+ protected toChildren(branch: ILeaf): ILeaf[];
43
47
  protected __onRemoveChild(event: ChildEvent): void;
48
+ protected __checkIdChange(event: PropertyEvent): void;
44
49
  protected __listenEvents(): void;
45
50
  protected __removeListenEvents(): void;
46
51
  destroy(): void;