Repository: dimitrinicolas/midi-controller-css
Branch: master
Commit: 6b0850131152
Files: 11
Total size: 32.6 KB
Directory structure:
gitextract_4zadc2mu/
├── .gitignore
├── lib/
│ ├── actions.js
│ ├── add-line.js
│ ├── delete-line.js
│ ├── focus-selector.js
│ ├── get-focus-node.js
│ ├── index.js
│ └── order.js
├── license.md
├── package.json
└── readme.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
npm-debug.log
node_modules
logs
*.log*
tmp
================================================
FILE: lib/actions.js
================================================
'use babel';
import path from 'path';
import play from 'play';
let tickSound = path.resolve(__dirname, '../assets/sounds/1.wav');
let tickSound2 = path.resolve(__dirname, '../assets/sounds/2.wav');
let lastValue = null;
let lastTime = 0;
let tick = (value, accent) => {
if (lastValue != value) {
let now = Date.now();
if (accent || now - lastTime > 50) {
lastTime = now;
lastValue = value;
if (accent) {
play.sound(tickSound);
}
else {
play.sound(tickSound2);
}
}
}
};
export default function actions(message) {
// console.log(message.data);
// TODO
// col 1 : @media with current media indicator
// % / px
// col 6 : bg color img linear gradient
// col 8 : all value
if (message.data[0] === 176 && message.data[1] === 42 && message.data[2] === 127) {
// STOP
this.deleteLine();
}
if (message.data[0] === 176 && message.data[1] === 58 && message.data[2] === 127) {
// LEFT
this.focusSelector(-1);
}
if (message.data[0] === 176 && message.data[1] === 59 && message.data[2] === 127) {
// RIGHT
this.focusSelector(1);
}
if (message.data[0] === 176 && message.data[2] === 127) {
// COLUMN 2 BUTTONS POSITION
var values = {
33: 'absolute',
49: 'relative',
65: 'absolute'
};
var position = values[message.data[1]];
if (message.data[1] === 65) {
this.addLine('position', function(node) {
return 'absolute 50% auto auto 50%';
}, { focus: true, cb: function() {
this.addLine('transform', function(node) {
return 'translateX(-50%) translateY(-50%)';
}, { focus: true });
}.bind(this)});
}
else if (position) {
this.getFocusNode(function(node) {
if (node && node.type === 'decl' && node.prop === 'position' && node.value.split(' ')[0] === position) {
this.addLine('position', function() { return position; }, { focus: true });
}
else {
this.addLine('position', function(node) {
var value = '';
if (node) {
value = node.value.split(' ');
value.shift();
value = value.join(' ');
}
if (value) {
value = ' ' + value;
}
return position + value;
}, { focus: true });
}
}.bind(this));
}
}
if (message.data[0] === 176 && message.data[1] === 1) {
// COLUMN 2 SLIDER POSITION
var px = Math.round(message.data[2] / 127 * 64);
this.addLine('position', function(node) {
var position = !node ? 'relative' : node.value.split(' ')[0];
px = px !== 0 ? px + 'px' : px;
tick(position + ' ' + px, px === 0);
return position + ' ' + px;
});
}
// if (message.data[0] === 176 && message.data[1] === 17) {
// // COLUMN 2 ORIENTATION POSITION
// // TODO
//
// if (message.data[2] === 127) {
// // LEFT
//
// this.addLine('position', function(node) {
// var position = !node ? 'relative' : node.value.split(' ')[0];
// var value = '';
// if (node) {
// value = node.value.split(' ');
// value.shift();
// if (value.length === 0) {
// value = '0 0';
// }
// else if (value.length === 1) {
// value = value[0] + ' ' + value[0];
// }
// else {
// value = value[0] + ' ' + value[1];
// }
// }
// if (value) {
// value = ' ' + value;
// }
// return position + value;
// });
// }
// if (message.data[2] === 1 || message.data[2] === 65) {
// // MIDDLE
//
// this.addLine('position', function(node) {
// var position = !node ? 'relative' : node.value.split(' ')[0];
// var value = '';
// if (node) {
// value = node.value.split(' ');
// value.shift();
// if (value.length === 0) {
// value = '0';
// }
// else {
// value = value[0];
// }
// }
// if (value) {
// value = ' ' + value;
// }
// return position + value;
// });
// }
// if (message.data[2] === 63) {
// // RIGHT
//
// this.addLine('position', function(node) {
// var position = !node ? 'relative' : node.value.split(' ')[0];
// var value = '';
// if (node) {
// value = node.value.split(' ');
// value.shift();
// if (value.length === 0) {
// value = '0 0';
// }
// else if (value.length === 1) {
// value = value[0] + ' ' + value[0];
// }
// else {
// value = value[0] + ' ' + value[1];
// }
// }
// if (value) {
// value = ' ' + value;
// }
// return position + value;
// });
// }
//
// }
if (message.data[0] === 176 && message.data[2] === 127) {
// COLUMN 3 BUTTONS DISPLAY
var values = {
34: 'block',
50: 'inline-block',
66: 'flex'
};
var display = values[message.data[1]];
if (display) {
this.addLine('display', function() { return display; }, { focus: true });
}
}
if (message.data[0] === 176 && message.data[1] === 2) {
// COLUMN 3 SLIDER DISPLAY
var px = Math.round(message.data[2] / 127 * 66);
if (px >= 65) { px = '100%'; }
else if (px !== 0) { px = px + 'px'; }
tick(px, (px === 0 || px === '100%'));
this.addLine('size', function(node) { return px; });
}
if (message.data[0] === 176 && message.data[2] === 127) {
// COLUMN 4 BUTTONS MARGIN/PADDING
var props = {
35: 'margin',
51: 'padding'
};
var prop = props[message.data[1]];
if (prop) {
this.addLine(prop, function(node) {
var value = !node ? '0' : node.value;
return value;
}, { focus: true });
}
}
if (message.data[0] === 176 && message.data[1] === 3) {
// COLUMN 4 SLIDER MARGIN/PADDING
var px = Math.round(message.data[2] / 127 * 64);
px = px !== 0 ? px + 'px' : px;
this.getFocusNode(function(node) {
if (node && node.type === 'decl') {
if (node.prop === 'margin' || node.prop === 'padding') {
tick(px, (px === 0));
this.addLine(node.prop, function() { return px; });
}
}
}.bind(this));
}
if (message.data[0] === 176 && message.data[2] === 127) {
// COLUMN 5 BUTTONS FONTS WEIGHT
var values = {
36: '500',
52: '400',
68: '300'
};
var weight = values[message.data[1]];
if (weight) {
this.getFocusNode(function(node) {
if (node && node.type === 'decl' && node.prop === 'position' && node.value.split(' ')[0] === position) {
this.addLine('font', function() { return 'title ' + weight + ' 16px'; }, { focus: true });
}
else {
this.addLine('font', function(node) {
var px = '16px';
if (node) {
var splitted = node.value.split(' ');
px = splitted[splitted.length - 1];
}
return 'title ' + weight + ' ' + px;
}, { focus: true });
}
}.bind(this));
}
}
if (message.data[0] === 176 && message.data[1] === 4) {
// COLUMN 5 SLIDER FONT SIZE
var px = Math.round(message.data[2] / 127 * 10) + 12;
px = px !== 0 ? px + 'px' : px;
this.addLine('font', function(node) {
var font = ['title', 'regular', 0];
if (node) {
font = node.value.split(' ');
}
font[font.length - 1] = px;
let result = font.join(' ');
tick(result, (px === 0));
return result;
});
}
if (message.data[0] === 176 && message.data[2] === 127) {
// COLUMN 6 BUTTONS TRANSITION
var values = {
37: '0.1s',
53: '0.2s',
69: '0.3s'
};
var transition = values[message.data[1]];
if (transition) {
this.addLine('transition', function() { return transition; }, { focus: true });
}
}
if (message.data[0] === 176 && message.data[1] === 5) {
// COLUMN 6 SLIDER TRANSITION
var sec = Math.round(Math.round(message.data[2] / 127 * 3 / 10 * 100) * 0.02 * 100) / 100;
sec = sec !== 0 ? sec + 's' : sec;
tick(sec, (sec === 0));
this.addLine('transition', function(node) { return sec; });
}
};
================================================
FILE: lib/add-line.js
================================================
'use babel';
var emptyLine = false;
import postcss from 'postcss';
import order from './order';
var timer = {};
function timeout(prop) {
if (timer[prop].prop, timer[prop].value) {
set(timer[prop].prop, timer[prop].value, timer[prop].options);
timer[prop] = {
time: Date.now() + 100,
prop: null,
value: null,
options: null,
timeout: null
};
}
}
export default function focusSelector(prop, value, options) {
if (!timer[prop]) {
set(prop, value, options);
timer[prop] = {
time: Date.now() + 100,
prop: null,
value: null,
options: null,
timeout: null
};
}
else {
var rel = timer[prop].time - Date.now();
if (rel > 0) {
timer[prop].prop = prop;
timer[prop].value = value;
if (timer[prop].timeout) {
clearTimeout(timer[prop].timeout);
}
timer[prop].timeout = setTimeout(timeout.bind(null, prop), rel);
}
else {
set(prop, value, options);
timer[prop] = {
time: Date.now() + 100,
prop: null,
value: null,
options: null,
timeout: null
};
}
}
};
function set(prop, value, opts) {
var options = opts || {};
var editor = atom.workspace.getActiveTextEditor();
if (!editor) {
return;
}
var cursor = editor.cursors[0];
var cursorPosition = editor.getCursorBufferPosition();
var css = editor.getText();
postcss([]).process(css, { from: undefined }).then(function(res) {
var currentNode = null;
var propPos = [0, 0];
for (var h = 0; h < order.length; h++) {
var index = order[h].indexOf(prop);
if (index > -1) {
propPos = [h, index];
break;
}
}
var propDist = (propPos[0] * 100 + propPos[1]);
for (var i = 0; i < res.root.nodes.length; i++) {
var node = res.root.nodes[i];
if (typeof node.selector === 'string') {
node.selectorHeight = node.selector.split("\n").length;
if (node.nodes[0]) {
node.startWhiteLine = node.nodes[0].source.start.line - (node.source.start.line + node.selectorHeight);
}
else {
node.startWhiteLine = 0;
}
if (node.nodes[node.nodes.length - 1]) {
node.endWhiteLine = (node.source.end.line - 1) - node.nodes[node.nodes.length - 1].source.end.line;
}
else {
node.endWhiteLine = 0;
}
node.properties = {};
for (var j = 0; j < node.nodes.length; j++) {
if (node.nodes[j].type === 'decl') {
node.properties[node.nodes[j].prop] = j;
}
}
if (cursorPosition.row >= node.source.start.line && cursorPosition.row <= node.source.end.line) {
currentNode = i;
}
}
}
if (currentNode !== null) {
currentNode = res.root.nodes[currentNode];
var dist = null;
var dest = null;
var toLine = 1;
if (typeof currentNode.properties[prop] !== 'undefined') {
var node = currentNode.nodes[currentNode.properties[prop]];
var newValue = value(node);
if (node.value == newValue && !options.focus) {
timer[prop].time = 0;
if (options.cb) { options.cb(); }
return;
}
var diff = (node.source.end.line - 1) - cursorPosition.row;
if (diff > 0) {
cursor.moveDown(diff);
}
else if (diff < 0) {
cursor.moveUp(Math.abs(diff));
}
cursor.moveToEndOfLine();
editor.deleteToBeginningOfLine();
var newCursorPosition = editor.getCursorBufferPosition();
var tab = newCursorPosition.column === 0 ? "\t" : '';
editor.insertText(tab + prop + ': ' + newValue + ';');
editor.moveLeft();
if (options.cb) { options.cb(); }
}
else {
for (var a = 0; a < order.length; a++) {
for (var b = 0; b < order[a].length; b++) {
var item = order[a][b];
if (typeof currentNode.properties[item] !== 'undefined') {
for (var h = 0; h < order.length; h++) {
var index = order[h].indexOf(item);
if (index > -1) {
var newDist = [h, index];
break;
}
}
if (dist === null || Math.abs(propDist - (dist[0] * 100 + dist[1])) > Math.abs(propDist - (newDist[0] * 100 + newDist[1]))) {
dist = [newDist[0], newDist[1]];
dest = item;
}
}
}
}
if (dist) {
if ((dist[0] * 100 + dist[1]) < propDist) {
toLine = 1;
}
else {
toLine = -1;
}
var insertLine = propPos[0] === dist[0] ? false : true;
}
else {
toLine = 0;
}
var ref;
if (dest) {
var ref = currentNode.nodes[currentNode.properties[dest]];
}
else {
ref = {
source: {
start: {
line: currentNode.source.start.line - 1
},
end: {
line: currentNode.source.start.line + 1
}
}
};
}
var diff;
if (toLine < 0) {
diff = (ref.source.start.line - 2) - cursorPosition.row;
}
else {
diff = (ref.source.end.line - 1) - cursorPosition.row;
}
if (currentNode.selectorHeight && !currentNode.nodes.length) {
diff += currentNode.selectorHeight - 1;
}
if (diff > 0) {
cursor.moveDown(diff);
}
else if (diff < 0) {
cursor.moveUp(Math.abs(diff));
}
cursor.moveToEndOfLine();
if (currentNode.nodes.length || emptyLine) {
editor.insertNewlineBelow();
}
if (insertLine && toLine < 0 && emptyLine) {
editor.insertNewlineBelow();
cursor.moveUp();
}
if (insertLine && toLine > 0 && emptyLine) {
editor.insertNewlineBelow();
}
var newCursorPosition = editor.getCursorBufferPosition();
var tab = newCursorPosition.column === 0 ? "\t" : '';
editor.insertText(tab + prop + ': ' + value(null) + ';');
editor.moveLeft();
if (options.cb) { options.cb(); }
}
}
});
}
================================================
FILE: lib/delete-line.js
================================================
'use babel';
export default function deleteLine() {
var editor = atom.workspace.getActiveTextEditor();
if (editor) {
var cursor = editor.cursors[0];
cursor.moveToEndOfLine();
editor.deleteToBeginningOfLine();
editor.delete();
}
};
================================================
FILE: lib/focus-selector.js
================================================
'use babel';
import postcss from 'postcss';
export default function focusSelector(index) {
var editor = atom.workspace.getActiveTextEditor();
if (!editor) {
return;
}
var cursor = editor.cursors[0];
var cursorPosition = editor.getCursorBufferPosition();
var css = editor.getText();
postcss([]).process(css, { from: undefined }).then(function(res) {
var currentNode = 0;
for (var i = 0; i < res.root.nodes.length; i++) {
var node = res.root.nodes[i];
if (cursorPosition.row >= node.source.start.line && cursorPosition.row <= node.source.end.line) {
currentNode = i;
break;
}
}
var focusNode = currentNode + index;
if (typeof res.root.nodes[focusNode] !== 'undefined') {
var node = res.root.nodes[focusNode];
var dest = node.source.end.line;
if (node.nodes[0]) {
dest = node.nodes[0].source.start.line;
}
var diff = (dest - 1) - cursorPosition.row;
if (diff > 0) {
cursor.moveDown(diff);
}
else if (diff < 0) {
cursor.moveUp(Math.abs(diff));
}
cursor.moveToEndOfLine();
}
});
};
================================================
FILE: lib/get-focus-node.js
================================================
'use babel';
import postcss from 'postcss';
export default function getFocusNode(cb) {
var editor = atom.workspace.getActiveTextEditor();
if (!editor) {
return;
}
var cursor = editor.cursors[0];
var cursorPosition = editor.getCursorBufferPosition();
var css = editor.getText();
postcss([]).process(css, { from: undefined }).then(function(res) {
var currentNode = 0;
for (var i = 0; i < res.root.nodes.length; i++) {
var node = res.root.nodes[i];
if (cursorPosition.row >= node.source.start.line && cursorPosition.row <= node.source.end.line) {
currentNode = i;
break;
}
}
currentNode = res.root.nodes[currentNode];
var focused = null;
for (var i = 0; i < currentNode.nodes.length; i++) {
var node = currentNode.nodes[i];
if (cursorPosition.row + 1 >= node.source.start.line && cursorPosition.row + 1 <= node.source.end.line) {
focused = node;
break;
}
}
cb(focused);
});
};
================================================
FILE: lib/index.js
================================================
'use babel';
import { CompositeDisposable } from 'atom';
import actions from './actions';
import getFocusNode from './get-focus-node';
import focusSelector from './focus-selector';
import addLine from './add-line';
import deleteLine from './delete-line';
var finalOutput;
export default {
subscriptions: null,
midi: null,
activate(state) {
this.subscriptions = new CompositeDisposable();
this.subscriptions.add(atom.commands.add('atom-workspace', {
'midi:convert': () => this.convert()
}));
if (navigator.requestMIDIAccess) {
navigator.requestMIDIAccess({
sysex: true
}).then(function(midiAccess) {
var inputs = midiAccess.inputs.values();
for (var input = inputs.next(); input && !input.done; input = inputs.next()) {
input.value.onmidimessage = actions.bind(this);
}
var outputs = midiAccess.outputs.values();
for (var output = outputs.next(); output && !output.done; output = outputs.next()) {
finalOutput = output;
// Inquiry Message Request
finalOutput.value.send([0xF0,0x7E,0x7F,0x06,0x01,0xF7]);
// (4) Mode Request
finalOutput.value.send([0xF0,0x42,0x40,0x00,0x01,0x13,0x00,0x1F,0x12,0x00,0xF7]);
// Inquiry Message Request
finalOutput.value.send([0xF0,0x7E,0x7F,0x06,0x01,0xF7]);
// (5) Current Scene Data Dump
finalOutput.value.send([0xF0,0x42,0x40,0x00,0x01,0x13,0x00,0x7F,0x7F,0x02,0x03,0x05,0x40,0x00,0x00,0x00,
0x01,0x10,0x01,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x10,0x00,0x00,0x7F,0x00,
0x01,0x00,0x20,0x00,0x7F,0x00,0x00,0x01,0x00,0x30,0x00,0x7F,0x00,0x00,0x01,0x00,
0x40,0x00,0x7F,0x00,0x10,0x00,0x01,0x00,0x01,0x00,0x7F,0x00,0x01,0x00,0x00,0x11,
0x00,0x7F,0x00,0x01,0x00,0x00,0x21,0x00,0x7F,0x00,0x01,0x00,0x31,0x00,0x00,0x7F,
0x00,0x01,0x00,0x41,0x00,0x00,0x7F,0x00,0x10,0x01,0x00,0x02,0x00,0x00,0x7F,0x00,
0x01,0x00,0x12,0x00,0x7F,0x00,0x00,0x01,0x00,0x22,0x00,0x7F,0x00,0x00,0x01,0x00,
0x32,0x00,0x7F,0x00,0x01,0x00,0x00,0x42,0x00,0x7F,0x00,0x10,0x01,0x00,0x00,0x03,
0x00,0x7F,0x00,0x01,0x00,0x00,0x13,0x00,0x7F,0x00,0x01,0x00,0x23,0x00,0x00,0x7F,
0x00,0x01,0x00,0x33,0x00,0x00,0x7F,0x00,0x01,0x00,0x43,0x00,0x7F,0x00,0x00,0x10,
0x01,0x00,0x04,0x00,0x7F,0x00,0x00,0x01,0x00,0x14,0x00,0x7F,0x00,0x00,0x01,0x00,
0x24,0x00,0x7F,0x00,0x01,0x00,0x00,0x34,0x00,0x7F,0x00,0x01,0x00,0x00,0x44,0x00,
0x7F,0x00,0x10,0x01,0x00,0x00,0x05,0x00,0x7F,0x00,0x01,0x00,0x15,0x00,0x00,0x7F,
0x00,0x01,0x00,0x25,0x00,0x00,0x7F,0x00,0x01,0x00,0x35,0x00,0x7F,0x00,0x00,0x01,
0x00,0x45,0x00,0x7F,0x00,0x00,0x10,0x01,0x00,0x06,0x00,0x7F,0x00,0x00,0x01,0x00,
0x16,0x00,0x7F,0x00,0x01,0x00,0x00,0x26,0x00,0x7F,0x00,0x01,0x00,0x00,0x36,0x00,
0x7F,0x00,0x01,0x00,0x46,0x00,0x00,0x7F,0x00,0x10,0x01,0x00,0x07,0x00,0x00,0x7F,
0x00,0x01,0x00,0x17,0x00,0x00,0x7F,0x00,0x01,0x00,0x27,0x00,0x7F,0x00,0x00,0x01,
0x00,0x37,0x00,0x7F,0x00,0x00,0x01,0x00,0x47,0x00,0x7F,0x00,0x10,0x00,0x01,0x00,
0x3A,0x00,0x7F,0x00,0x01,0x00,0x00,0x3B,0x00,0x7F,0x00,0x01,0x00,0x00,0x2E,0x00,
0x7F,0x00,0x01,0x00,0x3C,0x00,0x00,0x7F,0x00,0x01,0x00,0x3D,0x00,0x00,0x7F,0x00,
0x01,0x00,0x3E,0x00,0x7F,0x00,0x00,0x01,0x00,0x2B,0x00,0x7F,0x00,0x00,0x01,0x00,
0x2C,0x00,0x7F,0x00,0x01,0x00,0x00,0x2A,0x00,0x7F,0x00,0x01,0x00,0x00,0x29,0x00,
0x7F,0x00,0x01,0x00,0x2D,0x00,0x00,0x7F,0x00,0x7F,0x7F,0x7F,0x7F,0x00,0x7F,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xF7]);
// Inquiry Message Request
finalOutput.value.send([0xF0,0x7E,0x7F,0x06,0x01,0xF7]);
// (2) Scene Write Request
finalOutput.value.send([0xF0,0x42,0x40,0x00,0x01,0x13,0x00,0x1F,0x11,0x00,0xF7]);
for (var i = 0; i < 8; i++) {
setTimeout(function(i) {
finalOutput.value.send(new Uint8Array([176, 32 + i, 0x7F]));
}.bind(null, i), 1000 + i * 70);
setTimeout(function(i) {
finalOutput.value.send(new Uint8Array([176, 32 + i, 0x00]));
}.bind(null, i), 1200 + i * 70);
setTimeout(function(i) {
finalOutput.value.send(new Uint8Array([176, 48 + i, 0x7F]));
}.bind(null, i), 1000 + 100 + i * 70);
setTimeout(function(i) {
finalOutput.value.send(new Uint8Array([176, 48 + i, 0x00]));
}.bind(null, i), 1200 + 100 + i * 70);
setTimeout(function(i) {
finalOutput.value.send(new Uint8Array([176, 64 + i, 0x7F]));
}.bind(null, i), 1000 + 100 * 2 + i * 70);
setTimeout(function(i) {
finalOutput.value.send(new Uint8Array([176, 64 + i, 0x00]));
}.bind(null, i), 1200 + 100 * 2 + i * 70);
}
}
}.bind(this), function() {
console.error("No access to MIDI devices");
});
} else {
console.error("No MIDI support");
}
},
getFocusNode: getFocusNode,
focusSelector: focusSelector,
addLine: addLine,
deleteLine: deleteLine
};
================================================
FILE: lib/order.js
================================================
'use babel';
export default [
[
'position',
'top',
'right',
'bottom',
'left',
'z-index',
],
[
'display',
'visibility',
'flex',
'flex-grow',
'flex-shrink',
'flex-basis',
'flex-direction',
'flex-flow',
'flex-wrap',
'align-content',
'align-items',
'align-self',
'justify-content',
'order',
'float',
'size',
'width',
'min-width',
'max-width',
'height',
'min-height',
'max-height',
'margin',
'margin-top',
'margin-right',
'margin-bottom',
'margin-left',
'padding',
'padding-top',
'padding-right',
'padding-bottom',
'padding-left',
'vertical-align',
'overflow',
'overflow-x',
'overflow-y',
'box-sizing',
],
[
'font',
'font-weight',
'font-style',
'font-variant',
'font-size-adjust',
'font-stretch',
'font-size',
'font-family',
'color',
'text-decoration',
'text-transform',
'text-align',
'text-justify',
'text-outline',
'text-shadow',
'line-height',
'white-space',
'word-spacing',
'word-wrap',
'word-break',
'tab-size',
'hyphens',
'letter-spacing',
],
[
'opcaity',
'outline',
'outline-width',
'outline-style',
'outline-color',
'outline-offset',
'list-style',
'list-style-position',
'list-style-type',
'list-style-image',
'border',
'border-spacing',
'border-collapse',
'border-width',
'border-style',
'border-color',
'border-top',
'border-top-width',
'border-top-style',
'border-top-color',
'border-right',
'border-right-width',
'border-right-style',
'border-right-color',
'border-bottom',
'border-bottom-width',
'border-bottom-style',
'border-bottom-color',
'border-left',
'border-left-width',
'border-left-style',
'border-left-color',
'border-radius',
'border-top-left-radius',
'border-top-right-radius',
'border-bottom-right-radius',
'border-bottom-left-radius',
'border-image',
'border-image-source',
'border-image-slice',
'border-image-width',
'border-image-outset',
'border-image-repeat',
'border-top-image',
'border-right-image',
'border-bottom-image',
'border-left-image',
'border-corner-image',
'border-top-left-image',
'border-top-right-image',
'border-bottom-right-image',
'border-bottom-left-image',
'background',
'background-color',
'background-image',
'background-attachment',
'background-position',
'background-position-x',
'background-position-y',
'background-clip',
'background-origin',
'background-size',
'background-repeat',
'background-blend-mode',
'box-shadow',
'filter',
'resize',
'cursor',
'transform',
'transition',
'transition-delay',
'transition-timing-function',
'transition-duration',
'transition-property',
'transform',
'transform-origin',
'animation',
'animation-name',
'animation-duration',
'animation-play-state',
'animation-timing-function',
'animation-delay',
'animation-iteration-count',
'animation-direction',
'animation-fill-mode',
]
];
================================================
FILE: license.md
================================================
Copyright (c) 2016 NICOLAS Dimitri
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
================================================
FILE: package.json
================================================
{
"name": "midi-controller-css",
"main": "./lib/index",
"version": "1.2.0",
"description": "Use Korg NanoKontrol 2 to edit your css files",
"keywords": [
"midi",
"controller",
"css",
"atom",
"atom-package",
"korg",
"nanokontrol"
],
"repository": "https://github.com/dimitrinicolas/midi-controller-css",
"license": "MIT",
"engines": {
"atom": ">=1.0.0 <2.0.0"
},
"dependencies": {
"play": "^0.5.0",
"postcss": "^6.0.19"
}
}
================================================
FILE: readme.md
================================================
# Midi Controller Css
I type a lot of css, so I bought a Korg NanoKontrol 2 and built this lovely Atom package. Each column of buttons controls the values of one css property, and each slider sets the px/percent/... values. Ordinary snippets are outdated, go midi snippets!

