Skip to content

Commit fc13e22

Browse files
committed
add macro-data and update background.js to reflect new path
1 parent e926bad commit fc13e22

12 files changed

+1153
-1
lines changed

chrome-extension/js/background.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import * as A from './analytics.js';
55
let Plugins = P.default;
66
let tracker = A.default;
77

8-
const URL_PATH = 'https://raw.githubusercontent.com/UseMacro/macro-data/master/configs/'
8+
const URL_PATH = 'https://raw.githubusercontent.com/IAmMateo/macro-chrome-extension/macro-data/configs/'
99
const FILE_EXT = '.json'
1010

1111
function getCurrentTab(callback) {

macro-data/.gitignore

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
8+
# Runtime data
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
14+
# Directory for instrumented libs generated by jscoverage/JSCover
15+
lib-cov
16+
17+
# Coverage directory used by tools like istanbul
18+
coverage
19+
20+
# nyc test coverage
21+
.nyc_output
22+
23+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24+
.grunt
25+
26+
# Bower dependency directory (https://bower.io/)
27+
bower_components
28+
29+
# node-waf configuration
30+
.lock-wscript
31+
32+
# Compiled binary addons (https://nodejs.org/api/addons.html)
33+
build/Release
34+
35+
# Dependency directories
36+
node_modules/
37+
jspm_packages/
38+
39+
# Typescript v1 declaration files
40+
typings/
41+
42+
# Optional npm cache directory
43+
.npm
44+
45+
# Optional eslint cache
46+
.eslintcache
47+
48+
# Optional REPL history
49+
.node_repl_history
50+
51+
# Output of 'npm pack'
52+
*.tgz
53+
54+
# Yarn Integrity file
55+
.yarn-integrity
56+
57+
# dotenv environment variables file
58+
.env
59+
60+
# next.js build output
61+
.next
62+
63+
# Mac
64+
*.swp
65+
*.swo
66+
.DS_Store

macro-data/LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Chris Luc
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

macro-data/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Macro Data
2+
This repository contains all of the shortcuts organized in configuration files. We're using GitHub as a way to host a "shortcut database" for the time being, by crowdsourcing all of the existing shortcuts on popular websites.
3+
4+
View the existing shortcuts in `configs/`

macro-data/config_validator.js

+151
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
/**
2+
* USAGE: call this file using node and pass in directory with configs or config file
3+
* i.e. node config_validator.js example.com.json
4+
* i.e. node config_validator.js configs
5+
*
6+
* Validates shortcut JSON config
7+
* More details found here: https://paper.dropbox.com/doc/JSON-Data-Format-XaQ21RmPGZS778W2LKza2
8+
*/
9+
10+
let fs = require('fs');
11+
let path = require('path');
12+
13+
const SUPPORTED_OS = ['default', 'windows', 'macos', 'linux', 'ubuntu'];
14+
const ALPHABET_KEYS = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
15+
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
16+
const NUMBER_KEYS = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
17+
const SPECIAL_KEYS = ['`', 'esc', 'tab', 'caps', 'shift', 'fn', 'ctrl', 'alt', 'cmd', '-', '_', '=', '+', '?', 'back', 'delete',
18+
'enter', '[', ']', '\\', ';', "'", ',', '.', '/', 'up', 'down', 'left', 'right', 'home', 'end',
19+
'pg dn', 'pg up', 'win', 'space'];
20+
const SUPPORTED_KEYS = ALPHABET_KEYS.concat(NUMBER_KEYS, SPECIAL_KEYS);
21+
22+
main();
23+
24+
function main() {
25+
let pathArg = process.argv[2];
26+
let configArray = readInConfigs(pathArg);
27+
configArray.forEach((config) => {
28+
let res = validate(config.data);
29+
if (res.status === 'success') {
30+
console.log(config.path + ': success\n');
31+
} else {
32+
console.log(config.path + ': error: ' + res.error + '\n');
33+
}
34+
});
35+
}
36+
37+
function readInConfigs(pathArg) {
38+
let configArray = [];
39+
if (fs.lstatSync(pathArg).isDirectory()) {
40+
files = fs.readdirSync(pathArg);
41+
files.forEach((file) => {
42+
configArray = configArray.concat(readInConfigs(path.join(pathArg, file)));
43+
});
44+
} else {
45+
let data = JSON.parse(fs.readFileSync(pathArg, 'utf8'));
46+
configArray.push({path: pathArg, data: data});
47+
}
48+
return configArray;
49+
}
50+
51+
function validate(data) {
52+
try {
53+
validateConfig(data);
54+
return {status: 'success'};
55+
} catch (err) {
56+
return {status: 'error', error: err};
57+
}
58+
}
59+
60+
function validateConfig(config) {
61+
numKeys = Object.keys(config).length;
62+
if (numKeys > 3) throw 'more than 3 keys in config';
63+
if (numKeys === 3) validateStringProp(config, 'description');
64+
validateStringProp(config, 'name');
65+
validateArrayProp(config, 'sections');
66+
validateSections(config.sections);
67+
}
68+
69+
function validateSections(sections) {
70+
if (sections.length === 0) {
71+
return;
72+
}
73+
section = sections[0];
74+
numKeys = Object.keys(section).length;
75+
if (numKeys > 3) throw 'more than 3 keys in section';
76+
if (numKeys === 3) validateStringProp(section, 'description');
77+
validateStringProp(section, 'name');
78+
validateArrayProp(section, 'shortcuts');
79+
validateShortcuts(section.shortcuts);
80+
validateSections(sections.slice(1, sections.length));
81+
}
82+
83+
function validateShortcuts(shortcuts) {
84+
if (shortcuts.length === 0) {
85+
return;
86+
}
87+
shortcut = shortcuts[0];
88+
numKeys = Object.keys(shortcut).length;
89+
if (numKeys > 3) throw 'more than 3 keys in shortcut';
90+
if (numKeys === 3) validateStringProp(shortcut, 'description');
91+
validateStringProp(shortcut, 'name');
92+
validateArrayProp(shortcut, 'keys');
93+
validateKeys(shortcut.keys);
94+
validateShortcuts(shortcuts.slice(1, shortcuts.length));
95+
}
96+
97+
function validateKeys(keys) {
98+
if (keys.length === 0) {
99+
return;
100+
}
101+
key = keys[0];
102+
validateOSProp(key, 'default');
103+
for (var os in key) {
104+
if (SUPPORTED_OS.indexOf(os) > -1) validateOSProp(key, os);
105+
else throw 'unsupported os: ' + os + 'in object: ' + JSON.stringify(key);
106+
}
107+
validateKeys(keys.slice(1, keys.length));
108+
}
109+
110+
// Helper functions
111+
112+
function validateArrayProp(obj, prop) {
113+
if (!obj.hasOwnProperty(prop)) throw 'missing prop: ' + prop + ' in object: ' + JSON.stringify(obj);
114+
if (!(obj[prop] instanceof Array)) throw 'expected array for prop: ' + prop + ' in object: ' + JSON.stringify(obj);
115+
if (obj[prop].length === 0) throw 'array size === 0 for prop: ' + prop + ' in object: ' + JSON.stringify(obj);
116+
}
117+
118+
function validateStringProp(obj, prop) {
119+
if (!obj.hasOwnProperty(prop)) throw 'missing prop: ' + prop + ' in object: ' + JSON.stringify(obj);
120+
if (!isValidString(obj[prop])) throw 'invalid string for prop: ' + prop + ' in object: ' + JSON.stringify(obj);
121+
}
122+
123+
function isValidString(x) {
124+
return typeof x === 'string' && x === x.toLowerCase();
125+
}
126+
127+
function validateOSProp(obj, prop) {
128+
if (!obj.hasOwnProperty(prop)) throw 'missing prop: ' + prop + ' in object: ' + JSON.stringify(obj);
129+
if (!(obj[prop] instanceof Array)) throw 'expected type array for prop: ' + prop + ' in object: ' + JSON.stringify(obj);
130+
for (var i = 0; i < obj[prop].length; i++) {
131+
var key = obj[prop][i];
132+
if (!isValidString(key)) throw 'invalid string: ' + key + ' for os: ' + prop + ' in object: ' + JSON.stringify(obj);
133+
if (SUPPORTED_KEYS.indexOf(key) === -1) {
134+
validateIfKeyIsInPlusFormat(key);
135+
}
136+
}
137+
}
138+
139+
function validateIfKeyIsInPlusFormat(key) {
140+
let keys = key.split('+');
141+
if (keys.length > 1) {
142+
keys.forEach((k) => {
143+
if (SUPPORTED_KEYS.indexOf(k) === -1) {
144+
throw 'unsupported key: ' + k + ' for os: ' + prop + ' in object: ' + JSON.stringify(obj);
145+
}
146+
});
147+
} else {
148+
throw 'unsupported key: ' + key + ' for os: ' + prop + ' in object: ' + JSON.stringify(obj);
149+
}
150+
}
151+

0 commit comments

Comments
 (0)