@chancestv/tv-focus 0.3.0 → 0.4.0
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/dist/index.js +211 -256
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/ATTRIBUTION.md +11 -1
- package/src/engine/spatial-navigation.ts +210 -257
package/dist/index.js
CHANGED
|
@@ -64,278 +64,172 @@ function getRect(elem) {
|
|
|
64
64
|
rect.center.top = rect.center.bottom = rect.center.y;
|
|
65
65
|
return rect;
|
|
66
66
|
}
|
|
67
|
-
function
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}
|
|
80
|
-
if (center.y < targetRect.top) {
|
|
81
|
-
y = 0;
|
|
82
|
-
} else if (center.y <= targetRect.bottom) {
|
|
83
|
-
y = 1;
|
|
84
|
-
} else {
|
|
85
|
-
y = 2;
|
|
86
|
-
}
|
|
87
|
-
groupId = y * 3 + x;
|
|
88
|
-
groups[groupId].push(rect);
|
|
89
|
-
if ([0, 2, 6, 8].indexOf(groupId) !== -1) {
|
|
90
|
-
var threshold = straightOverlapThreshold;
|
|
91
|
-
if (rect.left <= targetRect.right - targetRect.width * threshold) {
|
|
92
|
-
if (groupId === 2) {
|
|
93
|
-
groups[1].push(rect);
|
|
94
|
-
} else if (groupId === 8) {
|
|
95
|
-
groups[7].push(rect);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (rect.right >= targetRect.left + targetRect.width * threshold) {
|
|
99
|
-
if (groupId === 0) {
|
|
100
|
-
groups[1].push(rect);
|
|
101
|
-
} else if (groupId === 6) {
|
|
102
|
-
groups[7].push(rect);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (rect.top <= targetRect.bottom - targetRect.height * threshold) {
|
|
106
|
-
if (groupId === 6) {
|
|
107
|
-
groups[3].push(rect);
|
|
108
|
-
} else if (groupId === 8) {
|
|
109
|
-
groups[5].push(rect);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
if (rect.bottom >= targetRect.top + targetRect.height * threshold) {
|
|
113
|
-
if (groupId === 0) {
|
|
114
|
-
groups[3].push(rect);
|
|
115
|
-
} else if (groupId === 2) {
|
|
116
|
-
groups[5].push(rect);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
67
|
+
function snMajorAxisDistanceRaw(direction, source, dest) {
|
|
68
|
+
switch (direction) {
|
|
69
|
+
case "left":
|
|
70
|
+
return source.left - dest.right;
|
|
71
|
+
case "right":
|
|
72
|
+
return dest.left - source.right;
|
|
73
|
+
case "up":
|
|
74
|
+
return source.top - dest.bottom;
|
|
75
|
+
case "down":
|
|
76
|
+
return dest.top - source.bottom;
|
|
77
|
+
default:
|
|
78
|
+
return 0;
|
|
120
79
|
}
|
|
121
|
-
return groups;
|
|
122
80
|
}
|
|
123
|
-
function
|
|
124
|
-
return
|
|
125
|
-
nearPlumbLineIsBetter: function(rect) {
|
|
126
|
-
var d;
|
|
127
|
-
if (rect.center.x < targetRect.center.x) {
|
|
128
|
-
d = targetRect.center.x - rect.right;
|
|
129
|
-
} else {
|
|
130
|
-
d = rect.left - targetRect.center.x;
|
|
131
|
-
}
|
|
132
|
-
return d < 0 ? 0 : d;
|
|
133
|
-
},
|
|
134
|
-
nearHorizonIsBetter: function(rect) {
|
|
135
|
-
var d;
|
|
136
|
-
if (rect.center.y < targetRect.center.y) {
|
|
137
|
-
d = targetRect.center.y - rect.bottom;
|
|
138
|
-
} else {
|
|
139
|
-
d = rect.top - targetRect.center.y;
|
|
140
|
-
}
|
|
141
|
-
return d < 0 ? 0 : d;
|
|
142
|
-
},
|
|
143
|
-
nearTargetLeftIsBetter: function(rect) {
|
|
144
|
-
var d;
|
|
145
|
-
if (rect.center.x < targetRect.center.x) {
|
|
146
|
-
d = targetRect.left - rect.right;
|
|
147
|
-
} else {
|
|
148
|
-
d = rect.left - targetRect.left;
|
|
149
|
-
}
|
|
150
|
-
return d < 0 ? 0 : d;
|
|
151
|
-
},
|
|
152
|
-
nearTargetTopIsBetter: function(rect) {
|
|
153
|
-
var d;
|
|
154
|
-
if (rect.center.y < targetRect.center.y) {
|
|
155
|
-
d = targetRect.top - rect.bottom;
|
|
156
|
-
} else {
|
|
157
|
-
d = rect.top - targetRect.top;
|
|
158
|
-
}
|
|
159
|
-
return d < 0 ? 0 : d;
|
|
160
|
-
},
|
|
161
|
-
topIsBetter: function(rect) {
|
|
162
|
-
return rect.top;
|
|
163
|
-
},
|
|
164
|
-
bottomIsBetter: function(rect) {
|
|
165
|
-
return -1 * rect.bottom;
|
|
166
|
-
},
|
|
167
|
-
leftIsBetter: function(rect) {
|
|
168
|
-
return rect.left;
|
|
169
|
-
},
|
|
170
|
-
rightIsBetter: function(rect) {
|
|
171
|
-
return -1 * rect.right;
|
|
172
|
-
}
|
|
173
|
-
};
|
|
81
|
+
function snMajorAxisDistance(direction, source, dest) {
|
|
82
|
+
return Math.max(0, snMajorAxisDistanceRaw(direction, source, dest));
|
|
174
83
|
}
|
|
175
|
-
function
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
84
|
+
function snMajorAxisDistanceToFarEdgeRaw(direction, source, dest) {
|
|
85
|
+
switch (direction) {
|
|
86
|
+
case "left":
|
|
87
|
+
return source.left - dest.left;
|
|
88
|
+
case "right":
|
|
89
|
+
return dest.right - source.right;
|
|
90
|
+
case "up":
|
|
91
|
+
return source.top - dest.top;
|
|
92
|
+
case "down":
|
|
93
|
+
return dest.bottom - source.bottom;
|
|
94
|
+
default:
|
|
95
|
+
return 0;
|
|
182
96
|
}
|
|
183
|
-
|
|
184
|
-
|
|
97
|
+
}
|
|
98
|
+
function snMajorAxisDistanceToFarEdge(direction, source, dest) {
|
|
99
|
+
return Math.max(1, snMajorAxisDistanceToFarEdgeRaw(direction, source, dest));
|
|
100
|
+
}
|
|
101
|
+
function snMinorAxisDistance(direction, source, dest) {
|
|
102
|
+
switch (direction) {
|
|
103
|
+
case "left":
|
|
104
|
+
case "right":
|
|
105
|
+
return Math.abs(source.center.y - dest.center.y);
|
|
106
|
+
case "up":
|
|
107
|
+
case "down":
|
|
108
|
+
return Math.abs(source.center.x - dest.center.x);
|
|
109
|
+
default:
|
|
110
|
+
return 0;
|
|
185
111
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
112
|
+
}
|
|
113
|
+
function snGetWeightedDistanceFor(major, minor) {
|
|
114
|
+
return 13 * major * major + minor * minor;
|
|
115
|
+
}
|
|
116
|
+
function snIsToDirectionOf(direction, source, dest) {
|
|
117
|
+
switch (direction) {
|
|
118
|
+
case "left":
|
|
119
|
+
return source.left >= dest.right;
|
|
120
|
+
case "right":
|
|
121
|
+
return source.right <= dest.left;
|
|
122
|
+
case "up":
|
|
123
|
+
return source.top >= dest.bottom;
|
|
124
|
+
case "down":
|
|
125
|
+
return source.bottom <= dest.top;
|
|
126
|
+
default:
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
function snIsCandidate(source, dest, direction) {
|
|
131
|
+
switch (direction) {
|
|
132
|
+
case "left":
|
|
133
|
+
return (source.right > dest.right || source.left >= dest.right) && source.left > dest.left;
|
|
134
|
+
case "right":
|
|
135
|
+
return (source.left < dest.left || source.right <= dest.left) && source.right < dest.right;
|
|
136
|
+
case "up":
|
|
137
|
+
return (source.bottom > dest.bottom || source.top >= dest.bottom) && source.top > dest.top;
|
|
138
|
+
case "down":
|
|
139
|
+
return (source.top < dest.top || source.bottom <= dest.top) && source.bottom < dest.bottom;
|
|
140
|
+
default:
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function snBeamsOverlap(direction, rect1, rect2) {
|
|
145
|
+
switch (direction) {
|
|
146
|
+
case "left":
|
|
147
|
+
case "right":
|
|
148
|
+
return rect2.bottom >= rect1.top && rect2.top <= rect1.bottom;
|
|
149
|
+
case "up":
|
|
150
|
+
case "down":
|
|
151
|
+
return rect2.right >= rect1.left && rect2.left <= rect1.right;
|
|
152
|
+
default:
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
function snBeamBeats(direction, source, rect1, rect2) {
|
|
157
|
+
var r1In = snBeamsOverlap(direction, source, rect1);
|
|
158
|
+
var r2In = snBeamsOverlap(direction, source, rect2);
|
|
159
|
+
if (r2In || !r1In) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
if (!snIsToDirectionOf(direction, source, rect2)) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
if (direction === "left" || direction === "right") {
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
return snMajorAxisDistance(direction, source, rect1) < snMajorAxisDistanceToFarEdge(direction, source, rect2);
|
|
169
|
+
}
|
|
170
|
+
function snIsBetterCandidate(direction, source, rect1, rect2) {
|
|
171
|
+
if (!snIsCandidate(source, rect1, direction)) {
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
if (!snIsCandidate(source, rect2, direction)) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
if (snBeamBeats(direction, source, rect1, rect2)) {
|
|
178
|
+
return true;
|
|
179
|
+
}
|
|
180
|
+
if (snBeamBeats(direction, source, rect2, rect1)) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return snGetWeightedDistanceFor(
|
|
184
|
+
snMajorAxisDistance(direction, source, rect1),
|
|
185
|
+
snMinorAxisDistance(direction, source, rect1)
|
|
186
|
+
) < snGetWeightedDistanceFor(
|
|
187
|
+
snMajorAxisDistance(direction, source, rect2),
|
|
188
|
+
snMinorAxisDistance(direction, source, rect2)
|
|
189
|
+
);
|
|
198
190
|
}
|
|
199
191
|
function navigate(target, direction, candidates, config, preferNearest) {
|
|
200
192
|
if (!target || !direction || !candidates || !candidates.length) {
|
|
201
193
|
return null;
|
|
202
194
|
}
|
|
195
|
+
var targetRect = getRect(target);
|
|
196
|
+
if (!targetRect) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
203
199
|
var rects = [];
|
|
204
200
|
for (var i = 0; i < candidates.length; i++) {
|
|
205
|
-
var
|
|
206
|
-
if (
|
|
207
|
-
|
|
201
|
+
var r = getRect(candidates[i]);
|
|
202
|
+
if (!r) {
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
if (!snIsCandidate(targetRect, r, direction)) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
if (config.straightOnly && !snBeamsOverlap(direction, targetRect, r)) {
|
|
209
|
+
continue;
|
|
208
210
|
}
|
|
211
|
+
rects.push(r);
|
|
209
212
|
}
|
|
210
213
|
if (!rects.length) {
|
|
211
214
|
return null;
|
|
212
215
|
}
|
|
213
|
-
var
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
var distanceFunction = generateDistanceFunction(targetRect);
|
|
218
|
-
var groups = partition(
|
|
219
|
-
rects,
|
|
220
|
-
targetRect,
|
|
221
|
-
config.straightOverlapThreshold
|
|
222
|
-
);
|
|
223
|
-
var internalGroups = partition(
|
|
224
|
-
groups[4],
|
|
225
|
-
targetRect.center,
|
|
226
|
-
config.straightOverlapThreshold
|
|
227
|
-
);
|
|
228
|
-
var priorities;
|
|
229
|
-
var df = distanceFunction;
|
|
230
|
-
var internalGroup, straightGroup, diagonalGroups;
|
|
231
|
-
var internalDist, straightDist, diagonalDist, mergedDist;
|
|
232
|
-
switch (direction) {
|
|
233
|
-
case "left":
|
|
234
|
-
internalGroup = internalGroups[0].concat(internalGroups[3]).concat(internalGroups[6]);
|
|
235
|
-
straightGroup = groups[3];
|
|
236
|
-
diagonalGroups = groups[0].concat(groups[6]);
|
|
237
|
-
internalDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
|
|
238
|
-
straightDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
|
|
239
|
-
diagonalDist = [
|
|
240
|
-
df.nearHorizonIsBetter,
|
|
241
|
-
df.rightIsBetter,
|
|
242
|
-
df.nearTargetTopIsBetter
|
|
243
|
-
];
|
|
244
|
-
mergedDist = [
|
|
245
|
-
df.nearPlumbLineIsBetter,
|
|
246
|
-
df.nearHorizonIsBetter,
|
|
247
|
-
df.topIsBetter
|
|
248
|
-
];
|
|
249
|
-
break;
|
|
250
|
-
case "right":
|
|
251
|
-
internalGroup = internalGroups[2].concat(internalGroups[5]).concat(internalGroups[8]);
|
|
252
|
-
straightGroup = groups[5];
|
|
253
|
-
diagonalGroups = groups[2].concat(groups[8]);
|
|
254
|
-
internalDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
|
|
255
|
-
straightDist = [df.nearPlumbLineIsBetter, df.topIsBetter];
|
|
256
|
-
diagonalDist = [
|
|
257
|
-
df.nearHorizonIsBetter,
|
|
258
|
-
df.leftIsBetter,
|
|
259
|
-
df.nearTargetTopIsBetter
|
|
260
|
-
];
|
|
261
|
-
mergedDist = [
|
|
262
|
-
df.nearPlumbLineIsBetter,
|
|
263
|
-
df.nearHorizonIsBetter,
|
|
264
|
-
df.topIsBetter
|
|
265
|
-
];
|
|
266
|
-
break;
|
|
267
|
-
case "up":
|
|
268
|
-
internalGroup = internalGroups[0].concat(internalGroups[1]).concat(internalGroups[2]);
|
|
269
|
-
straightGroup = groups[1];
|
|
270
|
-
diagonalGroups = groups[0].concat(groups[2]);
|
|
271
|
-
internalDist = [df.nearHorizonIsBetter, df.leftIsBetter];
|
|
272
|
-
straightDist = [df.nearHorizonIsBetter, df.leftIsBetter];
|
|
273
|
-
diagonalDist = [
|
|
274
|
-
df.nearPlumbLineIsBetter,
|
|
275
|
-
df.bottomIsBetter,
|
|
276
|
-
df.nearTargetLeftIsBetter
|
|
277
|
-
];
|
|
278
|
-
mergedDist = [
|
|
279
|
-
df.nearHorizonIsBetter,
|
|
280
|
-
df.nearPlumbLineIsBetter,
|
|
281
|
-
df.leftIsBetter
|
|
282
|
-
];
|
|
283
|
-
break;
|
|
284
|
-
case "down":
|
|
285
|
-
internalGroup = internalGroups[6].concat(internalGroups[7]).concat(internalGroups[8]);
|
|
286
|
-
straightGroup = groups[7];
|
|
287
|
-
diagonalGroups = groups[6].concat(groups[8]);
|
|
288
|
-
internalDist = [df.nearHorizonIsBetter, df.leftIsBetter];
|
|
289
|
-
straightDist = [df.nearHorizonIsBetter, df.leftIsBetter];
|
|
290
|
-
diagonalDist = [
|
|
291
|
-
df.nearPlumbLineIsBetter,
|
|
292
|
-
df.topIsBetter,
|
|
293
|
-
df.nearTargetLeftIsBetter
|
|
294
|
-
];
|
|
295
|
-
mergedDist = [
|
|
296
|
-
df.nearHorizonIsBetter,
|
|
297
|
-
df.nearPlumbLineIsBetter,
|
|
298
|
-
df.leftIsBetter
|
|
299
|
-
];
|
|
300
|
-
break;
|
|
301
|
-
default:
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
if (preferNearest) {
|
|
305
|
-
priorities = [
|
|
306
|
-
{ group: internalGroup, distance: internalDist },
|
|
307
|
-
{
|
|
308
|
-
group: config.straightOnly ? straightGroup : straightGroup.concat(diagonalGroups),
|
|
309
|
-
distance: mergedDist
|
|
310
|
-
}
|
|
311
|
-
];
|
|
312
|
-
} else {
|
|
313
|
-
priorities = [
|
|
314
|
-
{ group: internalGroup, distance: internalDist },
|
|
315
|
-
{ group: straightGroup, distance: straightDist },
|
|
316
|
-
{ group: diagonalGroups, distance: diagonalDist }
|
|
317
|
-
];
|
|
318
|
-
if (config.straightOnly) {
|
|
319
|
-
priorities.pop();
|
|
216
|
+
var best = rects[0];
|
|
217
|
+
for (var k = 1; k < rects.length; k++) {
|
|
218
|
+
if (snIsBetterCandidate(direction, targetRect, rects[k], best)) {
|
|
219
|
+
best = rects[k];
|
|
320
220
|
}
|
|
321
221
|
}
|
|
322
|
-
var destGroup = prioritize(priorities);
|
|
323
|
-
if (!destGroup) {
|
|
324
|
-
return null;
|
|
325
|
-
}
|
|
326
|
-
var dest = null;
|
|
327
222
|
if (config.rememberSource && config.previous && config.previous.destination === target && config.previous.reverse === direction) {
|
|
328
|
-
for (var j = 0; j <
|
|
329
|
-
if (
|
|
330
|
-
|
|
223
|
+
for (var j = 0; j < rects.length; j++) {
|
|
224
|
+
if (rects[j].element === config.previous.target) {
|
|
225
|
+
if (!snIsBetterCandidate(direction, targetRect, best, rects[j])) {
|
|
226
|
+
return rects[j].element;
|
|
227
|
+
}
|
|
331
228
|
break;
|
|
332
229
|
}
|
|
333
230
|
}
|
|
334
231
|
}
|
|
335
|
-
|
|
336
|
-
dest = destGroup[0].element;
|
|
337
|
-
}
|
|
338
|
-
return dest;
|
|
232
|
+
return best.element;
|
|
339
233
|
}
|
|
340
234
|
function generateId() {
|
|
341
235
|
var id;
|
|
@@ -615,7 +509,7 @@ function getScrollScope(elem) {
|
|
|
615
509
|
}
|
|
616
510
|
function navigateWithinScrollScope(target, direction, candidates, config, preferNearest) {
|
|
617
511
|
if (!candidates || candidates.length < 2) {
|
|
618
|
-
return navigate(target, direction, candidates, config
|
|
512
|
+
return navigate(target, direction, candidates, config);
|
|
619
513
|
}
|
|
620
514
|
var targetScope = getScrollScope(target);
|
|
621
515
|
var inScope = [];
|
|
@@ -628,9 +522,60 @@ function navigateWithinScrollScope(target, direction, candidates, config, prefer
|
|
|
628
522
|
}
|
|
629
523
|
}
|
|
630
524
|
if (inScope.length && outScope.length) {
|
|
631
|
-
return navigate(target, direction, inScope, config
|
|
525
|
+
return navigate(target, direction, inScope, config) || navigate(target, direction, outScope, config);
|
|
526
|
+
}
|
|
527
|
+
return navigate(target, direction, candidates, config);
|
|
528
|
+
}
|
|
529
|
+
function filterCandidatesByDirection(source, direction, sectionNavMap, excludeSectionId) {
|
|
530
|
+
var srcRect = getRect(source);
|
|
531
|
+
var kept = [];
|
|
532
|
+
for (var id in sectionNavMap) {
|
|
533
|
+
if (id === excludeSectionId) {
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
var elems = sectionNavMap[id];
|
|
537
|
+
if (!elems || !elems.length) {
|
|
538
|
+
continue;
|
|
539
|
+
}
|
|
540
|
+
var left = Infinity, top = Infinity, right = -Infinity, bottom = -Infinity;
|
|
541
|
+
var rects = [];
|
|
542
|
+
for (var i = 0; i < elems.length; i++) {
|
|
543
|
+
var r = getRect(elems[i]);
|
|
544
|
+
if (!r) {
|
|
545
|
+
continue;
|
|
546
|
+
}
|
|
547
|
+
rects.push(r);
|
|
548
|
+
if (r.left < left) {
|
|
549
|
+
left = r.left;
|
|
550
|
+
}
|
|
551
|
+
if (r.top < top) {
|
|
552
|
+
top = r.top;
|
|
553
|
+
}
|
|
554
|
+
if (r.right > right) {
|
|
555
|
+
right = r.right;
|
|
556
|
+
}
|
|
557
|
+
if (r.bottom > bottom) {
|
|
558
|
+
bottom = r.bottom;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
if (!rects.length) {
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
var unionRect = {
|
|
565
|
+
left,
|
|
566
|
+
top,
|
|
567
|
+
right,
|
|
568
|
+
bottom,
|
|
569
|
+
width: right - left,
|
|
570
|
+
height: bottom - top
|
|
571
|
+
};
|
|
572
|
+
if (snIsCandidate(srcRect, unionRect, direction)) {
|
|
573
|
+
for (var j = 0; j < rects.length; j++) {
|
|
574
|
+
kept.push(rects[j].element);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
632
577
|
}
|
|
633
|
-
return
|
|
578
|
+
return kept;
|
|
634
579
|
}
|
|
635
580
|
function focusNext(direction, currentFocusedElement, currentSectionId) {
|
|
636
581
|
var extSelector = currentFocusedElement.getAttribute("data-sn-" + direction);
|
|
@@ -658,12 +603,23 @@ function focusNext(direction, currentFocusedElement, currentSectionId) {
|
|
|
658
603
|
config
|
|
659
604
|
);
|
|
660
605
|
if (!next && config.restrict == "self-first") {
|
|
606
|
+
var prunedCandidates = filterCandidatesByDirection(
|
|
607
|
+
currentFocusedElement,
|
|
608
|
+
direction,
|
|
609
|
+
sectionNavigableElements,
|
|
610
|
+
currentSectionId
|
|
611
|
+
);
|
|
612
|
+
if (!prunedCandidates.length) {
|
|
613
|
+
prunedCandidates = exclude(
|
|
614
|
+
allNavigableElements,
|
|
615
|
+
currentSectionNavigableElements
|
|
616
|
+
);
|
|
617
|
+
}
|
|
661
618
|
next = navigateWithinScrollScope(
|
|
662
619
|
currentFocusedElement,
|
|
663
620
|
direction,
|
|
664
|
-
|
|
665
|
-
config
|
|
666
|
-
true
|
|
621
|
+
prunedCandidates,
|
|
622
|
+
config
|
|
667
623
|
);
|
|
668
624
|
}
|
|
669
625
|
} else {
|
|
@@ -671,8 +627,7 @@ function focusNext(direction, currentFocusedElement, currentSectionId) {
|
|
|
671
627
|
currentFocusedElement,
|
|
672
628
|
direction,
|
|
673
629
|
exclude(allNavigableElements, currentFocusedElement),
|
|
674
|
-
config
|
|
675
|
-
false
|
|
630
|
+
config
|
|
676
631
|
);
|
|
677
632
|
}
|
|
678
633
|
if (next) {
|