hexo-component-inferno 4.2.1 → 5.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.
Files changed (70) hide show
  1. package/README.md +5 -18
  2. package/asset/css/github-calendar.css +41 -0
  3. package/asset/js/algolia.js +18 -69
  4. package/asset/js/github-calendar.js +185 -0
  5. package/asset/js/google_cse.js +19 -68
  6. package/asset/js/insight.js +45 -208
  7. package/lib/core/commented_yaml.js +35 -0
  8. package/lib/core/default_value.js +150 -0
  9. package/lib/core/schema.js +8 -196
  10. package/lib/core/schema_util.js +14 -0
  11. package/lib/hexo/helper/cdn.js +10 -97
  12. package/lib/hexo/tag/tabs.js +4 -84
  13. package/lib/schema/comment/artalk.json +7 -1
  14. package/lib/schema/comment/facebook.json +1 -1
  15. package/lib/schema/comment/gitalk.json +23 -6
  16. package/lib/schema/comment/gitment.json +1 -1
  17. package/lib/schema/comment/twikoo.json +3 -3
  18. package/lib/schema/comment/waline.json +28 -3
  19. package/lib/schema/misc/open_graph.json +2 -1
  20. package/lib/schema/plugin/cookie_consent.json +2 -2
  21. package/lib/schema/plugin/mathjax.json +1 -1
  22. package/lib/schema/plugin/outdated_browser.json +1 -1
  23. package/lib/schema/share/bdshare.json +1 -1
  24. package/lib/schema/share/sharejs.json +1 -1
  25. package/lib/schema/share/web_share.json +13 -0
  26. package/lib/schema/widget/github_calendar.json +30 -0
  27. package/lib/schema/widget/profile.json +67 -0
  28. package/lib/util/archives.js +86 -0
  29. package/lib/util/categories.js +102 -0
  30. package/lib/util/cdn-rules.js +109 -0
  31. package/lib/util/cdn.js +116 -0
  32. package/lib/util/consent.js +122 -0
  33. package/lib/util/deprecate.js +1 -1
  34. package/lib/util/gallery.js +227 -0
  35. package/lib/util/insight-search.js +98 -0
  36. package/lib/util/searchbox.js +88 -0
  37. package/lib/util/tab-options.js +109 -0
  38. package/lib/view/comment/artalk.js +24 -6
  39. package/lib/view/comment/disqus.js +1 -1
  40. package/lib/view/comment/disqusjs.js +7 -6
  41. package/lib/view/comment/facebook.js +3 -16
  42. package/lib/view/comment/gitalk.js +18 -15
  43. package/lib/view/comment/gitment.js +2 -2
  44. package/lib/view/comment/twikoo.js +5 -3
  45. package/lib/view/comment/valine.js +4 -3
  46. package/lib/view/comment/waline.js +8 -6
  47. package/lib/view/common/article_media.js +6 -1
  48. package/lib/view/misc/open_graph.js +3 -5
  49. package/lib/view/plugin/cookie_consent.js +8 -7
  50. package/lib/view/plugin/gallery.js +42 -19
  51. package/lib/view/plugin/katex.js +4 -4
  52. package/lib/view/plugin/mathjax.js +10 -7
  53. package/lib/view/plugin/outdated_browser.js +59 -45
  54. package/lib/view/plugin/progressbar.js +6 -1
  55. package/lib/view/plugin/waline_pageview.js +2 -2
  56. package/lib/view/search/algolia.js +8 -3
  57. package/lib/view/search/google_cse.js +13 -10
  58. package/lib/view/search/insight.js +9 -2
  59. package/lib/view/share/addthis.js +4 -9
  60. package/lib/view/share/addtoany.js +23 -5
  61. package/lib/view/share/bdshare.js +9 -30
  62. package/lib/view/share/sharejs.js +7 -34
  63. package/lib/view/share/sharethis.js +21 -6
  64. package/lib/view/share/web_share.js +153 -0
  65. package/lib/view/widget/archives.js +19 -71
  66. package/lib/view/widget/categories.js +20 -67
  67. package/lib/view/widget/github_calendar.js +94 -0
  68. package/lib/view/widget/profile.js +194 -0
  69. package/lib/view/widget/subscribe_email.js +4 -26
  70. package/package.json +6 -4
