just-the-docs 0.2.6 → 0.3.1

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/_includes/css/custom.scss.liquid +1 -0
  4. data/_includes/css/just-the-docs.scss.liquid +7 -0
  5. data/_includes/head.html +4 -4
  6. data/_includes/nav.html +55 -40
  7. data/_includes/title.html +5 -1
  8. data/_includes/vendor/anchor_headings.html +2 -2
  9. data/_layouts/default.html +146 -73
  10. data/_layouts/table_wrappers.html +1 -1
  11. data/_sass/base.scss +16 -18
  12. data/_sass/code.scss +209 -71
  13. data/_sass/color_schemes/dark.scss +1 -1
  14. data/_sass/color_schemes/light.scss +0 -0
  15. data/_sass/content.scss +53 -5
  16. data/_sass/custom/custom.scss +0 -129
  17. data/_sass/labels.scss +5 -4
  18. data/_sass/layout.scss +67 -55
  19. data/_sass/modules.scss +20 -0
  20. data/_sass/navigation.scss +129 -53
  21. data/_sass/print.scss +40 -0
  22. data/_sass/search.scss +204 -48
  23. data/_sass/support/_functions.scss +2 -3
  24. data/_sass/support/_variables.scss +15 -9
  25. data/_sass/support/mixins/_layout.scss +1 -3
  26. data/_sass/support/mixins/_typography.scss +6 -1
  27. data/_sass/typography.scss +9 -7
  28. data/_sass/utilities/_layout.scss +74 -17
  29. data/_sass/utilities/_lists.scss +7 -1
  30. data/_sass/utilities/_spacing.scss +69 -25
  31. data/assets/css/just-the-docs-dark.scss +3 -0
  32. data/assets/css/just-the-docs-default.scss +8 -0
  33. data/assets/css/just-the-docs-light.scss +3 -0
  34. data/assets/js/just-the-docs.js +374 -197
  35. data/assets/js/zzzz-search-data.json +58 -0
  36. data/lib/tasks/search.rake +54 -9
  37. metadata +36 -24
  38. data/assets/css/dark-mode-preview.scss +0 -41
  39. data/assets/css/just-the-docs.scss +0 -44
  40. data/assets/js/search-data.json +0 -11
@@ -15,9 +15,7 @@
15
15
  @media (min-width: rem($value)) {
16
16
  @content;
17
17
  }
18
- }
19
-
20
- @else {
18
+ } @else {
21
19
  @warn "No value could be retrieved from `#{$media-query}`. "
22
20
  + "Please make sure it is defined in `$media-queries` map.";
23
21
  }
@@ -25,7 +25,7 @@
25
25
  }
26
26
 
