supremetechnopriest / react-idle-timer Goto Github PK
View Code? Open in Web Editor NEWUser activity timer component
Home Page: https://idletimer.dev
License: MIT License
User activity timer component
Home Page: https://idletimer.dev
License: MIT License
running into issues with Idle Timer causing snapshots to break as it shows as null
From the interface, index.d.ts:
/**
* Function to call when user is idle
*/
onIdle?: () => void;
/**
* Function to call when user becomes active
*/
onActive?: () => void;
/**
* Function to call when user have an activity
*/
onAction?: () => void;
Each of these prop functions are missing the Event argument, e.
Hi Guys, thanks for developing this package for react. I have used it for session timeout and after we deployed the application for testing, it is not working as expected , sometimes. The timeout time is 10 mins and if the user is idle for more than 10 mins and when he comes back, he will get an alert popup that says your session is expired and on clicking ok, the application will kick out the user and display the login page for the user to login again. The issue is a couple of times, not every time, the testers say that they did not get the popup alert and the application will just freeze (this is not related to the idle timer, I think it is related to the authentication we used). I think the issue here is for some reason the idle timer did not fire the alert popup but I could not replicate the issue on my local machine which makes it difficult to troubleshoot.
Here is a sample of my code
componentDidMount() {
this.setState({
remaining: this.idleTimer.getRemainingTime(),
lastActive: this.idleTimer.getLastActiveTime(),
elapsed: this.idleTimer.getElapsedTime()
});
setInterval(() => {
this.setState({
remaining: this.idleTimer.getRemainingTime(),
lastActive: this.idleTimer.getLastActiveTime(),
elapsed: this.idleTimer.getElapsedTime()
});
},
1000);
}
onActive(e: any) {
console.log('user is active', e);
console.log('time remaining', this.state.remaining);
console.log("time elapsed", this.state.elapsed);
if (this.state.remaining === 0) {
console.log("Your session has been expired ....");
alert("Your session has expired and you will be redirected to the login page.");
this.logout();
}
}
and this is what I have on render
render() {
let timeout: any;
let timeoutDuration = document.getElementById('timeout');
if (timeoutDuration != null) {
timeout = timeoutDuration.getAttribute('data-param');
}
return (
<IdleTimer
ref={(ref: any) => { this.idleTimer = ref }}
element={document}
onActive={this.onActive}
onIdle={this.onIdle}
timeout={timeout} startOnLoad>
<WrappedComponent {...this.props} />
</IdleTimer>
);
}
Thanks for your help.
Please :)
I've made a reproduction here; the IdleTimer works in the app but does not work when mounted during a test:
https://codesandbox.io/s/6vzxx83r0z
I get the error:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check the render method of `WrapperComponent`.
I'm specifically using the same enzyme
and enzyme-adapter-react-16
versions listed in the package.json.
Hi I may have missed it, but I was wondering if you can start the timer in its idle state.
The use case is that at the start of the day we switch on the devices, open the app and a call to action is present for any clients who walk in before the idle state (set to 5 minutes) has activated.
Thanks
Fraser
After reaching idle state, I'd like the component to be a no-op. Currently, events are still bound (potential perf issue), and handlers still called (unless stopOnIdle=true). Calling this.idleTimer.componentWillUnmount()
does the trick - but it's not semantically correct.
Would prefer a this.idleTimer.destroy()
(or similar) or have 'stopOnIdle' include events binding also. Thoughts?
Hey man. Not sure if this is the right place to contact you regarding this, but there is a typo in the 'props' section of the readme. Instead of having 'onAction' and 'onActive' you have both bullet points saying 'onActive'. Just wanted to let you know, love using this library.
I can't run this project..While running error occurs
E:\Projects\react-idle-timer-master>npm run start
[email protected] start E:\Projects\react-idle-timer-master
NODE_ENV=development node examples/server
'NODE_ENV' is not recognized as an internal or external command,
operable program or batch file.
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! [email protected] start: NODE_ENV=development node examples/serve r
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] start script.
npm ERR! This is probably not a problem with npm. There is likely additional log
ging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\keystrokeslnc08\AppData\Roaming\npm-cache_logs\2018-04-25
T12_10_40_698Z-debug.log
What will I do to remove this error??
I have animations that are set to appear, based on a specific time in a video. My animations appear at the proper time, but they pulse on/off in sync with the setInterval() property (example below):
setInterval(() => {
this.setState({
remaining: this.idleTimer.getRemainingTime(),
lastActive: this.idleTimer.getLastActiveTime(),
elapsed: this.idleTimer.getElapsedTime()
})
}, 1000)
I am using React 16 and Popmotion animation library.
I want to implement this in my project. can this be used with typescript?
Hi, thank you for your great work, I'm trying to use this library in my App, but it seems that onActive
and onIdle
are triggered only one time. Tried use your example, but no success, the same thing happens. The odd thing is, if I do new Date().getTime()
and pass to the component as timeout
, all the mentioned callbacks are triggered, but if i do 1000 * 60 * 40
and pass the result as timeout don't
. Can you help with this one?
Hi,
I am using react-idle-timer package in my react application to detect the application idle. It works fine in chrome browser but not in mozila firfox v61.0.2 .
Any one can help me for the same.
Thanks.
I'm using this library in an isomorphic application with react 16 and I get a warning
react-dom-server.browser.development.js:104 Warning: setState(...): Can only update a mounting component. This usually means you called setState() outside componentWillMount() on the server. This is a no-op.
I've noticed the warning occurs when I move my mouse
the problem occures in handleEvents()
this.setState({
lastActive: +new Date(), // store when user was last active
pageX: e.pageX, // update mouse coord
pageY: e.pageY
})
cause of the issue was componentWillMount()
I've moved the _bindEvents in didMount. Also please note that WillMount is deprecated in react16
Line https://github.com/SupremeTechnopriest/react-idle-timer/blob/master/src/index.js#L321, should it instead be
if (!remaining) return
since idle state corresponds to remaining = 0
?
I've noticed that my timer will not start unless I click or move my mouse over the page. I'd like the idle timer to start right away regardless of whether or not there's human interaction.
Feature request:
If we use timeout={0}
, the IdleTimer
component to not create any timers at all, and just be a pass-through component for its child component (i.e. the app
).
Why?
I use location.search
to get params
. One of them is the timeout
param. When we want to debug our app, we do not want the IdleTimer
to reload the page (this is what it now does, after 120 seconds). So we want to disable it without any extra code, by just using 0
as our timeout param.
Of course, we could use a very large number for timeout (still, the timer will be counting) OR reformat the <IdleTimer />
component to render conditionally.
If you don't provide any body for IdleTimer it throws an error.
I've looked at the code and I think the problem is that you return a empty string if no children are provided:
render() {
return this.props.children ? this.props.children : '';
}
You probably should return null in that case. Or an empty div/span element.
My current workaround is to use it like this: <IdleTimer ...><div></div></IdleTimer>
Package.json for version 4.0.3 has main set to 'build/index.js'. The build directory is not present in the npm package.
Importing IdleTimer from 'react-idle-timer/dist/index.min.js' is a work around for now.
Given this markup,
<IdleTimer
onAction={this.onExternalUserIsStillWorking}
throttle={this.props.externalKeepAliveThrottleMs}
/>
the result is
Uncaught TypeError: n.throttledAction is not a function
at HTMLDocument.n._handleEvent (index.es.js:66)
every time the user moves the mouse or anything else.
(in versions 4.1.3 and 4.2.3)
I haven't cloned the code, just skimmed it quickly in-browser on github, so forgive me if this makes no sense, but I think this is because throttledAction
is set to a throttled props.onAction
if props.throttle > 0
during the constructor, but is never updated if the component receives props after that.
Meanwhile, _handleEvent
checks if throttle > 0
live from this.props
and tries to call this.throttledAction(e)
if it is.
But if props.throttle
didn't have a value during the constructor, this.throttledAction
is undefined, even though props.throttle
does have a value now.
It looks like _handleEvent
is the only place that this.throttledAction
is used...
Maybe just call throttled(onAction, throttle)()
directly from _handleEvent
?
No, I guess that might get it garbage-collected if there's no actual reference to the function...
What about something like this:
// Fire debounced, throttled or raw onAction callback with event
if (debounce > 0) {
+ if (onAction && !this.debouncedAction) {
+ this.debouncedAction = debounced(props.onAction, props.debounce);
+ }
this.debouncedAction(e);
} else if (throttle > 0) {
+ if (onAction && !this.throttledAction) {
+ this.throttledAction = throttled(props.onAction, props.throttle);
+ }
this.throttledAction(e);
} else {
onAction(e);
}
I moved the tId
from state variable to instance variable and it works well now.
when I navigate away from a page w/ an idle timer on it, i get the following error:
Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the undefined component.
Following the react-idle-timer docs, the instruction is to use ref="idleTimer"
.
ref="idleTimer"
brings me the following warning: "Using string literals in ref attributes is deprecated (react/no-string-refs)"
And leading me to https://reactjs.org/docs/refs-and-the-dom.html
Legacy API: String Refs
If you worked with React before, you might be familiar with an older API where the ref attribute is a string, like "textInput", and the DOM node is accessed as this.refs.textInput. We advise against it because string refs have some issues, are considered legacy, and are likely to be removed in one of the future releases.
In this case, what's is recommended?
If required change I could follow the recommendation and maybe update the docs?
Thank you!
Set debounce
for a couple of seconds, then move the mouse -- note "user did something" outputs every 2 seconds.
Let it become idle then move the mouse -- notice that "user is active" shows immediately.
Currently this imports date-fns library even if it is never used. As the formatter can be provided could this removed so that it doesnt add to bundles when never used. I appreciate this is a breaking change but the workaround is very small and makes the dependency more explicit.
Is there a reason ref
is mandatory on the typescript props interface? I don't really need in my use-case.
18 Jan 16:35:29 - Browserify error { [Error: Cannot find module 'redbox-react' from '/Users/muslimbaig/github/Elements-Admin/node_modules/react-idle-timer/build']
stream:
Labeled {
_readableState:
ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: [],
length: 0,
pipes: [Object],
pipesCount: 1,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null,
resumeScheduled: false },
readable: true,
domain: null,
_events:
{ end: [Object],
error: [Object],
data: [Function: ondata],
_mutate: [Object] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: true,
highWaterMark: 16,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false },
writable: true,
allowHalfOpen: true,
_options: { objectMode: true },
_wrapOptions: { objectMode: true },
_streams: [ [Object], [Object] ],
length: 2,
label: 'deps' } }
18 Jan 16:35:29 - Browserify error { [Error: Cannot find module 'react-transform-catch-errors' from '/Users/muslimbaig/github/Elements-Admin/node_modules/react-idle-timer/build']
stream:
Labeled {
_readableState:
ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: [],
length: 0,
pipes: [Object],
pipesCount: 1,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null,
resumeScheduled: false },
readable: true,
domain: null,
_events:
{ end: [Object],
error: [Object],
data: [Function: ondata],
_mutate: [Object] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: true,
highWaterMark: 16,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false },
writable: true,
allowHalfOpen: true,
_options: { objectMode: true },
_wrapOptions: { objectMode: true },
_streams: [ [Object], [Object] ],
length: 2,
label: 'deps' } }
18 Jan 16:35:29 - Browserify error { [Error: Cannot find module 'react-transform-hmr' from '/Users/muslimbaig/github/Elements-Admin/node_modules/react-idle-timer/build']
stream:
Labeled {
_readableState:
ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: [],
length: 0,
pipes: [Object],
pipesCount: 1,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null,
resumeScheduled: false },
readable: true,
domain: null,
_events:
{ end: [Object],
error: [Object],
data: [Function: ondata],
_mutate: [Object] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: true,
highWaterMark: 16,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false },
writable: true,
allowHalfOpen: true,
_options: { objectMode: true },
_wrapOptions: { objectMode: true },
_streams: [ [Object], [Object] ],
length: 2,
label: 'deps' } }
18 Jan 16:35:29 - Browserify error { [Error: Cannot find module 'lodash.bindall' from '/Users/muslimbaig/github/Elements-Admin/node_modules/react-idle-timer/build']
stream:
Labeled {
_readableState:
ReadableState {
objectMode: true,
highWaterMark: 16,
buffer: [],
length: 0,
pipes: [Object],
pipesCount: 1,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null,
resumeScheduled: false },
readable: true,
domain: null,
_events:
{ end: [Object],
error: [Object],
data: [Function: ondata],
_mutate: [Object] },
_eventsCount: 4,
_maxListeners: undefined,
_writableState:
WritableState {
objectMode: true,
highWaterMark: 16,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
bufferedRequest: null,
lastBufferedRequest: null,
pendingcb: 0,
prefinished: true,
errorEmitted: false },
writable: true,
allowHalfOpen: true,
_options: { objectMode: true },
_wrapOptions: { objectMode: true },
_streams: [ [Object], [Object] ],
length: 2,
label: 'deps' } }
Idk maybe i'm doing it wrong, but as far as i can tell when i implement this, and someone goes idle for X amount of time, it works, and than that function is called over 80x, and completely breaks my program
My onIdle
handler does a setState that triggers a re-render of my component which doesn't have IdleTimer. The sequence is:
IdleTimer _toggleIdleState L317
my onIdle
my render
IdleTimer "componentWillUnmount"
IdleTimer _toggleIdleState setState L339
resulting in:
react-dom.development.js:506 Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
I could use a setImmediate() in my onIdle -- that might fix the issue. It may be safer in general to call your setState before calling the callbacks?
When I wrap around an iframe editor component, when it goes to ide state it won't comes back to active state even when I have something typed in the editor. It only comes to active state when the mousemoved off and into the browser tab. Does this component suppose to track the key press as well right?
<IdleTimer
// ref={ref => { this.idleTimer = ref }}
element={document}
onActive={this.onActive}
onIdle={this.onIdle}
// timeout={this.state.timeout}
timeout={1000 * 3}
startOnLoad={true}
>
<Frame
url={remote editor url}
width="100%"
height="100%"
id={this.componentId}
ref={(ref) => this.frame = ref}
className="myClassname"
display="initial"
position="relative"
onLoad={this.iframeLoaded()}
allowFullScreen={true}
/>
</IdleTimer>
Hi, just wanted to say I like this component and thinking about to use it but I wonder what will happens when a computer goes to sleep. Does the timeout function continue running or will it stop?
Screenshot with problem (note logs timings in millisecond): http://take.ms/RPTyz
Sandboxed: https://codesandbox.io/s/z2xm14nzm
I am trying to log out from all tabs of the same browser at a time when user is idle for all the tabs in present browser
I can't make my test of the component to work when it contains IdleTimer, the test just hangs without any messages. I'm using CRA + Jest + Enzyme. To replicate:
"dependencies": {
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"enzyme-to-json": "^3.3.4",
"prop-types": "^15.6.2",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"react-idle-timer": "^4.0.7",
"react-scripts": "1.1.4"
},
class App extends Component {
onIdle = e => {
console.log(e);
}
render() {
return (
<div className="App">
<IdleTimer timeout={10000} onIdle={this.onIdle}/>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
</div>
);
}
}
import React from 'react';
import ReactDOM from 'react-dom';
import {shallow, mount} from 'enzyme';
import App from './App';
// this works
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
ReactDOM.unmountComponentAtNode(div);
});
// this work
it('has header', () => {
const wrapper = mount(<App />);
const h1 = wrapper.find('h1');
expect(h1.first().html()).toBe('<h1 class="App-title">Welcome to React</h1>');
wrapper.unmount();
})
// this hangs
it('renders correctly (Snapshot)', () => {
const wrapper = shallow(<App />);
expect(wrapper).toMatchSnapshot();
})
Hi thanks for the wonderfully tested package.
I would like to track user time and pause when he is idle.
_onActive(e) {
console.log(this.idleTimer.getElapsedTime())
}
_onIdle(e) {
this.idleTimer.pause();
console.log("Time passed: ", this.idleTimer.getElapsedTime());
}
I expect that the Timer would stop, but and activate again when the user is active again. But this doesn't happen. The timer continues.
Thanks again for this package.
Hi, I set an initial value to one minute for the timeout and I get the final timeout value from an API and I use a componentDidUpdate and update the state to 10 mins. The callback gets triggered in a minute. Is there any way to override this?
`this.state = {
timeout: 60000
}
componentDidUpdate(prevProps) {
if(prevProps.idleTimerValue !== this.props.idleTimerValue) {
this.setState({timeout: this.props.idleTimerValue})
}
}
IdleTimer timeout={this.state.timeout} //renders after a minute />`
P.S: Cant use a component syntax here. No typo's here.
We are using react-idle-timer in our project, and I just realized that including it as a dependency massively increases the bundle size. This is due to React being included as a direct dependency of the library.
We should include all of the React libraries as "peerDependencies"
in package.json
. This is how Material UI, React Bootstrap handle this, and I believe other libraries do the same.
You can see below that react-idle-timer is 7.8% (!) of our bundle:
7.3% of which is contributed by React:
Hi,
I'm trying to pause on componentWillMount
by following the example in src_examples folder. I'm getting an Cannot read property 'pause' of undefined
error from this.refs.IdleTimer.pause
. How do I access the method properly?
Hello,
I am wondering if I put the this.idleTimer.pause()
inside the onIdle function shouldn't that stop the idle timer, regardless if the user moves the mouse or scroll?
I did noticed that this.idleTimer.pause() = undefined when I console.log that value.
Right now if the user moves the idleTimer gets activated and I don't want no timer to continue if onIdle function is activated.
Thanks!
`
.....
class App extends Component {
constructor(props) {
super(props);
this.idleTimer = null;
this.timer = null;
this.state = {
timeLeft: 30
};
}
onIdle = () => {
this.props.setSessionModal();
this.idleTimer.pause();
this.timer = setInterval(this.countdown, 3000);
};
countdown = () => {
if (this.state.timeLeft === 0) {
this.props.unAuthUser();
} else {
this.setState({ timeLeft: --this.state.timeLeft });
}
};
actionOk = () => {
clearInterval(this.timer);
this.setState({ timeLeft: 30 });
this.idleTimer.reset();
this.props.setSessionModal();
};
render() {
return (
<div>
<IdleTimer
ref={ref => {
this.idleTimer = ref;
}}
onIdle={this.onIdle}
timeout={5000}
>
{this.props.getSessionModal && (
<ModalSession
isActive={this.props.getSessionModal}
seconds={this.state.timeLeft}
actionCancel={this.props.unAuthUser}
actionOk={this.actionOk}
/>
)}
</IdleTimer>
</div>
);
}
}
export default App;`
Hi, I would like to report events from child components.
Specifically I want to be able to report back video watching as active time. Is it possible to get an API for that - f.x. as a method on the ref?
I'm using webpack for bundling. I only use this library in my client but in order to use it in webpack I have to use some code like this:
if (canUseDOM && enabled) { let Timer = require("react-idle-timer").default;
the reason for this is that if I try to use an import I'll get a build time error:
ReferenceError: document is not defined
at Object.<anonymous> (/Users/bmonro/Documents/Code/nui-redux/ext/@concur/nui-shell/node_modules/react-idle-timer/build/index.js:303:12)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:311:12)
at Module.require (module.js:366:17)
at require (module.js:385:17)
at Object.<anonymous> (/Users/bmonro/Documents/Code/nui-redux/ext/@concur/nui-shell/lib/components/IdleTimer.js:15:23)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
it would be nice if I didn't have to do this and could instead do a normal es6 style import.
Does this library work for react native? If so, can I update the docs?
Was looking for examples in the examples directory per the readme.md. Would be nice to see a couple of basic examples showing fire action after XX ms, resetting etc.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.