package/README.md CHANGED
@@ -13,8 +13,7 @@ for building [Hexo](https://hexo.io/) themes in JSX. It is the component library
13
13
  plugins, and SEO metadata, each with a JSON schema for its configuration.
14
14
  - **Hexo extensions**: generators, helpers, tag plugins, and a filter that merges the theme config into
15
15
  the template locals.
16
- - **Configuration tools**: a JSON schema loader that validates the theme config and generates its default
17
- values, and a framework for migrating configs between theme versions.
16
+ - **Configuration tools**: a JSON schema loader that validates the theme config and generates commented defaults.
18
17
 
19
18
  ## Requirements
20
19
 
@@ -104,9 +103,7 @@ const result = schema.validate(themeConfig); // true, or a list of errors
104
103
  const defaults = schema.getDefaultValue().toYaml(); // a commented default config
105
104
  ```
106
105
 
107
- For example, `{ "$ref": "/comment/giscus.json" }` in your schema refers to the Giscus schema of this
108
- library. `lib/core/migrate` upgrades existing configs between theme versions with a chain of `Migration`
109
- classes.
106
+ For example, `{ "$ref": "/comment/giscus.json" }` in your schema refers to the Giscus schema of this library.
110
107
 
111
108
  ### Utilities
112
109
 
@@ -124,25 +121,15 @@ classes.
124
121
 
125
122
  | Category | Components |
126
123
  | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
127
- | `comment` | Artalk, Beaudar, Changyan, Cusdis, Disqus, DisqusJS, Facebook, Giscus, Gitalk, Gitment, Isso, LiveRe, Twikoo, Utterances, Valine, Waline |
124
+ | `comment` | Artalk, Beaudar, Changyan, Cusdis, Disqus, DisqusJS, Facebook, Giscus, Gitalk 2 (preview), Gitment (deprecated), Isso, LiveRe, Twikoo, Utterances, Valine (deprecated), Waline |
128
125
  | `search` | Algolia, Baidu, Google CSE, Insight |
129
- | `share` | AddThis, AddToAny, Baidu Share, Share.js, ShareThis |
126
+ | `share` | AddThis (deprecated), AddToAny, Baidu Share (deprecated), Web Share, ShareThis |
130
127
  | `donate` | Afdian, Alipay, Buy Me a Coffee, Patreon, PayPal, WeChat |
131
- | `widget` | AdSense, archives, categories, follow.it, links, recent posts, email subscription, tags, table of contents |
128
+ | `widget` | AdSense, archives, categories, follow.it, GitHub contribution calendar, links, profile, recent posts, FeedBurner email (deprecated), tags, table of contents |
132
129
  | `plugin` | Baidu Analytics, Bing Webmaster, Busuanzi, CNZZ, cookie consent, gallery, Google Analytics, Hotjar, KaTeX, MathJax, Matomo, outdated browser warning, progress bar, StatCounter, Twitter conversion tracking, Umami, Waline page views |
133
130
  | `misc` | Article licensing, meta tags, Open Graph, paginator, structured data, web app |
134
131
  | `common` | Article media (a thumbnail with a title and date) |
135
132
 
136
- The components below are deprecated because their services have shut down or are shutting down. They print
137
- a warning when they are rendered, and will be removed in the next major version.
138
-
139
- | Component | Reason | Alternatives |
140
- | ------------------------ | ------------------------------------------------------------------------------ | -------------------------- |
141
- | `share/addthis` | AddThis shut down on May 31, 2023. | AddToAny, ShareThis |
142
- | `comment/gitment` | Gitment is no longer maintained, and its GitHub sign-in proxy no longer works. | Giscus, Utterances, Gitalk |
143
- | `comment/valine` | LeanCloud, where Valine stores the comments, shuts down on January 12, 2027. | Waline, Twikoo |
144
- | `widget/subscribe_email` | Google FeedBurner stopped email subscriptions in July 2021. | follow.it |
145
-
146
133
  The [API documentation](https://ppoffice.github.io/hexo-component-inferno/) lists the props of every
147
134
  component and the options of every module.
148
135
 
@@ -0,0 +1,41 @@
1
+ .github-calendar-chart {
2
+ --github-calendar-color: var(--github-calendar-default-color, #40c463);
3
+ --github-calendar-empty: color-mix(in srgb, currentColor 12%, transparent);
4
+ min-height: 116px;
5
+ }
6
+
7
+ .github-calendar-chart .github-calendar-link {
8
+ display: block;
9
+ color: inherit;
10
+ }
11
+
12
+ .github-calendar-chart svg {
13
+ display: block;
14
+ max-width: 100%;
15
+ }
16
+
17
+ .github-calendar-chart text {
18
+ fill: currentColor;
19
+ font-family: inherit;
20
+ font-size: 10px;
21
+ }
22
+
23
+ .github-calendar-chart rect {
24
+ fill: var(--github-calendar-empty);
25
+ }
26
+
27
+ .github-calendar-chart .github-calendar-level-1 {
28
+ fill: color-mix(in srgb, var(--github-calendar-color) 25%, var(--github-calendar-empty));
29
+ }
30
+
31
+ .github-calendar-chart .github-calendar-level-2 {
32
+ fill: color-mix(in srgb, var(--github-calendar-color) 50%, var(--github-calendar-empty));
33
+ }
34
+
35
+ .github-calendar-chart .github-calendar-level-3 {
36
+ fill: color-mix(in srgb, var(--github-calendar-color) 75%, var(--github-calendar-empty));
37
+ }
38
+
39
+ .github-calendar-chart .github-calendar-level-4 {
40
+ fill: var(--github-calendar-color);
41
+ }
@@ -1,6 +1,14 @@
1
- /* global instantsearch, algoliasearch */
1
+ /* global instantsearch */
2
2
  // eslint-disable-next-line no-unused-vars
3
3
  function loadAlgolia(config, translation) {
4
+ const $main = $('.searchbox');
5
+ let search = null;
6
+ const controller = window.loadSearchbox($main, {
7
+ onDestroy: () => {
8
+ // Widget initialization can fail before start completes. Dispose only initialized indices.
9
+ if (search && search.mainIndex.getHelper()) search.dispose();
10
+ },
11
+ });
4
12
  function escapeHTML(text) {
5
13
  return String(text).replace(/[&<>"']/g, (char) => {
6
14
  return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[char];
@@ -23,20 +31,23 @@ function loadAlgolia(config, translation) {
23
31
  .replace(/\[\/algolia-highlight\]/g, '</em>');
24
32
  }
25
33
 
26
- const search = instantsearch({
34
+ search = instantsearch({
27
35
  indexName: config.indexName,
28
- searchClient: algoliasearch(config.applicationId, config.apiKey),
36
+ searchClient: window['algoliasearch/lite'].liteClient(config.applicationId, config.apiKey),
37
+ // Preserve search-only behavior; do not enable automatic Insights tracking after upgrading.
38
+ insights: false,
29
39
  });
30
40
 
31
41
  search.addWidgets([
32
42
  instantsearch.widgets.configure({
33
43
  attributesToSnippet: [config.excerpt],
34
44
  }),
35
- ]);
36
-
37
- search.addWidget(
38
45
  instantsearch.widgets.searchBox({
39
46
  container: '#algolia-input',
47
+ // Disposing removes the widget DOM, but callers may still hold its old input node.
48
+ queryHook: (query, refine) => {
49
+ if (controller.isCurrent()) refine(query);
50
+ },
40
51
  placeholder: translation.hint,
41
52
  showReset: false,
42
53
  showSubmit: false,
@@ -47,15 +58,9 @@ function loadAlgolia(config, translation) {
47
58
  input: 'searchbox-input',
48
59
  },
49
60
  }),
50
- );
51
-
52
- search.addWidget(
53
61
  instantsearch.widgets.poweredBy({
54
62
  container: '#algolia-poweredby',
55
63
  }),
56
- );
57
-
58
- search.addWidget(
59
64
  instantsearch.widgets.hits({
60
65
  container: '.searchbox-body',
61
66
  escapeHTML: false,
@@ -84,9 +89,6 @@ function loadAlgolia(config, translation) {
84
89
  },
85
90
  },
86
91
  }),
87
- );
88
-
89
- search.addWidget(
90
92
  instantsearch.widgets.pagination({
91
93
  container: '.searchbox-footer',
92
94
  cssClasses: {
@@ -97,64 +99,11 @@ function loadAlgolia(config, translation) {
97
99
  disabledItem: 'disabled',
98
100
  },
99
101
  }),
100
- );
102
+ ]);
101
103
 
102
104
  search.start();
103
105
 
104
106
  if (location.hash.trim() === '#algolia-search') {
105
107
  $('.searchbox').addClass('show');
106
108
  }
107
-
108
- const $main = $('.searchbox');
109
- let opener = null;
110
-
111
- function open() {
112
- if (!$main.hasClass('show')) {
113
- opener = document.activeElement;
114
- $main.addClass('show');
115
- }
116
- $main.find('.searchbox-input').focus();
117
- }
118
-
119
- // Return the focus to the element that opened the search box, unless it moved elsewhere
120
- function close(restoreFocus = true) {
121
- $main.removeClass('show');
122
- if (restoreFocus && opener && document.contains(opener)) {
123
- opener.focus();
124
- }
125
- opener = null;
126
- }
127
-
128
- // Open the search box with "/" (unless typing in a field) or Ctrl/Cmd+K
129
- function isSearchShortcut(e) {
130
- if (e.altKey) {
131
- return false;
132
- }
133
- if (e.ctrlKey || e.metaKey) {
134
- return !e.shiftKey && typeof e.key === 'string' && e.key.toLowerCase() === 'k';
135
- }
136
- // e.key is "/" whatever keys type it on the keyboard layout, so do not check e.shiftKey
137
- const target = e.target;
138
- const typing = target.isContentEditable || /^(input|textarea|select)$/i.test(target.tagName);
139
- return e.key === '/' && !typing;
140
- }
141
-
142
- $(document)
143
- .on('click', '.navbar-main .search', open)
144
- .on('click', '.searchbox .searchbox-mask', () => close())
145
- .on('click', '.searchbox-close', () => close())
146
- .on('focusin', (e) => {
147
- // Close the search box when the focus moves to the rest of the page, e.g., by Tab
148
- if ($main.hasClass('show') && !$main[0].contains(e.target)) {
149
- close(false);
150
- }
151
- })
152
- .on('keydown', (e) => {
153
- if (isSearchShortcut(e)) {
154
- e.preventDefault();
155
- open();
156
- } else if (e.keyCode === 27 && $main.hasClass('show')) {
157
- close();
158
- }
159
- });
160
109
  }
@@ -0,0 +1,185 @@
1
+ (function () {
2
+ const DAY = 86400000;
3
+ const CELL = 11;
4
+ const GAP = 3;
5
+ const NS = 'http://www.w3.org/2000/svg';
6
+ const requests = new Map();
7
+ let destroy = () => {};
8
+
9
+ function load(username) {
10
+ const cached = requests.get(username);
11
+ if (cached && cached.expires > Date.now()) {
12
+ return cached.promise;
13
+ }
14
+ const controller = new AbortController();
15
+ const timer = setTimeout(() => controller.abort(), 15000);
16
+ const promise = fetch(
17
+ 'https://github-contributions-api.jogruber.de/v4/' + encodeURIComponent(username) + '?y=last',
18
+ {
19
+ signal: controller.signal,
20
+ credentials: 'omit',
21
+ referrerPolicy: 'no-referrer',
22
+ },
23
+ )
24
+ .then((response) => {
25
+ if (!response.ok) {
26
+ throw new Error('Calendar request failed');
27
+ }
28
+ return response.json();
29
+ })
30
+ .then((data) => {
31
+ if (!Array.isArray(data.contributions) || !data.contributions.length) {
32
+ throw new Error('Missing contribution data');
33
+ }
34
+ return data.contributions
35
+ .map((day) => {
36
+ const time = Date.parse(day.date + 'T00:00:00Z');
37
+ if (
38
+ !/^\d{4}-\d{2}-\d{2}$/.test(day.date) ||
39
+ !Number.isFinite(time) ||
40
+ !Number.isInteger(day.count) ||
41
+ day.count < 0 ||
42
+ !Number.isInteger(day.level) ||
43
+ day.level < 0 ||
44
+ day.level > 4
45
+ ) {
46
+ throw new Error('Invalid contribution data');
47
+ }
48
+ return { ...day, time };
49
+ })
50
+ .sort((a, b) => a.time - b.time);
51
+ })
52
+ .catch((error) => {
53
+ requests.delete(username);
54
+ throw error;
55
+ })
56
+ .finally(() => clearTimeout(timer));
57
+ requests.set(username, { promise, expires: Date.now() + 3600000 });
58
+ return promise;
59
+ }
60
+
61
+ function element(tag, attributes = {}, text) {
62
+ const node = document.createElementNS(NS, tag);
63
+ Object.keys(attributes).forEach((key) => node.setAttribute(key, attributes[key]));
64
+ if (text !== undefined) {
65
+ node.textContent = text;
66
+ }
67
+ return node;
68
+ }
69
+
70
+ function draw(chart, days) {
71
+ const width = chart.clientWidth;
72
+ if (!width) {
73
+ return;
74
+ }
75
+ const last = days[days.length - 1];
76
+ const lastSunday = last.time - new Date(last.time).getUTCDay() * DAY;
77
+ const firstSunday = days[0].time - new Date(days[0].time).getUTCDay() * DAY;
78
+ const totalWeeks = Math.round((lastSunday - firstSunday) / (7 * DAY)) + 1;
79
+ const weeks = Math.min(totalWeeks, Math.max(1, Math.floor((width + GAP) / (CELL + GAP))));
80
+ const start = lastSunday - (weeks - 1) * 7 * DAY;
81
+ const visible = days.filter((day) => day.time >= start);
82
+ const locale = (document.documentElement.lang || 'en').replace(/^vn$/, 'vi');
83
+ let monthFormat, dateFormat;
84
+ try {
85
+ monthFormat = new Intl.DateTimeFormat(locale, { month: 'short', timeZone: 'UTC' });
86
+ dateFormat = new Intl.DateTimeFormat(locale, { dateStyle: 'medium', timeZone: 'UTC' });
87
+ } catch (e) {
88
+ monthFormat = new Intl.DateTimeFormat('en', { month: 'short', timeZone: 'UTC' });
89
+ dateFormat = new Intl.DateTimeFormat('en', { dateStyle: 'medium', timeZone: 'UTC' });
90
+ }
91
+ const svg = element('svg', { width: weeks * (CELL + GAP) - GAP, height: 116, role: 'img' });
92
+ const range = dateFormat.format(visible[0].time) + ' – ' + dateFormat.format(last.time);
93
+ svg.setAttribute(
94
+ 'aria-label',
95
+ chart.closest('.widget').querySelector('.menu-label').textContent + ': ' + range,
96
+ );
97
+ const monthLabels = [];
98
+ let month = -1;
99
+ visible.forEach((day) => {
100
+ const week = Math.floor((day.time - start) / (7 * DAY));
101
+ const x = week * (CELL + GAP);
102
+ const date = new Date(day.time);
103
+ if (date.getUTCMonth() !== month) {
104
+ month = date.getUTCMonth();
105
+ const label = element('text', { x, y: 10 }, monthFormat.format(date));
106
+ svg.appendChild(label);
107
+ monthLabels.push({
108
+ label,
109
+ x,
110
+ partial: monthLabels.length === 0 && date.getUTCDate() !== 1,
111
+ });
112
+ }
113
+ const rect = element('rect', {
114
+ x,
115
+ y: 18 + date.getUTCDay() * (CELL + GAP),
116
+ width: CELL,
117
+ height: CELL,
118
+ rx: 2,
119
+ 'data-date': day.date,
120
+ 'data-level': day.level,
121
+ class: 'github-calendar-level-' + day.level,
122
+ });
123
+ rect.appendChild(element('title', {}, dateFormat.format(date) + ': ' + day.count));
124
+ svg.appendChild(rect);
125
+ });
126
+ chart.querySelector('.github-calendar-grid').replaceChildren(svg);
127
+ // Measure in the document so labels use the actual theme font and locale. A partial
128
+ // opening month must not suppress the next full month when both start in nearby weeks.
129
+ let lastLabelEnd = -8;
130
+ monthLabels.forEach(({ label, x, partial }, index) => {
131
+ const end = x + label.getComputedTextLength();
132
+ const next = monthLabels[index + 1];
133
+ if (
134
+ (partial && next && next.x < end + 8) ||
135
+ x < lastLabelEnd + 8 ||
136
+ end > Number(svg.getAttribute('width'))
137
+ ) {
138
+ label.remove();
139
+ } else {
140
+ lastLabelEnd = end;
141
+ }
142
+ });
143
+ }
144
+
145
+ window.HexoGithubCalendar = {
146
+ init() {
147
+ destroy();
148
+ let active = true;
149
+ const cleanups = [];
150
+ destroy = () => {
151
+ active = false;
152
+ cleanups.forEach((cleanup) => cleanup());
153
+ };
154
+ document.querySelectorAll('.github-calendar-chart[data-username]').forEach((chart) => {
155
+ const status = chart.querySelector('.github-calendar-status');
156
+ load(chart.dataset.username)
157
+ .then((days) => {
158
+ if (!active || !chart.isConnected) {
159
+ return;
160
+ }
161
+ status.hidden = true;
162
+ draw(chart, days);
163
+ if (typeof ResizeObserver !== 'undefined') {
164
+ const observer = new ResizeObserver(() => draw(chart, days));
165
+ observer.observe(chart);
166
+ cleanups.push(() => observer.disconnect());
167
+ } else {
168
+ const resize = () => draw(chart, days);
169
+ window.addEventListener('resize', resize);
170
+ cleanups.push(() => window.removeEventListener('resize', resize));
171
+ }
172
+ })
173
+ .catch(() => {
174
+ if (active && chart.isConnected) {
175
+ status.hidden = false;
176
+ status.textContent = chart.dataset.error;
177
+ chart.querySelector('.github-calendar-grid').textContent = chart
178
+ .closest('.widget')
179
+ .querySelector('.menu-label').textContent;
180
+ }
181
+ });
182
+ });
183
+ },
184
+ };
185
+ })();
@@ -1,5 +1,8 @@
1
1
  /* global google */
2
2
  (function (document, $) {
3
+ const controller = window.loadSearchbox($('.searchbox'), {
4
+ onDestroy: () => $(document).off('.googleSearch'),
5
+ });
3
6
  function debounce(func, wait, immediate) {
4
7
  let timeout;
5
8
  return function () {
@@ -16,72 +19,20 @@
16
19
  };
17
20
  }
18
21
 
19
- let opener = null;
20
-
21
- function open() {
22
- const $main = $('.searchbox');
23
- if (!$main.hasClass('show')) {
24
- opener = document.activeElement;
25
- $main.addClass('show');
26
- }
27
- $main.find('.searchbox-input').focus();
28
- }
29
-
30
- // Return the focus to the element that opened the search box, unless it moved elsewhere
31
- function close(restoreFocus = true) {
32
- $('.searchbox').removeClass('show');
33
- if (restoreFocus && opener && document.contains(opener)) {
34
- opener.focus();
35
- }
36
- opener = null;
37
- }
38
-
39
- // Open the search box with "/" (unless typing in a field) or Ctrl/Cmd+K
40
- function isSearchShortcut(e) {
41
- if (e.altKey) {
42
- return false;
43
- }
44
- if (e.ctrlKey || e.metaKey) {
45
- return !e.shiftKey && typeof e.key === 'string' && e.key.toLowerCase() === 'k';
46
- }
47
- // e.key is "/" whatever keys type it on the keyboard layout, so do not check e.shiftKey
48
- const target = e.target;
49
- const typing = target.isContentEditable || /^(input|textarea|select)$/i.test(target.tagName);
50
- return e.key === '/' && !typing;
51
- }
52
-
53
- $(document)
54
- .on('click', '.navbar-main .search', open)
55
- .on('click', '.searchbox .searchbox-mask', () => close())
56
- .on('click', '.searchbox-close', () => close())
57
- .on('focusin', (e) => {
58
- // Close the search box when the focus moves to the rest of the page, e.g., by Tab
59
- const main = $('.searchbox')[0];
60
- if (main && $(main).hasClass('show') && !main.contains(e.target)) {
61
- close(false);
62
- }
63
- })
64
- .on('keydown', (e) => {
65
- if (isSearchShortcut(e)) {
66
- e.preventDefault();
67
- open();
68
- } else if (e.keyCode === 27 && $('.searchbox').hasClass('show')) {
69
- close();
70
- }
71
- })
72
- .on(
73
- 'keydown',
74
- '.searchbox-input',
75
- debounce(function () {
76
- const value = $(this).val();
77
- try {
78
- const element = google.search.cse.element.getElement('searchresults-only0');
79
- if (value.trim() === '') {
80
- element.clearAllResults();
81
- } else {
82
- element.execute(value);
83
- }
84
- } catch (e) {}
85
- }, 300),
86
- );
22
+ $(document).on(
23
+ 'input.googleSearch',
24
+ '.searchbox-input',
25
+ debounce(function () {
26
+ if (!controller.isCurrent()) return;
27
+ const value = $(this).val();
28
+ try {
29
+ const element = google.search.cse.element.getElement('searchresults-only0');
30
+ if (value.trim() === '') {
31
+ element.clearAllResults();
32
+ } else {
33
+ element.execute(value);
34
+ }
35
+ } catch (e) {}
36
+ }, 300),
37
+ );
87
38
  })(document, jQuery);