27
27
  @mixin fs-4 {
28
- font-size: 14px !important;
28
+ font-size: 15px !important;
29
29
 
30
30
  @include mq(sm) {
31
31
  font-size: 16px !important;
@@ -45,11 +45,13 @@
45
45
 
46
46
  @include mq(sm) {
47
47
  font-size: 24px !important;
48
+ line-height: $body-heading-line-height;
48
49
  }
49
50
  }
50
51
 
51
52
  @mixin fs-7 {
52
53
  font-size: 24px !important;
54
+ line-height: $body-heading-line-height;
53
55
 
54
56
  @include mq(sm) {
55
57
  font-size: 32px !important;
@@ -58,6 +60,7 @@
58
60
 
59
61
  @mixin fs-8 {
60
62
  font-size: 32px !important;
63
+ line-height: $body-heading-line-height;
61
64
 
62
65
  @include mq(sm) {
63
66
  font-size: 36px !important;
@@ -66,6 +69,7 @@
66
69
 
67
70
  @mixin fs-9 {
68
71
  font-size: 36px !important;
72
+ line-height: $body-heading-line-height;
69
73
 
70
74
  @include mq(sm) {
71
75
  font-size: 42px !important;
@@ -74,6 +78,7 @@
74
78
 
75
79
  @mixin fs-10 {
76
80
  font-size: 42px !important;
81
+ line-height: $body-heading-line-height;
77
82
 
78
83
  @include mq(sm) {
79
84
  font-size: 48px !important;
@@ -22,7 +22,7 @@ h3,
22
22
  h4,
23
23
  .text-delta {
24
24
  @include fs-2;
25
- font-weight: 300;
25
+ font-weight: 400;
26
26
  text-transform: uppercase;
27
27
  letter-spacing: 0.1em;
28
28
  }
@@ -39,12 +39,6 @@ h6,
39
39
  color: $grey-dk-200;
40
40
  }
41
41
 
42
- li {
43
- .highlight {
44
- margin-top: $sp-2;
45
- }
46
- }
47
-
48
42
  .text-small {
49
43
  @include fs-2;
50
44
  }
@@ -53,6 +47,14 @@ li {
53
47
  font-family: $mono-font-family !important;
54
48
  }
55
49
 
50
+ .text-left {
51
+ text-align: left !important;
52
+ }
53
+
56
54
  .text-center {
57
55
  text-align: center !important;
58
56
  }
57
+
58
+ .text-right {
59
+ text-align: right !important;
60
+ }
@@ -5,11 +5,21 @@
5
5
 
6
6
  // Display
7
7
 
8
- .d-block { display: block !important; }
9
- .d-flex { display: flex !important; }
10
- .d-inline { display: inline !important; }
11
- .d-inline-block { display: inline-block !important; }
12
- .d-none { display: none !important; }
8
+ .d-block {
9
+ display: block !important;
10
+ }
11
+ .d-flex {
12
+ display: flex !important;
13
+ }
14
+ .d-inline {
15
+ display: inline !important;
16
+ }
17
+ .d-inline-block {
18
+ display: inline-block !important;
19
+ }
20
+ .d-none {
21
+ display: none !important;
22
+ }
13
23
 
14
24
  @each $media-query in map-keys($media-queries) {
15
25
  @for $i from 1 through length($spacers) {
@@ -18,21 +28,68 @@
18
28
  $scale: #{$i - 1};
19
29
 
20
30
  // .d-sm-block, .d-md-none, .d-lg-inline
21
- .d-#{$media-query}-block { display: block !important; }
22
- .d-#{$media-query}-flex { display: flex !important; }
23
- .d-#{$media-query}-inline { display: inline !important; }
24
- .d-#{$media-query}-inline-block { display: inline-block !important; }
25
- .d-#{$media-query}-none { display: none !important; }
26
-
31
+ .d-#{$media-query}-block {
32
+ display: block !important;
33
+ }
34
+ .d-#{$media-query}-flex {
35
+ display: flex !important;
36
+ }
37
+ .d-#{$media-query}-inline {
38
+ display: inline !important;
39
+ }
40
+ .d-#{$media-query}-inline-block {
41
+ display: inline-block !important;
42
+ }
43
+ .d-#{$media-query}-none {
44
+ display: none !important;
45
+ }
27
46
  }
28
47
  }
29
48
  }
30
49
 
50
+ // Horizontal alignment
51
+
52
+ .float-left {
53
+ float: left !important;
54
+ }
55
+
56
+ .float-right {
57
+ float: right !important;
58
+ }
59
+
60
+ .flex-justify-start {
61
+ justify-content: flex-start !important;
62
+ }
63
+
64
+ .flex-justify-end {
65
+ justify-content: flex-end !important;
66
+ }
67
+
68
+ .flex-justify-between {
69
+ justify-content: space-between !important;
70
+ }
71
+
72
+ .flex-justify-around {
73
+ justify-content: space-around !important;
74
+ }
75
+
31
76
  // Vertical alignment
32
77
 
33
- .v-align-baseline { vertical-align: baseline !important; }
34
- .v-align-bottom { vertical-align: bottom !important; }
35
- .v-align-middle { vertical-align: middle !important; }
36
- .v-align-text-bottom { vertical-align: text-bottom !important; }
37
- .v-align-text-top { vertical-align: text-top !important; }
38
- .v-align-top { vertical-align: top !important; }
78
+ .v-align-baseline {
79
+ vertical-align: baseline !important;
80
+ }
81
+ .v-align-bottom {
82
+ vertical-align: bottom !important;
83
+ }
84
+ .v-align-middle {
85
+ vertical-align: middle !important;
86
+ }
87
+ .v-align-text-bottom {
88
+ vertical-align: text-bottom !important;
89
+ }
90
+ .v-align-text-top {
91
+ vertical-align: text-top !important;
92
+ }
93
+ .v-align-top {
94
+ vertical-align: top !important;
95
+ }
@@ -2,10 +2,16 @@
2
2
  // Utility classes for lists
3
3
  //
4
4
 
5
- // stylelint-disable primer/selector-no-utility, primer/no-override
5
+ // stylelint-disable primer/selector-no-utility, primer/no-override, selector-max-type
6
6
 
7
7
  .list-style-none {
8
8
  padding: 0 !important;
9
9
  margin: 0 !important;
10
10
  list-style: none !important;
11
+
12
+ li {
13
+ &::before {
14
+ display: none !important;
15
+ }
16
+ }
11
17
  }
@@ -7,16 +7,31 @@
7
7
 
8
8
  // Margin spacer utilities
9
9
 
10
+ .mx-auto {
11
+ margin-right: auto !important;
12
+ margin-left: auto !important;
13
+ }
14
+
10
15
  @for $i from 1 through length($spacers) {
11
16
  $size: #{map-get($spacers, sp-#{$i - 1})};
12
17
  $scale: #{$i - 1};
13
18
 
14
19
  // .m-0, .m-1, .m-2...
15
- .m-#{$scale} { margin: #{$size} !important; }
16
- .mt-#{$scale} { margin-top: #{$size} !important; }
17
- .mr-#{$scale} { margin-right: #{$size} !important; }
18
- .mb-#{$scale} { margin-bottom: #{$size} !important; }
19
- .ml-#{$scale} { margin-left: #{$size} !important; }
20
+ .m-#{$scale} {
21
+ margin: #{$size} !important;
22
+ }
23
+ .mt-#{$scale} {
24
+ margin-top: #{$size} !important;
25
+ }
26
+ .mr-#{$scale} {
27
+ margin-right: #{$size} !important;
28
+ }
29
+ .mb-#{$scale} {
30
+ margin-bottom: #{$size} !important;
31
+ }
32
+ .ml-#{$scale} {
33
+ margin-left: #{$size} !important;
34
+ }
20
35
 
