Skip to content

Commit

Permalink
Find variable declarations from every file. Use styleVariables to fil…
Browse files Browse the repository at this point in the history
…ter selected files
  • Loading branch information
Hannu Pelkonen committed Dec 11, 2014
1 parent 0c5317b commit 4798ad7
Show file tree
Hide file tree
Showing 16 changed files with 532 additions and 445 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Port in which the server will run
Automatically generate style guide on file change. `--watch` does not run server. Combile with `--server` if you want to run server


Config JSON file could contain following settings
Config JSON file could look like following:

{
title: "My Style guide",
Expand Down Expand Up @@ -101,7 +101,6 @@ For more specific documentation. See [Build options](#build-options) section.
title: "My Styleguide",
server: true,
rootPath: outputPath,
styleVariables: '<LESS/SASS variable file>',
overviewPath: "<path to your overview.md>",
sass: {
// Options passed to gulp-sass
Expand Down Expand Up @@ -142,7 +141,6 @@ Then you are able to use the same gulp task inside you `Gruntfile`:
title: "My Styleguide",
server: true,
rootPath: outputPath,
styleVariables: '<LESS/SASS variable file>',
overviewPath: "<path to your overview.md>",
sass: {
// Options passed to gulp-sass
Expand Down Expand Up @@ -231,7 +229,7 @@ This allows Angular to deal with the routing. However, the static files should b
<a name="option-styleVariables"></a>
**styleVariables** (string, optional)

Path to the file containing SASS variables that can be used as modifiers in the KSS notation.
By default variable definitions are searched from every file passed in gulp.src. styleVariables parameter could be used to filter from which files variables are loaded.

<a name="option-filesConfig"></a>
**filesConfig** (array, optional) **(Experimental feature)**
Expand Down
2 changes: 2 additions & 0 deletions lib/app/js/services/Styleguide.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ angular.module('sgApp')

this.sections = {};
this.config = {};
this.variables = {};
this.status = {
hasError: false,
error: {}
Expand All @@ -24,6 +25,7 @@ angular.module('sgApp')
url: 'styleguide.json'
}).success(function(response) {
_this.config.data = response.config;
_this.variables.data = response.variables;
_this.sections.data = response.sections;
});
};
Expand Down
74 changes: 28 additions & 46 deletions lib/app/js/services/Variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,29 @@
_this.refreshDirtyStates();
}, true);

