simpread/src/read/read.jsx
2018-06-20 10:31:34 +08:00

278 lines
9.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

console.log( "=== simpread read load ===" )
import ProgressBar from 'schedule';
import * as spec from 'special';
import ReadCtlbar from 'readctlbar';
import * as toc from 'toc';
import * as modals from 'modals';
import * as se from 'siteeditor';
import * as kbd from 'keyboard';
import { storage, Clone } from 'storage';
import th from 'theme';
import * as ss from 'stylesheet';
import {browser} from 'browser';
import * as msg from 'message';
import * as highlight from 'highlight';
import * as run from 'runtime';
import * as tooltip from 'tooltip';
import * as waves from 'waves';
const rdcls = "simpread-read-root",
bgtmpl = `<div class="${rdcls}"></div>`,
rdclsjq = "." + rdcls,
$root = $( "html" ),
theme = "simpread-theme-root";
const Footer = () => {
return (
<sr-rd-footer>
<sr-rd-footer-group>
<sr-rd-footer-line></sr-rd-footer-line>
<sr-rd-footer-text>全文完</sr-rd-footer-text>
<sr-rd-footer-line></sr-rd-footer-line>
</sr-rd-footer-group>
<sr-rd-footer-copywrite>本文由 <a href="http://ksria.com/simpread" target="_blank">简悦 SimpRead</a> </sr-rd-footer-copywrite>
</sr-rd-footer>
)
}
class Read extends React.Component {
componentWillMount() {
$( "body" ).addClass( "simpread-hidden" );
th.Change( this.props.read.theme );
}
async componentDidMount() {
if ( $root.find( "sr-rd-content-error" ).length > 0 ) {
let msg = `当前页面结构改变导致不匹配阅读模式,请报告 <a href="https://github.com/Kenshin/simpread/issues/new" target="_blank">此页面</a>`;
this.props.read.highlight == true && ( msg += `,已启动 <a href='https://github.com/Kenshin/simpread/wiki/%E4%B8%B4%E6%97%B6%E9%98%85%E8%AF%BB%E6%A8%A1%E5%BC%8F' target='_blank' >临时阅读模式</a>。` )
new Notify().Render( 2, msg );
this.componentWillUnmount();
this.props.read.highlight == true && Highlight().done( dom => {
storage.pr.TempMode( "read", dom );
Render();
});
} else {
$root
.addClass( "simpread-font" )
.addClass( theme )
.find( rdclsjq )
.addClass( theme )
.sreffect( { opacity: 1 }, { delay: 100 })
.addClass( "simpread-read-root-show" );
this.props.read.fontfamily && ss.FontFamily( this.props.read.fontfamily );
this.props.read.fontsize && ss.FontSize( this.props.read.fontsize );
this.props.read.layout && ss.Layout( this.props.read.layout );
ss.Preview( this.props.read.custom );
storage.pr.state == "txt" && $( "sr-rd-content" ).css({ "word-wrap": "break-word", "white-space": "pre-wrap" });
storage.pr.current.site.desc == "" && $( "sr-rd-desc" ).addClass( "simpread-hidden" );
excludes( $("sr-rd-content"), this.props.wrapper.exclude );
storage.pr.Beautify( $( "sr-rd-content" ) );
storage.pr.Format( rdcls );
!this.props.wrapper.avatar && this.props.read.toc && toc.Render( "sr-read", $( "sr-rd-content" ), this.props.read.theme, this.props.read.toc_hide );
this.props.read.site.css && this.props.read.site.css.length > 0 &&
ss.SiteCSS( this.props.read.site.css );
kbd.Render( $( "sr-rd-content" ));
tooltip.Render( rdclsjq );
waves.Render({ root: rdclsjq });
storage.Statistics( "read" );
// test code
const plugin = {
user : {
uid : "vdmq0t08-ehpe-v5x6-168w-r9e2xg25lung",
name : "Kenshin Wang",
email : "kenshin@ksria.com",
},
version : "0.0.1",
id : "kw36BtjGu0",
name : "为阅读模式增加字数统计。",
icon : {
type : "",
bgColor : "#2196f3",
},
create : "Tue Jun 19 2018 17:08:18 GMT+0800 (CST)",
update : "",
global : true,
category : 0,
site : "",
style : "sr-plugin-count{position:fixed;display:block;left:5px;bottom:5px;font-size:12px}",
script : "var count=$content.text().length,html='<sr-plugin-count> 共计:'+count+' 个字 </sr-plugin-count>';$content.append(html);",
};
run.Install( "kw36BtjGu0" );
run.Exec( plugin );
}
}
componentWillUnmount() {
ss.FontSize( "" );
$root.removeClass( theme )
.removeClass( "simpread-font" );
$root.attr("style") && $root.attr( "style", $root.attr("style").replace( "font-size: 62.5%!important", "" ));
ss.SiteCSS();
$( "body" ).removeClass( "simpread-hidden" );
$( rdclsjq ).remove();
tooltip.Exit( rdclsjq );
}
/**
* Controlbar action event
* @param {string} type, include: exit, setting, save, scroll, option
* @param {string} value
* @param {string} custom value, storage.current.custom.art.xxx
*/
onAction( type, value, custom ) {
switch ( type ) {
case "exit":
this.exit();
break;
case "setting":
modals.Render( ()=>setTimeout( ()=>se.Render(), 500 ));
break;
case "siteeditor":
se.Render();
break;
case "fontfamily":
case "fontsize":
case "layout":
case "theme":
case "shortcuts":
case "custom":
type != "custom" ? storage.current[type]=value : storage.current.custom.art[custom]=value;
storage.Setcur( storage.current.mode );
break;
case "remove":
new Notify().Render( "移动鼠标选择不想显示的内容,只针对本次有效。" );
$( "panel-bg" ).length > 0 && $( "panel-bg" ).trigger( "click" );
Highlight().done( dom => {
$(dom).remove();
});
break;
case "highlight":
new Notify().Render( "移动鼠标选择高亮区域,以便生成阅读模式,将会在页面刷新后失效。" );
this.exit();
Highlight().done( dom => {
storage.pr.TempMode( "read", dom );
Render();
});
break;
/*
case "scroll":
$( "sr-read" ).velocity( "scroll", { offset: $( "body" ).scrollTop() + value });
break;
*/
}
}
// exit read mode
exit() {
Exit();
}
render() {
const Article = this.props.wrapper.avatar ?
<spec.Multiple include={ this.props.wrapper.include } avatar={ this.props.wrapper.avatar } /> :
<sr-rd-content dangerouslySetInnerHTML={{__html: this.props.wrapper.include }} ></sr-rd-content>;
const Page = this.props.wrapper.paging &&
<spec.Paging paging={ this.props.wrapper.paging } />;
return (
<sr-read>
<ProgressBar show={ this.props.read.progress } />
<sr-rd-title>{ this.props.wrapper.title }</sr-rd-title>
<sr-rd-desc>{ this.props.wrapper.desc }</sr-rd-desc>
{ Article }
{ Page }
<Footer />
<ReadCtlbar show={ this.props.read.controlbar }
multi={ this.props.wrapper.avatar ? true : false }
type={ this.props.wrapper.name }
site={{ title: this.props.wrapper.title, url: window.location.href }}
custom={ this.props.read.custom } onAction={ (t,v,c)=>this.onAction( t,v,c ) }/>
</sr-read>
)
}
}
/**
* Render entry
*
*/
function Render() {
storage.pr.ReadMode();
console.log( "current puread object is ", storage.pr )
ReactDOM.render( <Read read={ storage.current } wrapper={ storage.pr.html } />, getReadRoot() );
}
/**
* High light current page to read mode( read only )
*/
function Highlight() {
const dtd = $.Deferred();
highlight.Start().done( dom => {
dtd.resolve( dom );
});
return dtd;
}
/**
* Verify simpread-read-root tag exit
*
* @param {boolean}
* @return {boolean}
*/
function Exist( action ) {
if ( $root.find( rdclsjq ).length > 0 ) {
action && modals.Render( ()=>setTimeout( ()=>se.Render(), 500 ));
return true;
} else {
return false;
}
}
/**
* Exit
*/
function Exit() {
$( rdclsjq ).sreffect( { opacity: 0 }, {
delay: 100,
complete: ( elements ) => {
ReactDOM.unmountComponentAtNode( getReadRoot() );
}
}).addClass( "simpread-read-root-hide" );
}
/**
* Get read root
*
* @return {jquery} read root jquery object
*/
function getReadRoot() {
if ( $root.find( rdclsjq ).length == 0 ) {
$root.append( bgtmpl );
}
return $( rdclsjq )[0];
}
/**
* Set exclude style
*
* @param {jquery} jquery object
* @param {array} hidden html
*/
function excludes( $target, exclude ) {
const tags = storage.pr.Exclude( $target );
$target.find( tags ).remove();
}
export { Render, Exist, Exit, Highlight };