21
36
  .mx-#{$scale} {
22
37
  margin-right: #{$size} !important;
@@ -32,11 +47,10 @@
32
47
  margin-right: -#{$size} !important;
33
48
  margin-left: -#{$size} !important;
34
49
  }
35
- }
36
-
37
- .mx-auto {
38
- margin-right: auto !important;
39
- margin-left: auto !important;
50
+ .mx-#{$scale}-auto {
51
+ margin-right: auto !important;
52
+ margin-left: auto !important;
53
+ }
40
54
  }
41
55
 
42
56
  @each $media-query in map-keys($media-queries) {
@@ -46,11 +60,21 @@
46
60
  $scale: #{$i - 1};
47
61
 
48
62
  // .m-sm-0, .m-md-1, .m-lg-2...
49
- .m-#{$media-query}-#{$scale} { margin: #{$size} !important; }
50
- .mt-#{$media-query}-#{$scale} { margin-top: #{$size} !important; }
51
- .mr-#{$media-query}-#{$scale} { margin-right: #{$size} !important; }
52
- .mb-#{$media-query}-#{$scale} { margin-bottom: #{$size} !important; }
53
- .ml-#{$media-query}-#{$scale} { margin-left: #{$size} !important; }
63
+ .m-#{$media-query}-#{$scale} {
64
+ margin: #{$size} !important;
65
+ }
66
+ .mt-#{$media-query}-#{$scale} {
67
+ margin-top: #{$size} !important;
68
+ }
69
+ .mr-#{$media-query}-#{$scale} {
70
+ margin-right: #{$size} !important;
71
+ }
72
+ .mb-#{$media-query}-#{$scale} {
73
+ margin-bottom: #{$size} !important;
74
+ }
75
+ .ml-#{$media-query}-#{$scale} {
76
+ margin-left: #{$size} !important;
77
+ }
54
78
 
55
79
  .mx-#{$media-query}-#{$scale} {
56
80
  margin-right: #{$size} !important;
@@ -77,11 +101,21 @@
77
101
  $scale: #{$i - 1};
78
102
 
79
103
  // .p-0, .p-1, .p-2...
80
- .p-#{$scale} { padding: #{$size} !important; }
81
- .pt-#{$scale} { padding-top: #{$size} !important; }
82
- .pr-#{$scale} { padding-right: #{$size} !important; }
83
- .pb-#{$scale} { padding-bottom: #{$size} !important; }
84
- .pl-#{$scale} { padding-left: #{$size} !important; }
104
+ .p-#{$scale} {
105
+ padding: #{$size} !important;
106
+ }
107
+ .pt-#{$scale} {
108
+ padding-top: #{$size} !important;
109
+ }
110
+ .pr-#{$scale} {
111
+ padding-right: #{$size} !important;
112
+ }
113
+ .pb-#{$scale} {
114
+ padding-bottom: #{$size} !important;
115
+ }
116
+ .pl-#{$scale} {
117
+ padding-left: #{$size} !important;
118
+ }
85
119
 
86
120
  .px-#{$scale} {
87
121
  padding-right: #{$size} !important;
@@ -101,11 +135,21 @@
101
135
  $scale: #{$i - 1};
102
136
 
103
137
  // .p-sm-0, .p-md-1, .p-lg-2...
104
- .p-#{$media-query}-#{$scale} { padding: #{$size} !important; }
105
- .pt-#{$media-query}-#{$scale} { padding-top: #{$size} !important; }
106
- .pr-#{$media-query}-#{$scale} { padding-right: #{$size} !important; }
107
- .pb-#{$media-query}-#{$scale} { padding-bottom: #{$size} !important; }
108
- .pl-#{$media-query}-#{$scale} { padding-left: #{$size} !important; }
138
+ .p-#{$media-query}-#{$scale} {
139
+ padding: #{$size} !important;
140
+ }
141
+ .pt-#{$media-query}-#{$scale} {
142
+ padding-top: #{$size} !important;
143
+ }
144
+ .pr-#{$media-query}-#{$scale} {
145
+ padding-right: #{$size} !important;
146
+ }
147
+ .pb-#{$media-query}-#{$scale} {
148
+ padding-bottom: #{$size} !important;
149
+ }
150
+ .pl-#{$media-query}-#{$scale} {
151
+ padding-left: #{$size} !important;
152
+ }
109
153
 
110
154
  .px-#{$media-query}-#{$scale} {
111
155
  padding-right: #{$size} !important;
