rdoc 6.17.0 → 7.0.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.
- checksums.yaml +4 -4
- data/CONTRIBUTING.md +187 -0
- data/LEGAL.rdoc +6 -0
- data/README.md +20 -3
- data/lib/rdoc/code_object/any_method.rb +15 -7
- data/lib/rdoc/code_object/class_module.rb +13 -0
- data/lib/rdoc/code_object/constant.rb +9 -0
- data/lib/rdoc/code_object/method_attr.rb +13 -1
- data/lib/rdoc/code_object/top_level.rb +13 -1
- data/lib/rdoc/generator/aliki.rb +124 -0
- data/lib/rdoc/generator/template/aliki/_head.rhtml +4 -4
- data/lib/rdoc/generator/template/aliki/class.rhtml +3 -5
- data/lib/rdoc/generator/template/aliki/css/rdoc.css +217 -10
- data/lib/rdoc/generator/template/aliki/js/aliki.js +18 -3
- data/lib/rdoc/generator/template/aliki/js/{search.js → search_controller.js} +6 -6
- data/lib/rdoc/generator/template/aliki/js/search_navigation.js +105 -0
- data/lib/rdoc/generator/template/aliki/js/search_ranker.js +239 -0
- data/lib/rdoc/generator/template/darkfish/class.rhtml +3 -5
- data/lib/rdoc/options.rb +1 -1
- data/lib/rdoc/rubygems_hook.rb +3 -3
- data/lib/rdoc/version.rb +1 -1
- data/rdoc.gemspec +1 -1
- metadata +8 -6
- data/CONTRIBUTING.rdoc +0 -219
|
@@ -85,6 +85,16 @@
|
|
|
85
85
|
--color-th-background: var(--color-neutral-100);
|
|
86
86
|
--color-td-background: var(--color-neutral-50);
|
|
87
87
|
|
|
88
|
+
/* Search Type Badge Colors */
|
|
89
|
+
--color-search-type-class-bg: #e6f0ff;
|
|
90
|
+
--color-search-type-class-text: #0050a0;
|
|
91
|
+
--color-search-type-module-bg: #e6ffe6;
|
|
92
|
+
--color-search-type-module-text: #060;
|
|
93
|
+
--color-search-type-constant-bg: #fff0e6;
|
|
94
|
+
--color-search-type-constant-text: #995200;
|
|
95
|
+
--color-search-type-method-bg: #f0e6ff;
|
|
96
|
+
--color-search-type-method-text: #5200a0;
|
|
97
|
+
|
|
88
98
|
/* RGBA Colors (theme-agnostic) */
|
|
89
99
|
--color-overlay: rgb(0 0 0 / 50%);
|
|
90
100
|
--color-emphasis-bg: rgb(255 111 97 / 10%);
|
|
@@ -142,6 +152,7 @@
|
|
|
142
152
|
|
|
143
153
|
/* Shadows */
|
|
144
154
|
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 10%), 0 1px 2px -1px rgb(0 0 0 / 10%);
|
|
155
|
+
--shadow-md: 0 2px 8px rgb(0 0 0 / 10%);
|
|
145
156
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 10%), 0 4px 6px -4px rgb(0 0 0 / 10%);
|
|
146
157
|
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 10%), 0 8px 10px -6px rgb(0 0 0 / 10%);
|
|
147
158
|
|
|
@@ -158,6 +169,13 @@
|
|
|
158
169
|
/* Transitions */
|
|
159
170
|
--transition-fast: 150ms ease-in-out;
|
|
160
171
|
--transition-base: 200ms ease-in-out;
|
|
172
|
+
--transition-slow: 350ms ease-in-out;
|
|
173
|
+
--ease-out-smooth: cubic-bezier(0.4, 0, 0.2, 1);
|
|
174
|
+
|
|
175
|
+
/* Animation Durations */
|
|
176
|
+
--duration-fast: 250ms;
|
|
177
|
+
--duration-base: 300ms;
|
|
178
|
+
--duration-medium: 350ms;
|
|
161
179
|
|
|
162
180
|
/* Z-Index Scale */
|
|
163
181
|
--z-fixed: 300;
|
|
@@ -202,6 +220,7 @@
|
|
|
202
220
|
--color-accent-primary: var(--color-primary-500);
|
|
203
221
|
--color-accent-hover: var(--color-primary-400);
|
|
204
222
|
--color-accent-subtle: rgb(235 84 79 / 10%);
|
|
223
|
+
--color-accent-subtle-hover: rgb(235 84 79 / 20%);
|
|
205
224
|
--color-code-bg: var(--color-neutral-800);
|
|
206
225
|
--color-code-border: var(--color-neutral-700);
|
|
207
226
|
--color-nav-bg: var(--color-neutral-900);
|
|
@@ -209,8 +228,19 @@
|
|
|
209
228
|
--color-th-background: var(--color-background-tertiary);
|
|
210
229
|
--color-td-background: var(--color-background-secondary);
|
|
211
230
|
|
|
231
|
+
/* Search Type Badge Colors - Dark Theme */
|
|
232
|
+
--color-search-type-class-bg: #1e3a5f;
|
|
233
|
+
--color-search-type-class-text: #93c5fd;
|
|
234
|
+
--color-search-type-module-bg: #14532d;
|
|
235
|
+
--color-search-type-module-text: #86efac;
|
|
236
|
+
--color-search-type-constant-bg: #451a03;
|
|
237
|
+
--color-search-type-constant-text: #fcd34d;
|
|
238
|
+
--color-search-type-method-bg: #3b0764;
|
|
239
|
+
--color-search-type-method-text: #d8b4fe;
|
|
240
|
+
|
|
212
241
|
/* Dark theme shadows (slightly more subtle) */
|
|
213
242
|
--shadow-sm: 0 1px 3px 0 rgb(0 0 0 / 40%), 0 1px 2px -1px rgb(0 0 0 / 40%);
|
|
243
|
+
--shadow-md: 0 2px 8px rgb(0 0 0 / 40%);
|
|
214
244
|
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 40%), 0 4px 6px -4px rgb(0 0 0 / 40%);
|
|
215
245
|
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 40%), 0 8px 10px -6px rgb(0 0 0 / 40%);
|
|
216
246
|
|
|
@@ -291,7 +321,12 @@ pre {
|
|
|
291
321
|
border-radius: var(--radius-sm);
|
|
292
322
|
cursor: pointer;
|
|
293
323
|
opacity: 0.6;
|
|
294
|
-
transition:
|
|
324
|
+
transition:
|
|
325
|
+
opacity var(--transition-fast),
|
|
326
|
+
background var(--transition-fast),
|
|
327
|
+
border-color var(--transition-fast),
|
|
328
|
+
transform var(--transition-fast),
|
|
329
|
+
box-shadow var(--transition-fast);
|
|
295
330
|
display: flex;
|
|
296
331
|
align-items: center;
|
|
297
332
|
justify-content: center;
|
|
@@ -305,10 +340,18 @@ pre {
|
|
|
305
340
|
opacity: 1;
|
|
306
341
|
background: var(--color-background-tertiary);
|
|
307
342
|
border-color: var(--color-border-emphasis);
|
|
343
|
+
transform: translateY(-1px);
|
|
344
|
+
box-shadow: var(--shadow-md);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
.copy-code-button:focus {
|
|
348
|
+
outline: none;
|
|
349
|
+
box-shadow: 0 0 0 3px var(--color-accent-subtle);
|
|
308
350
|
}
|
|
309
351
|
|
|
310
352
|
.copy-code-button:active {
|
|
311
|
-
transform: scale(0.
|
|
353
|
+
transform: scale(0.92);
|
|
354
|
+
box-shadow: none;
|
|
312
355
|
}
|
|
313
356
|
|
|
314
357
|
.copy-code-button svg {
|
|
@@ -320,7 +363,7 @@ pre {
|
|
|
320
363
|
stroke-linecap: round;
|
|
321
364
|
stroke-linejoin: round;
|
|
322
365
|
color: var(--color-text-secondary);
|
|
323
|
-
transition: color var(--transition-fast);
|
|
366
|
+
transition: color var(--transition-fast), transform var(--transition-base);
|
|
324
367
|
}
|
|
325
368
|
|
|
326
369
|
.copy-code-button:hover svg {
|
|
@@ -457,7 +500,11 @@ header.top-navbar .navbar-search form {
|
|
|
457
500
|
border-radius: var(--radius-md);
|
|
458
501
|
color: var(--color-text-primary);
|
|
459
502
|
cursor: pointer;
|
|
460
|
-
transition:
|
|
503
|
+
transition:
|
|
504
|
+
background var(--transition-fast),
|
|
505
|
+
border-color var(--transition-fast),
|
|
506
|
+
color var(--transition-fast),
|
|
507
|
+
transform var(--transition-fast);
|
|
461
508
|
font-size: var(--font-size-lg);
|
|
462
509
|
line-height: 1;
|
|
463
510
|
width: 2.5rem;
|
|
@@ -468,6 +515,7 @@ header.top-navbar .navbar-search form {
|
|
|
468
515
|
background: var(--color-background-secondary);
|
|
469
516
|
border-color: var(--color-accent-primary);
|
|
470
517
|
color: var(--color-accent-primary);
|
|
518
|
+
transform: scale(1.05);
|
|
471
519
|
}
|
|
472
520
|
|
|
473
521
|
.theme-toggle:focus {
|
|
@@ -476,13 +524,17 @@ header.top-navbar .navbar-search form {
|
|
|
476
524
|
box-shadow: 0 0 0 3px var(--color-accent-subtle);
|
|
477
525
|
}
|
|
478
526
|
|
|
527
|
+
.theme-toggle:active {
|
|
528
|
+
transform: scale(0.95);
|
|
529
|
+
}
|
|
530
|
+
|
|
479
531
|
.theme-toggle-icon {
|
|
480
532
|
display: inline-block;
|
|
481
|
-
transition: transform var(--
|
|
533
|
+
transition: transform var(--duration-base) var(--ease-out-smooth);
|
|
482
534
|
}
|
|
483
535
|
|
|
484
536
|
.theme-toggle:hover .theme-toggle-icon {
|
|
485
|
-
transform: rotate(
|
|
537
|
+
transform: rotate(15deg) scale(1.1);
|
|
486
538
|
}
|
|
487
539
|
|
|
488
540
|
/* Mobile navbar */
|
|
@@ -537,11 +589,33 @@ nav {
|
|
|
537
589
|
background: var(--color-nav-bg);
|
|
538
590
|
color: var(--color-nav-text);
|
|
539
591
|
overflow: hidden auto;
|
|
592
|
+
overscroll-behavior: contain;
|
|
540
593
|
display: flex;
|
|
541
594
|
flex-direction: column;
|
|
542
595
|
position: sticky;
|
|
543
596
|
top: var(--layout-header-height);
|
|
544
597
|
height: calc(100vh - var(--layout-header-height));
|
|
598
|
+
scrollbar-width: thin;
|
|
599
|
+
scrollbar-color: var(--color-border-default) transparent;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/* Custom scrollbar for WebKit browsers */
|
|
603
|
+
nav::-webkit-scrollbar {
|
|
604
|
+
width: 6px;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
nav::-webkit-scrollbar-track {
|
|
608
|
+
background: transparent;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
nav::-webkit-scrollbar-thumb {
|
|
612
|
+
background: var(--color-border-default);
|
|
613
|
+
border-radius: var(--radius-sm);
|
|
614
|
+
transition: background var(--transition-fast);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
nav::-webkit-scrollbar-thumb:hover {
|
|
618
|
+
background: var(--color-border-emphasis);
|
|
545
619
|
}
|
|
546
620
|
|
|
547
621
|
/* Mobile navigation */
|
|
@@ -615,6 +689,18 @@ nav ul li {
|
|
|
615
689
|
line-height: var(--line-height-relaxed);
|
|
616
690
|
}
|
|
617
691
|
|
|
692
|
+
nav ul li a {
|
|
693
|
+
padding: var(--space-1) 0;
|
|
694
|
+
transition:
|
|
695
|
+
color var(--transition-fast),
|
|
696
|
+
transform var(--transition-fast),
|
|
697
|
+
padding var(--transition-fast);
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
nav ul li a:hover {
|
|
701
|
+
padding-left: var(--space-1);
|
|
702
|
+
}
|
|
703
|
+
|
|
618
704
|
nav ul ul {
|
|
619
705
|
padding-left: var(--space-5);
|
|
620
706
|
margin-top: var(--space-2);
|
|
@@ -632,6 +718,17 @@ nav a {
|
|
|
632
718
|
text-decoration: none;
|
|
633
719
|
}
|
|
634
720
|
|
|
721
|
+
/* Truncation for direct nav links (not links inside code tags) */
|
|
722
|
+
nav .nav-list > li > a,
|
|
723
|
+
nav .nav-section > ul > li > a,
|
|
724
|
+
nav .nav-section > dl > dd > a {
|
|
725
|
+
display: block;
|
|
726
|
+
max-width: 100%;
|
|
727
|
+
overflow: hidden;
|
|
728
|
+
text-overflow: ellipsis;
|
|
729
|
+
white-space: nowrap;
|
|
730
|
+
}
|
|
731
|
+
|
|
635
732
|
nav footer {
|
|
636
733
|
padding: var(--space-4);
|
|
637
734
|
border-top: 1px solid var(--color-border-default);
|
|
@@ -735,6 +832,11 @@ nav .nav-section-title {
|
|
|
735
832
|
font-size: var(--font-size-base);
|
|
736
833
|
font-weight: var(--font-weight-semibold);
|
|
737
834
|
color: inherit;
|
|
835
|
+
flex: 1;
|
|
836
|
+
min-width: 0;
|
|
837
|
+
overflow: hidden;
|
|
838
|
+
text-overflow: ellipsis;
|
|
839
|
+
white-space: nowrap;
|
|
738
840
|
}
|
|
739
841
|
|
|
740
842
|
nav .nav-section-chevron {
|
|
@@ -1113,19 +1215,54 @@ main .anchor-link:target {
|
|
|
1113
1215
|
main .method-source-code {
|
|
1114
1216
|
visibility: hidden;
|
|
1115
1217
|
max-height: 0;
|
|
1116
|
-
overflow:
|
|
1117
|
-
|
|
1218
|
+
overflow: hidden;
|
|
1219
|
+
opacity: 0;
|
|
1220
|
+
transform: translateY(-8px);
|
|
1221
|
+
transition:
|
|
1222
|
+
max-height var(--duration-medium) var(--ease-out-smooth),
|
|
1223
|
+
visibility var(--duration-medium),
|
|
1224
|
+
opacity var(--duration-fast) ease-out,
|
|
1225
|
+
transform var(--duration-fast) ease-out;
|
|
1118
1226
|
}
|
|
1119
1227
|
|
|
1120
1228
|
main .method-source-code pre {
|
|
1121
1229
|
border-color: var(--color-accent-hover);
|
|
1230
|
+
border-left: 3px solid var(--color-accent-primary);
|
|
1122
1231
|
width: 100%;
|
|
1123
1232
|
box-sizing: border-box;
|
|
1233
|
+
transition: border-color var(--transition-fast);
|
|
1234
|
+
scrollbar-width: thin;
|
|
1235
|
+
scrollbar-color: var(--color-border-default) transparent;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
main .method-source-code pre::-webkit-scrollbar {
|
|
1239
|
+
width: 6px;
|
|
1240
|
+
height: 6px;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
main .method-source-code pre::-webkit-scrollbar-track {
|
|
1244
|
+
background: transparent;
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
main .method-source-code pre::-webkit-scrollbar-thumb {
|
|
1248
|
+
background: var(--color-border-default);
|
|
1249
|
+
border-radius: var(--radius-sm);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
main .method-source-code pre::-webkit-scrollbar-thumb:hover {
|
|
1253
|
+
background: var(--color-border-emphasis);
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
main .method-source-code pre::-webkit-scrollbar-corner {
|
|
1257
|
+
background: transparent;
|
|
1124
1258
|
}
|
|
1125
1259
|
|
|
1126
1260
|
main .method-source-code.active-menu {
|
|
1127
1261
|
visibility: visible;
|
|
1128
1262
|
max-height: 100vh;
|
|
1263
|
+
overflow: auto;
|
|
1264
|
+
opacity: 1;
|
|
1265
|
+
transform: translateY(0);
|
|
1129
1266
|
}
|
|
1130
1267
|
|
|
1131
1268
|
main .method-description .method-calls-super {
|
|
@@ -1165,10 +1302,47 @@ main .method-heading .method-args {
|
|
|
1165
1302
|
}
|
|
1166
1303
|
|
|
1167
1304
|
main .method-controls {
|
|
1168
|
-
line-height: 20px;
|
|
1169
1305
|
float: right;
|
|
1170
|
-
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
main .method-controls summary {
|
|
1309
|
+
display: inline-block;
|
|
1310
|
+
line-height: 20px;
|
|
1311
|
+
color: var(--color-accent-primary);
|
|
1171
1312
|
cursor: pointer;
|
|
1313
|
+
padding: var(--space-1) var(--space-3);
|
|
1314
|
+
border-radius: var(--radius-sm);
|
|
1315
|
+
font-size: var(--font-size-sm);
|
|
1316
|
+
font-weight: var(--font-weight-medium);
|
|
1317
|
+
background: var(--color-accent-subtle);
|
|
1318
|
+
border: 1px solid transparent;
|
|
1319
|
+
transition:
|
|
1320
|
+
color var(--transition-fast),
|
|
1321
|
+
background var(--transition-fast),
|
|
1322
|
+
border-color var(--transition-fast),
|
|
1323
|
+
transform var(--transition-fast);
|
|
1324
|
+
user-select: none;
|
|
1325
|
+
-webkit-user-select: none;
|
|
1326
|
+
list-style: none;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
main .method-controls summary::-webkit-details-marker {
|
|
1330
|
+
display: none;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
main .method-controls summary:hover {
|
|
1334
|
+
background: var(--color-primary-100);
|
|
1335
|
+
border-color: var(--color-primary-300);
|
|
1336
|
+
transform: translateY(-1px);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
main .method-controls summary:active {
|
|
1340
|
+
transform: scale(0.96);
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
[data-theme="dark"] main .method-controls summary:hover {
|
|
1344
|
+
background: var(--color-accent-subtle-hover);
|
|
1345
|
+
border-color: var(--color-primary-500);
|
|
1172
1346
|
}
|
|
1173
1347
|
|
|
1174
1348
|
main .method-description,
|
|
@@ -1680,6 +1854,39 @@ footer.site-footer .footer-bottom:first-child {
|
|
|
1680
1854
|
font-weight: bold;
|
|
1681
1855
|
}
|
|
1682
1856
|
|
|
1857
|
+
#search-results .search-type {
|
|
1858
|
+
display: inline-block;
|
|
1859
|
+
margin-left: var(--space-2);
|
|
1860
|
+
padding: 0 var(--space-2);
|
|
1861
|
+
font-size: var(--font-size-xs);
|
|
1862
|
+
font-weight: 500;
|
|
1863
|
+
border-radius: var(--radius-sm);
|
|
1864
|
+
vertical-align: middle;
|
|
1865
|
+
background: var(--color-background-tertiary);
|
|
1866
|
+
color: var(--color-text-secondary);
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
#search-results .search-type-class {
|
|
1870
|
+
background: var(--color-search-type-class-bg);
|
|
1871
|
+
color: var(--color-search-type-class-text);
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
#search-results .search-type-module {
|
|
1875
|
+
background: var(--color-search-type-module-bg);
|
|
1876
|
+
color: var(--color-search-type-module-text);
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
#search-results .search-type-constant {
|
|
1880
|
+
background: var(--color-search-type-constant-bg);
|
|
1881
|
+
color: var(--color-search-type-constant-text);
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
#search-results .search-type-instance-method,
|
|
1885
|
+
#search-results .search-type-class-method {
|
|
1886
|
+
background: var(--color-search-type-method-bg);
|
|
1887
|
+
color: var(--color-search-type-method-text);
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1683
1890
|
#search-results li em {
|
|
1684
1891
|
background-color: var(--color-search-highlight-bg);
|
|
1685
1892
|
font-style: normal;
|
|
@@ -28,7 +28,7 @@ function createSearchInstance(input, result) {
|
|
|
28
28
|
|
|
29
29
|
result.classList.remove("initially-hidden");
|
|
30
30
|
|
|
31
|
-
const search = new
|
|
31
|
+
const search = new SearchController(search_data, input, result);
|
|
32
32
|
|
|
33
33
|
search.renderItem = function(result) {
|
|
34
34
|
const li = document.createElement('li');
|
|
@@ -40,8 +40,12 @@ function createSearchInstance(input, result) {
|
|
|
40
40
|
html += `<span class="params">${result.params}</span>`;
|
|
41
41
|
html += '</a>';
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
// Add type indicator
|
|
44
|
+
if (result.type) {
|
|
45
|
+
const typeLabel = this.formatType(result.type);
|
|
46
|
+
const typeClass = result.type.replace(/_/g, '-');
|
|
47
|
+
html += `<span class="search-type search-type-${this.escapeHTML(typeClass)}">${typeLabel}</span>`;
|
|
48
|
+
}
|
|
45
49
|
|
|
46
50
|
if (result.snippet)
|
|
47
51
|
html += `<div class="search-snippet">${result.snippet}</div>`;
|
|
@@ -51,6 +55,17 @@ function createSearchInstance(input, result) {
|
|
|
51
55
|
return li;
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
search.formatType = function(type) {
|
|
59
|
+
const typeLabels = {
|
|
60
|
+
'class': 'class',
|
|
61
|
+
'module': 'module',
|
|
62
|
+
'constant': 'const',
|
|
63
|
+
'instance_method': 'method',
|
|
64
|
+
'class_method': 'method'
|
|
65
|
+
};
|
|
66
|
+
return typeLabels[type] || type;
|
|
67
|
+
}
|
|
68
|
+
|
|
54
69
|
search.select = function(result) {
|
|
55
70
|
let href = result.firstChild.firstChild.href;
|
|
56
71
|
const query = this.input.value;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
SearchController = function(data, input, result) {
|
|
2
2
|
this.data = data;
|
|
3
3
|
this.input = input;
|
|
4
4
|
this.result = result;
|
|
5
5
|
|
|
6
6
|
this.current = null;
|
|
7
7
|
this.view = this.result.parentNode;
|
|
8
|
-
this.
|
|
8
|
+
this.ranker = new SearchRanker(data.index);
|
|
9
9
|
this.init();
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
SearchController.prototype = Object.assign({}, SearchNavigation, new function() {
|
|
13
13
|
var suid = 1;
|
|
14
14
|
|
|
15
15
|
this.init = function() {
|
|
@@ -25,7 +25,7 @@ Search.prototype = Object.assign({}, Navigation, new function() {
|
|
|
25
25
|
this.input.addEventListener('keyup', observer);
|
|
26
26
|
this.input.addEventListener('click', observer); // mac's clear field
|
|
27
27
|
|
|
28
|
-
this.
|
|
28
|
+
this.ranker.ready(function(results, isLast) {
|
|
29
29
|
_this.addResults(results, isLast);
|
|
30
30
|
})
|
|
31
31
|
|
|
@@ -36,7 +36,7 @@ Search.prototype = Object.assign({}, Navigation, new function() {
|
|
|
36
36
|
this.search = function(value, selectFirstMatch) {
|
|
37
37
|
this.selectFirstMatch = selectFirstMatch;
|
|
38
38
|
|
|
39
|
-
value = value.trim()
|
|
39
|
+
value = value.trim();
|
|
40
40
|
if (value) {
|
|
41
41
|
this.setNavigationActive(true);
|
|
42
42
|
} else {
|
|
@@ -53,7 +53,7 @@ Search.prototype = Object.assign({}, Navigation, new function() {
|
|
|
53
53
|
this.result.setAttribute('aria-busy', 'true');
|
|
54
54
|
this.result.setAttribute('aria-expanded', 'true');
|
|
55
55
|
this.firstRun = true;
|
|
56
|
-
this.
|
|
56
|
+
this.ranker.find(value);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* SearchNavigation allows movement using the arrow keys through the search results.
|
|
3
|
+
*
|
|
4
|
+
* When using this library you will need to set scrollIntoView to the
|
|
5
|
+
* appropriate function for your layout. Use scrollInWindow if the container
|
|
6
|
+
* is not scrollable and scrollInElement if the container is a separate
|
|
7
|
+
* scrolling region.
|
|
8
|
+
*/
|
|
9
|
+
SearchNavigation = new function() {
|
|
10
|
+
this.initNavigation = function() {
|
|
11
|
+
var _this = this;
|
|
12
|
+
|
|
13
|
+
document.addEventListener('keydown', function(e) {
|
|
14
|
+
_this.onkeydown(e);
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
this.navigationActive = true;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
this.setNavigationActive = function(state) {
|
|
21
|
+
this.navigationActive = state;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
this.onkeydown = function(e) {
|
|
25
|
+
if (!this.navigationActive) return;
|
|
26
|
+
switch(e.key) {
|
|
27
|
+
case 'ArrowLeft':
|
|
28
|
+
if (this.moveLeft()) e.preventDefault();
|
|
29
|
+
break;
|
|
30
|
+
case 'ArrowUp':
|
|
31
|
+
if (e.key == 'ArrowUp' || e.ctrlKey) {
|
|
32
|
+
if (this.moveUp()) e.preventDefault();
|
|
33
|
+
}
|
|
34
|
+
break;
|
|
35
|
+
case 'ArrowRight':
|
|
36
|
+
if (this.moveRight()) e.preventDefault();
|
|
37
|
+
break;
|
|
38
|
+
case 'ArrowDown':
|
|
39
|
+
if (e.key == 'ArrowDown' || e.ctrlKey) {
|
|
40
|
+
if (this.moveDown()) e.preventDefault();
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
case 'Enter':
|
|
44
|
+
if (this.current) e.preventDefault();
|
|
45
|
+
this.select(this.current);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
if (e.ctrlKey && e.shiftKey) this.select(this.current);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
this.moveRight = function() {
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this.moveLeft = function() {
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
this.move = function(isDown) {
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.moveUp = function() {
|
|
61
|
+
return this.move(false);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.moveDown = function() {
|
|
65
|
+
return this.move(true);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/*
|
|
69
|
+
* Scrolls to the given element in the scrollable element view.
|
|
70
|
+
*/
|
|
71
|
+
this.scrollInElement = function(element, view) {
|
|
72
|
+
var offset, viewHeight, viewScroll, height;
|
|
73
|
+
offset = element.offsetTop;
|
|
74
|
+
height = element.offsetHeight;
|
|
75
|
+
viewHeight = view.offsetHeight;
|
|
76
|
+
viewScroll = view.scrollTop;
|
|
77
|
+
|
|
78
|
+
if (offset - viewScroll + height > viewHeight) {
|
|
79
|
+
view.scrollTop = offset - viewHeight + height;
|
|
80
|
+
}
|
|
81
|
+
if (offset < viewScroll) {
|
|
82
|
+
view.scrollTop = offset;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
* Scrolls to the given element in the window. The second argument is
|
|
88
|
+
* ignored
|
|
89
|
+
*/
|
|
90
|
+
this.scrollInWindow = function(element, ignored) {
|
|
91
|
+
var offset, viewHeight, viewScroll, height;
|
|
92
|
+
offset = element.offsetTop;
|
|
93
|
+
height = element.offsetHeight;
|
|
94
|
+
viewHeight = window.innerHeight;
|
|
95
|
+
viewScroll = window.scrollY;
|
|
96
|
+
|
|
97
|
+
if (offset - viewScroll + height > viewHeight) {
|
|
98
|
+
window.scrollTo(window.scrollX, offset - viewHeight + height);
|
|
99
|
+
}
|
|
100
|
+
if (offset < viewScroll) {
|
|
101
|
+
window.scrollTo(window.scrollX, offset);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|