refactor(layout): plugin to jsx

This commit is contained in:
ppoffice 2019-12-22 12:16:19 -05:00
parent 725bce4cd5
commit b0f16cf892
41 changed files with 358 additions and 192 deletions

View File

@ -27,6 +27,8 @@ module.exports = cacheComponent(Alipay, 'donate.alipay', props => {
type: props.type,
qrcode: props.qrcode,
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -26,6 +26,8 @@ module.exports = cacheComponent(Patreon, 'donate.petreon', props => {
type: props.type,
url: props.url,
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -34,6 +34,8 @@ module.exports = cacheComponent(Paypal, 'donate.paypal', props => {
business: props.business,
currencyCode: props.currency_code,
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -27,6 +27,8 @@ module.exports = cacheComponent(Wechat, 'donate.wechat', props => {
type: props.type,
qrcode: props.qrcode,
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -1,5 +0,0 @@
<% if (head) { %>
<style>body>.footer,body>.navbar,body>.section{opacity:0}</style>
<% } else { %>
<%- _js('js/animation') %>
<% } %>

21
layout/plugin/animejs.jsx Normal file
View File

@ -0,0 +1,21 @@
'use strict';
const { Component } = require('inferno');
const { cacheComponent } = require('../util/cache');
class AnimeJs extends Component {
render() {
if (this.props.head) {
return <style dangerouslySetInnerHTML={{ __html: 'body>.footer,body>.navbar,body>.section{opacity:0}' }}></style>;
}
return <script src={this.props.url_for('/js/animation.js')}></script>;
}
}
module.exports = cacheComponent(AnimeJs, 'plugin.animejs', props => {
return {
head: props.head,
url_for: props.url_for
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { plugin } = locals;
if (!plugin) {
return null;
}
return locals;
}

View File

@ -1,8 +0,0 @@
<% if (head) { %>
<%- _css('css/back-to-top') %>
<% } else { %>
<a id="back-to-top" title="<%= __('plugin.backtotop') %>" href="javascript:;">
<i class="fas fa-chevron-up"></i>
</a>
<%- _js('js/back-to-top', true) %>
<% } %>

View File

@ -0,0 +1,31 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class BackToTop extends Component {
render() {
const { head, __, url_for } = this.props;
if (head) {
return <link rel="stylesheet" href={url_for('/css/back-to-top.css')} />;
}
return <Fragment>
<a id="back-to-top" title={__('plugin.backtotop')} href="javascript:;">
<i className="fas fa-chevron-up"></i>
</a>
<script src={url_for('/js/back-to-top.js')} defer={true}></script>
</Fragment>;
}
}
module.exports = cacheComponent(BackToTop, 'plugin.backtotop', props => {
return {
head: props.head,
__: props.__,
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { plugin } = locals;
if (!plugin) {
return null;
}
return locals;
}

View File

@ -1,9 +0,0 @@
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?<%= get_config_from_obj(plugin, 'tracking_id') %>";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>

View File

@ -0,0 +1,29 @@
'use strict';
const { Component } = require('inferno');
const { cacheComponent } = require('../util/cache');
class BaiduAnalytics extends Component {
render() {
const { trackingId } = this.props;
const js = `var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "//hm.baidu.com/hm.js?${trackingId}";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();`;
return <script dangerouslySetInnerHTML={{ __html: js }}></script>;
}
}
module.exports = cacheComponent(BaiduAnalytics, 'plugin.baiduanalytics', props => {
if (!props.head || !props.tracking_id) {
return null;
}
return {
trackingId: props.tracking_id
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { head, plugin } = locals;
if (!head || !plugin.tracking_id) {
return null;
}
return locals;
}

View File

@ -1 +0,0 @@
<script async="" src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

View File

@ -0,0 +1,17 @@
'use strict';
const { Component } = require('inferno');
const { cacheComponent } = require('../util/cache');
class Busuanzi extends Component {
render() {
return <script src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" async={true}></script>;
}
}
module.exports = cacheComponent(Busuanzi, 'plugin.busuanzi', props => {
if (!props.head) {
return null;
}
return {};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { head, plugin } = locals;
if (!head || !plugin) {
return null;
}
return locals;
}

View File

@ -1,8 +0,0 @@
<% if (head) { %>
<%- _css(cdn('lightgallery', '1.6.8', 'dist/css/lightgallery.min.css')) %>
<%- _css(cdn('justifiedGallery', '3.7.0', 'dist/css/justifiedGallery.min.css')) %>
<% } else { %>
<%- _js(cdn('lightgallery', '1.6.8', 'dist/js/lightgallery.min.js'), true) %>
<%- _js(cdn('justifiedGallery', '3.7.0', 'dist/js/jquery.justifiedGallery.min.js'), true) %>
<%- _js('js/gallery', true) %>
<% } %>

32
layout/plugin/gallery.jsx Normal file
View File

@ -0,0 +1,32 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class Gallery extends Component {
render() {
const { head, cdn, url_for } = this.props;
if (head) {
return <Fragment>
<link rel="stylesheet" href={cdn('lightgallery', '1.6.8', 'dist/css/lightgallery.min.css')} />
<link rel="stylesheet" href={cdn('justifiedGallery', '3.7.0', 'dist/css/justifiedGallery.min.css')} />
</Fragment>;
}
return <Fragment>
<script src={cdn('lightgallery', '1.6.8', 'dist/js/lightgallery.min.js')} defer={true}></script>
<script src={cdn('justifiedGallery', '3.7.0', 'dist/js/jquery.justifiedGallery.min.js')} defer={true}></script>
<script src={url_for('/js/gallery.js')} defer={true}></script>
</Fragment>;
}
}
module.exports = cacheComponent(Gallery, 'plugin.gallery', props => {
return {
head: props.head,
cdn: props.cdn,
url_for: props.url_for,
// for cache purpose only
_providers: props.providers.cdn
};
});

View File

@ -1,6 +0,0 @@
module.exports = (ctx, locals) => {
if (!locals.plugin) {
return null;
}
return locals;
}

View File

@ -1,8 +0,0 @@
<script async src="https://www.googletagmanager.com/gtag/js?id=<%= get_config_from_obj(plugin, 'tracking_id') %>"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '<%= get_config_from_obj(plugin, 'tracking_id') %>');
</script>

View File

@ -0,0 +1,30 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class GoogleAnalytics extends Component {
render() {
const { trackingId } = this.props;
const js = `window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${trackingId}');`;
return <Fragment>
<script src={`https://www.googletagmanager.com/gtag/js?id=${trackingId}`} async={true}></script>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>;
}
}
module.exports = cacheComponent(GoogleAnalytics, 'plugin.googleanalytics', props => {
if (!props.head || !props.tracking_id) {
return null;
}
return {
trackingId: props.tracking_id
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { head, plugin } = locals;
if (!head || !plugin.tracking_id) {
return null;
}
return locals;
}

View File

@ -1,10 +0,0 @@
<script>
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:<%= get_config_from_obj(plugin, 'site_id') %>,hjsv:6};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
</script>

32
layout/plugin/hotjar.jsx Normal file
View File

@ -0,0 +1,32 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class Hotjar extends Component {
render() {
const { siteId } = this.props;
const js = `(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:${siteId},hjsv:6};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');`;
return <Fragment>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>;
}
}
module.exports = cacheComponent(Hotjar, 'plugin.hotjar', props => {
if (!props.head || !props.site_id) {
return null;
}
return {
siteId: props.site_id
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { head, plugin } = locals;
if (!head || !plugin.site_id) {
return null;
}
return locals;
}

View File

@ -1,22 +0,0 @@
<%- _js(cdn('mathjax', '2.7.5', 'unpacked/MathJax.js?config=TeX-MML-AM_CHTML'), true) %>
<script>
document.addEventListener('DOMContentLoaded', function () {
MathJax.Hub.Config({
'HTML-CSS': {
matchFontHeight: false
},
SVG: {
matchFontHeight: false
},
CommonHTML: {
matchFontHeight: false
},
tex2jax: {
inlineMath: [
['$','$'],
['\\(','\\)']
]
}
});
});
</script>

46
layout/plugin/mathjax.jsx Normal file
View File

@ -0,0 +1,46 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class Mathjax extends Component {
render() {
const { cdn } = this.props;
const js = `document.addEventListener('DOMContentLoaded', function () {
MathJax.Hub.Config({
'HTML-CSS': {
matchFontHeight: false
},
SVG: {
matchFontHeight: false
},
CommonHTML: {
matchFontHeight: false
},
tex2jax: {
inlineMath: [
['$','$'],
['\\(','\\)']
]
}
});
});`;
return <Fragment>
<script src={cdn('mathjax', '2.7.5', 'unpacked/MathJax.js?config=TeX-MML-AM_CHTML')} async={true}></script>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>;
}
}
module.exports = cacheComponent(Mathjax, 'plugin.mathjax', props => {
if (props.head) {
return null;
}
return {
cdn: props.cdn,
// for cache purpose only
_providers: props.providers.cdn
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { head, plugin } = locals;
if (head || !plugin) {
return null;
}
return locals;
}

View File

@ -1,20 +0,0 @@
<% if (head) { %>
<%- _css(cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.css')) %>
<% } else { %>
<div id="outdated">
<h6>Your browser is out-of-date!</h6>
<p>Update your browser to view this website correctly. <a id="btnUpdateBrowser" href="http://outdatedbrowser.com/">Update
my browser now </a></p>
<p class="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<%- _js(cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.js'), true) %>
<script>
document.addEventListener("DOMContentLoaded", function () {
outdatedBrowser({
bgColor: '#f25648',
color: '#ffffff',
lowerThan: 'flex'
});
});
</script>
<% } %>

View File

@ -0,0 +1,44 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class OutdatedBrowser extends Component {
render() {
const { head, cdn } = this.props;
const js = `document.addEventListener("DOMContentLoaded", function () {
outdatedBrowser({
bgColor: '#f25648',
color: '#ffffff',
lowerThan: 'flex'
});
});`;
if (head) {
return <link rel="stylesheet" href={cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.css')} />;
}
return <Fragment>
<div id="outdated">
<h6>Your browser is out-of-date!</h6>
<p>
Update your browser to view this website correctly.&npsb;
<a id="btnUpdateBrowser" href="http://outdatedbrowser.com/">Update my browser now </a>
</p>
<p className="last"><a href="#" id="btnCloseUpdateBrowser" title="Close">&times;</a></p>
</div>
<script src={cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.js')} async={true}></script>
<script dangerouslySetInnerHTML={{ __html: js }}></script>
</Fragment>;
}
}
module.exports = cacheComponent(OutdatedBrowser, 'plugin.outdatedbrowser', props => {
return {
head: props.head,
cdn: props.cdn,
// for cache purpose only
_providers: props.providers.cdn
};
});

View File

@ -1,6 +0,0 @@
module.exports = (ctx, locals) => {
if (!locals.plugin) {
return null;
}
return locals;
}

View File

@ -1,2 +0,0 @@
<%- _css('css/progressbar') %>
<%- _js(cdn('pace-js', '1.0.2', 'pace.min.js')) %>

View File

@ -0,0 +1,27 @@
'use strict';
const { Component, Fragment } = require('inferno');
const { cacheComponent } = require('../util/cache');
class ProgressBar extends Component {
render() {
const { url_for, cdn } = this.props;
return <Fragment>
<link rel="stylesheet" href={url_for('/css/progressbar.css')} />
<script src={cdn('pace-js', '1.0.2', 'pace.min.js')}></script>
</Fragment>;
}
}
module.exports = cacheComponent(ProgressBar, 'plugin.progressbar', props => {
if (!props.head) {
return null;
}
return {
url_for: props.url_for,
cdn: props.cdn,
// for cache purpose only
_providers: props.providers.cdn
};
});

View File

@ -1,7 +0,0 @@
module.exports = (ctx, locals) => {
const { head, plugin } = locals;
if (!head || !plugin) {
return null;
}
return locals;
}

View File

@ -45,6 +45,8 @@ module.exports = cacheComponent(Baidu, 'search.baidu', props => {
return {
url: props.config.url,
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -83,6 +83,8 @@ module.exports = cacheComponent(Google, 'search.google', props => {
return {
cx: props.cx,
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -44,6 +44,8 @@ class Insight extends Component {
module.exports = cacheComponent(Insight, 'search.insight', props => {
return {
__: props.__,
url_for: props.url_for
url_for: props.url_for,
// for cache purpose only
_language: props.page.lang || props.page.language || props.language
};
});

View File

@ -5,7 +5,7 @@ const { cacheComponent } = require('../util/cache');
class BdShare extends Component {
render() {
const js = `window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "2", "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName('head')[0] || body).appendChild(createElement('script')).src = 'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=' + ~(-new Date() / 36e5)];`;
const js = 'window._bd_share_config = { "common": { "bdSnsKey": {}, "bdText": "", "bdMini": "2", "bdPic": "", "bdStyle": "0", "bdSize": "16" }, "share": {} }; with (document) 0[(getElementsByTagName(\'head\')[0] || body).appendChild(createElement(\'script\')).src = \'http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion=\' + ~(-new Date() / 36e5)];';
return <Fragment>
<div className="bdsharebuttonbox">
<a href="#" className="bds_more" data-cmd="more"></a>

View File

@ -8,7 +8,7 @@ class ShareJs extends Component {
const { cdn } = this.props;
return <Fragment>
<link rel="stylesheet" href={cdn('social-share.js', '1.0.16', 'dist/css/share.min.css')} />
<div class="social-share"></div>
<div className="social-share"></div>
<script src={cdn('social-share.js', '1.0.16', 'dist/js/social-share.min.js')}></script>
</Fragment>;
}

View File

@ -13,7 +13,7 @@ class ShareThis extends Component {
</div>;
}
return <Fragment>
<div class="sharethis-inline-share-buttons"></div>
<div className="sharethis-inline-share-buttons"></div>
<script src={installUrl} async={true}></script>
</Fragment>;
}

View File

@ -1,40 +1,44 @@
'use strict';
const crypto = require('crypto');
const { Component } = require('inferno');
const { Component } = require('inferno'); // eslint-disable-line no-unused-vars
const { createElement } = require('inferno-create-element');
const cache = {};
function computeHash(props) {
return crypto.createHash('md5').update(JSON.stringify(props)).digest("hex");
return crypto.createHash('md5').update(JSON.stringify(props)).digest('hex');
}
module.exports = {
/**
* Create cached component from a given component class.
* The cache ID is caculated from the input props.
*
*
* @param {Component} type JSX component class
* @param {string} prefix Cache ID prefix
* @param {Function} transform Transform the input props to target props and
* its result is used to compute cache ID
* @returns Cached JSX element if cache ID is found.
* @param {Function} transform Transform the input props to target props and
* its result is used to compute cache ID
* @returns Cached JSX element if cache ID is found.
* Return null if the props transform result is empty, which means the props
* passed to the createElement() indicates the element does not need to be created.
* Otherwise, create a new element and cache it if the transform function is provided.
*/
cacheComponent(type, prefix, transform) {
if (typeof transform !== 'function') {
return props => createElement(type, props);
} else {
return props => {
const targetProps = transform(props);
const cacheId = prefix + '-' + computeHash(targetProps);
if (!cacheId) {
return createElement(type, targetProps);
}
if (!cache[cacheId]) {
cache[cacheId] = createElement(type, targetProps);
}
return cache[cacheId];
};
}
return props => {
const targetProps = transform(props);
if (!targetProps) {
return null;
}
const cacheId = prefix + '-' + computeHash(targetProps);
if (!cacheId) {
return createElement(type, targetProps);
}
if (!cache[cacheId]) {
cache[cacheId] = createElement(type, targetProps);
}
return cache[cacheId];
};
}
};