@@ -0,0 +1,3 @@
1
+ ---
2
+ ---
3
+ {% include css/just-the-docs.scss.liquid color_scheme="dark" %}
@@ -0,0 +1,8 @@
1
+ ---
2
+ ---
3
+ {% if site.color_scheme and site.color_scheme != "nil" %}
4
+ {% assign color_scheme = site.color_scheme %}
5
+ {% else %}
6
+ {% assign color_scheme = "light" %}
7
+ {% endif %}
8
+ {% include css/just-the-docs.scss.liquid color_scheme=color_scheme %}
@@ -0,0 +1,3 @@
1
+ ---
2
+ ---
3
+ {% include css/just-the-docs.scss.liquid color_scheme="light" %}
@@ -24,24 +24,47 @@ jtd.onReady = function(ready) {
24
24
  // Show/hide mobile menu
25
25
 
26
26
  function initNav() {
27
- const mainNav = document.querySelector('.js-main-nav');
28
- const pageHeader = document.querySelector('.js-page-header');
29
- const navTrigger = document.querySelector('.js-main-nav-trigger');
27
+ jtd.addEvent(document, 'click', function(e){
28
+ var target = e.target;
29
+ while (target && !(target.classList && target.classList.contains('nav-list-expander'))) {
30
+ target = target.parentNode;
31
+ }
32
+ if (target) {
33
+ e.preventDefault();
34
+ target.parentNode.classList.toggle('active');
35
+ }
36
+ });
37
+
38
+ const siteNav = document.getElementById('site-nav');
39
+ const mainHeader = document.getElementById('main-header');
40
+ const menuButton = document.getElementById('menu-button');
30
41
 
31
- jtd.addEvent(navTrigger, 'click', function(e){
42
+ jtd.addEvent(menuButton, 'click', function(e){
32
43
  e.preventDefault();
33
- var text = navTrigger.innerText;
34
- var textToggle = navTrigger.getAttribute('data-text-toggle');
35
-
36
- mainNav.classList.toggle('nav-open');
37
- pageHeader.classList.toggle('nav-open');
38
- navTrigger.classList.toggle('nav-open');
39
- navTrigger.innerText = textToggle;
40
- navTrigger.setAttribute('data-text-toggle', text);
41
- textToggle = text;
42
- })
44
+
45
+ if (menuButton.classList.toggle('nav-open')) {
46
+ siteNav.classList.add('nav-open');
47
+ mainHeader.classList.add('nav-open');
48
+ } else {
49
+ siteNav.classList.remove('nav-open');
50
+ mainHeader.classList.remove('nav-open');
51
+ }
52
+ });
53
+
54
+ {%- if site.search_enabled != false and site.search.button %}
55
+ const searchInput = document.getElementById('search-input');
56
+ const searchButton = document.getElementById('search-button');
57
+
58
+ jtd.addEvent(searchButton, 'click', function(e){
59
+ e.preventDefault();
60
+
61
+ mainHeader.classList.add('nav-open');
62
+ searchInput.focus();
63
+ });
64
+ {%- endif %}
43
65
  }
44
66
 
67
+ {%- if site.search_enabled != false %}
45
68
  // Site search
46
69
 
47
70
  function initSearch() {
@@ -50,243 +73,397 @@ function initSearch() {
50
73
 
51
74
  request.onload = function(){
52
75
  if (request.status >= 200 && request.status < 400) {
53
- // Success!
54
- var data = JSON.parse(request.responseText);
76
+ var docs = JSON.parse(request.responseText);
77
+
78
+ lunr.tokenizer.separator = {{ site.search.tokenizer_separator | default: site.search_tokenizer_separator | default: "/[\s\-/]+/" }}
55
79
 
56
- lunr.tokenizer.separator = /[\s\-/]+/
57
- var index = lunr(function () {
80
+ var index = lunr(function(){
58
81
  this.ref('id');
59
82
  this.field('title', { boost: 200 });
60
83
  this.field('content', { boost: 2 });
61
- this.field('url');
84
+ {%- if site.search.rel_url != false %}
85
+ this.field('relUrl');
86
+ {%- endif %}
62
87
  this.metadataWhitelist = ['position']
63
88
 
64
- for (var i in data) {
89
+ for (var i in docs) {
65
90
  this.add({
66
91
  id: i,
67
- title: data[i].title,
68
- content: data[i].content,
69
- url: data[i].url
92
+ title: docs[i].title,
93
+ content: docs[i].content,
94
+ {%- if site.search.rel_url != false %}
95
+ relUrl: docs[i].relUrl
96
+ {%- endif %}
70
97
  });
71
98
  }
72
99
  });
73
100
 
74
- searchResults(index, data);
101
+ searchLoaded(index, docs);
75
102
  } else {
76
- // We reached our target server, but it returned an error
77
103
  console.log('Error loading ajax request. Request status:' + request.status);
78
104
  }
79
105
  };
80
106
 
81
107
  request.onerror = function(){
82
- // There was a connection error of some sort
83
108
  console.log('There was a connection error');
84
109
  };
85
110
 
86
111
  request.send();
112
+ }
113
+
114
+ function searchLoaded(index, docs) {
115
+ var index = index;
116
+ var docs = docs;
117
+ var searchInput = document.getElementById('search-input');
118
+ var searchResults = document.getElementById('search-results');
119
+ var mainHeader = document.getElementById('main-header');
120
+ var currentInput;
121
+ var currentSearchIndex = 0;
122
+
123
+ function showSearch() {
124
+ document.documentElement.classList.add('search-active');
125
+ }
87
126
 
88
- function searchResults(index, data) {
89
- var index = index;
90
- var docs = data;
91
- var searchInput = document.querySelector('.js-search-input');
92
- var searchResults = document.querySelector('.js-search-results');
127
+ function hideSearch() {
128
+ document.documentElement.classList.remove('search-active');
129
+ }
93
130
 
94
- function hideResults() {
95
- searchResults.innerHTML = '';
96
- searchResults.classList.remove('active');
131
+ function update() {
132
+ currentSearchIndex++;
133
+
134
+ var input = searchInput.value;
135
+ if (input === '') {
136
+ hideSearch();
137
+ } else {
138
+ showSearch();
139
+ // scroll search input into view, workaround for iOS Safari
140
+ window.scroll(0, -1);
141
+ setTimeout(function(){ window.scroll(0, 0); }, 0);
142
+ }
143
+ if (input === currentInput) {
144
+ return;
145
+ }
146
+ currentInput = input;
147
+ searchResults.innerHTML = '';
148
+ if (input === '') {
149
+ return;
97
150
  }
98
151
 
99
- jtd.addEvent(searchInput, 'keydown', function(e){
100
- switch (e.keyCode) {
101
- case 38: // arrow up
102
- e.preventDefault();
103
- var active = document.querySelector('.search-result.active');
104
- if (active) {
105
- active.classList.remove('active');
106
- if (active.parentElement.previousSibling) {
107
- var previous = active.parentElement.previousSibling.querySelector('.search-result');
108
- previous.classList.add('active');
109
- }
110
- }
111
- return;
112
- case 40: // arrow down
113
- e.preventDefault();
114
- var active = document.querySelector('.search-result.active');
115
- if (active) {
116
- if (active.parentElement.nextSibling) {
117
- var next = active.parentElement.nextSibling.querySelector('.search-result');
118
- active.classList.remove('active');
119
- next.classList.add('active');
120
- }
121
- } else {
122
- var next = document.querySelector('.search-result');
123
- if (next) {
124
- next.classList.add('active');
125
- }
126
- }
127
- return;
128
- case 13: // enter
129
- e.preventDefault();
130
- var active = document.querySelector('.search-result.active');
131
- if (active) {
132
- active.click();
133
- } else {
134
- var first = document.querySelector('.search-result');
135
- if (first) {
136
- first.click();
137
- }
138
- }
139
- return;
140
- }
152
+ var results = index.query(function (query) {
153
+ var tokens = lunr.tokenizer(input)
154
+ query.term(tokens, {
155
+ boost: 10
156
+ });
157
+ query.term(tokens, {
158
+ wildcard: lunr.Query.wildcard.TRAILING
159
+ });
141
160
  });
142
161
 
143
- jtd.addEvent(searchInput, 'keyup', function(e){
144
- switch (e.keyCode) {
145
- case 27: // When esc key is pressed, hide the results and clear the field
146
- hideResults();
147
- searchInput.value = '';
148
- return;
149
- case 38: // arrow up
150
- case 40: // arrow down
151
- case 13: // enter
152
- e.preventDefault();
153
- return;
162
+ if ((results.length == 0) && (input.length > 2)) {
163
+ var tokens = lunr.tokenizer(input).filter(function(token, i) {
164
+ return token.str.length < 20;
165
+ })
166
+ if (tokens.length > 0) {
167
+ results = index.query(function (query) {
168
+ query.term(tokens, {
169
+ editDistance: Math.round(Math.sqrt(input.length / 2 - 1))
170
+ });
171
+ });
154
172
  }
173
+ }
174
+
175
+ if (results.length == 0) {
176
+ var noResultsDiv = document.createElement('div');
177
+ noResultsDiv.classList.add('search-no-result');
178
+ noResultsDiv.innerText = 'No results found';
179
+ searchResults.appendChild(noResultsDiv);
155
180
 
156
- hideResults();
181
+ } else {
182
+ var resultsList = document.createElement('ul');
183
+ resultsList.classList.add('search-results-list');
184
+ searchResults.appendChild(resultsList);
185
+
186
+ addResults(resultsList, results, 0, 10, 100, currentSearchIndex);
187
+ }
157
188
 
158
- var input = this.value;
159
- if (input === '') {
189
+ function addResults(resultsList, results, start, batchSize, batchMillis, searchIndex) {
190
+ if (searchIndex != currentSearchIndex) {
160
191
  return;
161
192
  }
193
+ for (var i = start; i < (start + batchSize); i++) {
194
+ if (i == results.length) {
195
+ return;
196
+ }
197
+ addResult(resultsList, results[i]);
198
+ }
199
+ setTimeout(function() {
200
+ addResults(resultsList, results, start + batchSize, batchSize, batchMillis, searchIndex);
201
+ }, batchMillis);
202
+ }
162
203
 
163
- var results = index.query(function (query) {
164
- var tokens = lunr.tokenizer(input)
165
- query.term(tokens, {
166
- boost: 10
167
- });
168
- query.term(tokens, {
169
- wildcard: lunr.Query.wildcard.TRAILING
170
- });
171
- });
204
+ function addResult(resultsList, result) {
205
+ var doc = docs[result.ref];
206
+
207
+ var resultsListItem = document.createElement('li');
208
+ resultsListItem.classList.add('search-results-list-item');
209
+ resultsList.appendChild(resultsListItem);
210
+
211
+ var resultLink = document.createElement('a');
212
+ resultLink.classList.add('search-result');
213
+ resultLink.setAttribute('href', doc.url);
214
+ resultsListItem.appendChild(resultLink);
215
+
216
+ var resultTitle = document.createElement('div');
217
+ resultTitle.classList.add('search-result-title');
218
+ resultLink.appendChild(resultTitle);
219
+
220
+ var resultDoc = document.createElement('div');
221
+ resultDoc.classList.add('search-result-doc');
222
+ resultDoc.innerHTML = '<svg viewBox="0 0 24 24" class="search-result-icon"><use xlink:href="#svg-doc"></use></svg>';
223
+ resultTitle.appendChild(resultDoc);
224
+
225
+ var resultDocTitle = document.createElement('div');
226
+ resultDocTitle.classList.add('search-result-doc-title');
227
+ resultDocTitle.innerHTML = doc.doc;
228
+ resultDoc.appendChild(resultDocTitle);
229
+ var resultDocOrSection = resultDocTitle;
230
+
231
+ if (doc.doc != doc.title) {
232
+ resultDoc.classList.add('search-result-doc-parent');
233
+ var resultSection = document.createElement('div');
234
+ resultSection.classList.add('search-result-section');
235
+ resultSection.innerHTML = doc.title;
236
+ resultTitle.appendChild(resultSection);
237
+ resultDocOrSection = resultSection;
238
+ }
172
239
 
173
- if (results.length > 0) {
174
- searchResults.classList.add('active');
175
- var resultsList = document.createElement('ul');
176
- resultsList.classList.add('search-results-list');
177
- searchResults.appendChild(resultsList);
178
-
179
- for (var i in results) {
180
- var result = results[i];
181
- var doc = docs[result.ref];
182
-
183
- var resultsListItem = document.createElement('li');
184
- resultsListItem.classList.add('search-results-list-item');
185
- resultsList.appendChild(resultsListItem);
186
-
187
- var resultLink = document.createElement('a');
188
- resultLink.classList.add('search-result');
189
- resultLink.setAttribute('href', doc.url);
190
- resultsListItem.appendChild(resultLink);
191
-
192
- var resultTitle = document.createElement('div');
193
- resultTitle.classList.add('search-result-title');
194
- resultTitle.innerText = doc.title;
195
- resultLink.appendChild(resultTitle);
196
-
197
- var resultRelUrl = document.createElement('span');
198
- resultRelUrl.classList.add('search-result-rel-url');
199
- resultRelUrl.innerText = doc.relUrl;
200
- resultTitle.appendChild(resultRelUrl);
201
-
202
- var metadata = result.matchData.metadata;
203
- var contentFound = false;
204
- for (var j in metadata) {
205
- if (metadata[j].title) {
206
- var position = metadata[j].title.position[0];
207
- var start = position[0];
208
- var end = position[0] + position[1];
209
- resultTitle.innerHTML = doc.title.substring(0, start) + '<span class="search-result-highlight">' + doc.title.substring(start, end) + '</span>' + doc.title.substring(end, doc.title.length)+'<span class="search-result-rel-url">'+doc.relUrl+'</span>';
210
-
211
- } else if (metadata[j].content && !contentFound) {
212
- contentFound = true;
213
-
214
- var position = metadata[j].content.position[0];
215
- var start = position[0];
216
- var end = position[0] + position[1];
217
- var previewStart = start;
218
- var previewEnd = end;
219
- var ellipsesBefore = true;
220
- var ellipsesAfter = true;
221
- for (var k = 0; k < 3; k++) {
222
- var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
223
- var nextDot = doc.content.lastIndexOf('.', previewStart - 2);
224
- if ((nextDot > 0) && (nextDot > nextSpace)) {
225
- previewStart = nextDot + 1;
226
- ellipsesBefore = false;
227
- break;
228
- }
229
- if (nextSpace < 0) {
230
- previewStart = 0;
231
- ellipsesBefore = false;
232
- break;
233
- }
234
- previewStart = nextSpace + 1;
240
+ var metadata = result.matchData.metadata;
241
+ var titlePositions = [];
242
+ var contentPositions = [];
243
+ for (var j in metadata) {
244
+ var meta = metadata[j];
245
+ if (meta.title) {
246
+ var positions = meta.title.position;
247
+ for (var k in positions) {
248
+ titlePositions.push(positions[k]);
249
+ }
250
+ }
251
+ if (meta.content) {
252
+ var positions = meta.content.position;
253
+ for (var k in positions) {
254
+ var position = positions[k];
255
+ var previewStart = position[0];
256
+ var previewEnd = position[0] + position[1];
257
+ var ellipsesBefore = true;
258
+ var ellipsesAfter = true;
259
+ for (var k = 0; k < {{ site.search.preview_words_before | default: 5 }}; k++) {
260
+ var nextSpace = doc.content.lastIndexOf(' ', previewStart - 2);
261
+ var nextDot = doc.content.lastIndexOf('. ', previewStart - 2);
262
+ if ((nextDot >= 0) && (nextDot > nextSpace)) {
263
+ previewStart = nextDot + 1;
264
+ ellipsesBefore = false;
265
+ break;
235
266
  }
236
- for (var k = 0; k < 10; k++) {
237
- var nextSpace = doc.content.indexOf(' ', previewEnd + 1);
238
- var nextDot = doc.content.indexOf('.', previewEnd + 1);
239
- if ((nextDot > 0) && (nextDot < nextSpace)) {
240
- previewEnd = nextDot;
241
- ellipsesAfter = false;
242
- break;
243
- }
244
- if (nextSpace < 0) {
245
- previewEnd = doc.content.length;
246
- ellipsesAfter = false;
247
- break;
248
- }
249
- previewEnd = nextSpace;
267
+ if (nextSpace < 0) {
268
+ previewStart = 0;
269
+ ellipsesBefore = false;
270
+ break;
250
271
  }
251
- var preview = doc.content.substring(previewStart, start);
252
- if (ellipsesBefore) {
253
- preview = '... ' + preview;
272
+ previewStart = nextSpace + 1;
273
+ }
274
+ for (var k = 0; k < {{ site.search.preview_words_after | default: 10 }}; k++) {
275
+ var nextSpace = doc.content.indexOf(' ', previewEnd + 1);
276
+ var nextDot = doc.content.indexOf('. ', previewEnd + 1);
277
+ if ((nextDot >= 0) && (nextDot < nextSpace)) {
278
+ previewEnd = nextDot;
279
+ ellipsesAfter = false;
280
+ break;
254
281
  }
255
- preview += '<span class="search-result-highlight">' + doc.content.substring(start, end) + '</span>';
256
- preview += doc.content.substring(end, previewEnd);
257
- if (ellipsesAfter) {
258
- preview += ' ...';
282
+ if (nextSpace < 0) {
283
+ previewEnd = doc.content.length;
284
+ ellipsesAfter = false;
285
+ break;
259
286
  }
287
+ previewEnd = nextSpace;
288
+ }
289
+ contentPositions.push({
290
+ highlight: position,
291
+ previewStart: previewStart, previewEnd: previewEnd,
292
+ ellipsesBefore: ellipsesBefore, ellipsesAfter: ellipsesAfter
293
+ });
294
+ }
295
+ }
296
+ }
297
+
298
+ if (titlePositions.length > 0) {
299
+ titlePositions.sort(function(p1, p2){ return p1[0] - p2[0] });
300
+ resultDocOrSection.innerHTML = '';
301
+ addHighlightedText(resultDocOrSection, doc.title, 0, doc.title.length, titlePositions);
302
+ }
260
303
 
261
- var resultPreview = document.createElement('div');
262
- resultPreview.classList.add('search-result-preview');
263
- resultPreview.innerHTML = preview;
264
- resultLink.appendChild(resultPreview);
304
+ if (contentPositions.length > 0) {
305
+ contentPositions.sort(function(p1, p2){ return p1.highlight[0] - p2.highlight[0] });
306
+ var contentPosition = contentPositions[0];
307
+ var previewPosition = {
308
+ highlight: [contentPosition.highlight],
309
+ previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
310
+ ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
311
+ };
312
+ var previewPositions = [previewPosition];
313
+ for (var j = 1; j < contentPositions.length; j++) {
314
+ contentPosition = contentPositions[j];
315
+ if (previewPosition.previewEnd < contentPosition.previewStart) {
316
+ previewPosition = {
317
+ highlight: [contentPosition.highlight],
318
+ previewStart: contentPosition.previewStart, previewEnd: contentPosition.previewEnd,
319
+ ellipsesBefore: contentPosition.ellipsesBefore, ellipsesAfter: contentPosition.ellipsesAfter
265
320
  }
321
+ previewPositions.push(previewPosition);
322
+ } else {
323
+ previewPosition.highlight.push(contentPosition.highlight);
324
+ previewPosition.previewEnd = contentPosition.previewEnd;
325
+ previewPosition.ellipsesAfter = contentPosition.ellipsesAfter;
326
+ }
327
+ }
328
+
329
+ var resultPreviews = document.createElement('div');
330
+ resultPreviews.classList.add('search-result-previews');
331
+ resultLink.appendChild(resultPreviews);
332
+
333
+ var content = doc.content;
334
+ for (var j = 0; j < Math.min(previewPositions.length, {{ site.search.previews | default: 3 }}); j++) {
335
+ var position = previewPositions[j];
336
+
337
+ var resultPreview = document.createElement('div');
338
+ resultPreview.classList.add('search-result-preview');
339
+ resultPreviews.appendChild(resultPreview);
340
+
341
+ if (position.ellipsesBefore) {
342
+ resultPreview.appendChild(document.createTextNode('... '));
343
+ }
344
+ addHighlightedText(resultPreview, content, position.previewStart, position.previewEnd, position.highlight);
345
+ if (position.ellipsesAfter) {
346
+ resultPreview.appendChild(document.createTextNode(' ...'));
266
347
  }
267
348
  }
268
349
  }
269
- });
270
350
 
271
- jtd.addEvent(searchInput, 'blur', function(){
272
- setTimeout(function(){ hideResults() }, 300);
273
- });
351
+ {%- if site.search.rel_url != false %}
352
+ var resultRelUrl = document.createElement('span');
353
+ resultRelUrl.classList.add('search-result-rel-url');
354
+ resultRelUrl.innerText = doc.relUrl;
355
+ resultTitle.appendChild(resultRelUrl);
356
+ {%- endif %}
357
+ }
358
+
359
+ function addHighlightedText(parent, text, start, end, positions) {
360
+ var index = start;
361
+ for (var i in positions) {
362
+ var position = positions[i];
363
+ var span = document.createElement('span');
364
+ span.innerHTML = text.substring(index, position[0]);
365
+ parent.appendChild(span);
366
+ index = position[0] + position[1];
367
+ var highlight = document.createElement('span');
368
+ highlight.classList.add('search-result-highlight');
369
+ highlight.innerHTML = text.substring(position[0], index);
370
+ parent.appendChild(highlight);
371
+ }
372
+ var span = document.createElement('span');
373
+ span.innerHTML = text.substring(index, end);
374
+ parent.appendChild(span);
375
+ }
274
376
  }
377
+
378
+ jtd.addEvent(searchInput, 'focus', function(){
379
+ setTimeout(update, 0);
380
+ });
381
+
382
+ jtd.addEvent(searchInput, 'keyup', function(e){
383
+ switch (e.keyCode) {
384
+ case 27: // When esc key is pressed, hide the results and clear the field
385
+ searchInput.value = '';
386
+ break;
387
+ case 38: // arrow up
388
+ case 40: // arrow down
389
+ case 13: // enter
390
+ e.preventDefault();
391
+ return;
392
+ }
393
+ update();
394
+ });
395
+
396
+ jtd.addEvent(searchInput, 'keydown', function(e){
397
+ switch (e.keyCode) {
398
+ case 38: // arrow up
399
+ e.preventDefault();
400
+ var active = document.querySelector('.search-result.active');
401
+ if (active) {
402
+ active.classList.remove('active');
403
+ if (active.parentElement.previousSibling) {
404
+ var previous = active.parentElement.previousSibling.querySelector('.search-result');
405
+ previous.classList.add('active');
406
+ }
407
+ }
408
+ return;
409
+ case 40: // arrow down
410
+ e.preventDefault();
411
+ var active = document.querySelector('.search-result.active');
412
+ if (active) {
413
+ if (active.parentElement.nextSibling) {
414
+ var next = active.parentElement.nextSibling.querySelector('.search-result');
415
+ active.classList.remove('active');
416
+ next.classList.add('active');
417
+ }
418
+ } else {
419
+ var next = document.querySelector('.search-result');
420
+ if (next) {
421
+ next.classList.add('active');
422
+ }
423
+ }
424
+ return;
425
+ case 13: // enter
426
+ e.preventDefault();
427
+ var active = document.querySelector('.search-result.active');
428
+ if (active) {
429
+ active.click();
430
+ } else {
431
+ var first = document.querySelector('.search-result');
432
+ if (first) {
433
+ first.click();
434
+ }
435
+ }
436
+ return;
437
+ }
438
+ });
439
+
440
+ jtd.addEvent(document, 'click', function(e){
441
+ if (e.target != searchInput) {
442
+ hideSearch();
443
+ }
444
+ });
445
+ }
446
+ {%- endif %}
447
+
448
+ // Switch theme
449
+
450
+ jtd.getTheme = function() {
451
+ var cssFileHref = document.querySelector('[rel="stylesheet"]').getAttribute('href');
452
+ return cssFileHref.substring(cssFileHref.lastIndexOf('-') + 1, cssFileHref.length - 4);
275
453
  }
276
454
 
277
- function pageFocus() {
278
- var mainContent = document.querySelector('.js-main-content');
279
- mainContent.focus();
455
+ jtd.setTheme = function(theme) {
456
+ var cssFile = document.querySelector('[rel="stylesheet"]');
457
+ cssFile.setAttribute('href', '{{ "assets/css/just-the-docs-" | absolute_url }}' + theme + '.css');
280
458
  }
281
459
 
282
460
  // Document ready
283
461
 
284
462
  jtd.onReady(function(){
285
463
  initNav();
286
- pageFocus();
287
- if (typeof lunr !== 'undefined') {
288
- initSearch();
289
- }
464
+ {%- if site.search_enabled != false %}
465
+ initSearch();
466
+ {%- endif %}
290
467
  });
291
468
 
292
469
  })(window.jtd = window.jtd || {});