@leafer/selector 1.0.0-rc.4 → 1.0.0-rc.6

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