hexo-theme-gnix 1.1.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 (143) hide show
  1. package/README.md +106 -0
  2. package/include/hexo/filter/locals.js +109 -0
  3. package/include/hexo/generator/categories.js +12 -0
  4. package/include/hexo/generator/category.js +52 -0
  5. package/include/hexo/generator/insight.js +50 -0
  6. package/include/hexo/generator/manifest.js +23 -0
  7. package/include/hexo/generator/tags.js +12 -0
  8. package/include/hexo/helper/cdn.js +21 -0
  9. package/include/hexo/helper/page.js +27 -0
  10. package/include/hexo/view.js +40 -0
  11. package/include/register.js +11 -0
  12. package/include/util/common.js +33 -0
  13. package/languages/en.yml +47 -0
  14. package/languages/fr.yml +46 -0
  15. package/languages/ja.yml +46 -0
  16. package/languages/zh-CN.yml +47 -0
  17. package/languages/zh-TW.yml +47 -0
  18. package/layout/archive.jsx +118 -0
  19. package/layout/categories.jsx +137 -0
  20. package/layout/category.jsx +38 -0
  21. package/layout/comment/disqus.jsx +79 -0
  22. package/layout/comment/disqusjs.jsx +127 -0
  23. package/layout/comment/giscus.jsx +193 -0
  24. package/layout/comment/gitalk.jsx +141 -0
  25. package/layout/comment/twikoo.jsx +63 -0
  26. package/layout/comment/utterances.jsx +86 -0
  27. package/layout/comment/valine.jsx +143 -0
  28. package/layout/comment/waline.jsx +156 -0
  29. package/layout/common/article.jsx +131 -0
  30. package/layout/common/article_cover.jsx +33 -0
  31. package/layout/common/article_media.jsx +34 -0
  32. package/layout/common/comment.jsx +38 -0
  33. package/layout/common/footer.jsx +228 -0
  34. package/layout/common/head.jsx +242 -0
  35. package/layout/common/navbar.jsx +219 -0
  36. package/layout/common/plugins.jsx +39 -0
  37. package/layout/common/scripts.jsx +49 -0
  38. package/layout/common/search.jsx +22 -0
  39. package/layout/common/theme_selector.jsx +79 -0
  40. package/layout/common/toc.jsx +53 -0
  41. package/layout/index.jsx +29 -0
  42. package/layout/layout.jsx +34 -0
  43. package/layout/misc/article_licensing.jsx +114 -0
  44. package/layout/misc/meta.jsx +61 -0
  45. package/layout/misc/open_graph.jsx +164 -0
  46. package/layout/misc/paginator.jsx +90 -0
  47. package/layout/misc/structured_data.jsx +110 -0
  48. package/layout/misc/web_app.jsx +106 -0
  49. package/layout/page.jsx +12 -0
  50. package/layout/plugin/bing_webmaster.jsx +47 -0
  51. package/layout/plugin/busuanzi.jsx +40 -0
  52. package/layout/plugin/clarity.jsx +22 -0
  53. package/layout/plugin/cookie_consent.jsx +136 -0
  54. package/layout/plugin/google_analytics.jsx +66 -0
  55. package/layout/plugin/google_tag_mamager.jsx +41 -0
  56. package/layout/plugin/netlify.jsx +39 -0
  57. package/layout/plugin/pjax.jsx +20 -0
  58. package/layout/plugin/statcounter.jsx +69 -0
  59. package/layout/plugin/twitter_conversion_tracking.jsx +51 -0
  60. package/layout/post.jsx +16 -0
  61. package/layout/search/insight.jsx +53 -0
  62. package/layout/tag.jsx +29 -0
  63. package/layout/tags.jsx +55 -0
  64. package/package.json +42 -0
  65. package/scripts/index.js +1 -0
  66. package/source/css/callout_blocks.css +204 -0
  67. package/source/css/default.css +1590 -0
  68. package/source/css/font/woff2/Futura-Book.woff2 +0 -0
  69. package/source/css/font/woff2/Paris2024-Variable.woff2 +0 -0
  70. package/source/css/font/woff2/doto.woff2 +0 -0
  71. package/source/css/optional/chinese.css +17 -0
  72. package/source/css/responsive/desktop.css +164 -0
  73. package/source/css/responsive/mobile.css +46 -0
  74. package/source/css/responsive/tablet.css +46 -0
  75. package/source/css/responsive/touch.css +254 -0
  76. package/source/css/shiki/shiki.min.css +1 -0
  77. package/source/css/twikoo.css +2143 -0
  78. package/source/img/avatar.webp +0 -0
  79. package/source/img/background.webp +0 -0
  80. package/source/img/favicon.svg +6 -0
  81. package/source/img/logo.svg +9 -0
  82. package/source/img/og_image.png +0 -0
  83. package/source/js/busuanzi.js +46 -0
  84. package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.css +6 -0
  85. package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.js +1 -0
  86. package/source/js/host/iconify-icon/3.0.2/iconify-icon.min.js +12 -0
  87. package/source/js/host/medium-zoom/dist/medium-zoom.min.js +2 -0
  88. package/source/js/host/mermaid/mermaid.min.js +2811 -0
  89. package/source/js/host/pjax/0.2.8/pjax.min.js +1 -0
  90. package/source/js/host/twikoo/1.6.41/dist/twikoo.all.min.js +2 -0
  91. package/source/js/insight.js +330 -0
  92. package/source/js/instant-page.min.js +1 -0
  93. package/source/js/live2d_Asoul/Model/Ava/Ava.4096/texture_00.webp +0 -0
  94. package/source/js/live2d_Asoul/Model/Ava/Ava.moc3 +0 -0
  95. package/source/js/live2d_Asoul/Model/Ava/Ava.model3.json +323 -0
  96. package/source/js/live2d_Asoul/Model/Ava/Ava.physics3.json +1225 -0
  97. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_idle.motion3.json +1 -0
  98. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_shake01.motion3.json +1 -0
  99. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_shake02.motion3.json +1 -0
  100. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap01.motion3.json +1 -0
  101. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap02.motion3.json +1 -0
  102. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap03.motion3.json +1 -0
  103. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap04.motion3.json +1 -0
  104. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap05.motion3.json +1 -0
  105. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap06.motion3.json +1 -0
  106. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap07.motion3.json +1 -0
  107. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap08.motion3.json +1 -0
  108. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap09.motion3.json +1 -0
  109. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap10.motion3.json +1 -0
  110. package/source/js/live2d_Asoul/Model/Ava/motions/Ava_tap11.motion3.json +1 -0
  111. package/source/js/live2d_Asoul/Model/Ava/raw.ex.json +16 -0
  112. package/source/js/live2d_Asoul/Model/Ava/raw.model3.json +321 -0
  113. package/source/js/live2d_Asoul/Model/Diana/Diana.4096/texture_00.webp +0 -0
  114. package/source/js/live2d_Asoul/Model/Diana/Diana.moc3 +0 -0
  115. package/source/js/live2d_Asoul/Model/Diana/Diana.model3.json +212 -0
  116. package/source/js/live2d_Asoul/Model/Diana/Diana.physics3.json +764 -0
  117. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_idle.motion3.json +1 -0
  118. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap01.motion3.json +1 -0
  119. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap02.motion3.json +1 -0
  120. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap03.motion3.json +1 -0
  121. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap04.motion3.json +1 -0
  122. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap05.motion3.json +1 -0
  123. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap06.motion3.json +1 -0
  124. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap07.motion3.json +1 -0
  125. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap08.motion3.json +1 -0
  126. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap09.motion3.json +1 -0
  127. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap10.motion3.json +1 -0
  128. package/source/js/live2d_Asoul/Model/Diana/motions/Diana_tap11.motion3.json +1 -0
  129. package/source/js/live2d_Asoul/Model/Diana/raw.ex.json +16 -0
  130. package/source/js/live2d_Asoul/Model/Diana/raw.model3.json +210 -0
  131. package/source/js/live2d_Asoul/TweenLite.js +12 -0
  132. package/source/js/live2d_Asoul/cubism4.min.js +2 -0
  133. package/source/js/live2d_Asoul/live2dcubismcore.min.js +9 -0
  134. package/source/js/live2d_Asoul/load.js +231 -0
  135. package/source/js/live2d_Asoul/pio.css +161 -0
  136. package/source/js/live2d_Asoul/pio.js +296 -0
  137. package/source/js/live2d_Asoul/pio_sdk4.js +149 -0
  138. package/source/js/live2d_Asoul/pixi.min.js +9 -0
  139. package/source/js/main.js +218 -0
  140. package/source/js/pjax.js +29 -0
  141. package/source/js/shiki/shiki.js +191 -0
  142. package/source/js/theme-selector.js +206 -0
  143. package/util/cache.js +47 -0
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Web app meta tags.
3
+ * @module view/misc/web_app
4
+ */
5
+ const { Component, cacheComponent } = require("../../include/util/common");
6
+ /**
7
+ * Web app meta tags.
8
+ *
9
+ * @example
10
+ * <WebApp
11
+ * name="******"
12
+ * manifest="/path/to/manifest.json"
13
+ * tileIcon="/path/to/image"
14
+ * themeColor="#000000"
15
+ * icons={[
16
+ * { src: '/path/to/image', sizes: '128x128 256x256' },
17
+ * { src: '/path/to/image', sizes: '512x512' },
18
+ * ]} />
19
+ */
20
+ class WebApp extends Component {
21
+ render() {
22
+ const { name, manifest, tileIcon, themeColor } = this.props;
23
+
24
+ let icons = [];
25
+ if (Array.isArray(this.props.icons)) {
26
+ icons = this.props.icons.map((icon) => {
27
+ const { sizes, src } = icon;
28
+ if (src && sizes) {
29
+ return icon.sizes.split(/\s+/).map((size) => ({ sizes: size, src }));
30
+ }
31
+ return null;
32
+ });
33
+ icons = icons.filter(Boolean);
34
+ icons = [].concat(...icons);
35
+ }
36
+
37
+ return (
38
+ <>
39
+ <link rel="manifest" href={manifest} />
40
+ {themeColor ? <meta name="theme-color" content={themeColor} /> : null}
41
+ {/* Windows Pinned Site */}
42
+ <meta name="application-name" content={name} />
43
+ {tileIcon ? (
44
+ <meta name="msapplication-TileImage" content={tileIcon} />
45
+ ) : null}
46
+ {themeColor ? (
47
+ <meta name="msapplication-TileColor" content={themeColor} />
48
+ ) : null}
49
+ {/* iOS home screen launcher */}
50
+ <meta name="mobile-web-app-capable" content="yes" />
51
+ <meta name="apple-mobile-web-app-title" content={name} />
52
+ <meta name="apple-mobile-web-app-status-bar-style" content="default" />
53
+ {icons.map((icon) => (
54
+ <link rel="apple-touch-icon" sizes={icon.sizes} href={icon.src} />
55
+ ))}
56
+ </>
57
+ );
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Cacheable web app meta tags.
63
+ * <p>
64
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
65
+ * ({@link module:hexo/filter/locals}) and manifest generator ({@link module:hexo/generator/manifest}).
66
+ *
67
+ * @see module:util/cache.cacheComponent
68
+ * @example
69
+ * <WebApp.Cacheable
70
+ * name="******"
71
+ * themeColor="#000000"
72
+ * favicon="/path/to/image"
73
+ * icons={[
74
+ * { src: '/path/to/image', sizes: '128x128 256x256' },
75
+ * { src: '/path/to/image', sizes: '512x512' },
76
+ * ]}
77
+ * helper={{ url_for: function() {...} }} />
78
+ */
79
+ WebApp.Cacheable = cacheComponent(WebApp, "misc.webapp", (props) => {
80
+ const { name, themeColor, favicon, icons, helper } = props;
81
+
82
+ let tileIcon = null;
83
+ if (Array.isArray(icons)) {
84
+ tileIcon = icons.find(
85
+ (icon) => icon.sizes.toLowerCase().indexOf("144x144") > -1,
86
+ );
87
+ if (tileIcon) {
88
+ tileIcon = tileIcon.src;
89
+ } else if (icons.length) {
90
+ tileIcon = icons[0].src;
91
+ }
92
+ }
93
+ if (!tileIcon) {
94
+ tileIcon = favicon;
95
+ }
96
+
97
+ return {
98
+ name,
99
+ icons,
100
+ tileIcon,
101
+ themeColor,
102
+ manifest: helper.url_for("/manifest.json"),
103
+ };
104
+ });
105
+
106
+ module.exports = WebApp;
@@ -0,0 +1,12 @@
1
+ const { Component } = require("../include/util/common");
2
+ const Article = require("./common/article");
3
+
4
+ module.exports = class extends Component {
5
+ render() {
6
+ const { config, page, helper } = this.props;
7
+
8
+ return (
9
+ <Article config={config} page={page} helper={helper} index={false} />
10
+ );
11
+ }
12
+ };
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Bing Webmaster Tools plugin JSX component.
3
+ * @module view/plugin/bing_webmaster
4
+ */
5
+ const { Component, cacheComponent } = require("../../include/util/common");
6
+ /**
7
+ * Bing Webmaster Tools plugin JSX component.
8
+ *
9
+ * @see https://www.bing.com/toolbox/webmaster/
10
+ * @example
11
+ * <BingWebmaster trackingId="******" />
12
+ */
13
+ class BingWebmaster extends Component {
14
+ render() {
15
+ const { trackingId } = this.props;
16
+
17
+ return <meta name="msvalidate.01" content={trackingId} />;
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Cacheable Bing Webmaster Tools plugin JSX component.
23
+ * <p>
24
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
25
+ * ({@link module:hexo/filter/locals}).
26
+ *
27
+ * @see module:util/cache.cacheComponent
28
+ * @example
29
+ * <BingWebmaster.Cacheable
30
+ * head={true}
31
+ * plugin={{ tracking_id: '*******' }} />
32
+ */
33
+ BingWebmaster.Cacheable = cacheComponent(
34
+ BingWebmaster,
35
+ "plugin.bingwebmaster",
36
+ (props) => {
37
+ const { head, plugin } = props;
38
+ if (!head || !plugin.tracking_id) {
39
+ return null;
40
+ }
41
+ return {
42
+ trackingId: plugin.tracking_id,
43
+ };
44
+ },
45
+ );
46
+
47
+ module.exports = BingWebmaster;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Busuanzi visitor counter plugin JSX component.
3
+ * @module view/plugin/baidu_analytics
4
+ */
5
+ const { Component, cacheComponent } = require("../../include/util/common");
6
+ /**
7
+ * Busuanzi visitor counter plugin JSX component.
8
+ *
9
+ * @see https://busuanzi.ibruce.info/
10
+ * @example
11
+ * <Busuanzi />
12
+ */
13
+ class Busuanzi extends Component {
14
+ render() {
15
+ return (
16
+ // busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js
17
+ <script defer src="/js/busuanzi.js"></script>
18
+ // <script src="https://vercount.one/js" defer={true}></script>
19
+ );
20
+ }
21
+ }
22
+
23
+ /**
24
+ * Cacheable Busuanzi visitor counter plugin JSX component.
25
+ * <p>
26
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
27
+ * ({@link module:hexo/filter/locals}).
28
+ *
29
+ * @see module:util/cache.cacheComponent
30
+ * @example
31
+ * <Busuanzi.Cacheable head={true} />
32
+ */
33
+ Busuanzi.Cacheable = cacheComponent(Busuanzi, "plugin.busuanzi", (props) => {
34
+ if (!props.head) {
35
+ return null;
36
+ }
37
+ return {};
38
+ });
39
+
40
+ module.exports = Busuanzi;
@@ -0,0 +1,22 @@
1
+ const { Component, cacheComponent } = require("../../include/util/common");
2
+
3
+ class Clarity extends Component {
4
+ render() {
5
+ const { trackingId } = this.props;
6
+
7
+ const js = `(function(c,l,a,r,i,t,y){ c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)}; t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i; y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y); })(window, document, "clarity", "script", "${trackingId}");`;
8
+ return <script dangerouslySetInnerHTML={{ __html: js }}></script>;
9
+ }
10
+ }
11
+
12
+ Clarity.Cacheable = cacheComponent(Clarity, "plugin.clarity", (props) => {
13
+ const { head, plugin } = props;
14
+ if (!head || !plugin.tracking_id) {
15
+ return null;
16
+ }
17
+ return {
18
+ trackingId: plugin.tracking_id,
19
+ };
20
+ });
21
+
22
+ module.exports = Clarity;
@@ -0,0 +1,136 @@
1
+ const { Component, cacheComponent } = require("../../include/util/common");
2
+ /**
3
+ * A JSX component for alerting users about the use of cookies.
4
+ *
5
+ * @see https://www.osano.com/cookieconsent/
6
+ * @example
7
+ * <CookieConsent
8
+ * head={true}
9
+ * type="info"
10
+ * theme="classic"
11
+ * static={false}
12
+ * position="bottom-left"
13
+ * policyLink="/path/to/cookie/policy"
14
+ * text={{
15
+ * message: 'This website uses cookies to improve your experience.',
16
+ * dismiss: 'Got it!',
17
+ * allow: 'Allow cookies',
18
+ * deny: 'Decline',
19
+ * link: 'Learn more',
20
+ * policy: 'Cookie Policy',
21
+ * }}
22
+ * cssUrl="/path/to/cookieconsent.css"
23
+ * jsUrl="/path/to/cookieconsent.js" />
24
+ */
25
+ class CookieConsent extends Component {
26
+ render() {
27
+ const { head, text, jsUrl, cssUrl } = this.props;
28
+ const { type, theme, position, policyLink } = this.props;
29
+ const { message, dismiss, allow, deny, link, policy } = text;
30
+
31
+ const js = `window.addEventListener("load", () => {
32
+ window.cookieconsent.initialise({
33
+ type: ${JSON.stringify(type)},
34
+ theme: ${JSON.stringify(theme)},
35
+ static: ${JSON.stringify(this.props.static)},
36
+ position: ${JSON.stringify(position)},
37
+ content: {
38
+ message: ${JSON.stringify(message)},
39
+ dismiss: ${JSON.stringify(dismiss)},
40
+ allow: ${JSON.stringify(allow)},
41
+ deny: ${JSON.stringify(deny)},
42
+ link: ${JSON.stringify(link)},
43
+ policy: ${JSON.stringify(policy)},
44
+ href: ${JSON.stringify(policyLink)},
45
+ },
46
+ palette: {
47
+ popup: {
48
+ background: "var(--base)",
49
+ text: "var(--text)"
50
+ },
51
+ button: {
52
+ background: "var(--blue)"
53
+ },
54
+ },
55
+ });
56
+ });`;
57
+
58
+ if (head) {
59
+ return (
60
+ <link
61
+ rel="preload"
62
+ href={cssUrl}
63
+ as="style"
64
+ onload="this.onload=null;this.rel='stylesheet'"
65
+ />
66
+ );
67
+ }
68
+ return (
69
+ <>
70
+ <script src={jsUrl} defer={true} onLoad={js}></script>
71
+ {/* <script dangerouslySetInnerHTML={{ __html: js }}></script> */}
72
+ </>
73
+ );
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Cacheable JSX component for alerting users about the use of cookies.
79
+ * <p>
80
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
81
+ * ({@link module:hexo/filter/locals}).
82
+ *
83
+ * @see module:util/cache.cacheComponent
84
+ * @example
85
+ * <CookieConsent.Cacheable
86
+ * head={true}
87
+ * plugin={{
88
+ * info: "info",
89
+ * theme: "classic",
90
+ * static: false,
91
+ * position: "bottom-left",
92
+ * policyLink: "/path/to/cookie/policy"
93
+ * }}
94
+ * helper={{
95
+ * __: function() {...},
96
+ * cdn: function() {...}
97
+ * }} />
98
+ */
99
+ CookieConsent.Cacheable = cacheComponent(
100
+ CookieConsent,
101
+ "plugin.cookieconsent",
102
+ (props) => {
103
+ const { head, plugin, helper } = props;
104
+ const {
105
+ type = "info",
106
+ theme = "edgeless",
107
+ position = "bottom-left",
108
+ policyLink = "https://www.cookiesandyou.com/",
109
+ } = plugin;
110
+
111
+ return {
112
+ head,
113
+ type,
114
+ theme,
115
+ position,
116
+ policyLink,
117
+ static: plugin.static || false,
118
+ text: {
119
+ message: helper.__("plugin.cookie_consent.message"),
120
+ dismiss: helper.__("plugin.cookie_consent.dismiss"),
121
+ allow: helper.__("plugin.cookie_consent.allow"),
122
+ deny: helper.__("plugin.cookie_consent.deny"),
123
+ link: helper.__("plugin.cookie_consent.link"),
124
+ policy: helper.__("plugin.cookie_consent.policy"),
125
+ },
126
+ cssUrl: helper.cdn(
127
+ "cookieconsent",
128
+ "3.1.1",
129
+ "build/cookieconsent.min.css",
130
+ ),
131
+ jsUrl: helper.cdn("cookieconsent", "3.1.1", "build/cookieconsent.min.js"),
132
+ };
133
+ },
134
+ );
135
+
136
+ module.exports = CookieConsent;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Google Analytics plugin JSX component.
3
+ * @module view/plugin/google_analytics
4
+ */
5
+ const {
6
+ Component,
7
+ Fragment,
8
+ cacheComponent,
9
+ } = require("../../include/util/common");
10
+
11
+ /**
12
+ * Google Analytics plugin JSX component.
13
+ *
14
+ * @see https://analytics.google.com/analytics/web
15
+ * @example
16
+ * <GoogleAnalytics trackingId="******" />
17
+ */
18
+ class GoogleAnalytics extends Component {
19
+ render() {
20
+ const { trackingId } = this.props;
21
+
22
+ const js = `window.dataLayer = window.dataLayer || [];
23
+ function gtag(){dataLayer.push(arguments);}
24
+ gtag('js', new Date());
25
+
26
+ gtag('config', '${trackingId}');`;
27
+
28
+ return (
29
+ <Fragment>
30
+ <script
31
+ async={true}
32
+ src={`https://www.googletagmanager.com/gtag/js?id=${trackingId}`}
33
+ ></script>
34
+ <script dangerouslySetInnerHTML={{ __html: js }}></script>
35
+ </Fragment>
36
+ );
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Cacheable Google Analytics plugin JSX component.
42
+ * <p>
43
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
44
+ * ({@link module:hexo/filter/locals}).
45
+ *
46
+ * @see module:util/cache.cacheComponent
47
+ * @example
48
+ * <GoogleAnalytics.Cacheable
49
+ * head={true}
50
+ * plugin={{ tracking_id: '*******' }} />
51
+ */
52
+ GoogleAnalytics.Cacheable = cacheComponent(
53
+ GoogleAnalytics,
54
+ "plugin.googleanalytics",
55
+ (props) => {
56
+ const { head, plugin } = props;
57
+ if (!head || !plugin.tracking_id) {
58
+ return null;
59
+ }
60
+ return {
61
+ trackingId: plugin.tracking_id,
62
+ };
63
+ },
64
+ );
65
+
66
+ module.exports = GoogleAnalytics;
@@ -0,0 +1,41 @@
1
+ const { Component, cacheComponent } = require("../../include/util/common");
2
+
3
+ class GoogleAnalytics extends Component {
4
+ render() {
5
+ const { trackingId, head } = this.props;
6
+
7
+ if (head) {
8
+ const js = `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
9
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
10
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
11
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
12
+ })(window,document,'script','dataLayer','${trackingId}');`;
13
+ return <script dangerouslySetInnerHTML={{ __html: js }}></script>;
14
+ }
15
+
16
+ return (
17
+ <noscript
18
+ dangerouslySetInnerHTML={{
19
+ __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=${trackingId}" height="0" width="0" style="display:none;visibility:hidden"></iframe>`,
20
+ }}
21
+ ></noscript>
22
+ );
23
+ }
24
+ }
25
+
26
+ GoogleAnalytics.Cacheable = cacheComponent(
27
+ GoogleAnalytics,
28
+ "plugin.google_tag_manager",
29
+ (props) => {
30
+ const { head, plugin } = props;
31
+ if (!plugin || !plugin.tracking_id) {
32
+ return null;
33
+ }
34
+ return {
35
+ trackingId: plugin.tracking_id,
36
+ head: Boolean(head),
37
+ };
38
+ },
39
+ );
40
+
41
+ module.exports = GoogleAnalytics;
@@ -0,0 +1,39 @@
1
+ const {
2
+ Component,
3
+ Fragment,
4
+ cacheComponent,
5
+ } = require("../../include/util/common");
6
+
7
+ const netlifyJs = `if (window.netlifyIdentity) {
8
+ window.netlifyIdentity.on("init", function(user) {
9
+ if (!user) {
10
+ window.netlifyIdentity.on("login", function() {
11
+ document.location.href = "/admin/";
12
+ });
13
+ }
14
+ });
15
+ }`;
16
+
17
+ class Netlify extends Component {
18
+ render() {
19
+ if (this.props.head) {
20
+ return null;
21
+ }
22
+ return (
23
+ <Fragment>
24
+ <script
25
+ defer
26
+ src="https://identity.netlify.com/v1/netlify-identity-widget.js"
27
+ ></script>
28
+ <script defer dangerouslySetInnerHTML={{ __html: netlifyJs }}></script>
29
+ </Fragment>
30
+ );
31
+ }
32
+ }
33
+
34
+ Netlify.Cacheable = cacheComponent(Netlify, "plugin.netlify", (props) => {
35
+ const { head } = props;
36
+ return { head };
37
+ });
38
+
39
+ module.exports = Netlify;
@@ -0,0 +1,20 @@
1
+ const { Component, Fragment } = require("../../include/util/common");
2
+
3
+ class Pjax extends Component {
4
+ render() {
5
+ if (this.props.head) {
6
+ return null;
7
+ }
8
+ const { helper } = this.props;
9
+ const { url_for, cdn } = helper;
10
+
11
+ return (
12
+ <Fragment>
13
+ <script defer src={cdn("pjax", "0.2.8", "pjax.min.js")}></script>
14
+ <script defer src={url_for("/js/pjax.js")}></script>
15
+ </Fragment>
16
+ );
17
+ }
18
+ }
19
+
20
+ module.exports = Pjax;
@@ -0,0 +1,69 @@
1
+ const { Component, cacheComponent } = require("../../include/util/common");
2
+
3
+ /**
4
+ * Statcounter statistics plugin JSX component.
5
+ *
6
+ * @see https://statcounter.com/
7
+ * @example
8
+ * <Statcounter project="******" security="******" />
9
+ */
10
+ class Statcounter extends Component {
11
+ render() {
12
+ const { project, security } = this.props;
13
+
14
+ const js = `
15
+ var sc_project=${JSON.stringify(project)};
16
+ var sc_invisible=1;
17
+ var sc_security=${JSON.stringify(security)};
18
+ var sc_https=1;
19
+ var sc_remove_link=1;`;
20
+ return (
21
+ <>
22
+ <script dangerouslySetInnerHTML={{ __html: js }}></script>
23
+ <script
24
+ src="https://www.statcounter.com/counter/counter.js"
25
+ async
26
+ ></script>
27
+ <noscript>
28
+ <div class="statcounter">
29
+ <img
30
+ class="statcounter"
31
+ src={`https://c.statcounter.com/${project}/0/${security}/1/`}
32
+ alt="real time web analytics"
33
+ />
34
+ </div>
35
+ </noscript>
36
+ </>
37
+ );
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Cacheable Statcounter statistics plugin JSX component.
43
+ * <p>
44
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
45
+ * ({@link module:hexo/filter/locals}).
46
+ *
47
+ * @see module:util/cache.cacheComponent
48
+ * @example
49
+ * <Statcounter.Cacheable
50
+ * head={false}
51
+ * plugin={{ project: '******', security: '******' }} />
52
+ */
53
+ Statcounter.Cacheable = cacheComponent(
54
+ Statcounter,
55
+ "plugin.statcounter",
56
+ (props) => {
57
+ const { head, plugin } = props;
58
+ const { project, security } = plugin;
59
+ if (head || !project || !security) {
60
+ return null;
61
+ }
62
+ return {
63
+ project,
64
+ security,
65
+ };
66
+ },
67
+ );
68
+
69
+ module.exports = Statcounter.Cacheable;
@@ -0,0 +1,51 @@
1
+ const { Component, cacheComponent } = require("../../include/util/common");
2
+ /**
3
+ * Twitter conversion tracking plugin JSX component.
4
+ *
5
+ * @see https://business.twitter.com/en/help/campaign-measurement-and-analytics/conversion-tracking-for-websites.html
6
+ * @example
7
+ * <TwiterCT pixelId="******" />
8
+ */
9
+ class TwiterCT extends Component {
10
+ render() {
11
+ const { pixelId } = this.props;
12
+
13
+ const js = `
14
+ !function(e,t,n,s,u,a){e.twq||(s=e.twq=function(){s.exe?s.exe.apply(s,arguments):s.queue.push(arguments);
15
+ },s.version='1.1',s.queue=[],u=t.createElement(n),u.async=!0,u.src='//static.ads-twitter.com/uwt.js',
16
+ a=t.getElementsByTagName(n)[0],a.parentNode.insertBefore(u,a))}(window,document,'script');
17
+ twq('init', ${JSON.stringify(pixelId)});
18
+ twq('track', 'PageView');
19
+ `;
20
+
21
+ return <script dangerouslySetInnerHTML={{ __html: js }}></script>;
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Cacheable Twitter conversion tracking plugin JSX component.
27
+ * <p>
28
+ * This class is supposed to be used in combination with the <code>locals</code> hexo filter
29
+ * ({@link module:hexo/filter/locals}).
30
+ *
31
+ * @see module:util/cache.cacheComponent
32
+ * @example
33
+ * <TwiterCT.Cacheable
34
+ * head={false}
35
+ * plugin={{ pixel_id: '******' }} />
36
+ */
37
+ TwiterCT.Cacheable = cacheComponent(
38
+ TwiterCT,
39
+ "plugin.twitterconversiontracking",
40
+ (props) => {
41
+ const { head, plugin } = props;
42
+ if (head || !plugin.pixel_id) {
43
+ return null;
44
+ }
45
+ return {
46
+ pixelId: plugin.pixel_id,
47
+ };
48
+ },
49
+ );
50
+
51
+ module.exports = TwiterCT;
@@ -0,0 +1,16 @@
1
+ const { Component } = require("../include/util/common");
2
+ const Article = require("./common/article");
3
+ const Widgets = require("./common/toc");
4
+
5
+ module.exports = class extends Component {
6
+ render() {
7
+ const { config, page, helper } = this.props;
8
+
9
+ return (
10
+ <>
11
+ <Article config={config} page={page} helper={helper} index={false} />
12
+ <Widgets {...this.props} />
13
+ </>
14
+ );
15
+ }
16
+ };