Merge pull request #51 from Eeems/master

Firefox support
This commit is contained in:
Alan Hamlett
2018-07-02 22:18:36 -07:00
committed by GitHub
32 changed files with 111 additions and 68 deletions

17
.gitattributes vendored Normal file
View File

@@ -0,0 +1,17 @@
.bowerrc text eol=lf
.jshintignore text eol=lf
AUTHORS text eol=lf
LICENSE text eol=lf
.csslintrc text eol=lf
*.less text eol=lf
*.html text eol=lf
*.js text eol=lf
*.json text eol=lf
*.css text eol=lf
*.jsx text eol=lf
.gitignore text eol=lf
.gitattributes text eol=lf
.gitmodules text eol=lf
.jshintrc text eol=lf
*.md text eol=lf
*.rst text eol=lf

4
.gitignore vendored
View File

@@ -26,9 +26,11 @@ node_modules
.DS_Store
vendor/
vendor/bower_components
.idea
# Generated chrome extension
public/
web-ext-artifacts/
.web-extension-id

0
.gitmodules vendored Normal file
View File

View File

@@ -1,16 +1,16 @@
/* global chrome */
/* global browser */
var React = require('react');
var MainList = React.createClass({
_openOptionsPage: function() {
if (chrome.runtime.openOptionsPage) {
if (browser.runtime.openOptionsPage) {
// New way to open options pages, if supported (Chrome 42+).
chrome.runtime.openOptionsPage();
browser.runtime.openOptionsPage();
} else {
// Reasonable fallback.
window.open(chrome.runtime.getURL('options.html'));
window.open(browser.runtime.getURL('options.html'));
}
},

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
var React = require('react');
var ReactCSSTransitionGroup = require('react-addons-css-transition-group');
@@ -37,13 +37,13 @@ var Options = React.createClass({
restoreSettings: function () {
var that = this;
chrome.storage.sync.get({
browser.storage.sync.get({
theme: config.theme,
blacklist: '',
whitelist: '',
loggingType: config.loggingType,
loggingStyle: config.loggingStyle
}, function (items) {
}).then(function (items) {
that.setState({
theme: items.theme,
blacklist: items.blacklist,
@@ -75,13 +75,13 @@ var Options = React.createClass({
var whitelist = that.state.whitelist.trim();
// Sync options with google storage.
chrome.storage.sync.set({
browser.storage.sync.set({
theme: theme,
blacklist: blacklist,
whitelist: whitelist,
loggingType: loggingType,
loggingStyle: loggingStyle
}, function () {
}).then(function () {
// Set state to be newly entered values.
that.setState({
theme: theme,

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
var React = require("react");
var $ = require('jquery');
@@ -40,9 +40,9 @@ var Wakatime = React.createClass({
if (data !== false) {
chrome.storage.sync.get({
browser.storage.sync.get({
loggingEnabled: config.loggingEnabled
}, function(items) {
}).then(function(items) {
that.setState({loggingEnabled: items.loggingEnabled});
if (items.loggingEnabled === true) {
@@ -129,7 +129,7 @@ var Wakatime = React.createClass({
changeExtensionState('notLogging');
chrome.storage.sync.set({
browser.storage.sync.set({
loggingEnabled: false
});
},
@@ -141,7 +141,7 @@ var Wakatime = React.createClass({
changeExtensionState('allGood');
chrome.storage.sync.set({
browser.storage.sync.set({
loggingEnabled: true
});
},

View File

@@ -1,11 +1,11 @@
/* global chrome */
/* global browser */
//jshint esnext:true
var config = {
// Extension name
name: 'WakaTime',
// Extension version
version: chrome.app.getDetails().version,
version: browser.runtime.getManifest().version,
// Time for idle state of the browser
// The user is considered idle if there was
// no activity in the browser for x seconds

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
//jshint esnext:true
var $ = require('jquery');
@@ -77,19 +77,19 @@ class WakaTimeCore {
* and sends it to WakaTime for logging.
*/
recordHeartbeat() {
chrome.storage.sync.get({
browser.storage.sync.get({
loggingEnabled: config.loggingEnabled,
loggingStyle: config.loggingStyle,
blacklist: '',
whitelist: ''
}, (items) => {
}).then((items) => {
if (items.loggingEnabled === true) {
changeExtensionState('allGood');
chrome.idle.queryState(config.detectionIntervalInSeconds, (newState) => {
browser.idle.queryState(config.detectionIntervalInSeconds).then((newState) => {
if (newState === 'active') {
// Get current tab URL.
chrome.tabs.query({active: true}, (tabs) => {
browser.tabs.query({active: true}).then((tabs) => {
var currentActiveTab = tabs[0];
var debug = false;
@@ -193,7 +193,7 @@ class WakaTimeCore {
time: moment().format('X'),
project: heartbeat.project || '<<LAST_PROJECT>>',
is_debugging: debug,
plugin: 'chrome-wakatime/' + config.version
plugin: 'browser-wakatime/' + config.version
});
}
@@ -207,9 +207,9 @@ class WakaTimeCore {
_getLoggingType() {
var deferredObject = $.Deferred();
chrome.storage.sync.get({
browser.storage.sync.get({
loggingType: config.loggingType
}, function (items) {
}).then(function (items) {
deferredObject.resolve(items.loggingType);
});
@@ -284,4 +284,4 @@ class WakaTimeCore {
}
export default WakaTimeCore;
//export default WakaTimeCore;

View File

@@ -1,12 +1,12 @@
/* global chrome */
/* global browser */
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
var backgroundPageConnection = browser.runtime.connect({
name: "devtools-page"
});
// Send a message to background page with the current active tabId
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
tabId: browser.devtools.inspectedWindow.tabId
});

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
// Core
var WakaTimeCore = require("./core/WakaTimeCore").default;
@@ -11,7 +11,7 @@ var wakatime = new WakaTimeCore();
var connections = {};
// 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
// window.setTimeout on old chrome versions.
if (alarm && alarm.name == 'heartbeatAlarm') {
@@ -23,14 +23,14 @@ chrome.alarms.onAlarm.addListener(function (alarm) {
});
// 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.
*/
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');
@@ -43,11 +43,11 @@ chrome.tabs.onActivated.addListener(function (activeInfo) {
* 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.
*/
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
browser.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status === 'complete') {
// 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 (tabId == tabs[0].id) {
console.log('recording a heartbeat - tab updated');
@@ -64,7 +64,7 @@ chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
* This is in charge of detecting if devtools are opened or closed
* and sending a heartbeat depending on that.
*/
chrome.runtime.onConnect.addListener(function (port) {
browser.runtime.onConnect.addListener(function (port) {
if (port.name == "devtools-page") {

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
var config = require('../config');
@@ -19,26 +19,26 @@ function changeExtensionIcon(color) {
path = './graphics/wakatime-logo-38' + color + '.png';
chrome.browserAction.setIcon({
browser.browserAction.setIcon({
path: path
});
}
if (color === '') {
chrome.storage.sync.get({
browser.storage.sync.get({
theme: config.theme
}, function (items) {
}).then(function (items) {
if (items.theme == config.theme) {
path = './graphics/wakatime-logo-38.png';
chrome.browserAction.setIcon({
browser.browserAction.setIcon({
path: path
});
}
else {
path = './graphics/wakatime-logo-38-white.png';
chrome.browserAction.setIcon({
browser.browserAction.setIcon({
path: path
});
}

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
var config = require('../config');
@@ -16,7 +16,7 @@ function changeExtensionTooltip(text) {
text = config.name + ' - ' + text;
}
chrome.browserAction.setTitle({title: text});
browser.browserAction.setTitle({title: text});
}
module.exports = changeExtensionTooltip;

View File

@@ -1,4 +1,4 @@
/* global chrome */
/* global browser */
/* This is a fix for Bootstrap requiring jQuery */
global.jQuery = require('jquery');

View File

@@ -1,6 +1,6 @@
/*!
* Bootstrap v3.3.6 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/

View File

@@ -59,7 +59,7 @@
.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 > .dropdown-toggle:not(:first-child) {
.border-left-radius(0);

View File

@@ -181,7 +181,7 @@ input[type="search"] {
// 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
//
// 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) {
input[type="date"],

View File

@@ -1,9 +1,9 @@
// WebKit-style focus
.tab-focus() {
// Default
outline: thin dotted;
// WebKit
// WebKit-specific. Other browsers will keep their default outline style.
// (Initially tried to also force default via `outline: initial`,
// but that seems to erroneously remove the outline in Firefox altogether.)
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}

View File

@@ -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
// the help of our collapse JavaScript plugin.

View File

@@ -120,7 +120,7 @@ hr {
// 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 {
position: absolute;

View File

@@ -1,6 +1,6 @@
/*!
* Bootstrap v3.3.6 (http://getbootstrap.com)
* Copyright 2011-2015 Twitter, Inc.
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/

View File

@@ -111,7 +111,7 @@
//** Global background color for active items (e.g., navs or dropdowns).
@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;
//** Carets increase slightly in size for larger components.
@caret-width-large: 5px;

View File

@@ -1,6 +1,8 @@
var del = require('del');
var gulp = require('gulp');
var elixir = require('laravel-elixir');
var exec = require('child_process').exec;
var fs = require('fs');
/*
|--------------------------------------------------------------------------
@@ -16,6 +18,15 @@ gulp.task('postinstall', function (cb) {
//so we remove them on postinstall
del('node_modules/**/*.pem', cb);
});
gulp.task('webextension',function(cb){
exec('npm install',{
cwd: 'node_modules/webextension-polyfill/'
},function(){
var stream = fs.createWriteStream('public/js/browser-polyfill.min.js');
stream.on('done',cb);
fs.createReadStream('node_modules/webextension-polyfill/dist/browser-polyfill.min.js').pipe(stream);
});
});
/*
|--------------------------------------------------------------------------
@@ -30,14 +41,19 @@ gulp.task('postinstall', function (cb) {
elixir.config.assetsPath = 'assets/';
elixir.extend('webextension', function(){
return gulp.start('webextension');
});
elixir(function (mix) {
mix.webextension();
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/fonts', 'public/fonts');
mix.less('app.less');
mix.browserify('app.jsx', 'public/js/app.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('devtools.js', 'public/js/devtools.js', 'assets/js');
mix.browserify('devtools.js', 'public/js/devtools.js', 'assets/js');*/
});

View File

@@ -20,6 +20,7 @@
],
"background": {
"scripts": [
"public/js/browser-polyfill.min.js",
"public/js/events.js"
],
"persistent": false
@@ -35,5 +36,10 @@
"options_ui": {
"page": "options.html",
"chrome_style": false
},
"applications": {
"gecko": {
"id": "addon@wakatime.com"
}
}
}

View File

@@ -50,7 +50,8 @@
"moment": "^2.13.0",
"react": "^16.2.0",
"react-addons-css-transition-group": "^15.1.0",
"react-dom": "^16.2.0"
"react-dom": "^16.2.0",
"webextension-polyfill": "^0.2.1"
},
"jshintConfig": {
"asi": false,

View File

@@ -7,6 +7,7 @@
<title>WakaTime</title>
<link href="public/css/app.css" rel="stylesheet">
<script src="public/js/browser-polyfill.min.js"></script>
</head>
<body>

View File

@@ -1,7 +1,7 @@
var chai = require('chai');
var expect = chai.expect;
import changeExtensionIcon from '../../assets/js/helpers/changeExtensionIcon';
//import changeExtensionIcon from '../../assets/js/helpers/changeExtensionIcon';
describe('changeExtensionIcon', function() {
it('should be a function', function() {

View File

@@ -1,7 +1,7 @@
var chai = require('chai');
var expect = chai.expect;
import changeExtensionState from '../../assets/js/helpers/changeExtensionState';
//import changeExtensionState from '../../assets/js/helpers/changeExtensionState';
describe('changeExtensionState', function() {
it('should be a function', function() {

View File

@@ -3,7 +3,7 @@ var sinon = require('sinon-chai');
var chrome = require('sinon-chrome');
var expect = chai.expect;
import changeExtensionTooltip from '../../assets/js/helpers/changeExtensionTooltip';
//import changeExtensionTooltip from '../../assets/js/helpers/changeExtensionTooltip';
describe('changeExtensionTooltip', function() {
it('should be a function', function() {

View File

@@ -1,7 +1,7 @@
var chai = require('chai');
var expect = chai.expect;
import contains from '../../assets/js/helpers/contains';
//import contains from '../../assets/js/helpers/contains';
describe('contains', function() {
it('should be a function', function() {

View File

@@ -1,7 +1,7 @@
var chai = require('chai');
var expect = chai.expect;
import getDomainFromUrl from '../../assets/js/helpers/getDomainFromUrl';
//import getDomainFromUrl from '../../assets/js/helpers/getDomainFromUrl';
describe('getDomainFromUrl', function() {
it('should be a function', function() {

View File

@@ -1,7 +1,7 @@
var chai = require('chai');
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() {
it('should be a function', function() {