Force lineendings on more file types

This commit is contained in:
Nathaniel van Diepen
2017-04-18 12:12:54 -06:00
parent fc454a555b
commit 84f30cc918
55 changed files with 4569 additions and 4563 deletions

6
.gitattributes vendored
View File

@@ -2,3 +2,9 @@
.jshintignore text eol=lf .jshintignore text eol=lf
AUTHORS text eol=lf AUTHORS text eol=lf
LICENSE 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

View File

@@ -1,6 +1,6 @@
{ {
"scripts": { "scripts": {
"lint": "jshint ." "lint": "jshint ."
}, },
"pre-commit": ["lint", "validate", "test"] "pre-commit": ["lint", "validate", "test"]
} }

View File

@@ -1,67 +1,67 @@
/* global browser */ /* 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: browser.runtime.getManifest().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://wakatime.com/api/v1/users/current/heartbeats', heartbeatApiUrl: 'https://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://wakatime.com/api/v1/users/current', currentUserApiUrl: 'https://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://wakatime.com/api/v1/users/current/summaries', summariesApiUrl: 'https://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;

View File

@@ -1,256 +1,256 @@
/* global browser */ /* 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() {
browser.storage.sync.get({ browser.storage.sync.get({
loggingEnabled: config.loggingEnabled, loggingEnabled: config.loggingEnabled,
loggingStyle: config.loggingStyle, loggingStyle: config.loggingStyle,
blacklist: '', blacklist: '',
whitelist: '' whitelist: ''
}).then((items) => { }).then((items) => {
if (items.loggingEnabled === true) { if (items.loggingEnabled === true) {
changeExtensionState('allGood'); changeExtensionState('allGood');
browser.idle.queryState(config.detectionIntervalInSeconds).then((newState) => { browser.idle.queryState(config.detectionIntervalInSeconds).then((newState) => {
if (newState === 'active') { if (newState === 'active') {
// Get current tab URL. // Get current tab URL.
browser.tabs.query({active: true}).then((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: 'browser-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();
browser.storage.sync.get({ browser.storage.sync.get({
loggingType: config.loggingType loggingType: config.loggingType
}).then(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;

View File

@@ -1,12 +1,12 @@
/* global browser */ /* global browser */
// Create a connection to the background page // Create a connection to the background page
var backgroundPageConnection = browser.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: browser.devtools.inspectedWindow.tabId tabId: browser.devtools.inspectedWindow.tabId
}); });

View File

@@ -1,100 +1,100 @@
/* global browser */ /* 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
browser.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.
browser.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.
*/ */
browser.tabs.onActivated.addListener(function (activeInfo) { browser.tabs.onActivated.addListener(function (activeInfo) {
browser.tabs.get(activeInfo.tabId).then(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.
*/ */
browser.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.
browser.tabs.query({active: true}).then(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.
*/ */
browser.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();
}); });
} }
}); });

View File

@@ -1,50 +1,50 @@
/* global browser */ /* 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';
browser.browserAction.setIcon({ browser.browserAction.setIcon({
path: path path: path
}); });
} }
if (color === '') { if (color === '') {
browser.storage.sync.get({ browser.storage.sync.get({
theme: config.theme theme: config.theme
}).then(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';
browser.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';
browser.browserAction.setIcon({ browser.browserAction.setIcon({
path: path path: path
}); });
} }
}); });
} }
} }
module.exports = changeExtensionIcon; module.exports = changeExtensionIcon;

View File

@@ -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;

View File

@@ -1,22 +1,22 @@
/* global browser */ /* 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;
} }
browser.browserAction.setTitle({title: text}); browser.browserAction.setTitle({title: text});
} }
module.exports = changeExtensionTooltip; module.exports = changeExtensionTooltip;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
} }

View File

@@ -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"
] ]
] ]
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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);
} }
} }

View File

@@ -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; }
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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";

File diff suppressed because it is too large Load Diff

View File

@@ -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; }

View File

@@ -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));
} }
} }

View File

@@ -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;
} }
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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(); }

View File

@@ -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; }

File diff suppressed because it is too large Load Diff

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -1,2 +1,2 @@
@navbar-margin-bottom: 0px; @navbar-margin-bottom: 0px;
@navbar-border-radius: 0px; @navbar-border-radius: 0px;

View File

@@ -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"
} }
} }

View File

@@ -1,2 +1,2 @@
<!DOCTYPE html> <!DOCTYPE html>
<script src="public/js/devtools.js"></script> <script src="public/js/devtools.js"></script>

View File

@@ -1,63 +1,63 @@
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');
var exec = require('child_process').exec; var exec = require('child_process').exec;
var fs = require('fs'); var fs = require('fs');
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| 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);
}); });
gulp.task('webextension',function(cb){ gulp.task('webextension',function(cb){
exec('npm install',{ exec('npm install',{
cwd: 'vendor/webextension-polyfill/' cwd: 'vendor/webextension-polyfill/'
},function(){ },function(){
exec('grunt',{ exec('grunt',{
cwd: 'vendor/webextension-polyfill/' cwd: 'vendor/webextension-polyfill/'
},function(){ },function(){
var stream = fs.createWriteStream('public/js/browser-polyfill.min.js'); var stream = fs.createWriteStream('public/js/browser-polyfill.min.js');
stream.on('done',cb); stream.on('done',cb);
fs.createReadStream('vendor/webextension-polyfill/dist/browser-polyfill.min.js').pipe(stream); fs.createReadStream('vendor/webextension-polyfill/dist/browser-polyfill.min.js').pipe(stream);
}); });
}); });
}); });
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| 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.extend('webextension', function(){ elixir.extend('webextension', function(){
return gulp.start('webextension'); return gulp.start('webextension');
}); });
elixir(function (mix) { elixir(function (mix) {
mix.webextension(); mix.webextension();
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');*/
}); });

View File

@@ -1,45 +1,45 @@
{ {
"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/browser-polyfill.min.js", "public/js/browser-polyfill.min.js",
"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
}, },
"applications": { "applications": {
"gecko": { "gecko": {
"id": "addon@wakatime.com" "id": "addon@wakatime.com"
} }
} }
} }

View File

@@ -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>

View File

@@ -1,18 +1,18 @@
<!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">
<script src="public/js/browser-polyfill.min.js"></script> <script src="public/js/browser-polyfill.min.js"></script>
</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>

View File

@@ -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;
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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>

View File

@@ -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);
}); });
}); });

View File

@@ -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');
}); });
}); });

View File

@@ -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');
}); });
}); });

View File

@@ -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'});
// }); // });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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');
}); });
}); });

View File

@@ -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);
}); });
}); });

View File

@@ -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);
}); });