Initial work to get working in Firefox
This commit is contained in:
4
.bowerrc
4
.bowerrc
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"directory": "vendor/bower_components"
|
"directory": "vendor/bower_components"
|
||||||
}
|
}
|
||||||
68
.gitignore
vendored
68
.gitignore
vendored
@@ -1,34 +1,34 @@
|
|||||||
# Logs
|
# Logs
|
||||||
logs
|
logs
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
# Runtime data
|
# Runtime data
|
||||||
pids
|
pids
|
||||||
*.pid
|
*.pid
|
||||||
*.seed
|
*.seed
|
||||||
|
|
||||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
lib-cov
|
lib-cov
|
||||||
|
|
||||||
# Coverage directory used by tools like istanbul
|
# Coverage directory used by tools like istanbul
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
.grunt
|
.grunt
|
||||||
|
|
||||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||||
build/Release
|
build/Release
|
||||||
|
|
||||||
# Dependency directory
|
# Dependency directory
|
||||||
# Deployed apps should consider commenting this line out:
|
# Deployed apps should consider commenting this line out:
|
||||||
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
|
# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git
|
||||||
node_modules
|
node_modules
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
vendor/
|
vendor/
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
# Generated chrome extension
|
# Generated chrome extension
|
||||||
public/
|
public/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
coverage/
|
coverage/
|
||||||
node_modules/
|
node_modules/
|
||||||
public/
|
public/
|
||||||
vendor/
|
vendor/
|
||||||
tests/
|
tests/
|
||||||
20
.jshintrc
20
.jshintrc
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"node": true,
|
"node": true,
|
||||||
"curly": true,
|
"curly": true,
|
||||||
"latedef": true,
|
"latedef": true,
|
||||||
"quotmark": true,
|
"quotmark": true,
|
||||||
"undef": true,
|
"undef": true,
|
||||||
"unused": true,
|
"unused": true,
|
||||||
"trailing": true,
|
"trailing": true,
|
||||||
"predef": [ "chrome" ]
|
"predef": [ "chrome" ]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "jshint ."
|
"lint": "jshint ."
|
||||||
},
|
},
|
||||||
"pre-commit": ["lint", "validate", "test"]
|
"pre-commit": ["lint", "validate", "test"]
|
||||||
}
|
}
|
||||||
|
|||||||
28
AUTHORS
28
AUTHORS
@@ -1,14 +1,14 @@
|
|||||||
WakaTime is written and maintained by Alan Hamlett and
|
WakaTime is written and maintained by Alan Hamlett and
|
||||||
various contributors:
|
various contributors:
|
||||||
|
|
||||||
|
|
||||||
Development Lead
|
Development Lead
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
- Alan Hamlett <alan.hamlett@gmail.com>
|
- Alan Hamlett <alan.hamlett@gmail.com>
|
||||||
- Mario Bašić <mario.basic@outlook.com>
|
- Mario Bašić <mario.basic@outlook.com>
|
||||||
|
|
||||||
|
|
||||||
Patches and Suggestions
|
Patches and Suggestions
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|||||||
48
HISTORY.rst
48
HISTORY.rst
@@ -1,24 +1,24 @@
|
|||||||
|
|
||||||
History
|
History
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
||||||
1.0.2 (2016-06-30)
|
1.0.2 (2016-06-30)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
- Fix bug preventing options from saving. #42
|
- Fix bug preventing options from saving. #42
|
||||||
|
|
||||||
|
|
||||||
1.0.1 (2016-06-29)
|
1.0.1 (2016-06-29)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
- Fix blacklist setting.
|
- Fix blacklist setting.
|
||||||
- Misc bug fixes related to icon popup.
|
- Misc bug fixes related to icon popup.
|
||||||
- Send plugin name and version with heartbeat data. #41
|
- Send plugin name and version with heartbeat data. #41
|
||||||
|
|
||||||
|
|
||||||
1.0.0 (2016-06-29)
|
1.0.0 (2016-06-29)
|
||||||
++++++++++++++++++
|
++++++++++++++++++
|
||||||
|
|
||||||
- Birth
|
- Birth
|
||||||
|
|
||||||
|
|||||||
62
LICENSE
62
LICENSE
@@ -1,31 +1,31 @@
|
|||||||
BSD 3-Clause License
|
BSD 3-Clause License
|
||||||
|
|
||||||
Copyright (c) 2014 by the respective authors (see AUTHORS file).
|
Copyright (c) 2014 by the respective authors (see AUTHORS file).
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright
|
||||||
notice, this list of conditions and the following disclaimer.
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above copyright
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer
|
notice, this list of conditions and the following disclaimer
|
||||||
in the documentation and/or other materials provided
|
in the documentation and/or other materials provided
|
||||||
with the distribution.
|
with the distribution.
|
||||||
|
|
||||||
* Neither the names of WakaTime, nor the names of its
|
* Neither the names of WakaTime, nor the names of its
|
||||||
contributors may be used to endorse or promote products derived
|
contributors may be used to endorse or promote products derived
|
||||||
from this software without specific prior written permission.
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
||||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|||||||
150
README.md
150
README.md
@@ -1,75 +1,75 @@
|
|||||||
chrome-wakatime
|
chrome-wakatime
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Automatic time tracking for stats about your website debugging, research, documentation, etc.
|
Automatic time tracking for stats about your website debugging, research, documentation, etc.
|
||||||
|
|
||||||
|
|
||||||
##Installation
|
##Installation
|
||||||
|
|
||||||
1. Install the extension:
|
1. Install the extension:
|
||||||
|
|
||||||
[](https://chrome.google.com/webstore/detail/wakatime/jnbbnacmeggbgdjgaoojpmhdlkkpblgi)
|
[](https://chrome.google.com/webstore/detail/wakatime/jnbbnacmeggbgdjgaoojpmhdlkkpblgi)
|
||||||
|
|
||||||
2. Login to [WakaTime](https://wakatime.com/).
|
2. Login to [WakaTime](https://wakatime.com/).
|
||||||
|
|
||||||
3. Use Chrome like you normally do and your time will be tracked for you automatically.
|
3. Use Chrome like you normally do and your time will be tracked for you automatically.
|
||||||
|
|
||||||
4. Visit https://wakatime.com to see your logged time.
|
4. Visit https://wakatime.com to see your logged time.
|
||||||
|
|
||||||
5. Use in conjunction with [other WakaTime plugins](https://wakatime.com/plugins).
|
5. Use in conjunction with [other WakaTime plugins](https://wakatime.com/plugins).
|
||||||
|
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
## Development instructions
|
## Development instructions
|
||||||
|
|
||||||
> For development purposes only.
|
> For development purposes only.
|
||||||
|
|
||||||
To get started, install NPM and Bower dependencies, and do an initial build with Gulp:
|
To get started, install NPM and Bower dependencies, and do an initial build with Gulp:
|
||||||
```
|
```
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
To build the extension once:
|
To build the extension once:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run gulp
|
npm run gulp
|
||||||
```
|
```
|
||||||
|
|
||||||
To monitor changes:
|
To monitor changes:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm run watch
|
npm run watch
|
||||||
```
|
```
|
||||||
|
|
||||||
Run tests:
|
Run tests:
|
||||||
|
|
||||||
```
|
```
|
||||||
npm test
|
npm test
|
||||||
```
|
```
|
||||||
|
|
||||||
Lint code *(Both JS and JSX)*:
|
Lint code *(Both JS and JSX)*:
|
||||||
|
|
||||||
```
|
```
|
||||||
jsxhint --jsx-only .
|
jsxhint --jsx-only .
|
||||||
```
|
```
|
||||||
|
|
||||||
### Automatic code linting
|
### Automatic code linting
|
||||||
|
|
||||||
There is a precommit hook that lints the code before commiting the changes.
|
There is a precommit hook that lints the code before commiting the changes.
|
||||||
|
|
||||||
|
|
||||||
### Load unpacked in Chrome
|
### Load unpacked in Chrome
|
||||||
|
|
||||||
1. Clone repository to disk
|
1. Clone repository to disk
|
||||||
2. Go to `Settings` -> `Extensions`
|
2. Go to `Settings` -> `Extensions`
|
||||||
3. Enable `Developer mode`
|
3. Enable `Developer mode`
|
||||||
4. Click `Load unpacked extension...`
|
4. Click `Load unpacked extension...`
|
||||||
5. Select repository directory
|
5. Select repository directory
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
|
|
||||||
/* This is a fix for Bootstrap requiring jQuery */
|
/* This is a fix for Bootstrap requiring jQuery */
|
||||||
global.jQuery = require('jquery');
|
global.jQuery = require('jquery');
|
||||||
require('bootstrap');
|
require('bootstrap');
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
// React components
|
// React components
|
||||||
var WakaTime = require('./components/WakaTime.jsx');
|
var WakaTime = require('./components/WakaTime.jsx');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<WakaTime />,
|
<WakaTime />,
|
||||||
document.getElementById('wakatime')
|
document.getElementById('wakatime')
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
var classNames = require('classnames');
|
var classNames = require('classnames');
|
||||||
|
|
||||||
var Alert = React.createClass({
|
var Alert = React.createClass({
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
type: React.PropTypes.string.isRequired,
|
type: React.PropTypes.string.isRequired,
|
||||||
text: React.PropTypes.string.isRequired
|
text: React.PropTypes.string.isRequired
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return(
|
return(
|
||||||
<div className={classNames('alert', 'alert-' + this.props.type)}>{this.props.text}</div>
|
<div className={classNames('alert', 'alert-' + this.props.type)}>{this.props.text}</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = Alert;
|
module.exports = Alert;
|
||||||
|
|||||||
@@ -1,106 +1,106 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var MainList = React.createClass({
|
var MainList = React.createClass({
|
||||||
|
|
||||||
_openOptionsPage: function() {
|
_openOptionsPage: function() {
|
||||||
if (chrome.runtime.openOptionsPage) {
|
if (browser.runtime.openOptionsPage) {
|
||||||
// New way to open options pages, if supported (Chrome 42+).
|
// New way to open options pages, if supported (Chrome 42+).
|
||||||
chrome.runtime.openOptionsPage();
|
browser.runtime.openOptionsPage();
|
||||||
} else {
|
} else {
|
||||||
// Reasonable fallback.
|
// Reasonable fallback.
|
||||||
window.open(chrome.runtime.getURL('options.html'));
|
window.open(browser.runtime.getURL('options.html'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
var loginLogoutButton = function() {
|
var loginLogoutButton = function() {
|
||||||
if (that.props.loggedIn === true) {
|
if (that.props.loggedIn === true) {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<a href="#" className="list-group-item" onClick={that.props.logoutUser}>
|
<a href="#" className="list-group-item" onClick={that.props.logoutUser}>
|
||||||
<i className="fa fa-fw fa-sign-out"></i>
|
<i className="fa fa-fw fa-sign-out"></i>
|
||||||
Logout
|
Logout
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a target="_blank" href="https://wakatime.com/login" className="list-group-item">
|
<a target="_blank" href="https://wakatime.com/login" className="list-group-item">
|
||||||
<i className="fa fa-fw fa-sign-in"></i>
|
<i className="fa fa-fw fa-sign-in"></i>
|
||||||
Login
|
Login
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// If logging is enabled, display that info to user
|
// If logging is enabled, display that info to user
|
||||||
var loggingStatus = function() {
|
var loggingStatus = function() {
|
||||||
if(that.props.loggingEnabled === true && that.props.loggedIn === true)
|
if(that.props.loggingEnabled === true && that.props.loggedIn === true)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
<p>
|
<p>
|
||||||
<a href="#" onClick={that.props.disableLogging} className="btn btn-danger btn-block">Disable logging</a>
|
<a href="#" onClick={that.props.disableLogging} className="btn btn-danger btn-block">Disable logging</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if(that.props.loggingEnabled === false && that.props.loggedIn === true)
|
else if(that.props.loggingEnabled === false && that.props.loggedIn === true)
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
<p>
|
<p>
|
||||||
<a href="#" onClick={that.props.enableLogging} className="btn btn-success btn-block">Enable logging</a>
|
<a href="#" onClick={that.props.enableLogging} className="btn btn-success btn-block">Enable logging</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var totalTimeLoggedToday = function() {
|
var totalTimeLoggedToday = function() {
|
||||||
if (that.props.loggedIn === true) {
|
if (that.props.loggedIn === true) {
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-xs-12">
|
<div className="col-xs-12">
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<p>{that.props.totalTimeLoggedToday}</p>
|
<p>{that.props.totalTimeLoggedToday}</p>
|
||||||
<small><cite>TOTAL TIME LOGGED TODAY</cite></small>
|
<small><cite>TOTAL TIME LOGGED TODAY</cite></small>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
{totalTimeLoggedToday()}
|
{totalTimeLoggedToday()}
|
||||||
|
|
||||||
{loggingStatus()}
|
{loggingStatus()}
|
||||||
|
|
||||||
<div className="list-group">
|
<div className="list-group">
|
||||||
<a href="#" className="list-group-item" onClick={this._openOptionsPage}>
|
<a href="#" className="list-group-item" onClick={this._openOptionsPage}>
|
||||||
<i className="fa fa-fw fa-cogs"></i>
|
<i className="fa fa-fw fa-cogs"></i>
|
||||||
Options
|
Options
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{loginLogoutButton()}
|
{loginLogoutButton()}
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = MainList;
|
module.exports = MainList;
|
||||||
|
|||||||
@@ -1,89 +1,89 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var NavBar = React.createClass({
|
var NavBar = React.createClass({
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
var signedInAs = function() {
|
var signedInAs = function() {
|
||||||
if (that.props.loggedIn === true) {
|
if (that.props.loggedIn === true) {
|
||||||
return (
|
return (
|
||||||
<p className="navbar-text">Signed in as <b>{that.props.user.full_name}</b></p>
|
<p className="navbar-text">Signed in as <b>{that.props.user.full_name}</b></p>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var dashboard = function() {
|
var dashboard = function() {
|
||||||
if (that.props.loggedIn === true) {
|
if (that.props.loggedIn === true) {
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://wakatime.com/dashboard">
|
<a target="_blank" href="https://wakatime.com/dashboard">
|
||||||
<i className="fa fa-fw fa-tachometer"></i>
|
<i className="fa fa-fw fa-tachometer"></i>
|
||||||
Dashboard
|
Dashboard
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var customRules = function() {
|
var customRules = function() {
|
||||||
if (that.props.loggedIn === true) {
|
if (that.props.loggedIn === true) {
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://wakatime.com/settings/rules">
|
<a target="_blank" href="https://wakatime.com/settings/rules">
|
||||||
<i className="fa fa-fw fa-filter"></i>
|
<i className="fa fa-fw fa-filter"></i>
|
||||||
Custom Rules
|
Custom Rules
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<nav className="navbar navbar-default" role="navigation">
|
<nav className="navbar navbar-default" role="navigation">
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
<div className="navbar-header">
|
<div className="navbar-header">
|
||||||
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
<button type="button" className="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
|
||||||
<span className="sr-only">Toggle navigation</span>
|
<span className="sr-only">Toggle navigation</span>
|
||||||
<i className="fa fa-fw fa-cogs"></i>
|
<i className="fa fa-fw fa-cogs"></i>
|
||||||
</button>
|
</button>
|
||||||
<a target="_blank" className="navbar-brand" href="https://wakatime.com">
|
<a target="_blank" className="navbar-brand" href="https://wakatime.com">
|
||||||
WakaTime
|
WakaTime
|
||||||
<img src="graphics/wakatime-logo-48.png" />
|
<img src="graphics/wakatime-logo-48.png" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||||
{signedInAs()}
|
{signedInAs()}
|
||||||
<ul className="nav navbar-nav">
|
<ul className="nav navbar-nav">
|
||||||
{customRules()}
|
{customRules()}
|
||||||
{dashboard()}
|
{dashboard()}
|
||||||
<li className="dropdown">
|
<li className="dropdown">
|
||||||
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
<a href="#" className="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||||
<i className="fa fa-fw fa-info"></i>
|
<i className="fa fa-fw fa-info"></i>
|
||||||
About
|
About
|
||||||
<span className="caret"></span>
|
<span className="caret"></span>
|
||||||
</a>
|
</a>
|
||||||
<ul className="dropdown-menu" role="menu">
|
<ul className="dropdown-menu" role="menu">
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://github.com/wakatime/chrome-wakatime/issues">
|
<a target="_blank" href="https://github.com/wakatime/chrome-wakatime/issues">
|
||||||
<i className="fa fa-fw fa-bug"></i>
|
<i className="fa fa-fw fa-bug"></i>
|
||||||
Report an Issue</a>
|
Report an Issue</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a target="_blank" href="https://github.com/wakatime/chrome-wakatime">
|
<a target="_blank" href="https://github.com/wakatime/chrome-wakatime">
|
||||||
<i className="fa fa-fw fa-github"></i>
|
<i className="fa fa-fw fa-github"></i>
|
||||||
View on GitHub</a>
|
View on GitHub</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = NavBar;
|
module.exports = NavBar;
|
||||||
|
|||||||
@@ -1,214 +1,214 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
|
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
|
||||||
|
|
||||||
var config = require('../config');
|
var config = require('../config');
|
||||||
|
|
||||||
// React components
|
// React components
|
||||||
var Alert = require('./Alert.jsx');
|
var Alert = require('./Alert.jsx');
|
||||||
var SitesList = require('./SitesList.jsx');
|
var SitesList = require('./SitesList.jsx');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* One thing to keep in mind is that you cannot use this.refs.blacklist if
|
* One thing to keep in mind is that you cannot use this.refs.blacklist if
|
||||||
* the blacklist select box is not being rendered on the form.
|
* the blacklist select box is not being rendered on the form.
|
||||||
*
|
*
|
||||||
* @type {*|Function}
|
* @type {*|Function}
|
||||||
*/
|
*/
|
||||||
var Options = React.createClass({
|
var Options = React.createClass({
|
||||||
|
|
||||||
getInitialState: function () {
|
getInitialState: function () {
|
||||||
return {
|
return {
|
||||||
theme: config.theme,
|
theme: config.theme,
|
||||||
blacklist: '',
|
blacklist: '',
|
||||||
whitelist: '',
|
whitelist: '',
|
||||||
loggingType: config.loggingType,
|
loggingType: config.loggingType,
|
||||||
loggingStyle: config.loggingStyle,
|
loggingStyle: config.loggingStyle,
|
||||||
displayAlert: false,
|
displayAlert: false,
|
||||||
alertType: config.alert.success.type,
|
alertType: config.alert.success.type,
|
||||||
alertText: config.alert.success.text
|
alertText: config.alert.success.text
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function () {
|
componentDidMount: function () {
|
||||||
this.restoreSettings();
|
this.restoreSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
restoreSettings: function () {
|
restoreSettings: function () {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
chrome.storage.sync.get({
|
browser.storage.sync.get({
|
||||||
theme: config.theme,
|
theme: config.theme,
|
||||||
blacklist: '',
|
blacklist: '',
|
||||||
whitelist: '',
|
whitelist: '',
|
||||||
loggingType: config.loggingType,
|
loggingType: config.loggingType,
|
||||||
loggingStyle: config.loggingStyle
|
loggingStyle: config.loggingStyle
|
||||||
}, function (items) {
|
}).then(function (items) {
|
||||||
that.setState({
|
that.setState({
|
||||||
theme: items.theme,
|
theme: items.theme,
|
||||||
blacklist: items.blacklist,
|
blacklist: items.blacklist,
|
||||||
whitelist: items.whitelist,
|
whitelist: items.whitelist,
|
||||||
loggingType: items.loggingType,
|
loggingType: items.loggingType,
|
||||||
loggingStyle: items.loggingStyle
|
loggingStyle: items.loggingStyle
|
||||||
});
|
});
|
||||||
|
|
||||||
that.refs.theme.value = items.theme;
|
that.refs.theme.value = items.theme;
|
||||||
that.refs.loggingType.value = items.loggingType;
|
that.refs.loggingType.value = items.loggingType;
|
||||||
that.refs.loggingStyle.value = items.loggingStyle;
|
that.refs.loggingStyle.value = items.loggingStyle;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleSubmit: function (e) {
|
_handleSubmit: function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.saveSettings();
|
this.saveSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveSettings: function () {
|
saveSettings: function () {
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
var theme = this.refs.theme.value.trim();
|
var theme = this.refs.theme.value.trim();
|
||||||
var loggingType = this.refs.loggingType.value.trim();
|
var loggingType = this.refs.loggingType.value.trim();
|
||||||
var loggingStyle = this.refs.loggingStyle.value.trim();
|
var loggingStyle = this.refs.loggingStyle.value.trim();
|
||||||
// Trimming blacklist and whitelist removes blank lines and spaces.
|
// Trimming blacklist and whitelist removes blank lines and spaces.
|
||||||
var blacklist = that.state.blacklist.trim();
|
var blacklist = that.state.blacklist.trim();
|
||||||
var whitelist = that.state.whitelist.trim();
|
var whitelist = that.state.whitelist.trim();
|
||||||
|
|
||||||
// Sync options with google storage.
|
// Sync options with google storage.
|
||||||
chrome.storage.sync.set({
|
browser.storage.sync.set({
|
||||||
theme: theme,
|
theme: theme,
|
||||||
blacklist: blacklist,
|
blacklist: blacklist,
|
||||||
whitelist: whitelist,
|
whitelist: whitelist,
|
||||||
loggingType: loggingType,
|
loggingType: loggingType,
|
||||||
loggingStyle: loggingStyle
|
loggingStyle: loggingStyle
|
||||||
}, function () {
|
}).then(function () {
|
||||||
// Set state to be newly entered values.
|
// Set state to be newly entered values.
|
||||||
that.setState({
|
that.setState({
|
||||||
theme: theme,
|
theme: theme,
|
||||||
blacklist: blacklist,
|
blacklist: blacklist,
|
||||||
whitelist: whitelist,
|
whitelist: whitelist,
|
||||||
loggingType: loggingType,
|
loggingType: loggingType,
|
||||||
loggingStyle: loggingStyle,
|
loggingStyle: loggingStyle,
|
||||||
displayAlert: true
|
displayAlert: true
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_displayBlackOrWhiteList: function () {
|
_displayBlackOrWhiteList: function () {
|
||||||
var loggingStyle = this.refs.loggingStyle.value.trim();
|
var loggingStyle = this.refs.loggingStyle.value.trim();
|
||||||
|
|
||||||
this.setState({loggingStyle: loggingStyle});
|
this.setState({loggingStyle: loggingStyle});
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateBlacklistState: function(sites){
|
_updateBlacklistState: function(sites){
|
||||||
this.setState({
|
this.setState({
|
||||||
blacklist: sites
|
blacklist: sites
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateWhitelistState: function(sites){
|
_updateWhitelistState: function(sites){
|
||||||
this.setState({
|
this.setState({
|
||||||
whitelist: sites
|
whitelist: sites
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
var alert = function() {
|
var alert = function() {
|
||||||
if(that.state.displayAlert === true){
|
if(that.state.displayAlert === true){
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
that.setState({displayAlert:false});
|
that.setState({displayAlert:false});
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
return(
|
return(
|
||||||
<Alert key={that.state.alertText} type={that.state.alertType} text={that.state.alertText} />
|
<Alert key={that.state.alertText} type={that.state.alertType} text={that.state.alertText} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var loggingStyle = function () {
|
var loggingStyle = function () {
|
||||||
|
|
||||||
if (that.state.loggingStyle == 'blacklist') {
|
if (that.state.loggingStyle == 'blacklist') {
|
||||||
return (
|
return (
|
||||||
<SitesList
|
<SitesList
|
||||||
handleChange={that._updateBlacklistState}
|
handleChange={that._updateBlacklistState}
|
||||||
label="Blacklist"
|
label="Blacklist"
|
||||||
sites={that.state.blacklist}
|
sites={that.state.blacklist}
|
||||||
helpText="Sites that you don't want to show in your reports." />
|
helpText="Sites that you don't want to show in your reports." />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SitesList
|
<SitesList
|
||||||
handleChange={that._updateWhitelistState}
|
handleChange={that._updateWhitelistState}
|
||||||
label="Whitelist"
|
label="Whitelist"
|
||||||
sites={that.state.whitelist}
|
sites={that.state.whitelist}
|
||||||
helpText="Sites that you want to show in your reports." />
|
helpText="Sites that you want to show in your reports." />
|
||||||
);
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-12">
|
<div className="col-md-12">
|
||||||
|
|
||||||
<ReactCSSTransitionGroup transitionName="alert" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
|
<ReactCSSTransitionGroup transitionName="alert" transitionEnterTimeout={500} transitionLeaveTimeout={300}>
|
||||||
{alert()}
|
{alert()}
|
||||||
</ReactCSSTransitionGroup>
|
</ReactCSSTransitionGroup>
|
||||||
|
|
||||||
<form className="form-horizontal" onSubmit={this._handleSubmit}>
|
<form className="form-horizontal" onSubmit={this._handleSubmit}>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-lg-2 control-label">Logging style</label>
|
<label className="col-lg-2 control-label">Logging style</label>
|
||||||
|
|
||||||
<div className="col-lg-10">
|
<div className="col-lg-10">
|
||||||
<select className="form-control" ref="loggingStyle" defaultValue="blacklist" onChange={this._displayBlackOrWhiteList}>
|
<select className="form-control" ref="loggingStyle" defaultValue="blacklist" onChange={this._displayBlackOrWhiteList}>
|
||||||
<option value="blacklist">All except blacklisted sites</option>
|
<option value="blacklist">All except blacklisted sites</option>
|
||||||
<option value="whitelist">Only whitelisted sites</option>
|
<option value="whitelist">Only whitelisted sites</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{loggingStyle()}
|
{loggingStyle()}
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-lg-2 control-label">Logging type</label>
|
<label className="col-lg-2 control-label">Logging type</label>
|
||||||
|
|
||||||
<div className="col-lg-10">
|
<div className="col-lg-10">
|
||||||
<select className="form-control" ref="loggingType" defaultValue="domain">
|
<select className="form-control" ref="loggingType" defaultValue="domain">
|
||||||
<option value="domain">Only the domain</option>
|
<option value="domain">Only the domain</option>
|
||||||
<option value="url">Entire URL</option>
|
<option value="url">Entire URL</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="theme" className="col-lg-2 control-label">Theme</label>
|
<label htmlFor="theme" className="col-lg-2 control-label">Theme</label>
|
||||||
|
|
||||||
<div className="col-lg-10">
|
<div className="col-lg-10">
|
||||||
<select className="form-control" ref="theme" defaultValue="light">
|
<select className="form-control" ref="theme" defaultValue="light">
|
||||||
<option value="light">Light</option>
|
<option value="light">Light</option>
|
||||||
<option value="dark">Dark</option>
|
<option value="dark">Dark</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<div className="col-lg-10 col-lg-offset-2">
|
<div className="col-lg-10 col-lg-offset-2">
|
||||||
<button type="submit" className="btn btn-primary">Save</button>
|
<button type="submit" className="btn btn-primary">Save</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = Options;
|
module.exports = Options;
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
var React = require('react');
|
var React = require('react');
|
||||||
|
|
||||||
var SitesList = React.createClass({
|
var SitesList = React.createClass({
|
||||||
|
|
||||||
getDefaultProps: function () {
|
getDefaultProps: function () {
|
||||||
return {
|
return {
|
||||||
placeholder: 'http://google.com'
|
placeholder: 'http://google.com'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
_handleChange: function (event) {
|
_handleChange: function (event) {
|
||||||
var sites = event.target.value;
|
var sites = event.target.value;
|
||||||
|
|
||||||
this.props.handleChange(sites);
|
this.props.handleChange(sites);
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function () {
|
render: function () {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="sites" className="col-lg-2 control-label">{this.props.label}</label>
|
<label htmlFor="sites" className="col-lg-2 control-label">{this.props.label}</label>
|
||||||
|
|
||||||
<div className="col-lg-10">
|
<div className="col-lg-10">
|
||||||
<textarea className="form-control" rows="3" ref="sites" onChange={this._handleChange}
|
<textarea className="form-control" rows="3" ref="sites" onChange={this._handleChange}
|
||||||
placeholder={this.props.placeholder} value={this.props.sites}></textarea>
|
placeholder={this.props.placeholder} value={this.props.sites}></textarea>
|
||||||
<span className="help-block">{this.props.helpText}
|
<span className="help-block">{this.props.helpText}
|
||||||
<br/>
|
<br/>
|
||||||
One line per site.</span>
|
One line per site.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = SitesList;
|
module.exports = SitesList;
|
||||||
|
|||||||
@@ -1,173 +1,173 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
var React = require("react");
|
var React = require("react");
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
|
|
||||||
var config = require('../config');
|
var config = require('../config');
|
||||||
|
|
||||||
// React components
|
// React components
|
||||||
var NavBar = require('./NavBar.jsx');
|
var NavBar = require('./NavBar.jsx');
|
||||||
var MainList = require('./MainList.jsx');
|
var MainList = require('./MainList.jsx');
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
var WakaTimeCore = require('../core/WakaTimeCore').default;
|
var WakaTimeCore = require('../core/WakaTimeCore').default;
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
var changeExtensionState = require('../helpers/changeExtensionState');
|
var changeExtensionState = require('../helpers/changeExtensionState');
|
||||||
|
|
||||||
var Wakatime = React.createClass({
|
var Wakatime = React.createClass({
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
user: {
|
user: {
|
||||||
full_name: null,
|
full_name: null,
|
||||||
email: null,
|
email: null,
|
||||||
photo: null
|
photo: null
|
||||||
},
|
},
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
loggingEnabled: config.loggingEnabled,
|
loggingEnabled: config.loggingEnabled,
|
||||||
totalTimeLoggedToday: '0 minutes'
|
totalTimeLoggedToday: '0 minutes'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
|
||||||
var wakatime = new WakaTimeCore();
|
var wakatime = new WakaTimeCore();
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
wakatime.checkAuth().done(function(data) {
|
wakatime.checkAuth().done(function(data) {
|
||||||
|
|
||||||
if (data !== false) {
|
if (data !== false) {
|
||||||
|
|
||||||
chrome.storage.sync.get({
|
browser.storage.sync.get({
|
||||||
loggingEnabled: config.loggingEnabled
|
loggingEnabled: config.loggingEnabled
|
||||||
}, function(items) {
|
}).then(function(items) {
|
||||||
that.setState({loggingEnabled: items.loggingEnabled});
|
that.setState({loggingEnabled: items.loggingEnabled});
|
||||||
|
|
||||||
if (items.loggingEnabled === true) {
|
if (items.loggingEnabled === true) {
|
||||||
changeExtensionState('allGood');
|
changeExtensionState('allGood');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
changeExtensionState('notLogging');
|
changeExtensionState('notLogging');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
that.setState({
|
that.setState({
|
||||||
user: {
|
user: {
|
||||||
full_name: data.full_name,
|
full_name: data.full_name,
|
||||||
email: data.email,
|
email: data.email,
|
||||||
photo: data.photo
|
photo: data.photo
|
||||||
},
|
},
|
||||||
loggedIn: true
|
loggedIn: true
|
||||||
});
|
});
|
||||||
|
|
||||||
wakatime.getTotalTimeLoggedToday().done(function(grand_total) {
|
wakatime.getTotalTimeLoggedToday().done(function(grand_total) {
|
||||||
that.setState({
|
that.setState({
|
||||||
totalTimeLoggedToday: grand_total.text
|
totalTimeLoggedToday: grand_total.text
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
changeExtensionState('notSignedIn');
|
changeExtensionState('notSignedIn');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
logoutUser: function() {
|
logoutUser: function() {
|
||||||
var deferredObject = $.Deferred();
|
var deferredObject = $.Deferred();
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: config.logoutUserUrl,
|
url: config.logoutUserUrl,
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
success: function() {
|
success: function() {
|
||||||
|
|
||||||
deferredObject.resolve(that);
|
deferredObject.resolve(that);
|
||||||
|
|
||||||
},
|
},
|
||||||
error: function(xhr, status, err) {
|
error: function(xhr, status, err) {
|
||||||
|
|
||||||
console.error(config.logoutUserUrl, status, err.toString());
|
console.error(config.logoutUserUrl, status, err.toString());
|
||||||
|
|
||||||
deferredObject.resolve(that);
|
deferredObject.resolve(that);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferredObject.promise();
|
return deferredObject.promise();
|
||||||
},
|
},
|
||||||
|
|
||||||
_logoutUser: function() {
|
_logoutUser: function() {
|
||||||
|
|
||||||
var that = this;
|
var that = this;
|
||||||
|
|
||||||
this.logoutUser().done(function(){
|
this.logoutUser().done(function(){
|
||||||
|
|
||||||
that.setState({
|
that.setState({
|
||||||
user: {
|
user: {
|
||||||
full_name: null,
|
full_name: null,
|
||||||
email: null,
|
email: null,
|
||||||
photo: null
|
photo: null
|
||||||
},
|
},
|
||||||
loggedIn: false,
|
loggedIn: false,
|
||||||
loggingEnabled: false
|
loggingEnabled: false
|
||||||
});
|
});
|
||||||
|
|
||||||
changeExtensionState('notSignedIn');
|
changeExtensionState('notSignedIn');
|
||||||
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_disableLogging: function() {
|
_disableLogging: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
loggingEnabled: false
|
loggingEnabled: false
|
||||||
});
|
});
|
||||||
|
|
||||||
changeExtensionState('notLogging');
|
changeExtensionState('notLogging');
|
||||||
|
|
||||||
chrome.storage.sync.set({
|
browser.storage.sync.set({
|
||||||
loggingEnabled: false
|
loggingEnabled: false
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
_enableLogging: function() {
|
_enableLogging: function() {
|
||||||
this.setState({
|
this.setState({
|
||||||
loggingEnabled: true
|
loggingEnabled: true
|
||||||
});
|
});
|
||||||
|
|
||||||
changeExtensionState('allGood');
|
changeExtensionState('allGood');
|
||||||
|
|
||||||
chrome.storage.sync.set({
|
browser.storage.sync.set({
|
||||||
loggingEnabled: true
|
loggingEnabled: true
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<NavBar
|
<NavBar
|
||||||
user={this.state.user}
|
user={this.state.user}
|
||||||
loggedIn={this.state.loggedIn} />
|
loggedIn={this.state.loggedIn} />
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-md-12">
|
<div className="col-md-12">
|
||||||
<MainList
|
<MainList
|
||||||
disableLogging={this._disableLogging}
|
disableLogging={this._disableLogging}
|
||||||
enableLogging={this._enableLogging}
|
enableLogging={this._enableLogging}
|
||||||
loggingEnabled={this.state.loggingEnabled}
|
loggingEnabled={this.state.loggingEnabled}
|
||||||
user={this.state.user}
|
user={this.state.user}
|
||||||
totalTimeLoggedToday={this.state.totalTimeLoggedToday}
|
totalTimeLoggedToday={this.state.totalTimeLoggedToday}
|
||||||
logoutUser={this._logoutUser}
|
logoutUser={this._logoutUser}
|
||||||
loggedIn={this.state.loggedIn} />
|
loggedIn={this.state.loggedIn} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = Wakatime;
|
module.exports = Wakatime;
|
||||||
|
|||||||
@@ -1,67 +1,67 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
//jshint esnext:true
|
//jshint esnext:true
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
// Extension name
|
// Extension name
|
||||||
name: 'WakaTime',
|
name: 'WakaTime',
|
||||||
// Extension version
|
// Extension version
|
||||||
version: chrome.app.getDetails().version,
|
version: browser.runtime.getManifest().version,
|
||||||
// Time for idle state of the browser
|
// Time for idle state of the browser
|
||||||
// The user is considered idle if there was
|
// The user is considered idle if there was
|
||||||
// no activity in the browser for x seconds
|
// no activity in the browser for x seconds
|
||||||
detectionIntervalInSeconds: 60,
|
detectionIntervalInSeconds: 60,
|
||||||
// Default logging style
|
// Default logging style
|
||||||
// Log all except blacklisted sites
|
// Log all except blacklisted sites
|
||||||
// or log only the white listed sites.
|
// or log only the white listed sites.
|
||||||
loggingStyle: 'blacklist',
|
loggingStyle: 'blacklist',
|
||||||
// Default logging type
|
// Default logging type
|
||||||
loggingType: 'domain',
|
loggingType: 'domain',
|
||||||
// By default logging is enabled
|
// By default logging is enabled
|
||||||
loggingEnabled: true,
|
loggingEnabled: true,
|
||||||
// Url to which to send the heartbeat
|
// Url to which to send the heartbeat
|
||||||
heartbeatApiUrl: 'https://api.wakatime.com/api/v1/users/current/heartbeats',
|
heartbeatApiUrl: 'https://api.wakatime.com/api/v1/users/current/heartbeats',
|
||||||
// Url from which to detect if the user is logged in
|
// Url from which to detect if the user is logged in
|
||||||
currentUserApiUrl: 'https://api.wakatime.com/api/v1/users/current',
|
currentUserApiUrl: 'https://api.wakatime.com/api/v1/users/current',
|
||||||
// The url to logout the user from wakatime
|
// The url to logout the user from wakatime
|
||||||
logoutUserUrl: 'https://wakatime.com/logout',
|
logoutUserUrl: 'https://wakatime.com/logout',
|
||||||
// Gets stats from the WakaTime API
|
// Gets stats from the WakaTime API
|
||||||
summariesApiUrl: 'https://api.wakatime.com/api/v1/users/current/summaries',
|
summariesApiUrl: 'https://api.wakatime.com/api/v1/users/current/summaries',
|
||||||
// Different colors for different states of the extension
|
// Different colors for different states of the extension
|
||||||
colors: {
|
colors: {
|
||||||
allGood: '',
|
allGood: '',
|
||||||
notLogging: 'gray',
|
notLogging: 'gray',
|
||||||
notSignedIn: 'red',
|
notSignedIn: 'red',
|
||||||
lightTheme: 'white'
|
lightTheme: 'white'
|
||||||
},
|
},
|
||||||
// Tooltips for each of the extension states
|
// Tooltips for each of the extension states
|
||||||
tooltips: {
|
tooltips: {
|
||||||
allGood: '',
|
allGood: '',
|
||||||
notLogging: 'Not logging',
|
notLogging: 'Not logging',
|
||||||
notSignedIn: 'Not signed In',
|
notSignedIn: 'Not signed In',
|
||||||
blacklisted: 'This URL is blacklisted',
|
blacklisted: 'This URL is blacklisted',
|
||||||
whitelisted: 'This URL is not on your whitelist'
|
whitelisted: 'This URL is not on your whitelist'
|
||||||
},
|
},
|
||||||
// Default theme
|
// Default theme
|
||||||
theme: 'light',
|
theme: 'light',
|
||||||
// Valid extension states
|
// Valid extension states
|
||||||
states: [
|
states: [
|
||||||
'allGood',
|
'allGood',
|
||||||
'notLogging',
|
'notLogging',
|
||||||
'notSignedIn',
|
'notSignedIn',
|
||||||
'blacklisted',
|
'blacklisted',
|
||||||
'whitelisted'
|
'whitelisted'
|
||||||
],
|
],
|
||||||
// Predefined alert type and text for success and failure.
|
// Predefined alert type and text for success and failure.
|
||||||
alert: {
|
alert: {
|
||||||
success: {
|
success: {
|
||||||
type: 'success',
|
type: 'success',
|
||||||
text: 'Options have been saved!'
|
text: 'Options have been saved!'
|
||||||
},
|
},
|
||||||
failure: {
|
failure: {
|
||||||
type: 'danger',
|
type: 'danger',
|
||||||
text: 'There was an error while saving the options!'
|
text: 'There was an error while saving the options!'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = config;
|
module.exports = config;
|
||||||
|
|||||||
@@ -1,256 +1,256 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
//jshint esnext:true
|
//jshint esnext:true
|
||||||
|
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var moment = require('moment');
|
var moment = require('moment');
|
||||||
|
|
||||||
var config = require('./../config');
|
var config = require('./../config');
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
var getDomainFromUrl = require('./../helpers/getDomainFromUrl');
|
var getDomainFromUrl = require('./../helpers/getDomainFromUrl');
|
||||||
var changeExtensionState = require('../helpers/changeExtensionState');
|
var changeExtensionState = require('../helpers/changeExtensionState');
|
||||||
var in_array = require('./../helpers/in_array');
|
var in_array = require('./../helpers/in_array');
|
||||||
var contains = require('./../helpers/contains');
|
var contains = require('./../helpers/contains');
|
||||||
|
|
||||||
class WakaTimeCore {
|
class WakaTimeCore {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.tabsWithDevtoolsOpen = [];
|
this.tabsWithDevtoolsOpen = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settter for tabsWithDevtoolsOpen
|
* Settter for tabsWithDevtoolsOpen
|
||||||
*
|
*
|
||||||
* @param tabs
|
* @param tabs
|
||||||
*/
|
*/
|
||||||
setTabsWithDevtoolsOpen(tabs) {
|
setTabsWithDevtoolsOpen(tabs) {
|
||||||
this.tabsWithDevtoolsOpen = tabs;
|
this.tabsWithDevtoolsOpen = tabs;
|
||||||
}
|
}
|
||||||
|
|
||||||
getTotalTimeLoggedToday() {
|
getTotalTimeLoggedToday() {
|
||||||
var deferredObject = $.Deferred();
|
var deferredObject = $.Deferred();
|
||||||
|
|
||||||
var today = moment().format('YYYY-MM-DD');
|
var today = moment().format('YYYY-MM-DD');
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: config.summariesApiUrl + '?start=' + today + '&end=' + today,
|
url: config.summariesApiUrl + '?start=' + today + '&end=' + today,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: (data) => {
|
success: (data) => {
|
||||||
|
|
||||||
deferredObject.resolve(data.data[0].grand_total);
|
deferredObject.resolve(data.data[0].grand_total);
|
||||||
|
|
||||||
},
|
},
|
||||||
error: (xhr, status, err) => {
|
error: (xhr, status, err) => {
|
||||||
|
|
||||||
console.error(config.summariesApiUrl, status, err.toString());
|
console.error(config.summariesApiUrl, status, err.toString());
|
||||||
|
|
||||||
deferredObject.resolve(false);
|
deferredObject.resolve(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferredObject.promise();
|
return deferredObject.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the user is logged in.
|
* Checks if the user is logged in.
|
||||||
*
|
*
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
checkAuth() {
|
checkAuth() {
|
||||||
var deferredObject = $.Deferred();
|
var deferredObject = $.Deferred();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: config.currentUserApiUrl,
|
url: config.currentUserApiUrl,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
success: (data) => {
|
success: (data) => {
|
||||||
|
|
||||||
deferredObject.resolve(data.data);
|
deferredObject.resolve(data.data);
|
||||||
|
|
||||||
},
|
},
|
||||||
error: (xhr, status, err) => {
|
error: (xhr, status, err) => {
|
||||||
|
|
||||||
console.error(config.currentUserApiUrl, status, err.toString());
|
console.error(config.currentUserApiUrl, status, err.toString());
|
||||||
|
|
||||||
deferredObject.resolve(false);
|
deferredObject.resolve(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferredObject.promise();
|
return deferredObject.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Depending on various factors detects the current active tab URL or domain,
|
* Depending on various factors detects the current active tab URL or domain,
|
||||||
* and sends it to WakaTime for logging.
|
* and sends it to WakaTime for logging.
|
||||||
*/
|
*/
|
||||||
recordHeartbeat() {
|
recordHeartbeat() {
|
||||||
|
|
||||||
chrome.storage.sync.get({
|
browser.storage.sync.get({
|
||||||
loggingEnabled: config.loggingEnabled,
|
loggingEnabled: config.loggingEnabled,
|
||||||
loggingStyle: config.loggingStyle,
|
loggingStyle: config.loggingStyle,
|
||||||
blacklist: '',
|
blacklist: '',
|
||||||
whitelist: ''
|
whitelist: ''
|
||||||
}, (items) => {
|
}).then((items) => {
|
||||||
if (items.loggingEnabled === true) {
|
if (items.loggingEnabled === true) {
|
||||||
|
|
||||||
changeExtensionState('allGood');
|
changeExtensionState('allGood');
|
||||||
|
|
||||||
chrome.idle.queryState(config.detectionIntervalInSeconds, (newState) => {
|
browser.idle.queryState(config.detectionIntervalInSeconds).then((newState) => {
|
||||||
|
|
||||||
if (newState === 'active') {
|
if (newState === 'active') {
|
||||||
// Get current tab URL.
|
// Get current tab URL.
|
||||||
chrome.tabs.query({active: true}, (tabs) => {
|
browser.tabs.query({active: true}).then((tabs) => {
|
||||||
|
|
||||||
var currentActiveTab = tabs[0];
|
var currentActiveTab = tabs[0];
|
||||||
|
|
||||||
var debug = false;
|
var debug = false;
|
||||||
// If the current active tab has devtools open
|
// If the current active tab has devtools open
|
||||||
if (in_array(currentActiveTab.id, this.tabsWithDevtoolsOpen)) debug = true;
|
if (in_array(currentActiveTab.id, this.tabsWithDevtoolsOpen)) debug = true;
|
||||||
|
|
||||||
if (items.loggingStyle == 'blacklist') {
|
if (items.loggingStyle == 'blacklist') {
|
||||||
if (! contains(currentActiveTab.url, items.blacklist)) {
|
if (! contains(currentActiveTab.url, items.blacklist)) {
|
||||||
this.sendHeartbeat(currentActiveTab.url, debug);
|
this.sendHeartbeat(currentActiveTab.url, debug);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
changeExtensionState('blacklisted');
|
changeExtensionState('blacklisted');
|
||||||
console.log(currentActiveTab.url + ' is on a blacklist.');
|
console.log(currentActiveTab.url + ' is on a blacklist.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.loggingStyle == 'whitelist') {
|
if (items.loggingStyle == 'whitelist') {
|
||||||
if (contains(currentActiveTab.url, items.whitelist)) {
|
if (contains(currentActiveTab.url, items.whitelist)) {
|
||||||
this.sendHeartbeat(currentActiveTab.url, debug);
|
this.sendHeartbeat(currentActiveTab.url, debug);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
changeExtensionState('whitelisted');
|
changeExtensionState('whitelisted');
|
||||||
console.log(currentActiveTab.url + ' is not on a whitelist.');
|
console.log(currentActiveTab.url + ' is not on a whitelist.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
changeExtensionState('notLogging');
|
changeExtensionState('notLogging');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates payload for the heartbeat and returns it as JSON.
|
* Creates payload for the heartbeat and returns it as JSON.
|
||||||
*
|
*
|
||||||
* @param entity
|
* @param entity
|
||||||
* @param type
|
* @param type
|
||||||
* @param debug
|
* @param debug
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_preparePayload(entity, type, debug = false) {
|
_preparePayload(entity, type, debug = false) {
|
||||||
return JSON.stringify({
|
return JSON.stringify({
|
||||||
entity: entity,
|
entity: entity,
|
||||||
type: type,
|
type: type,
|
||||||
time: moment().format('X'),
|
time: moment().format('X'),
|
||||||
project: '<<LAST_PROJECT>>',
|
project: '<<LAST_PROJECT>>',
|
||||||
is_debugging: debug,
|
is_debugging: debug,
|
||||||
plugin: 'chrome-wakatime/' + config.version
|
plugin: 'browser-wakatime/' + config.version
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a promise with logging type variable.
|
* Returns a promise with logging type variable.
|
||||||
*
|
*
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_getLoggingType() {
|
_getLoggingType() {
|
||||||
var deferredObject = $.Deferred();
|
var deferredObject = $.Deferred();
|
||||||
|
|
||||||
chrome.storage.sync.get({
|
browser.storage.sync.get({
|
||||||
loggingType: config.loggingType
|
loggingType: config.loggingType
|
||||||
}, function (items) {
|
}).then(function (items) {
|
||||||
deferredObject.resolve(items.loggingType);
|
deferredObject.resolve(items.loggingType);
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferredObject.promise();
|
return deferredObject.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given the entity and logging type it creates a payload and
|
* Given the entity and logging type it creates a payload and
|
||||||
* sends an ajax post request to the API.
|
* sends an ajax post request to the API.
|
||||||
*
|
*
|
||||||
* @param entity
|
* @param entity
|
||||||
* @param debug
|
* @param debug
|
||||||
*/
|
*/
|
||||||
sendHeartbeat(entity, debug) {
|
sendHeartbeat(entity, debug) {
|
||||||
|
|
||||||
var payload = null;
|
var payload = null;
|
||||||
|
|
||||||
this._getLoggingType().done((loggingType) => {
|
this._getLoggingType().done((loggingType) => {
|
||||||
|
|
||||||
// Get only the domain from the entity.
|
// Get only the domain from the entity.
|
||||||
// And send that in heartbeat
|
// And send that in heartbeat
|
||||||
if (loggingType == 'domain') {
|
if (loggingType == 'domain') {
|
||||||
|
|
||||||
var domain = getDomainFromUrl(entity);
|
var domain = getDomainFromUrl(entity);
|
||||||
|
|
||||||
payload = this._preparePayload(domain, 'domain', debug);
|
payload = this._preparePayload(domain, 'domain', debug);
|
||||||
|
|
||||||
console.log(payload);
|
console.log(payload);
|
||||||
|
|
||||||
this.sendAjaxRequestToApi(payload);
|
this.sendAjaxRequestToApi(payload);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Send entity in heartbeat
|
// Send entity in heartbeat
|
||||||
else if (loggingType == 'url') {
|
else if (loggingType == 'url') {
|
||||||
payload = this._preparePayload(entity, 'url', debug);
|
payload = this._preparePayload(entity, 'url', debug);
|
||||||
|
|
||||||
console.log(payload);
|
console.log(payload);
|
||||||
|
|
||||||
this.sendAjaxRequestToApi(payload);
|
this.sendAjaxRequestToApi(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends AJAX request with payload to the heartbeat API as JSON.
|
* Sends AJAX request with payload to the heartbeat API as JSON.
|
||||||
*
|
*
|
||||||
* @param payload
|
* @param payload
|
||||||
* @param method
|
* @param method
|
||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
sendAjaxRequestToApi(payload, method = 'POST') {
|
sendAjaxRequestToApi(payload, method = 'POST') {
|
||||||
|
|
||||||
var deferredObject = $.Deferred();
|
var deferredObject = $.Deferred();
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: config.heartbeatApiUrl,
|
url: config.heartbeatApiUrl,
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
method: method,
|
method: method,
|
||||||
data: payload,
|
data: payload,
|
||||||
statusCode: {
|
statusCode: {
|
||||||
401: function () {
|
401: function () {
|
||||||
changeExtensionState('notSignedIn');
|
changeExtensionState('notSignedIn');
|
||||||
},
|
},
|
||||||
201: function () {
|
201: function () {
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
success: (response) => {
|
success: (response) => {
|
||||||
deferredObject.resolve(this);
|
deferredObject.resolve(this);
|
||||||
},
|
},
|
||||||
error: (xhr, status, err) => {
|
error: (xhr, status, err) => {
|
||||||
console.error(config.heartbeatApiUrl, status, err.toString());
|
console.error(config.heartbeatApiUrl, status, err.toString());
|
||||||
|
|
||||||
deferredObject.resolve(this);
|
deferredObject.resolve(this);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferredObject.promise();
|
return deferredObject.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default WakaTimeCore;
|
export default WakaTimeCore;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
// Create a connection to the background page
|
// Create a connection to the background page
|
||||||
var backgroundPageConnection = chrome.runtime.connect({
|
var backgroundPageConnection = browser.runtime.connect({
|
||||||
name: "devtools-page"
|
name: "devtools-page"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send a message to background page with the current active tabId
|
// Send a message to background page with the current active tabId
|
||||||
backgroundPageConnection.postMessage({
|
backgroundPageConnection.postMessage({
|
||||||
name: 'init',
|
name: 'init',
|
||||||
tabId: chrome.devtools.inspectedWindow.tabId
|
tabId: browser.devtools.inspectedWindow.tabId
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,100 +1,100 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
var WakaTimeCore = require("./core/WakaTimeCore").default;
|
var WakaTimeCore = require("./core/WakaTimeCore").default;
|
||||||
|
|
||||||
// initialize class
|
// initialize class
|
||||||
var wakatime = new WakaTimeCore();
|
var wakatime = new WakaTimeCore();
|
||||||
|
|
||||||
// Holds currently open connections (ports) with devtools
|
// Holds currently open connections (ports) with devtools
|
||||||
// Uses tabId as index key.
|
// Uses tabId as index key.
|
||||||
var connections = {};
|
var connections = {};
|
||||||
|
|
||||||
// Add a listener to resolve alarms
|
// Add a listener to resolve alarms
|
||||||
chrome.alarms.onAlarm.addListener(function (alarm) {
|
browser.alarms.onAlarm.addListener(function (alarm) {
|
||||||
// |alarm| can be undefined because onAlarm also gets called from
|
// |alarm| can be undefined because onAlarm also gets called from
|
||||||
// window.setTimeout on old chrome versions.
|
// window.setTimeout on old chrome versions.
|
||||||
if (alarm && alarm.name == 'heartbeatAlarm') {
|
if (alarm && alarm.name == 'heartbeatAlarm') {
|
||||||
|
|
||||||
console.log('recording a heartbeat - alarm triggered');
|
console.log('recording a heartbeat - alarm triggered');
|
||||||
|
|
||||||
wakatime.recordHeartbeat();
|
wakatime.recordHeartbeat();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create a new alarm for heartbeats.
|
// Create a new alarm for heartbeats.
|
||||||
chrome.alarms.create('heartbeatAlarm', {periodInMinutes: 2});
|
browser.alarms.create('heartbeatAlarm', {periodInMinutes: 2});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever a active tab is changed it records a heartbeat with that tab url.
|
* Whenever a active tab is changed it records a heartbeat with that tab url.
|
||||||
*/
|
*/
|
||||||
chrome.tabs.onActivated.addListener(function (activeInfo) {
|
browser.tabs.onActivated.addListener(function (activeInfo) {
|
||||||
|
|
||||||
chrome.tabs.get(activeInfo.tabId, function (tab) {
|
browser.tabs.get(activeInfo.tabId).then(function (tab) {
|
||||||
|
|
||||||
console.log('recording a heartbeat - active tab changed');
|
console.log('recording a heartbeat - active tab changed');
|
||||||
|
|
||||||
wakatime.recordHeartbeat();
|
wakatime.recordHeartbeat();
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whenever any tab is updated it checks if the updated tab is the tab that is
|
* Whenever any tab is updated it checks if the updated tab is the tab that is
|
||||||
* currently active and if it is, then it records a heartbeat.
|
* currently active and if it is, then it records a heartbeat.
|
||||||
*/
|
*/
|
||||||
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
|
browser.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
|
||||||
|
|
||||||
if (changeInfo.status === 'complete') {
|
if (changeInfo.status === 'complete') {
|
||||||
// Get current tab URL.
|
// Get current tab URL.
|
||||||
chrome.tabs.query({active: true}, function(tabs) {
|
browser.tabs.query({active: true}).then(function(tabs) {
|
||||||
// If tab updated is the same as active tab
|
// If tab updated is the same as active tab
|
||||||
if (tabId == tabs[0].id) {
|
if (tabId == tabs[0].id) {
|
||||||
console.log('recording a heartbeat - tab updated');
|
console.log('recording a heartbeat - tab updated');
|
||||||
|
|
||||||
wakatime.recordHeartbeat();
|
wakatime.recordHeartbeat();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is in charge of detecting if devtools are opened or closed
|
* This is in charge of detecting if devtools are opened or closed
|
||||||
* and sending a heartbeat depending on that.
|
* and sending a heartbeat depending on that.
|
||||||
*/
|
*/
|
||||||
chrome.runtime.onConnect.addListener(function (port) {
|
browser.runtime.onConnect.addListener(function (port) {
|
||||||
|
|
||||||
if (port.name == "devtools-page") {
|
if (port.name == "devtools-page") {
|
||||||
|
|
||||||
// Listen to messages sent from the DevTools page
|
// Listen to messages sent from the DevTools page
|
||||||
port.onMessage.addListener(function (message, sender, sendResponse) {
|
port.onMessage.addListener(function (message, sender, sendResponse) {
|
||||||
if (message.name == "init") {
|
if (message.name == "init") {
|
||||||
|
|
||||||
connections[message.tabId] = port;
|
connections[message.tabId] = port;
|
||||||
|
|
||||||
wakatime.setTabsWithDevtoolsOpen(Object.keys(connections));
|
wakatime.setTabsWithDevtoolsOpen(Object.keys(connections));
|
||||||
|
|
||||||
wakatime.recordHeartbeat();
|
wakatime.recordHeartbeat();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
port.onDisconnect.addListener(function (port) {
|
port.onDisconnect.addListener(function (port) {
|
||||||
|
|
||||||
var tabs = Object.keys(connections);
|
var tabs = Object.keys(connections);
|
||||||
|
|
||||||
for (var i = 0, len = tabs.length; i < len; i ++) {
|
for (var i = 0, len = tabs.length; i < len; i ++) {
|
||||||
if (connections[tabs[i]] == port) {
|
if (connections[tabs[i]] == port) {
|
||||||
delete connections[tabs[i]];
|
delete connections[tabs[i]];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wakatime.setTabsWithDevtoolsOpen(Object.keys(connections));
|
wakatime.setTabsWithDevtoolsOpen(Object.keys(connections));
|
||||||
|
|
||||||
wakatime.recordHeartbeat();
|
wakatime.recordHeartbeat();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
var config = require('../config');
|
var config = require('../config');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It changes the extension icon color.
|
* It changes the extension icon color.
|
||||||
* Supported values are: 'red', 'white', 'gray' and ''.
|
* Supported values are: 'red', 'white', 'gray' and ''.
|
||||||
*
|
*
|
||||||
* @param color
|
* @param color
|
||||||
*/
|
*/
|
||||||
function changeExtensionIcon(color) {
|
function changeExtensionIcon(color) {
|
||||||
|
|
||||||
color = color ? color : '';
|
color = color ? color : '';
|
||||||
|
|
||||||
var path = null;
|
var path = null;
|
||||||
|
|
||||||
if (color !== '') {
|
if (color !== '') {
|
||||||
color = '-' + color;
|
color = '-' + color;
|
||||||
|
|
||||||
path = './graphics/wakatime-logo-38' + color + '.png';
|
path = './graphics/wakatime-logo-38' + color + '.png';
|
||||||
|
|
||||||
chrome.browserAction.setIcon({
|
browser.browserAction.setIcon({
|
||||||
path: path
|
path: path
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color === '') {
|
if (color === '') {
|
||||||
chrome.storage.sync.get({
|
browser.storage.sync.get({
|
||||||
theme: config.theme
|
theme: config.theme
|
||||||
}, function (items) {
|
}).then(function (items) {
|
||||||
if (items.theme == config.theme) {
|
if (items.theme == config.theme) {
|
||||||
path = './graphics/wakatime-logo-38.png';
|
path = './graphics/wakatime-logo-38.png';
|
||||||
|
|
||||||
chrome.browserAction.setIcon({
|
browser.browserAction.setIcon({
|
||||||
path: path
|
path: path
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
path = './graphics/wakatime-logo-38-white.png';
|
path = './graphics/wakatime-logo-38-white.png';
|
||||||
|
|
||||||
chrome.browserAction.setIcon({
|
browser.browserAction.setIcon({
|
||||||
path: path
|
path: path
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = changeExtensionIcon;
|
module.exports = changeExtensionIcon;
|
||||||
|
|||||||
@@ -1,42 +1,42 @@
|
|||||||
var config = require('../config');
|
var config = require('../config');
|
||||||
|
|
||||||
// Helpers
|
// Helpers
|
||||||
var changeExtensionIcon = require('./changeExtensionIcon');
|
var changeExtensionIcon = require('./changeExtensionIcon');
|
||||||
var changeExtensionTooltip = require('./changeExtensionTooltip');
|
var changeExtensionTooltip = require('./changeExtensionTooltip');
|
||||||
var in_array = require('./in_array');
|
var in_array = require('./in_array');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current state of the extension.
|
* Sets the current state of the extension.
|
||||||
*
|
*
|
||||||
* @param state
|
* @param state
|
||||||
*/
|
*/
|
||||||
function changeExtensionState(state) {
|
function changeExtensionState(state) {
|
||||||
if (! in_array(state, config.states)) {
|
if (! in_array(state, config.states)) {
|
||||||
throw new Error('Not a valid state!');
|
throw new Error('Not a valid state!');
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'allGood':
|
case 'allGood':
|
||||||
changeExtensionIcon(config.colors.allGood);
|
changeExtensionIcon(config.colors.allGood);
|
||||||
changeExtensionTooltip(config.tooltips.allGood);
|
changeExtensionTooltip(config.tooltips.allGood);
|
||||||
break;
|
break;
|
||||||
case 'notLogging':
|
case 'notLogging':
|
||||||
changeExtensionIcon(config.colors.notLogging);
|
changeExtensionIcon(config.colors.notLogging);
|
||||||
changeExtensionTooltip(config.tooltips.notLogging);
|
changeExtensionTooltip(config.tooltips.notLogging);
|
||||||
break;
|
break;
|
||||||
case 'notSignedIn':
|
case 'notSignedIn':
|
||||||
changeExtensionIcon(config.colors.notSignedIn);
|
changeExtensionIcon(config.colors.notSignedIn);
|
||||||
changeExtensionTooltip(config.tooltips.notSignedIn);
|
changeExtensionTooltip(config.tooltips.notSignedIn);
|
||||||
break;
|
break;
|
||||||
case 'blacklisted':
|
case 'blacklisted':
|
||||||
changeExtensionIcon(config.colors.notLogging);
|
changeExtensionIcon(config.colors.notLogging);
|
||||||
changeExtensionTooltip(config.tooltips.blacklisted);
|
changeExtensionTooltip(config.tooltips.blacklisted);
|
||||||
break;
|
break;
|
||||||
case 'whitelisted':
|
case 'whitelisted':
|
||||||
changeExtensionIcon(config.colors.notLogging);
|
changeExtensionIcon(config.colors.notLogging);
|
||||||
changeExtensionTooltip(config.tooltips.whitelisted);
|
changeExtensionTooltip(config.tooltips.whitelisted);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = changeExtensionState;
|
module.exports = changeExtensionState;
|
||||||
@@ -1,22 +1,22 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
var config = require('../config');
|
var config = require('../config');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* It changes the extension title
|
* It changes the extension title
|
||||||
*
|
*
|
||||||
* @param text
|
* @param text
|
||||||
*/
|
*/
|
||||||
function changeExtensionTooltip(text) {
|
function changeExtensionTooltip(text) {
|
||||||
|
|
||||||
if (text === '') {
|
if (text === '') {
|
||||||
text = config.name;
|
text = config.name;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
text = config.name + ' - ' + text;
|
text = config.name + ' - ' + text;
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.browserAction.setTitle({title: text});
|
browser.browserAction.setTitle({title: text});
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = changeExtensionTooltip;
|
module.exports = changeExtensionTooltip;
|
||||||
@@ -1,29 +1,29 @@
|
|||||||
/**
|
/**
|
||||||
* Creates an array from list using \n as delimiter
|
* Creates an array from list using \n as delimiter
|
||||||
* and checks if any element in list is contained in the url.
|
* and checks if any element in list is contained in the url.
|
||||||
*
|
*
|
||||||
* @param url
|
* @param url
|
||||||
* @param list
|
* @param list
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
function contains(url, list) {
|
function contains(url, list) {
|
||||||
var lines = list.split('\n');
|
var lines = list.split('\n');
|
||||||
|
|
||||||
for (var i = 0; i < lines.length; i ++) {
|
for (var i = 0; i < lines.length; i ++) {
|
||||||
|
|
||||||
// Trim all lines from the list one by one
|
// Trim all lines from the list one by one
|
||||||
var cleanLine = lines[i].trim();
|
var cleanLine = lines[i].trim();
|
||||||
|
|
||||||
// If by any chance one line in the list is empty, ignore it
|
// If by any chance one line in the list is empty, ignore it
|
||||||
if(cleanLine === '') continue;
|
if(cleanLine === '') continue;
|
||||||
|
|
||||||
// If url contains the current line return true
|
// If url contains the current line return true
|
||||||
if (url.indexOf(cleanLine) > -1) {
|
if (url.indexOf(cleanLine) > -1) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = contains;
|
module.exports = contains;
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* Returns domain from given URL.
|
* Returns domain from given URL.
|
||||||
*
|
*
|
||||||
* @param url
|
* @param url
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
function getDomainFromUrl(url) {
|
function getDomainFromUrl(url) {
|
||||||
var parts = url.split('/');
|
var parts = url.split('/');
|
||||||
|
|
||||||
return parts[0] + "//" + parts[2];
|
return parts[0] + "//" + parts[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = getDomainFromUrl;
|
module.exports = getDomainFromUrl;
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
/**
|
/**
|
||||||
* Returns boolean if needle is found in haystack or not.
|
* Returns boolean if needle is found in haystack or not.
|
||||||
*
|
*
|
||||||
* @param needle
|
* @param needle
|
||||||
* @param haystack
|
* @param haystack
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
function in_array(needle, haystack) {
|
function in_array(needle, haystack) {
|
||||||
for (var i = 0; i < haystack.length; i ++) {
|
for (var i = 0; i < haystack.length; i ++) {
|
||||||
if (needle == haystack[i]) {
|
if (needle == haystack[i]) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = in_array;
|
module.exports = in_array;
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
/* global chrome */
|
/* global browser */
|
||||||
|
|
||||||
/* This is a fix for Bootstrap requiring jQuery */
|
/* This is a fix for Bootstrap requiring jQuery */
|
||||||
global.jQuery = require('jquery');
|
global.jQuery = require('jquery');
|
||||||
require('bootstrap');
|
require('bootstrap');
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactDOM = require('react-dom');
|
var ReactDOM = require('react-dom');
|
||||||
|
|
||||||
// React components
|
// React components
|
||||||
var Options = require('./components/Options.jsx');
|
var Options = require('./components/Options.jsx');
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Options />,
|
<Options />,
|
||||||
document.getElementById('wakatime-options')
|
document.getElementById('wakatime-options')
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,30 +1,30 @@
|
|||||||
@import "bootstrap/bootstrap";
|
@import "bootstrap/bootstrap";
|
||||||
@import "font-awesome/font-awesome";
|
@import "font-awesome/font-awesome";
|
||||||
@import "bootswatch/paper/bootswatch";
|
@import "bootswatch/paper/bootswatch";
|
||||||
@import "bootswatch/paper/variables";
|
@import "bootswatch/paper/variables";
|
||||||
@import "variables";
|
@import "variables";
|
||||||
@import "partials/_animations";
|
@import "partials/_animations";
|
||||||
|
|
||||||
body {
|
body {
|
||||||
min-width: 357px;
|
min-width: 357px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a.navbar-brand {
|
a.navbar-brand {
|
||||||
img {
|
img {
|
||||||
margin-top: -12px;
|
margin-top: -12px;
|
||||||
float: left;
|
float: left;
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
div.container {
|
div.container {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas#icon {
|
canvas#icon {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div#status {
|
div#status {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,304 +1,304 @@
|
|||||||
{
|
{
|
||||||
"always-semicolon": true,
|
"always-semicolon": true,
|
||||||
"block-indent": 2,
|
"block-indent": 2,
|
||||||
"color-case": "lower",
|
"color-case": "lower",
|
||||||
"color-shorthand": true,
|
"color-shorthand": true,
|
||||||
"element-case": "lower",
|
"element-case": "lower",
|
||||||
"eof-newline": true,
|
"eof-newline": true,
|
||||||
"leading-zero": false,
|
"leading-zero": false,
|
||||||
"remove-empty-rulesets": true,
|
"remove-empty-rulesets": true,
|
||||||
"space-after-colon": 1,
|
"space-after-colon": 1,
|
||||||
"space-after-combinator": 1,
|
"space-after-combinator": 1,
|
||||||
"space-before-selector-delimiter": 0,
|
"space-before-selector-delimiter": 0,
|
||||||
"space-between-declarations": "\n",
|
"space-between-declarations": "\n",
|
||||||
"space-after-opening-brace": "\n",
|
"space-after-opening-brace": "\n",
|
||||||
"space-before-closing-brace": "\n",
|
"space-before-closing-brace": "\n",
|
||||||
"space-before-colon": 0,
|
"space-before-colon": 0,
|
||||||
"space-before-combinator": 1,
|
"space-before-combinator": 1,
|
||||||
"space-before-opening-brace": 1,
|
"space-before-opening-brace": 1,
|
||||||
"strip-spaces": true,
|
"strip-spaces": true,
|
||||||
"unitless-zero": true,
|
"unitless-zero": true,
|
||||||
"vendor-prefix-align": true,
|
"vendor-prefix-align": true,
|
||||||
"sort-order": [
|
"sort-order": [
|
||||||
[
|
[
|
||||||
"position",
|
"position",
|
||||||
"top",
|
"top",
|
||||||
"right",
|
"right",
|
||||||
"bottom",
|
"bottom",
|
||||||
"left",
|
"left",
|
||||||
"z-index",
|
"z-index",
|
||||||
"display",
|
"display",
|
||||||
"float",
|
"float",
|
||||||
"width",
|
"width",
|
||||||
"min-width",
|
"min-width",
|
||||||
"max-width",
|
"max-width",
|
||||||
"height",
|
"height",
|
||||||
"min-height",
|
"min-height",
|
||||||
"max-height",
|
"max-height",
|
||||||
"-webkit-box-sizing",
|
"-webkit-box-sizing",
|
||||||
"-moz-box-sizing",
|
"-moz-box-sizing",
|
||||||
"box-sizing",
|
"box-sizing",
|
||||||
"-webkit-appearance",
|
"-webkit-appearance",
|
||||||
"padding",
|
"padding",
|
||||||
"padding-top",
|
"padding-top",
|
||||||
"padding-right",
|
"padding-right",
|
||||||
"padding-bottom",
|
"padding-bottom",
|
||||||
"padding-left",
|
"padding-left",
|
||||||
"margin",
|
"margin",
|
||||||
"margin-top",
|
"margin-top",
|
||||||
"margin-right",
|
"margin-right",
|
||||||
"margin-bottom",
|
"margin-bottom",
|
||||||
"margin-left",
|
"margin-left",
|
||||||
"overflow",
|
"overflow",
|
||||||
"overflow-x",
|
"overflow-x",
|
||||||
"overflow-y",
|
"overflow-y",
|
||||||
"-webkit-overflow-scrolling",
|
"-webkit-overflow-scrolling",
|
||||||
"-ms-overflow-x",
|
"-ms-overflow-x",
|
||||||
"-ms-overflow-y",
|
"-ms-overflow-y",
|
||||||
"-ms-overflow-style",
|
"-ms-overflow-style",
|
||||||
"clip",
|
"clip",
|
||||||
"clear",
|
"clear",
|
||||||
"font",
|
"font",
|
||||||
"font-family",
|
"font-family",
|
||||||
"font-size",
|
"font-size",
|
||||||
"font-style",
|
"font-style",
|
||||||
"font-weight",
|
"font-weight",
|
||||||
"font-variant",
|
"font-variant",
|
||||||
"font-size-adjust",
|
"font-size-adjust",
|
||||||
"font-stretch",
|
"font-stretch",
|
||||||
"font-effect",
|
"font-effect",
|
||||||
"font-emphasize",
|
"font-emphasize",
|
||||||
"font-emphasize-position",
|
"font-emphasize-position",
|
||||||
"font-emphasize-style",
|
"font-emphasize-style",
|
||||||
"font-smooth",
|
"font-smooth",
|
||||||
"-webkit-hyphens",
|
"-webkit-hyphens",
|
||||||
"-moz-hyphens",
|
"-moz-hyphens",
|
||||||
"hyphens",
|
"hyphens",
|
||||||
"line-height",
|
"line-height",
|
||||||
"color",
|
"color",
|
||||||
"text-align",
|
"text-align",
|
||||||
"-webkit-text-align-last",
|
"-webkit-text-align-last",
|
||||||
"-moz-text-align-last",
|
"-moz-text-align-last",
|
||||||
"-ms-text-align-last",
|
"-ms-text-align-last",
|
||||||
"text-align-last",
|
"text-align-last",
|
||||||
"text-emphasis",
|
"text-emphasis",
|
||||||
"text-emphasis-color",
|
"text-emphasis-color",
|
||||||
"text-emphasis-style",
|
"text-emphasis-style",
|
||||||
"text-emphasis-position",
|
"text-emphasis-position",
|
||||||
"text-decoration",
|
"text-decoration",
|
||||||
"text-indent",
|
"text-indent",
|
||||||
"text-justify",
|
"text-justify",
|
||||||
"text-outline",
|
"text-outline",
|
||||||
"-ms-text-overflow",
|
"-ms-text-overflow",
|
||||||
"text-overflow",
|
"text-overflow",
|
||||||
"text-overflow-ellipsis",
|
"text-overflow-ellipsis",
|
||||||
"text-overflow-mode",
|
"text-overflow-mode",
|
||||||
"text-shadow",
|
"text-shadow",
|
||||||
"text-transform",
|
"text-transform",
|
||||||
"text-wrap",
|
"text-wrap",
|
||||||
"-webkit-text-size-adjust",
|
"-webkit-text-size-adjust",
|
||||||
"-ms-text-size-adjust",
|
"-ms-text-size-adjust",
|
||||||
"letter-spacing",
|
"letter-spacing",
|
||||||
"-ms-word-break",
|
"-ms-word-break",
|
||||||
"word-break",
|
"word-break",
|
||||||
"word-spacing",
|
"word-spacing",
|
||||||
"-ms-word-wrap",
|
"-ms-word-wrap",
|
||||||
"word-wrap",
|
"word-wrap",
|
||||||
"-moz-tab-size",
|
"-moz-tab-size",
|
||||||
"-o-tab-size",
|
"-o-tab-size",
|
||||||
"tab-size",
|
"tab-size",
|
||||||
"white-space",
|
"white-space",
|
||||||
"vertical-align",
|
"vertical-align",
|
||||||
"list-style",
|
"list-style",
|
||||||
"list-style-position",
|
"list-style-position",
|
||||||
"list-style-type",
|
"list-style-type",
|
||||||
"list-style-image",
|
"list-style-image",
|
||||||
"pointer-events",
|
"pointer-events",
|
||||||
"-ms-touch-action",
|
"-ms-touch-action",
|
||||||
"touch-action",
|
"touch-action",
|
||||||
"cursor",
|
"cursor",
|
||||||
"visibility",
|
"visibility",
|
||||||
"zoom",
|
"zoom",
|
||||||
"flex-direction",
|
"flex-direction",
|
||||||
"flex-order",
|
"flex-order",
|
||||||
"flex-pack",
|
"flex-pack",
|
||||||
"flex-align",
|
"flex-align",
|
||||||
"table-layout",
|
"table-layout",
|
||||||
"empty-cells",
|
"empty-cells",
|
||||||
"caption-side",
|
"caption-side",
|
||||||
"border-spacing",
|
"border-spacing",
|
||||||
"border-collapse",
|
"border-collapse",
|
||||||
"content",
|
"content",
|
||||||
"quotes",
|
"quotes",
|
||||||
"counter-reset",
|
"counter-reset",
|
||||||
"counter-increment",
|
"counter-increment",
|
||||||
"resize",
|
"resize",
|
||||||
"-webkit-user-select",
|
"-webkit-user-select",
|
||||||
"-moz-user-select",
|
"-moz-user-select",
|
||||||
"-ms-user-select",
|
"-ms-user-select",
|
||||||
"-o-user-select",
|
"-o-user-select",
|
||||||
"user-select",
|
"user-select",
|
||||||
"nav-index",
|
"nav-index",
|
||||||
"nav-up",
|
"nav-up",
|
||||||
"nav-right",
|
"nav-right",
|
||||||
"nav-down",
|
"nav-down",
|
||||||
"nav-left",
|
"nav-left",
|
||||||
"background",
|
"background",
|
||||||
"background-color",
|
"background-color",
|
||||||
"background-image",
|
"background-image",
|
||||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
|
"-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
|
||||||
"filter:progid:DXImageTransform.Microsoft.gradient",
|
"filter:progid:DXImageTransform.Microsoft.gradient",
|
||||||
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
"filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
|
||||||
"filter",
|
"filter",
|
||||||
"background-repeat",
|
"background-repeat",
|
||||||
"background-attachment",
|
"background-attachment",
|
||||||
"background-position",
|
"background-position",
|
||||||
"background-position-x",
|
"background-position-x",
|
||||||
"background-position-y",
|
"background-position-y",
|
||||||
"-webkit-background-clip",
|
"-webkit-background-clip",
|
||||||
"-moz-background-clip",
|
"-moz-background-clip",
|
||||||
"background-clip",
|
"background-clip",
|
||||||
"background-origin",
|
"background-origin",
|
||||||
"-webkit-background-size",
|
"-webkit-background-size",
|
||||||
"-moz-background-size",
|
"-moz-background-size",
|
||||||
"-o-background-size",
|
"-o-background-size",
|
||||||
"background-size",
|
"background-size",
|
||||||
"border",
|
"border",
|
||||||
"border-color",
|
"border-color",
|
||||||
"border-style",
|
"border-style",
|
||||||
"border-width",
|
"border-width",
|
||||||
"border-top",
|
"border-top",
|
||||||
"border-top-color",
|
"border-top-color",
|
||||||
"border-top-style",
|
"border-top-style",
|
||||||
"border-top-width",
|
"border-top-width",
|
||||||
"border-right",
|
"border-right",
|
||||||
"border-right-color",
|
"border-right-color",
|
||||||
"border-right-style",
|
"border-right-style",
|
||||||
"border-right-width",
|
"border-right-width",
|
||||||
"border-bottom",
|
"border-bottom",
|
||||||
"border-bottom-color",
|
"border-bottom-color",
|
||||||
"border-bottom-style",
|
"border-bottom-style",
|
||||||
"border-bottom-width",
|
"border-bottom-width",
|
||||||
"border-left",
|
"border-left",
|
||||||
"border-left-color",
|
"border-left-color",
|
||||||
"border-left-style",
|
"border-left-style",
|
||||||
"border-left-width",
|
"border-left-width",
|
||||||
"border-radius",
|
"border-radius",
|
||||||
"border-top-left-radius",
|
"border-top-left-radius",
|
||||||
"border-top-right-radius",
|
"border-top-right-radius",
|
||||||
"border-bottom-right-radius",
|
"border-bottom-right-radius",
|
||||||
"border-bottom-left-radius",
|
"border-bottom-left-radius",
|
||||||
"-webkit-border-image",
|
"-webkit-border-image",
|
||||||
"-moz-border-image",
|
"-moz-border-image",
|
||||||
"-o-border-image",
|
"-o-border-image",
|
||||||
"border-image",
|
"border-image",
|
||||||
"-webkit-border-image-source",
|
"-webkit-border-image-source",
|
||||||
"-moz-border-image-source",
|
"-moz-border-image-source",
|
||||||
"-o-border-image-source",
|
"-o-border-image-source",
|
||||||
"border-image-source",
|
"border-image-source",
|
||||||
"-webkit-border-image-slice",
|
"-webkit-border-image-slice",
|
||||||
"-moz-border-image-slice",
|
"-moz-border-image-slice",
|
||||||
"-o-border-image-slice",
|
"-o-border-image-slice",
|
||||||
"border-image-slice",
|
"border-image-slice",
|
||||||
"-webkit-border-image-width",
|
"-webkit-border-image-width",
|
||||||
"-moz-border-image-width",
|
"-moz-border-image-width",
|
||||||
"-o-border-image-width",
|
"-o-border-image-width",
|
||||||
"border-image-width",
|
"border-image-width",
|
||||||
"-webkit-border-image-outset",
|
"-webkit-border-image-outset",
|
||||||
"-moz-border-image-outset",
|
"-moz-border-image-outset",
|
||||||
"-o-border-image-outset",
|
"-o-border-image-outset",
|
||||||
"border-image-outset",
|
"border-image-outset",
|
||||||
"-webkit-border-image-repeat",
|
"-webkit-border-image-repeat",
|
||||||
"-moz-border-image-repeat",
|
"-moz-border-image-repeat",
|
||||||
"-o-border-image-repeat",
|
"-o-border-image-repeat",
|
||||||
"border-image-repeat",
|
"border-image-repeat",
|
||||||
"outline",
|
"outline",
|
||||||
"outline-width",
|
"outline-width",
|
||||||
"outline-style",
|
"outline-style",
|
||||||
"outline-color",
|
"outline-color",
|
||||||
"outline-offset",
|
"outline-offset",
|
||||||
"-webkit-box-shadow",
|
"-webkit-box-shadow",
|
||||||
"-moz-box-shadow",
|
"-moz-box-shadow",
|
||||||
"box-shadow",
|
"box-shadow",
|
||||||
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
"filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
|
||||||
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
|
"-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
|
||||||
"opacity",
|
"opacity",
|
||||||
"-ms-interpolation-mode",
|
"-ms-interpolation-mode",
|
||||||
"-webkit-transition",
|
"-webkit-transition",
|
||||||
"-moz-transition",
|
"-moz-transition",
|
||||||
"-ms-transition",
|
"-ms-transition",
|
||||||
"-o-transition",
|
"-o-transition",
|
||||||
"transition",
|
"transition",
|
||||||
"-webkit-transition-delay",
|
"-webkit-transition-delay",
|
||||||
"-moz-transition-delay",
|
"-moz-transition-delay",
|
||||||
"-ms-transition-delay",
|
"-ms-transition-delay",
|
||||||
"-o-transition-delay",
|
"-o-transition-delay",
|
||||||
"transition-delay",
|
"transition-delay",
|
||||||
"-webkit-transition-timing-function",
|
"-webkit-transition-timing-function",
|
||||||
"-moz-transition-timing-function",
|
"-moz-transition-timing-function",
|
||||||
"-ms-transition-timing-function",
|
"-ms-transition-timing-function",
|
||||||
"-o-transition-timing-function",
|
"-o-transition-timing-function",
|
||||||
"transition-timing-function",
|
"transition-timing-function",
|
||||||
"-webkit-transition-duration",
|
"-webkit-transition-duration",
|
||||||
"-moz-transition-duration",
|
"-moz-transition-duration",
|
||||||
"-ms-transition-duration",
|
"-ms-transition-duration",
|
||||||
"-o-transition-duration",
|
"-o-transition-duration",
|
||||||
"transition-duration",
|
"transition-duration",
|
||||||
"-webkit-transition-property",
|
"-webkit-transition-property",
|
||||||
"-moz-transition-property",
|
"-moz-transition-property",
|
||||||
"-ms-transition-property",
|
"-ms-transition-property",
|
||||||
"-o-transition-property",
|
"-o-transition-property",
|
||||||
"transition-property",
|
"transition-property",
|
||||||
"-webkit-transform",
|
"-webkit-transform",
|
||||||
"-moz-transform",
|
"-moz-transform",
|
||||||
"-ms-transform",
|
"-ms-transform",
|
||||||
"-o-transform",
|
"-o-transform",
|
||||||
"transform",
|
"transform",
|
||||||
"-webkit-transform-origin",
|
"-webkit-transform-origin",
|
||||||
"-moz-transform-origin",
|
"-moz-transform-origin",
|
||||||
"-ms-transform-origin",
|
"-ms-transform-origin",
|
||||||
"-o-transform-origin",
|
"-o-transform-origin",
|
||||||
"transform-origin",
|
"transform-origin",
|
||||||
"-webkit-animation",
|
"-webkit-animation",
|
||||||
"-moz-animation",
|
"-moz-animation",
|
||||||
"-ms-animation",
|
"-ms-animation",
|
||||||
"-o-animation",
|
"-o-animation",
|
||||||
"animation",
|
"animation",
|
||||||
"-webkit-animation-name",
|
"-webkit-animation-name",
|
||||||
"-moz-animation-name",
|
"-moz-animation-name",
|
||||||
"-ms-animation-name",
|
"-ms-animation-name",
|
||||||
"-o-animation-name",
|
"-o-animation-name",
|
||||||
"animation-name",
|
"animation-name",
|
||||||
"-webkit-animation-duration",
|
"-webkit-animation-duration",
|
||||||
"-moz-animation-duration",
|
"-moz-animation-duration",
|
||||||
"-ms-animation-duration",
|
"-ms-animation-duration",
|
||||||
"-o-animation-duration",
|
"-o-animation-duration",
|
||||||
"animation-duration",
|
"animation-duration",
|
||||||
"-webkit-animation-play-state",
|
"-webkit-animation-play-state",
|
||||||
"-moz-animation-play-state",
|
"-moz-animation-play-state",
|
||||||
"-ms-animation-play-state",
|
"-ms-animation-play-state",
|
||||||
"-o-animation-play-state",
|
"-o-animation-play-state",
|
||||||
"animation-play-state",
|
"animation-play-state",
|
||||||
"-webkit-animation-timing-function",
|
"-webkit-animation-timing-function",
|
||||||
"-moz-animation-timing-function",
|
"-moz-animation-timing-function",
|
||||||
"-ms-animation-timing-function",
|
"-ms-animation-timing-function",
|
||||||
"-o-animation-timing-function",
|
"-o-animation-timing-function",
|
||||||
"animation-timing-function",
|
"animation-timing-function",
|
||||||
"-webkit-animation-delay",
|
"-webkit-animation-delay",
|
||||||
"-moz-animation-delay",
|
"-moz-animation-delay",
|
||||||
"-ms-animation-delay",
|
"-ms-animation-delay",
|
||||||
"-o-animation-delay",
|
"-o-animation-delay",
|
||||||
"animation-delay",
|
"animation-delay",
|
||||||
"-webkit-animation-iteration-count",
|
"-webkit-animation-iteration-count",
|
||||||
"-moz-animation-iteration-count",
|
"-moz-animation-iteration-count",
|
||||||
"-ms-animation-iteration-count",
|
"-ms-animation-iteration-count",
|
||||||
"-o-animation-iteration-count",
|
"-o-animation-iteration-count",
|
||||||
"animation-iteration-count",
|
"animation-iteration-count",
|
||||||
"-webkit-animation-direction",
|
"-webkit-animation-direction",
|
||||||
"-moz-animation-direction",
|
"-moz-animation-direction",
|
||||||
"-ms-animation-direction",
|
"-ms-animation-direction",
|
||||||
"-o-animation-direction",
|
"-o-animation-direction",
|
||||||
"animation-direction"
|
"animation-direction"
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
{
|
{
|
||||||
"adjoining-classes": false,
|
"adjoining-classes": false,
|
||||||
"box-sizing": false,
|
"box-sizing": false,
|
||||||
"box-model": false,
|
"box-model": false,
|
||||||
"compatible-vendor-prefixes": false,
|
"compatible-vendor-prefixes": false,
|
||||||
"floats": false,
|
"floats": false,
|
||||||
"font-sizes": false,
|
"font-sizes": false,
|
||||||
"gradients": false,
|
"gradients": false,
|
||||||
"important": false,
|
"important": false,
|
||||||
"known-properties": false,
|
"known-properties": false,
|
||||||
"outline-none": false,
|
"outline-none": false,
|
||||||
"qualified-headings": false,
|
"qualified-headings": false,
|
||||||
"regex-selectors": false,
|
"regex-selectors": false,
|
||||||
"shorthand": false,
|
"shorthand": false,
|
||||||
"text-indent": false,
|
"text-indent": false,
|
||||||
"unique-headings": false,
|
"unique-headings": false,
|
||||||
"universal-selector": false,
|
"universal-selector": false,
|
||||||
"unqualified-attributes": false
|
"unqualified-attributes": false
|
||||||
}
|
}
|
||||||
|
|||||||
4
assets/less/bootstrap/bootstrap.less
vendored
4
assets/less/bootstrap/bootstrap.less
vendored
@@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* Bootstrap v3.3.6 (http://getbootstrap.com)
|
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2016 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@
|
|||||||
.border-right-radius(0);
|
.border-right-radius(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it
|
// Need .dropdown-toggle since :last-child doesn't apply, given that a .dropdown-menu is used immediately after it
|
||||||
.btn-group > .btn:last-child:not(:first-child),
|
.btn-group > .btn:last-child:not(:first-child),
|
||||||
.btn-group > .dropdown-toggle:not(:first-child) {
|
.btn-group > .dropdown-toggle:not(:first-child) {
|
||||||
.border-left-radius(0);
|
.border-left-radius(0);
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ input[type="search"] {
|
|||||||
// set a pixel line-height that matches the given height of the input, but only
|
// set a pixel line-height that matches the given height of the input, but only
|
||||||
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
|
// for Safari. See https://bugs.webkit.org/show_bug.cgi?id=139848
|
||||||
//
|
//
|
||||||
// Note that as of 8.3, iOS doesn't support `datetime` or `week`.
|
// Note that as of 9.3, iOS doesn't support `week`.
|
||||||
|
|
||||||
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
@media screen and (-webkit-min-device-pixel-ratio: 0) {
|
||||||
input[type="date"],
|
input[type="date"],
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// WebKit-style focus
|
// WebKit-style focus
|
||||||
|
|
||||||
.tab-focus() {
|
.tab-focus() {
|
||||||
// Default
|
// WebKit-specific. Other browsers will keep their default outline style.
|
||||||
outline: thin dotted;
|
// (Initially tried to also force default via `outline: initial`,
|
||||||
// WebKit
|
// but that seems to erroneously remove the outline in Firefox altogether.)
|
||||||
outline: 5px auto -webkit-focus-ring-color;
|
outline: 5px auto -webkit-focus-ring-color;
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,7 +214,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Collapsable panels (aka, accordion)
|
// Collapsible panels (aka, accordion)
|
||||||
//
|
//
|
||||||
// Wrap a series of panels in `.panel-group` to turn them into an accordion with
|
// Wrap a series of panels in `.panel-group` to turn them into an accordion with
|
||||||
// the help of our collapse JavaScript plugin.
|
// the help of our collapse JavaScript plugin.
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ hr {
|
|||||||
|
|
||||||
// Only display content to screen readers
|
// Only display content to screen readers
|
||||||
//
|
//
|
||||||
// See: http://a11yproject.com/posts/how-to-hide-content/
|
// See: http://a11yproject.com/posts/how-to-hide-content
|
||||||
|
|
||||||
.sr-only {
|
.sr-only {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* Bootstrap v3.3.6 (http://getbootstrap.com)
|
* Bootstrap v3.3.7 (http://getbootstrap.com)
|
||||||
* Copyright 2011-2015 Twitter, Inc.
|
* Copyright 2011-2016 Twitter, Inc.
|
||||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@
|
|||||||
//** Global background color for active items (e.g., navs or dropdowns).
|
//** Global background color for active items (e.g., navs or dropdowns).
|
||||||
@component-active-bg: @brand-primary;
|
@component-active-bg: @brand-primary;
|
||||||
|
|
||||||
//** Width of the `border` for generating carets that indicator dropdowns.
|
//** Width of the `border` for generating carets that indicate dropdowns.
|
||||||
@caret-width-base: 4px;
|
@caret-width-base: 4px;
|
||||||
//** Carets increase slightly in size for larger components.
|
//** Carets increase slightly in size for larger components.
|
||||||
@caret-width-large: 5px;
|
@caret-width-large: 5px;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
68
assets/less/font-awesome/animated.less
vendored
68
assets/less/font-awesome/animated.less
vendored
@@ -1,34 +1,34 @@
|
|||||||
// Animated Icons
|
// Animated Icons
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
|
||||||
.@{fa-css-prefix}-spin {
|
.@{fa-css-prefix}-spin {
|
||||||
-webkit-animation: fa-spin 2s infinite linear;
|
-webkit-animation: fa-spin 2s infinite linear;
|
||||||
animation: fa-spin 2s infinite linear;
|
animation: fa-spin 2s infinite linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{fa-css-prefix}-pulse {
|
.@{fa-css-prefix}-pulse {
|
||||||
-webkit-animation: fa-spin 1s infinite steps(8);
|
-webkit-animation: fa-spin 1s infinite steps(8);
|
||||||
animation: fa-spin 1s infinite steps(8);
|
animation: fa-spin 1s infinite steps(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes fa-spin {
|
@-webkit-keyframes fa-spin {
|
||||||
0% {
|
0% {
|
||||||
-webkit-transform: rotate(0deg);
|
-webkit-transform: rotate(0deg);
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(359deg);
|
-webkit-transform: rotate(359deg);
|
||||||
transform: rotate(359deg);
|
transform: rotate(359deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fa-spin {
|
@keyframes fa-spin {
|
||||||
0% {
|
0% {
|
||||||
-webkit-transform: rotate(0deg);
|
-webkit-transform: rotate(0deg);
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(359deg);
|
-webkit-transform: rotate(359deg);
|
||||||
transform: rotate(359deg);
|
transform: rotate(359deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
assets/less/font-awesome/bordered-pulled.less
vendored
50
assets/less/font-awesome/bordered-pulled.less
vendored
@@ -1,25 +1,25 @@
|
|||||||
// Bordered & Pulled
|
// Bordered & Pulled
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.@{fa-css-prefix}-border {
|
.@{fa-css-prefix}-border {
|
||||||
padding: .2em .25em .15em;
|
padding: .2em .25em .15em;
|
||||||
border: solid .08em @fa-border-color;
|
border: solid .08em @fa-border-color;
|
||||||
border-radius: .1em;
|
border-radius: .1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.@{fa-css-prefix}-pull-left { float: left; }
|
.@{fa-css-prefix}-pull-left { float: left; }
|
||||||
.@{fa-css-prefix}-pull-right { float: right; }
|
.@{fa-css-prefix}-pull-right { float: right; }
|
||||||
|
|
||||||
.@{fa-css-prefix} {
|
.@{fa-css-prefix} {
|
||||||
&.@{fa-css-prefix}-pull-left { margin-right: .3em; }
|
&.@{fa-css-prefix}-pull-left { margin-right: .3em; }
|
||||||
&.@{fa-css-prefix}-pull-right { margin-left: .3em; }
|
&.@{fa-css-prefix}-pull-right { margin-left: .3em; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deprecated as of 4.4.0 */
|
/* Deprecated as of 4.4.0 */
|
||||||
.pull-right { float: right; }
|
.pull-right { float: right; }
|
||||||
.pull-left { float: left; }
|
.pull-left { float: left; }
|
||||||
|
|
||||||
.@{fa-css-prefix} {
|
.@{fa-css-prefix} {
|
||||||
&.pull-left { margin-right: .3em; }
|
&.pull-left { margin-right: .3em; }
|
||||||
&.pull-right { margin-left: .3em; }
|
&.pull-right { margin-left: .3em; }
|
||||||
}
|
}
|
||||||
|
|||||||
24
assets/less/font-awesome/core.less
vendored
24
assets/less/font-awesome/core.less
vendored
@@ -1,12 +1,12 @@
|
|||||||
// Base Class Definition
|
// Base Class Definition
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.@{fa-css-prefix} {
|
.@{fa-css-prefix} {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
|
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
|
||||||
font-size: inherit; // can't have font-size inherit on line above, so need to override
|
font-size: inherit; // can't have font-size inherit on line above, so need to override
|
||||||
text-rendering: auto; // optimizelegibility throws things off #1094
|
text-rendering: auto; // optimizelegibility throws things off #1094
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
12
assets/less/font-awesome/fixed-width.less
vendored
12
assets/less/font-awesome/fixed-width.less
vendored
@@ -1,6 +1,6 @@
|
|||||||
// Fixed Width Icons
|
// Fixed Width Icons
|
||||||
// -------------------------
|
// -------------------------
|
||||||
.@{fa-css-prefix}-fw {
|
.@{fa-css-prefix}-fw {
|
||||||
width: (18em / 14);
|
width: (18em / 14);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|||||||
36
assets/less/font-awesome/font-awesome.less
vendored
36
assets/less/font-awesome/font-awesome.less
vendored
@@ -1,18 +1,18 @@
|
|||||||
/*!
|
/*!
|
||||||
* Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome
|
* Font Awesome 4.6.3 by @davegandy - http://fontawesome.io - @fontawesome
|
||||||
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
* License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@import "variables.less";
|
@import "variables.less";
|
||||||
@import "mixins.less";
|
@import "mixins.less";
|
||||||
@import "path.less";
|
@import "path.less";
|
||||||
@import "core.less";
|
@import "core.less";
|
||||||
@import "larger.less";
|
@import "larger.less";
|
||||||
@import "fixed-width.less";
|
@import "fixed-width.less";
|
||||||
@import "list.less";
|
@import "list.less";
|
||||||
@import "bordered-pulled.less";
|
@import "bordered-pulled.less";
|
||||||
@import "animated.less";
|
@import "animated.less";
|
||||||
@import "rotated-flipped.less";
|
@import "rotated-flipped.less";
|
||||||
@import "stacked.less";
|
@import "stacked.less";
|
||||||
@import "icons.less";
|
@import "icons.less";
|
||||||
@import "screen-reader.less";
|
@import "screen-reader.less";
|
||||||
|
|||||||
1466
assets/less/font-awesome/icons.less
vendored
1466
assets/less/font-awesome/icons.less
vendored
File diff suppressed because it is too large
Load Diff
26
assets/less/font-awesome/larger.less
vendored
26
assets/less/font-awesome/larger.less
vendored
@@ -1,13 +1,13 @@
|
|||||||
// Icon Sizes
|
// Icon Sizes
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
/* makes the font 33% larger relative to the icon container */
|
/* makes the font 33% larger relative to the icon container */
|
||||||
.@{fa-css-prefix}-lg {
|
.@{fa-css-prefix}-lg {
|
||||||
font-size: (4em / 3);
|
font-size: (4em / 3);
|
||||||
line-height: (3em / 4);
|
line-height: (3em / 4);
|
||||||
vertical-align: -15%;
|
vertical-align: -15%;
|
||||||
}
|
}
|
||||||
.@{fa-css-prefix}-2x { font-size: 2em; }
|
.@{fa-css-prefix}-2x { font-size: 2em; }
|
||||||
.@{fa-css-prefix}-3x { font-size: 3em; }
|
.@{fa-css-prefix}-3x { font-size: 3em; }
|
||||||
.@{fa-css-prefix}-4x { font-size: 4em; }
|
.@{fa-css-prefix}-4x { font-size: 4em; }
|
||||||
.@{fa-css-prefix}-5x { font-size: 5em; }
|
.@{fa-css-prefix}-5x { font-size: 5em; }
|
||||||
|
|||||||
38
assets/less/font-awesome/list.less
vendored
38
assets/less/font-awesome/list.less
vendored
@@ -1,19 +1,19 @@
|
|||||||
// List Icons
|
// List Icons
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.@{fa-css-prefix}-ul {
|
.@{fa-css-prefix}-ul {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
margin-left: @fa-li-width;
|
margin-left: @fa-li-width;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
> li { position: relative; }
|
> li { position: relative; }
|
||||||
}
|
}
|
||||||
.@{fa-css-prefix}-li {
|
.@{fa-css-prefix}-li {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: -@fa-li-width;
|
left: -@fa-li-width;
|
||||||
width: @fa-li-width;
|
width: @fa-li-width;
|
||||||
top: (2em / 14);
|
top: (2em / 14);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
&.@{fa-css-prefix}-lg {
|
&.@{fa-css-prefix}-lg {
|
||||||
left: (-@fa-li-width + (4em / 14));
|
left: (-@fa-li-width + (4em / 14));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
120
assets/less/font-awesome/mixins.less
vendored
120
assets/less/font-awesome/mixins.less
vendored
@@ -1,60 +1,60 @@
|
|||||||
// Mixins
|
// Mixins
|
||||||
// --------------------------
|
// --------------------------
|
||||||
|
|
||||||
.fa-icon() {
|
.fa-icon() {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
|
font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration
|
||||||
font-size: inherit; // can't have font-size inherit on line above, so need to override
|
font-size: inherit; // can't have font-size inherit on line above, so need to override
|
||||||
text-rendering: auto; // optimizelegibility throws things off #1094
|
text-rendering: auto; // optimizelegibility throws things off #1094
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-icon-rotate(@degrees, @rotation) {
|
.fa-icon-rotate(@degrees, @rotation) {
|
||||||
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})";
|
||||||
-webkit-transform: rotate(@degrees);
|
-webkit-transform: rotate(@degrees);
|
||||||
-ms-transform: rotate(@degrees);
|
-ms-transform: rotate(@degrees);
|
||||||
transform: rotate(@degrees);
|
transform: rotate(@degrees);
|
||||||
}
|
}
|
||||||
|
|
||||||
.fa-icon-flip(@horiz, @vert, @rotation) {
|
.fa-icon-flip(@horiz, @vert, @rotation) {
|
||||||
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
|
-ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)";
|
||||||
-webkit-transform: scale(@horiz, @vert);
|
-webkit-transform: scale(@horiz, @vert);
|
||||||
-ms-transform: scale(@horiz, @vert);
|
-ms-transform: scale(@horiz, @vert);
|
||||||
transform: scale(@horiz, @vert);
|
transform: scale(@horiz, @vert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Only display content to screen readers. A la Bootstrap 4.
|
// Only display content to screen readers. A la Bootstrap 4.
|
||||||
//
|
//
|
||||||
// See: http://a11yproject.com/posts/how-to-hide-content/
|
// See: http://a11yproject.com/posts/how-to-hide-content/
|
||||||
|
|
||||||
.sr-only() {
|
.sr-only() {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 1px;
|
width: 1px;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: -1px;
|
margin: -1px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
clip: rect(0,0,0,0);
|
clip: rect(0,0,0,0);
|
||||||
border: 0;
|
border: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use in conjunction with .sr-only to only display content when it's focused.
|
// Use in conjunction with .sr-only to only display content when it's focused.
|
||||||
//
|
//
|
||||||
// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
|
// Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
|
||||||
//
|
//
|
||||||
// Credit: HTML5 Boilerplate
|
// Credit: HTML5 Boilerplate
|
||||||
|
|
||||||
.sr-only-focusable() {
|
.sr-only-focusable() {
|
||||||
&:active,
|
&:active,
|
||||||
&:focus {
|
&:focus {
|
||||||
position: static;
|
position: static;
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
clip: auto;
|
clip: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
30
assets/less/font-awesome/path.less
vendored
30
assets/less/font-awesome/path.less
vendored
@@ -1,15 +1,15 @@
|
|||||||
/* FONT PATH
|
/* FONT PATH
|
||||||
* -------------------------- */
|
* -------------------------- */
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'FontAwesome';
|
font-family: 'FontAwesome';
|
||||||
src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
|
src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}');
|
||||||
src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
|
src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'),
|
||||||
url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
|
url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'),
|
||||||
url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
|
url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'),
|
||||||
url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
|
url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'),
|
||||||
url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
|
url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg');
|
||||||
// src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
|
// src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|||||||
40
assets/less/font-awesome/rotated-flipped.less
vendored
40
assets/less/font-awesome/rotated-flipped.less
vendored
@@ -1,20 +1,20 @@
|
|||||||
// Rotated & Flipped Icons
|
// Rotated & Flipped Icons
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
|
.@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); }
|
||||||
.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
|
.@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); }
|
||||||
.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
|
.@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); }
|
||||||
|
|
||||||
.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
|
.@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); }
|
||||||
.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
|
.@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); }
|
||||||
|
|
||||||
// Hook for IE8-9
|
// Hook for IE8-9
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
:root .@{fa-css-prefix}-rotate-90,
|
:root .@{fa-css-prefix}-rotate-90,
|
||||||
:root .@{fa-css-prefix}-rotate-180,
|
:root .@{fa-css-prefix}-rotate-180,
|
||||||
:root .@{fa-css-prefix}-rotate-270,
|
:root .@{fa-css-prefix}-rotate-270,
|
||||||
:root .@{fa-css-prefix}-flip-horizontal,
|
:root .@{fa-css-prefix}-flip-horizontal,
|
||||||
:root .@{fa-css-prefix}-flip-vertical {
|
:root .@{fa-css-prefix}-flip-vertical {
|
||||||
filter: none;
|
filter: none;
|
||||||
}
|
}
|
||||||
|
|||||||
10
assets/less/font-awesome/screen-reader.less
vendored
10
assets/less/font-awesome/screen-reader.less
vendored
@@ -1,5 +1,5 @@
|
|||||||
// Screen Readers
|
// Screen Readers
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.sr-only { .sr-only(); }
|
.sr-only { .sr-only(); }
|
||||||
.sr-only-focusable { .sr-only-focusable(); }
|
.sr-only-focusable { .sr-only-focusable(); }
|
||||||
|
|||||||
40
assets/less/font-awesome/stacked.less
vendored
40
assets/less/font-awesome/stacked.less
vendored
@@ -1,20 +1,20 @@
|
|||||||
// Stacked Icons
|
// Stacked Icons
|
||||||
// -------------------------
|
// -------------------------
|
||||||
|
|
||||||
.@{fa-css-prefix}-stack {
|
.@{fa-css-prefix}-stack {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 2em;
|
width: 2em;
|
||||||
height: 2em;
|
height: 2em;
|
||||||
line-height: 2em;
|
line-height: 2em;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
|
.@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
.@{fa-css-prefix}-stack-1x { line-height: inherit; }
|
.@{fa-css-prefix}-stack-1x { line-height: inherit; }
|
||||||
.@{fa-css-prefix}-stack-2x { font-size: 2em; }
|
.@{fa-css-prefix}-stack-2x { font-size: 2em; }
|
||||||
.@{fa-css-prefix}-inverse { color: @fa-inverse; }
|
.@{fa-css-prefix}-inverse { color: @fa-inverse; }
|
||||||
|
|||||||
1488
assets/less/font-awesome/variables.less
vendored
1488
assets/less/font-awesome/variables.less
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,17 @@
|
|||||||
.alert-enter {
|
.alert-enter {
|
||||||
opacity: 0.01;
|
opacity: 0.01;
|
||||||
transition: opacity 1s ease-in;
|
transition: opacity 1s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-enter.alert-enter-active {
|
.alert-enter.alert-enter-active {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-leave {
|
.alert-leave {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity 1s ease-in;
|
transition: opacity 1s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alert-leave.alert-leave-active {
|
.alert-leave.alert-leave-active {
|
||||||
opacity: 0.01;
|
opacity: 0.01;
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
background: @body-bg;
|
background: @body-bg;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
background: @brand-primary;
|
background: @brand-primary;
|
||||||
-webkit-border-radius: 0;
|
-webkit-border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-corner {
|
::-webkit-scrollbar-corner {
|
||||||
background: #000;
|
background: #000;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
@navbar-margin-bottom: 0px;
|
@navbar-margin-bottom: 0px;
|
||||||
@navbar-border-radius: 0px;
|
@navbar-border-radius: 0px;
|
||||||
|
|||||||
28
bower.json
28
bower.json
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "WakaTime",
|
"name": "WakaTime",
|
||||||
"ignore": [
|
"ignore": [
|
||||||
"**/.*",
|
"**/.*",
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"bower_components",
|
"bower_components",
|
||||||
"test",
|
"test",
|
||||||
"tests"
|
"tests"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"font-awesome": "~4.6.3",
|
"font-awesome": "~4.6.3",
|
||||||
"bootstrap": "~3.3.4"
|
"bootstrap": "~3.3.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<script src="public/js/devtools.js"></script>
|
<script src="public/js/devtools.js"></script>
|
||||||
|
|||||||
86
gulpfile.js
86
gulpfile.js
@@ -1,43 +1,43 @@
|
|||||||
var del = require('del');
|
var del = require('del');
|
||||||
var gulp = require('gulp');
|
var gulp = require('gulp');
|
||||||
var elixir = require('laravel-elixir');
|
var elixir = require('laravel-elixir');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Pre-defined Gulp Tasks
|
| Pre-defined Gulp Tasks
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Tasks outside the scope of Elixir can be predefined before setting it up.
|
| Tasks outside the scope of Elixir can be predefined before setting it up.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
gulp.task('postinstall', function (cb) {
|
gulp.task('postinstall', function (cb) {
|
||||||
// .pem files cause Chrome to show a bunch of warnings
|
// .pem files cause Chrome to show a bunch of warnings
|
||||||
//so we remove them on postinstall
|
//so we remove them on postinstall
|
||||||
del('node_modules/**/*.pem', cb);
|
del('node_modules/**/*.pem', cb);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Elixir Asset Management
|
| Elixir Asset Management
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
|
| Elixir provides a clean, fluent API for defining some basic Gulp tasks
|
||||||
| for your Laravel application. By default, we are compiling the Less
|
| for your Laravel application. By default, we are compiling the Less
|
||||||
| file for our application, as well as publishing vendor resources.
|
| file for our application, as well as publishing vendor resources.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
elixir.config.assetsPath = 'assets/';
|
elixir.config.assetsPath = 'assets/';
|
||||||
|
|
||||||
elixir(function (mix) {
|
elixir(function (mix) {
|
||||||
mix.copy('vendor/bower_components/bootstrap/less', 'assets/less/bootstrap');
|
mix.copy('vendor/bower_components/bootstrap/less', 'assets/less/bootstrap');
|
||||||
mix.copy('vendor/bower_components/bootstrap/fonts', 'public/fonts');
|
mix.copy('vendor/bower_components/bootstrap/fonts', 'public/fonts');
|
||||||
mix.copy('vendor/bower_components/font-awesome/less', 'assets/less/font-awesome');
|
mix.copy('vendor/bower_components/font-awesome/less', 'assets/less/font-awesome');
|
||||||
mix.copy('vendor/bower_components/font-awesome/fonts', 'public/fonts');
|
mix.copy('vendor/bower_components/font-awesome/fonts', 'public/fonts');
|
||||||
mix.less('app.less');
|
mix.less('app.less');
|
||||||
mix.browserify('app.jsx', 'public/js/app.js', 'assets/js');
|
mix.browserify('app.jsx', 'public/js/app.js', 'assets/js');
|
||||||
mix.browserify('events.js', 'public/js/events.js', 'assets/js');
|
mix.browserify('events.js', 'public/js/events.js', 'assets/js');
|
||||||
mix.browserify('options.jsx', 'public/js/options.js', 'assets/js');
|
mix.browserify('options.jsx', 'public/js/options.js', 'assets/js');
|
||||||
mix.browserify('devtools.js', 'public/js/devtools.js', 'assets/js');
|
mix.browserify('devtools.js', 'public/js/devtools.js', 'assets/js');
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,39 +1,44 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "WakaTime",
|
"name": "WakaTime",
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"description": "Automatic time tracking for Chrome.",
|
"description": "Automatic time tracking for Chrome.",
|
||||||
"homepage_url": "https://wakatime.com",
|
"homepage_url": "https://wakatime.com",
|
||||||
"devtools_page": "devtools.html",
|
"devtools_page": "devtools.html",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "graphics/wakatime-logo-16.png",
|
"16": "graphics/wakatime-logo-16.png",
|
||||||
"48": "graphics/wakatime-logo-48.png",
|
"48": "graphics/wakatime-logo-48.png",
|
||||||
"128": "graphics/wakatime-logo-128.png"
|
"128": "graphics/wakatime-logo-128.png"
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"https://api.wakatime.com/*",
|
"https://api.wakatime.com/*",
|
||||||
"https://wakatime.com/*",
|
"https://wakatime.com/*",
|
||||||
"alarms",
|
"alarms",
|
||||||
"tabs",
|
"tabs",
|
||||||
"storage",
|
"storage",
|
||||||
"idle"
|
"idle"
|
||||||
],
|
],
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"public/js/events.js"
|
"public/js/events.js"
|
||||||
],
|
],
|
||||||
"persistent": false
|
"persistent": false
|
||||||
},
|
},
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
"default_icon": {
|
"default_icon": {
|
||||||
"19": "graphics/wakatime-logo-19.png",
|
"19": "graphics/wakatime-logo-19.png",
|
||||||
"38": "graphics/wakatime-logo-38.png"
|
"38": "graphics/wakatime-logo-38.png"
|
||||||
},
|
},
|
||||||
"default_title": "WakaTime",
|
"default_title": "WakaTime",
|
||||||
"default_popup": "popup.html"
|
"default_popup": "popup.html"
|
||||||
},
|
},
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "options.html",
|
"page": "options.html",
|
||||||
"chrome_style": false
|
"chrome_style": false
|
||||||
}
|
},
|
||||||
}
|
"applicaitons": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "addon@wakatime.com"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
34
options.html
34
options.html
@@ -1,17 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>WakaTime options</title>
|
<title>WakaTime options</title>
|
||||||
|
|
||||||
<link href="public/css/app.css" rel="stylesheet">
|
<link href="public/css/app.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="wakatime-options"></div>
|
<div id="wakatime-options"></div>
|
||||||
|
|
||||||
<script src="public/js/options.js"></script>
|
<script src="public/js/options.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
134
package.json
134
package.json
@@ -1,67 +1,67 @@
|
|||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --verbose --coverage && mocha --compilers js:mocha-traceur tests/**/*.spec.js",
|
"test": "jest --verbose --coverage && mocha --compilers js:mocha-traceur tests/**/*.spec.js",
|
||||||
"test-react": "jest --verbose --coverage",
|
"test-react": "jest --verbose --coverage",
|
||||||
"test-js": "node_modules/.bin/phantomjs tests/run.js",
|
"test-js": "node_modules/.bin/phantomjs tests/run.js",
|
||||||
"start": "npm install && bower install && gulp",
|
"start": "npm install && bower install && gulp",
|
||||||
"gulp": "gulp",
|
"gulp": "gulp",
|
||||||
"watch": "gulp watch",
|
"watch": "gulp watch",
|
||||||
"lint": "jsxhint --jsx-only .",
|
"lint": "jsxhint --jsx-only .",
|
||||||
"postinstall": "gulp postinstall",
|
"postinstall": "gulp postinstall",
|
||||||
"validate": "npm ls"
|
"validate": "npm ls"
|
||||||
},
|
},
|
||||||
"pre-commit": [
|
"pre-commit": [
|
||||||
"lint"
|
"lint"
|
||||||
],
|
],
|
||||||
"jest": {
|
"jest": {
|
||||||
"testFileExtensions": [
|
"testFileExtensions": [
|
||||||
"jest.js"
|
"jest.js"
|
||||||
],
|
],
|
||||||
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
|
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
|
||||||
"testDirectoryName": "tests",
|
"testDirectoryName": "tests",
|
||||||
"unmockedModulePathPatterns": [
|
"unmockedModulePathPatterns": [
|
||||||
"<rootDir>/node_modules/react"
|
"<rootDir>/node_modules/react"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"babel-jest": "^13.0.0",
|
"babel-jest": "^13.0.0",
|
||||||
"bower": "^1.7.9",
|
"bower": "^1.7.9",
|
||||||
"chai": "^3.5.0",
|
"chai": "^3.5.0",
|
||||||
"del": "^2.2.1",
|
"del": "^2.2.1",
|
||||||
"gulp": "^3.9.1",
|
"gulp": "^3.9.1",
|
||||||
"jest-cli": "^13.0.0",
|
"jest-cli": "^13.0.0",
|
||||||
"jshint": "^2.9.2",
|
"jshint": "^2.9.2",
|
||||||
"jsxhint": "^0.15.1",
|
"jsxhint": "^0.15.1",
|
||||||
"laravel-elixir": "^5.0.0",
|
"laravel-elixir": "^5.0.0",
|
||||||
"mocha": "^2.5.3",
|
"mocha": "^2.5.3",
|
||||||
"mocha-sinon": "^1.1.5",
|
"mocha-sinon": "^1.1.5",
|
||||||
"mocha-traceur": "^2.1.0",
|
"mocha-traceur": "^2.1.0",
|
||||||
"precommit-hook": "^3.0.0",
|
"precommit-hook": "^3.0.0",
|
||||||
"sinon": "^1.17.4",
|
"sinon": "^1.17.4",
|
||||||
"sinon-chai": "^2.8.0",
|
"sinon-chai": "^2.8.0",
|
||||||
"sinon-chrome": "^1.1.2",
|
"sinon-chrome": "^1.1.2",
|
||||||
"traceur": "^0.0.111"
|
"traceur": "^0.0.111"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bootstrap": "^3.3.6",
|
"bootstrap": "^3.3.6",
|
||||||
"classnames": "^2.2.5",
|
"classnames": "^2.2.5",
|
||||||
"jquery": "^3.0.0",
|
"jquery": "^3.0.0",
|
||||||
"moment": "^2.13.0",
|
"moment": "^2.13.0",
|
||||||
"react": "^15.1.0",
|
"react": "^15.1.0",
|
||||||
"react-addons-css-transition-group": "^15.1.0",
|
"react-addons-css-transition-group": "^15.1.0",
|
||||||
"react-dom": "^15.1.0"
|
"react-dom": "^15.1.0"
|
||||||
},
|
},
|
||||||
"jshintConfig": {
|
"jshintConfig": {
|
||||||
"asi": false,
|
"asi": false,
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"curly": false,
|
"curly": false,
|
||||||
"expr": true,
|
"expr": true,
|
||||||
"indent": 4,
|
"indent": 4,
|
||||||
"loopfunc": true,
|
"loopfunc": true,
|
||||||
"node": true,
|
"node": true,
|
||||||
"trailing": true,
|
"trailing": true,
|
||||||
"undef": true,
|
"undef": true,
|
||||||
"white": true
|
"white": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
34
popup.html
34
popup.html
@@ -1,17 +1,17 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>WakaTime</title>
|
<title>WakaTime</title>
|
||||||
|
|
||||||
<link href="public/css/app.css" rel="stylesheet">
|
<link href="public/css/app.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<div id="wakatime"></div>
|
<div id="wakatime"></div>
|
||||||
|
|
||||||
<script src="public/js/app.js"></script>
|
<script src="public/js/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,40 +1,40 @@
|
|||||||
var fs = require('fs');
|
var fs = require('fs');
|
||||||
var page;
|
var page;
|
||||||
var beforeLoadFn;
|
var beforeLoadFn;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
page = require('webpage').create();
|
page = require('webpage').create();
|
||||||
|
|
||||||
page.onConsoleMessage = function(msg) { console.log(msg); };
|
page.onConsoleMessage = function(msg) { console.log(msg); };
|
||||||
|
|
||||||
page.onError = function(msg, trace) {
|
page.onError = function(msg, trace) {
|
||||||
var msgStack = [msg];
|
var msgStack = [msg];
|
||||||
if (trace && trace.length) {
|
if (trace && trace.length) {
|
||||||
msgStack.push('TRACE:');
|
msgStack.push('TRACE:');
|
||||||
trace.forEach(function(t) {
|
trace.forEach(function(t) {
|
||||||
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
|
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// we need try..catch here as mocha throws error that catched by phantom.onError
|
// we need try..catch here as mocha throws error that catched by phantom.onError
|
||||||
try {
|
try {
|
||||||
mocha.throwError(msgStack.join('\n'));
|
mocha.throwError(msgStack.join('\n'));
|
||||||
} catch(e) { }
|
} catch(e) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
page.onInitialized = function() {
|
page.onInitialized = function() {
|
||||||
page.injectJs(node_modules + 'chai/chai.js');
|
page.injectJs(node_modules + 'chai/chai.js');
|
||||||
page.injectJs(node_modules + 'sinon/pkg/sinon.js');
|
page.injectJs(node_modules + 'sinon/pkg/sinon.js');
|
||||||
page.injectJs(node_modules + 'sinon-chrome/chrome.js');
|
page.injectJs(node_modules + 'sinon-chrome/chrome.js');
|
||||||
page.injectJs(node_modules + 'sinon-chrome/src/phantom-tweaks.js');
|
page.injectJs(node_modules + 'sinon-chrome/src/phantom-tweaks.js');
|
||||||
page.injectJs(node_modules + 'require-stub/index.js');
|
page.injectJs(node_modules + 'require-stub/index.js');
|
||||||
// call additional function defined in tests
|
// call additional function defined in tests
|
||||||
if (beforeLoadFn) {
|
if (beforeLoadFn) {
|
||||||
beforeLoadFn();
|
beforeLoadFn();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function() {
|
afterEach(function() {
|
||||||
page.close();
|
page.close();
|
||||||
beforeLoadFn = null;
|
beforeLoadFn = null;
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
jest.dontMock('../../assets/js/components/Alert.jsx');
|
jest.dontMock('../../assets/js/components/Alert.jsx');
|
||||||
|
|
||||||
describe('Alert', function() {
|
describe('Alert', function() {
|
||||||
var React, Alert, TestUtils, Component;
|
var React, Alert, TestUtils, Component;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// Setup our tools
|
// Setup our tools
|
||||||
React = require('react/addons');
|
React = require('react/addons');
|
||||||
Alert = require('../../assets/js/components/Alert.jsx');
|
Alert = require('../../assets/js/components/Alert.jsx');
|
||||||
TestUtils = React.addons.TestUtils;
|
TestUtils = React.addons.TestUtils;
|
||||||
// Create the React component here using TestUtils and store into Component
|
// Create the React component here using TestUtils and store into Component
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
expect(2 + 2).toEqual(4);
|
expect(2 + 2).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
jest.dontMock('../../assets/js/components/MainList.jsx');
|
jest.dontMock('../../assets/js/components/MainList.jsx');
|
||||||
|
|
||||||
describe('MainList', function() {
|
describe('MainList', function() {
|
||||||
var React, MainList, TestUtils, Component;
|
var React, MainList, TestUtils, Component;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// Setup our tools
|
// Setup our tools
|
||||||
React = require('react/addons');
|
React = require('react/addons');
|
||||||
MainList = require('../../assets/js/components/MainList.jsx');
|
MainList = require('../../assets/js/components/MainList.jsx');
|
||||||
TestUtils = React.addons.TestUtils;
|
TestUtils = React.addons.TestUtils;
|
||||||
// Create the React component here using TestUtils and store into Component
|
// Create the React component here using TestUtils and store into Component
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
expect(2 + 2).toEqual(4);
|
expect(2 + 2).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
jest.dontMock('../../assets/js/components/Navbar.jsx');
|
jest.dontMock('../../assets/js/components/Navbar.jsx');
|
||||||
|
|
||||||
describe('Navbar', function() {
|
describe('Navbar', function() {
|
||||||
var React, Navbar, TestUtils, Component;
|
var React, Navbar, TestUtils, Component;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// Setup our tools
|
// Setup our tools
|
||||||
React = require('react/addons');
|
React = require('react/addons');
|
||||||
Navbar = require('../../assets/js/components/Navbar.jsx');
|
Navbar = require('../../assets/js/components/Navbar.jsx');
|
||||||
TestUtils = React.addons.TestUtils;
|
TestUtils = React.addons.TestUtils;
|
||||||
// Create the React component here using TestUtils and store into Component
|
// Create the React component here using TestUtils and store into Component
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
expect(2 + 2).toEqual(4);
|
expect(2 + 2).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
jest.dontMock('../../assets/js/components/Options.jsx');
|
jest.dontMock('../../assets/js/components/Options.jsx');
|
||||||
|
|
||||||
describe('Options', function() {
|
describe('Options', function() {
|
||||||
var React, Options, TestUtils, Component;
|
var React, Options, TestUtils, Component;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// Setup our tools
|
// Setup our tools
|
||||||
React = require('react/addons');
|
React = require('react/addons');
|
||||||
Options = require('../../assets/js/components/Options.jsx');
|
Options = require('../../assets/js/components/Options.jsx');
|
||||||
TestUtils = React.addons.TestUtils;
|
TestUtils = React.addons.TestUtils;
|
||||||
// Create the React component here using TestUtils and store into Component
|
// Create the React component here using TestUtils and store into Component
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
expect(2 + 2).toEqual(4);
|
expect(2 + 2).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
jest.dontMock('../../assets/js/components/SitesList.jsx');
|
jest.dontMock('../../assets/js/components/SitesList.jsx');
|
||||||
|
|
||||||
describe('SitesList', function() {
|
describe('SitesList', function() {
|
||||||
var React, SitesList, TestUtils, Component;
|
var React, SitesList, TestUtils, Component;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// Setup our tools
|
// Setup our tools
|
||||||
React = require('react/addons');
|
React = require('react/addons');
|
||||||
SitesList = require('../../assets/js/components/SitesList.jsx');
|
SitesList = require('../../assets/js/components/SitesList.jsx');
|
||||||
TestUtils = React.addons.TestUtils;
|
TestUtils = React.addons.TestUtils;
|
||||||
// Create the React component here using TestUtils and store into Component
|
// Create the React component here using TestUtils and store into Component
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
expect(2 + 2).toEqual(4);
|
expect(2 + 2).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
jest.dontMock('../../assets/js/components/Wakatime.jsx');
|
jest.dontMock('../../assets/js/components/Wakatime.jsx');
|
||||||
|
|
||||||
describe('Wakatime', function() {
|
describe('Wakatime', function() {
|
||||||
var React, Wakatime, TestUtils, Component;
|
var React, Wakatime, TestUtils, Component;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
// Setup our tools
|
// Setup our tools
|
||||||
React = require('react/addons');
|
React = require('react/addons');
|
||||||
Wakatime = require('../../assets/js/components/Wakatime.jsx');
|
Wakatime = require('../../assets/js/components/Wakatime.jsx');
|
||||||
TestUtils = React.addons.TestUtils;
|
TestUtils = React.addons.TestUtils;
|
||||||
// Create the React component here using TestUtils and store into Component
|
// Create the React component here using TestUtils and store into Component
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
expect(2 + 2).toEqual(4);
|
expect(2 + 2).toEqual(4);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title></title>
|
<title></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var sinon = require('sinon');
|
var sinon = require('sinon');
|
||||||
var chrome = require('sinon-chrome');
|
var chrome = require('sinon-chrome');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
describe('Chrome Dev Tools', function() {
|
describe('Chrome Dev Tools', function() {
|
||||||
it('should work', function() {
|
it('should work', function() {
|
||||||
chrome.browserAction.setTitle({title: 'hello'});
|
chrome.browserAction.setTitle({title: 'hello'});
|
||||||
sinon.assert.calledOnce(chrome.browserAction.setTitle);
|
sinon.assert.calledOnce(chrome.browserAction.setTitle);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
import changeExtensionIcon from '../../assets/js/helpers/changeExtensionIcon';
|
import changeExtensionIcon from '../../assets/js/helpers/changeExtensionIcon';
|
||||||
|
|
||||||
describe('changeExtensionIcon', function() {
|
describe('changeExtensionIcon', function() {
|
||||||
it('should be a function', function() {
|
it('should be a function', function() {
|
||||||
expect(changeExtensionIcon).to.be.a('function');
|
expect(changeExtensionIcon).to.be.a('function');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
import changeExtensionState from '../../assets/js/helpers/changeExtensionState';
|
import changeExtensionState from '../../assets/js/helpers/changeExtensionState';
|
||||||
|
|
||||||
describe('changeExtensionState', function() {
|
describe('changeExtensionState', function() {
|
||||||
it('should be a function', function() {
|
it('should be a function', function() {
|
||||||
expect(changeExtensionState).to.be.a('function');
|
expect(changeExtensionState).to.be.a('function');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var sinon = require('sinon-chai');
|
var sinon = require('sinon-chai');
|
||||||
var chrome = require('sinon-chrome');
|
var chrome = require('sinon-chrome');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
import changeExtensionTooltip from '../../assets/js/helpers/changeExtensionTooltip';
|
import changeExtensionTooltip from '../../assets/js/helpers/changeExtensionTooltip';
|
||||||
|
|
||||||
describe('changeExtensionTooltip', function() {
|
describe('changeExtensionTooltip', function() {
|
||||||
it('should be a function', function() {
|
it('should be a function', function() {
|
||||||
expect(changeExtensionTooltip).to.be.a('function');
|
expect(changeExtensionTooltip).to.be.a('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
// it('should change the extension tooltip', function() {
|
// it('should change the extension tooltip', function() {
|
||||||
// changeExtensionTooltip('WakaTime');
|
// changeExtensionTooltip('WakaTime');
|
||||||
// expect(chrome.browserAction.setTitle).toHaveBeenCalledWith({title: 'Wakatime'});
|
// expect(chrome.browserAction.setTitle).toHaveBeenCalledWith({title: 'Wakatime'});
|
||||||
// sinon.assert.calledWithMatch(chrome.browserAction.setTitle, {title: 'WakaTime'});
|
// sinon.assert.calledWithMatch(chrome.browserAction.setTitle, {title: 'WakaTime'});
|
||||||
// });
|
// });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
import contains from '../../assets/js/helpers/contains';
|
import contains from '../../assets/js/helpers/contains';
|
||||||
|
|
||||||
describe('contains', function() {
|
describe('contains', function() {
|
||||||
it('should be a function', function() {
|
it('should be a function', function() {
|
||||||
expect(contains).to.be.a('function');
|
expect(contains).to.be.a('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should match url against blacklist and return true', function() {
|
it('should match url against blacklist and return true', function() {
|
||||||
|
|
||||||
var list = "localhost\ntest.com";
|
var list = "localhost\ntest.com";
|
||||||
|
|
||||||
var url = 'http://localhost/fooapp';
|
var url = 'http://localhost/fooapp';
|
||||||
expect(contains(url, list)).to.equal(true);
|
expect(contains(url, list)).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not match url against blacklist and return false', function() {
|
it('should not match url against blacklist and return false', function() {
|
||||||
|
|
||||||
var list = "localhost2\ntest.com";
|
var list = "localhost2\ntest.com";
|
||||||
|
|
||||||
var url = 'http://localhost/fooapp';
|
var url = 'http://localhost/fooapp';
|
||||||
expect(contains(url, list)).to.equal(false);
|
expect(contains(url, list)).to.equal(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
import getDomainFromUrl from '../../assets/js/helpers/getDomainFromUrl';
|
import getDomainFromUrl from '../../assets/js/helpers/getDomainFromUrl';
|
||||||
|
|
||||||
describe('getDomainFromUrl', function() {
|
describe('getDomainFromUrl', function() {
|
||||||
it('should be a function', function() {
|
it('should be a function', function() {
|
||||||
expect(getDomainFromUrl).to.be.a('function');
|
expect(getDomainFromUrl).to.be.a('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return the domain', function() {
|
it('should return the domain', function() {
|
||||||
expect(getDomainFromUrl('http://google.com/something/very/secret')).to.equal('http://google.com');
|
expect(getDomainFromUrl('http://google.com/something/very/secret')).to.equal('http://google.com');
|
||||||
|
|
||||||
expect(getDomainFromUrl('http://www.google.com/something/very/secret')).to.equal('http://www.google.com');
|
expect(getDomainFromUrl('http://www.google.com/something/very/secret')).to.equal('http://www.google.com');
|
||||||
|
|
||||||
// This is not how it was imaged to work, but let's leave it here as a warning.
|
// This is not how it was imaged to work, but let's leave it here as a warning.
|
||||||
expect(getDomainFromUrl('google.com/something/very/secret')).to.equal('google.com//very');
|
expect(getDomainFromUrl('google.com/something/very/secret')).to.equal('google.com//very');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
var chai = require('chai');
|
var chai = require('chai');
|
||||||
var expect = chai.expect;
|
var expect = chai.expect;
|
||||||
|
|
||||||
import in_array from '../../assets/js/helpers/in_array';
|
import in_array from '../../assets/js/helpers/in_array';
|
||||||
|
|
||||||
describe('in_array', function() {
|
describe('in_array', function() {
|
||||||
it('should be a function', function() {
|
it('should be a function', function() {
|
||||||
expect(in_array).to.be.a('function');
|
expect(in_array).to.be.a('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find the needle and return true', function() {
|
it('should find the needle and return true', function() {
|
||||||
expect(in_array('4', ['4', '3', '2', '1'])).to.equal(true);
|
expect(in_array('4', ['4', '3', '2', '1'])).to.equal(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not find the needle and it should return false', function() {
|
it('should not find the needle and it should return false', function() {
|
||||||
expect(in_array('5', ['4', '3', '2', '1'])).to.equal(false);
|
expect(in_array('5', ['4', '3', '2', '1'])).to.equal(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
46
tests/run.js
46
tests/run.js
@@ -1,24 +1,24 @@
|
|||||||
/**
|
/**
|
||||||
* Test Runner for Mocha tests
|
* Test Runner for Mocha tests
|
||||||
* Using phantomjs to render page and execute scripts
|
* Using phantomjs to render page and execute scripts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var node_modules = '../node_modules/';
|
var node_modules = '../node_modules/';
|
||||||
phantom.injectJs(node_modules + 'mocha/mocha.js');
|
phantom.injectJs(node_modules + 'mocha/mocha.js');
|
||||||
phantom.injectJs(node_modules + 'sinon-chrome/src/phantom-tweaks.js');
|
phantom.injectJs(node_modules + 'sinon-chrome/src/phantom-tweaks.js');
|
||||||
mocha.setup({ui: 'bdd', reporter: 'spec'});
|
mocha.setup({ui: 'bdd', reporter: 'spec'});
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
phantom.injectJs('beforeeach.js');
|
phantom.injectJs('beforeeach.js');
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
phantom.injectJs('helpers/changeExtensionTooltip.spec.js');
|
phantom.injectJs('helpers/changeExtensionTooltip.spec.js');
|
||||||
|
|
||||||
// Execute
|
// Execute
|
||||||
mocha.run(function(failures) {
|
mocha.run(function(failures) {
|
||||||
// setTimeout is needed to supress "Unsafe JavaScript attempt to access..."
|
// setTimeout is needed to supress "Unsafe JavaScript attempt to access..."
|
||||||
// see https://github.com/ariya/phantomjs/issues/12697
|
// see https://github.com/ariya/phantomjs/issues/12697
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
phantom.exit(failures);
|
phantom.exit(failures);
|
||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user