Skip to content

Commit

Permalink
Refactored inject
Browse files Browse the repository at this point in the history
  • Loading branch information
jgranstrom committed Jan 26, 2017
1 parent a909d43 commit 02e283d
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 26 deletions.
22 changes: 14 additions & 8 deletions lib/extract.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const sass = require('node-sass');
const path = require('path');
const { parseDeclarations } = require('./parse');
const { load, loadSync } = require('./load');
const { injectFunctions } = require('./inject');
const { injectExtractionFunctions } = require('./inject');

Promise.promisifyAll(sass);

Expand Down Expand Up @@ -99,32 +99,38 @@ function augmentExtractionCompilerOption(compileOptions, completeExtractionFunct
const extractionCompileOptions = Object.assign({}, compileOptions);

extractionCompileOptions.functions = completeExtractionFunctions;
extractionCompileOptions.filename = entryFilename;
extractionCompileOptions.data = extractionMap[entryFilename].injectedData;

return extractionCompileOptions;
}

function getFileId(filename) {
return new Buffer(filename).toString('base64').replace(/=/g, '');
}

function processFile(filename, includedData, extractionMap, completeExtractionFunctions) {
const declarations = parseDeclarations(includedData);
const variableResults = {};

const declarationResultHandler = (context, declaration, value) => {
if(!variableResults[context]) {
variableResults[context] = {};
const globalDeclarationResultHandler = (declaration, value) => {
if(!variableResults.global) {
variableResults.global = {};
}

variableResults[context][declaration.declaration] = { value, expression: declaration.expression };
variableResults.global[declaration.declaration] = { value, expression: declaration.expression };
}

const injection = injectFunctions(filename, includedData, declarations, declarationResultHandler);
const fileId = getFileId(filename);
const injection = injectExtractionFunctions(fileId, declarations, { globalDeclarationResultHandler });
completeExtractionFunctions = Object.assign(completeExtractionFunctions, injection.injectedFunctions);

const injectedData = `${includedData}\n\n${injection.injectedData}`;

extractionMap[filename] = {
includedData,
declarations,
variableResults,
injectedData: injection.injectedData,
injectedData: injectedData,
injectedFunctions: injection.injectedFunctions,
};
}
Expand Down
46 changes: 28 additions & 18 deletions lib/inject.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,47 @@
const { createStructuredValue } = require('./struct');

const FN_PREFIX = '_INJECT_';
const FN_PREFIX_IMPLICIT_GLOBAL = 'IG_';
const FN_PREFIX_EXPLICIT_GLOBAL = 'EG_';
const FN_SUFFIX_VALUE = '_VALUE';

function inject(context, filename, fnPrefix, declaration, declarationResultHandler) {
const fileId = new Buffer(filename).toString('base64').replace(/=/g, '');
const fnName = `${fileId}_${context}_${FN_PREFIX}${fnPrefix}${declaration.declarationClean}`;

const injectedFunction = (sassValue) => {
const FN_PREFIX = '___SV_INJECT';
const FN_PREFIX_IMPLICIT_GLOBAL = 'IG';
const FN_PREFIX_EXPLICIT_GLOBAL = 'EG';
const FN_SUFFIX_VALUE = 'VALUE';

/**
* Create injection function and source for a file, category, declaration and result handler
*/
function createInjection(fileId, categoryPrefix, declaration, declarationResultHandler) {
const fnName = `${FN_PREFIX}_${fileId}_${categoryPrefix}_${declaration.declarationClean}`;

const injectedFunction = function(sassValue) {
const value = createStructuredValue(sassValue);
declarationResultHandler(context, declaration, value, sassValue);
declarationResultHandler(declaration, value, sassValue);
return sassValue;
};

const injectedCode = `$${fnName}${FN_SUFFIX_VALUE}: ${fnName}(${declaration.declaration});\n`
const injectedCode = `$${fnName}: ${fnName}(${declaration.declaration});\n`

return { fnName, injectedFunction, injectedCode };
}

exports.injectFunctions = (filename, data, declarations, declarationResultHandler) => {
let injectedData = `${data}\n\n`;
/**
* Create injection functions for extraction variable values
* Returns injection sass source and the injected functions
* Declaration result handlers will be called with the extracted value of each declaration
* Provided file id will be used to ensure unique function names per file
*/
exports.injectExtractionFunctions = (fileId, declarations, { globalDeclarationResultHandler }) => {
let injectedData = ``;
const injectedFunctions = {};

declarations.implicitGlobals.forEach((declaration) => {
const { fnName, injectedFunction, injectedCode } = inject('global', filename, FN_PREFIX_IMPLICIT_GLOBAL, declaration, declarationResultHandler);
// Create injections for implicit global variables
declarations.implicitGlobals.forEach(declaration => {
const { fnName, injectedFunction, injectedCode } = createInjection(fileId, FN_PREFIX_IMPLICIT_GLOBAL, declaration, globalDeclarationResultHandler);
injectedFunctions[fnName] = injectedFunction;
injectedData += injectedCode;
});

declarations.explicitGlobals.forEach((declaration) => {
const { fnName, injectedFunction, injectedCode } = inject('global', filename, FN_PREFIX_EXPLICIT_GLOBAL, declaration, declarationResultHandler);
// Create injections for explicit global variables
declarations.explicitGlobals.forEach(declaration => {
const { fnName, injectedFunction, injectedCode } = createInjection(fileId, FN_PREFIX_EXPLICIT_GLOBAL, declaration, globalDeclarationResultHandler);
injectedFunctions[fnName] = injectedFunction;
injectedData += injectedCode;
});
Expand Down

0 comments on commit 02e283d

Please sign in to comment.