@leafer/selector 1.0.0-rc.5 → 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.5",
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.5"
25
+ "@leafer/core": "1.0.0-rc.6"
26
26
  },
27
27
  "devDependencies": {
28
- "@leafer/interface": "1.0.0-rc.5"
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,11 +1,7 @@
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, 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
- interface IFind {
7
- (leaf: ILeaf): boolean
8
- }
4
+ import { Pather } from './Pather'
9
5
 
10
6
 
11
7
  export class Selector implements ISelector {
@@ -16,113 +12,125 @@ export class Selector implements ISelector {
16
12
 
17
13
  public config: ISelectorConfig = {}
18
14
 
19
- protected findPath: FindPath
15
+ protected pather: Pather
16
+
17
+
18
+ protected innerIdMap: ILeafMap = {}
19
+ protected idMap: ILeafMap = {}
20
20
 
21
- protected innerIdList: ILeafMap = {}
22
- protected idList: ILeafMap = {}
23
- protected classNameList: ILeafArrayMap = {}
24
- protected tagNameList: ILeafArrayMap = {}
21
+ protected findLeaf: ILeaf
22
+
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
+ }
25
29
 
26
30
  protected __eventIds: IEventListenerId[]
27
31
 
32
+
28
33
  constructor(target: ILeaf, userConfig?: ISelectorConfig) {
29
34
  this.target = target
30
35
  if (userConfig) this.config = DataHelper.default(userConfig, this.config)
31
- this.findPath = new FindPath(target, this)
36
+ this.pather = new Pather(target, this)
32
37
  this.__listenEvents()
33
38
  }
34
39
 
35
40
  public getByPoint(hitPoint: IPointData, hitRadius: number, options?: ISelectPathOptions): ISelectPathResult {
36
41
  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)
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)
49
62
  }
50
63
  }
51
64
 
52
- public getByInnerId(name: number, branch?: ILeaf): ILeaf {
53
- let cache = this.innerIdList[name]
65
+ public getByInnerId(innerId: number, branch?: ILeaf): ILeaf {
66
+ const cache = this.innerIdMap[innerId]
54
67
  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
68
+ this.eachFind(this.toChildren(branch), this.methods.innerId, null, innerId)
69
+ return this.findLeaf
67
70
  }
68
71
 
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
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
84
77
  }
85
78
 
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
79
+ public getByClassName(className: string, branch?: ILeaf): ILeaf[] {
80
+ return this.getByMethod(this.methods.className, branch, false, className) as ILeaf[]
94
81
  }
95
82
 
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
83
+ public getByTag(tag: string, branch?: ILeaf): ILeaf[] {
84
+ return this.getByMethod(this.methods.tag, branch, false, tag) as ILeaf[]
104
85
  }
105
86
 
106
- protected loopFind(branch: ILeaf, find: IFind): void {
107
- if (find(branch)) return
108
- const { children } = branch
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
91
+ }
92
+
93
+
94
+ protected eachFind(children: ILeaf[], method: IFindMethod, list?: ILeaf[], options?: any,): void {
95
+ let child: ILeaf
109
96
  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)
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)
113
107
  }
114
108
  }
115
109
 
110
+ protected toChildren(branch: ILeaf): ILeaf[] {
111
+ this.findLeaf = null
112
+ return [branch || this.target]
113
+ }
114
+
115
+
116
116
  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
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
+ }
120
127
  }
121
128
 
122
129
 
123
130
  protected __listenEvents(): void {
124
131
  this.__eventIds = [
125
- 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)
126
134
  ]
127
135
  }
128
136
 
@@ -134,11 +142,10 @@ export class Selector implements ISelector {
134
142
  public destroy(): void {
135
143
  if (this.__eventIds.length) {
136
144
  this.__removeListenEvents()
137
- this.findPath.destroy()
138
- this.innerIdList = {}
139
- this.idList = {}
140
- this.classNameList = {}
141
- this.tagNameList = {}
145
+ this.pather.destroy()
146
+ this.findLeaf = null
147
+ this.innerIdMap = {}
148
+ this.idMap = {}
142
149
  }
143
150
  }
144
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,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
24
  list: ILeafList;
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) => 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
+ };
34
36
  protected __eventIds: IEventListenerId[];
35
37
  constructor(target: ILeaf, userConfig?: ISelectorConfig);
36
38
  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;
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[];
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;