This usb midi controller is costless and very complete for its size. I bought a used one for 20€ ($25).
You can have a look at [lib/actions.js](lib/actions.js) for a complete list of features.
PS: Most of the snippets only works with some popular PostCSS plugins, you can check my list on my [personnal front-end framework](https://github.com/dimitrinicolas/front-end-stack/blob/master/build/postcss.config.js).

With some helpers:

gitextract_4zadc2mu/ ├── .gitignore ├── lib/ │ ├── actions.js │ ├── add-line.js │ ├── delete-line.js │ ├── focus-selector.js │ ├── get-focus-node.js │ ├── index.js │ └── order.js ├── license.md ├── package.json └── readme.md
SYMBOL INDEX (8 symbols across 6 files)
FILE: lib/actions.js
function actions (line 30) | function actions(message) {
FILE: lib/add-line.js
function timeout (line 10) | function timeout(prop) {
function focusSelector (line 23) | function focusSelector(prop, value, options) {
function set (line 59) | function set(prop, value, opts) {
FILE: lib/delete-line.js
function deleteLine (line 3) | function deleteLine() {
FILE: lib/focus-selector.js
function focusSelector (line 5) | function focusSelector(index) {
FILE: lib/get-focus-node.js
function getFocusNode (line 5) | function getFocusNode(cb) {
FILE: lib/index.js
method activate (line 17) | activate(state) {
Condensed preview — 11 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (35K chars).
[
{
"path": ".gitignore",
"chars": 53,
"preview": ".DS_Store\nnpm-debug.log\nnode_modules\nlogs\n*.log*\ntmp\n"
},
{
"path": "lib/actions.js",
"chars": 10149,
"preview": "'use babel';\n\nimport path from 'path';\nimport play from 'play';\n\nlet tickSound = path.resolve(__dirname, '../assets/soun"
},
{
"path": "lib/add-line.js",
"chars": 7971,
"preview": "'use babel';\n\nvar emptyLine = false;\n\nimport postcss from 'postcss';\nimport order from './order';\n\nvar timer = {};\n\nfunc"
},
{
"path": "lib/delete-line.js",
"chars": 279,
"preview": "'use babel';\n\nexport default function deleteLine() {\n\n var editor = atom.workspace.getActiveTextEditor();\n\n if (ed"
},
{
"path": "lib/focus-selector.js",
"chars": 1315,
"preview": "'use babel';\n\nimport postcss from 'postcss';\n\nexport default function focusSelector(index) {\n\n var editor = atom.work"
},
{
"path": "lib/get-focus-node.js",
"chars": 1123,
"preview": "'use babel';\n\nimport postcss from 'postcss';\n\nexport default function getFocusNode(cb) {\n\n var editor = atom.workspac"
},
{
"path": "lib/index.js",
"chars": 6152,
"preview": "'use babel';\n\nimport { CompositeDisposable } from 'atom';\n\nimport actions from './actions';\nimport getFocusNode from './"
},
{
"path": "lib/order.js",
"chars": 3911,
"preview": "'use babel';\n\nexport default [\n\n [\n 'position',\n 'top',\n 'right',\n 'bottom',\n 'lef"
},
{
"path": "license.md",
"chars": 1059,
"preview": "Copyright (c) 2016 NICOLAS Dimitri\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this"
},
{
"path": "package.json",
"chars": 487,
"preview": "{\n \"name\": \"midi-controller-css\",\n \"main\": \"./lib/index\",\n \"version\": \"1.2.0\",\n \"description\": \"Use Korg NanoKontrol"
},
{
"path": "readme.md",
"chars": 840,
"preview": "# Midi Controller Css\n\nI type a lot of css, so I bought a Korg NanoKontrol 2 and built this lovely Atom package. Each co"
}
]
About this extraction
This page contains the full source code of the dimitrinicolas/midi-controller-css GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 11 files (32.6 KB), approximately 9.0k tokens, and a symbol index with 8 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.