this.getLocalVarByName = function(name) {
this.variableMatches = function(var1, var2) {
return var1.name === var2.name && var1.file === var2.file;
};

this.getLocalVar = function(variable) {
for (var i = this.variables.length - 1; i >= 0; i--) {
if (this.variables[i].name === name) {
if (this.variableMatches(this.variables[i], variable)) {
return this.variables[i];
}
}
};

this.getLocalIndexByName = function(name) {
this.getLocalIndex = function(variable) {
for (var i = this.variables.length - 1; i >= 0; i--) {
if (this.variables[i].name === name) {
if (this.variableMatches(this.variables[i], variable)) {
return i;
}
}
};

this.getServerVarByName = function(name) {
this.getServerVar = function(variable) {
for (var i = serverData.length - 1; i >= 0; i--) {
if (serverData[i].name === name) {
if (this.variableMatches(serverData[i], variable)) {
return serverData[i];
}
}
Expand All @@ -44,7 +48,7 @@
var _this = this;
// Mark variables that differ from the server version as dirty
angular.forEach(_this.variables, function(variable) {
var serverVar = _this.getServerVarByName(variable.name);
var serverVar = _this.getServerVar(variable);
if (serverVar && serverVar.value !== variable.value && !variable.dirty) {
variable.dirty = true;
} else if (serverVar && serverVar.value === variable.value && variable.dirty) {
Expand All @@ -59,36 +63,38 @@
} else {
for (var i = 0; i < serverData.length; i++) {
var oldIndex;
if (this.variables[i] && this.variables[i].name !== serverData[i].name) {
if (!this.getServerVarByName(this.variables[i].name)) {
if (this.variables[i] && !this.variableMatches(this.variables[i], serverData[i])) {
if (!this.getServerVar(this.variables[i])) {
// This variable does not exists anymore on the server. Remove it
this.variables.splice(i, 1);
} else if (this.getLocalVarByName(serverData[i].name) && !this.getLocalVarByName(serverData[i].name).dirty) {
} else if (this.getLocalVar(serverData[i]) && !this.getLocalVar(serverData[i]).dirty) {
// The variable already exists but in another position
// It is not changed so we can just remove it
oldIndex = this.getLocalIndexByName(serverData[i].name);
oldIndex = this.getLocalIndex(serverData[i]);
this.variables.splice(oldIndex, 1);
this.variables.splice(i, 0, {name: serverData[i].name, value: serverData[i].value});
} else if (this.getLocalVarByName(serverData[i].name)) {
this.variables.splice(i, 0, angular.copy(serverData[i]));
} else if (this.getLocalVar(serverData[i])) {
// The variable already exists but in another position
// It is changed so we need to keep the old values
oldIndex = this.getLocalIndexByName(serverData[i].name);
oldIndex = this.getLocalIndex(serverData[i]);
var oldValue = this.variables[oldIndex].value;
this.variables.splice(oldIndex, 1);
this.variables.splice(i, 0, {name: serverData[i].name, value: oldValue});
var newObject = angular.copy(serverData[i]);
newObject.value = oldValue;
this.variables.splice(i, 0, newObject);
} else {
// The variable does not exists anywhere else. Just add it
this.variables.splice(i, 0, {name: serverData[i].name, value: serverData[i].value});
this.variables.splice(i, 0, angular.copy(serverData[i]));
}
} else if (this.variables[i] && this.variables[i].name === serverData[i].name) {
} else if (this.variables[i] && this.variableMatches(this.variables[i], serverData[i])) {
// Variable exists already locally
// Update value if variable does not have any local changes
if (!this.variables[i].dirty) {
this.variables[i].value = serverData[i].value;
}
} else if (!this.variables[i]) {
// Add new local variable
this.variables.push({name: serverData[i].name, value: serverData[i].value});
this.variables.push(angular.copy(serverData[i]));
}
}
}
Expand All @@ -98,7 +104,7 @@
var _this = this;
// Reset every key to corresponding server value
angular.forEach(this.variables, function(variable) {
var serverVar = _this.getServerVarByName(variable.name);
var serverVar = _this.getServerVar(variable);
if (serverVar) {
variable.value = serverVar.value;
}
Expand All @@ -117,29 +123,9 @@
return this;
};

this.sync = function(method) {
var validMethods = ['load', 'save'];

// Parameter validation
if (validMethods.indexOf(method) === -1) {
throw 'No valid method provided. Available methods: ' + validMethods.join(', ');
}

// Load variables from server or localStorage
if (method === 'load') {
this.socket.emit('request variables from server');
}

// Save variables to server
if (method === 'save') {
this.socket.emit('variables to server', this.variables);
}
};

this.saveVariables = function() {
var _this = this;
if (this.socket) {
_this.sync('save');
this.socket.emit('variables to server', this.variables);
} else {
throw 'Socket not available.';
}
Expand All @@ -152,14 +138,10 @@

// Update new server data when it is available
$rootScope.$watch(function() {
return Styleguide.config.data;
return Styleguide.variables.data;
}, function(newValue) {
if (newValue) {
if (newValue.settings) {
serverData = newValue.settings;
} else {
serverData = [];
}
serverData = newValue;
_this.refreshValues();
_this.refreshDirtyStates();
}
Expand Down
2 changes: 1 addition & 1 deletion lib/app/sass/_styleguide_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ $secondary-color: #E4E4E4;
$tertiary-color: #F7FCF1;

// Button and link colors
$primary-action-color: #EB7F00;
$primary-action-color: #70e7e0;
$default-action-color: #1695A3;
$action-color-change: 5%;

Expand Down
81 changes: 50 additions & 31 deletions lib/modules/io.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,61 @@
var fs = require('fs'),
path = require('path'),
Q = require('q'),
parser = require('./variable-parser');

module.exports = function(ioServer, options) {

var loadVariables,
saveVariables,
io = ioServer,
var io = ioServer,
compileError = false;

if (options.styleVariables && !fs.existsSync(options.styleVariables)) {
console.error('Could not find SASS variables file', options.styleVariables);
return;
}

loadVariables = function(socket) {
return function() {
var values, syntax = path.extname(options.styleVariables).substring(1);
fs.readFile(options.styleVariables, {encoding: 'utf8'}, function(err, data) {
if (err) {
return console.error(err);
}
values = parser.parseVariables(data, syntax);
socket.emit('variables from server', values);
console.log('EVENT: variables from server');
function groupVariablesByFilename(variables) {
return variables.reduce(function(prev, curr) {
var filePath = curr.file;
if (!prev[filePath]) {
prev[filePath] = [];
}
prev[filePath].push(curr);
return prev;
}, {});
}

function saveVariables(variables) {
return Q.Promise(function(resolve) {

// First group variables by file name
var groupedVariables = groupVariablesByFilename(variables),
filePromises = [];

// Go trough every file and update variables defined in that file
Object.keys(groupedVariables).forEach(function(filePath) {
filePromises.push(Q.promise(function(resolveFile) {
var fileVariables = groupedVariables[filePath],
syntax = path.extname(filePath).substring(1);

// Read original file contents to be updated
fs.readFile(filePath, {encoding: 'utf8'}, function(err, originalData) {
// Update variables and store results back to the original file
var data = parser.setVariables(originalData, syntax, fileVariables);
fs.writeFile(filePath, data, function(err) {
if (err) {
console.error(err);
}
resolveFile();
});
});
}));
});
};
};

saveVariables = function(socket) {
return function(variables) {
var syntax = path.extname(options.styleVariables).substring(1);
fs.readFile(options.styleVariables, {encoding: 'utf8'}, function(err, originalData) {
var data = parser.setVariables(originalData, syntax, variables);
fs.writeFile(options.styleVariables, data, function(err, data) {
if (err) {
return console.error(err);
}
socket.emit('variables saved to server', data);
console.log('EVENT: variables saved to server');
});
Q.all(filePromises).then(function() {
resolve();
});
};
};
});
}

function emitProgressStart() {
io.sockets.emit('styleguide progress start');
Expand All @@ -66,8 +79,12 @@ module.exports = function(ioServer, options) {

io.on('connection', function(socket) {
console.log('Socket connection established (id:', socket.conn.id + ')');
socket.on('request variables from server', loadVariables(socket));
socket.on('variables to server', saveVariables(socket));
socket.on('variables to server', function(variables) {
saveVariables(variables).then(function() {
socket.emit('variables saved to server');
console.log('EVENT: variables saved to server');
});
});
if (compileError) {
emitCompileError();
} else {
Expand All @@ -76,6 +93,8 @@ module.exports = function(ioServer, options) {
});

return {
saveVariables: saveVariables,
groupVariablesByFilename: groupVariablesByFilename,
emitProgressStart: emitProgressStart,
emitCompileError: emitCompileError,
emitCompileSuccess: emitCompileSuccess
Expand Down
Loading

0 comments on commit 4798ad7

Please sign in to comment.