2016-01-27 10:29:26 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
Definition of the FRESHTheme class.
|
|
|
|
@module core/fresh-theme
|
|
|
|
@license MIT. See LICENSE.md for details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
(function() {
|
2016-02-11 16:48:44 +00:00
|
|
|
var EXTEND, FRESHTheme, FS, HMSTATUS, PATH, READFILES, _, _load, _loadOne, friendlyName, loadSafeJson, moment, parsePath, pathExists, validator;
|
2016-01-27 10:29:26 +00:00
|
|
|
|
|
|
|
FS = require('fs');
|
|
|
|
|
|
|
|
validator = require('is-my-json-valid');
|
|
|
|
|
|
|
|
_ = require('underscore');
|
|
|
|
|
|
|
|
PATH = require('path');
|
|
|
|
|
|
|
|
parsePath = require('parse-filepath');
|
|
|
|
|
|
|
|
pathExists = require('path-exists').sync;
|
|
|
|
|
|
|
|
EXTEND = require('extend');
|
|
|
|
|
|
|
|
HMSTATUS = require('./status-codes');
|
|
|
|
|
|
|
|
moment = require('moment');
|
|
|
|
|
|
|
|
loadSafeJson = require('../utils/safe-json-loader');
|
|
|
|
|
|
|
|
READFILES = require('recursive-readdir-sync');
|
|
|
|
|
|
|
|
|
2016-02-11 16:48:44 +00:00
|
|
|
/* A representation of a FRESH theme asset.
|
2016-01-27 10:29:26 +00:00
|
|
|
@class FRESHTheme
|
|
|
|
*/
|
|
|
|
|
|
|
|
FRESHTheme = (function() {
|
2018-02-01 11:52:06 +00:00
|
|
|
function FRESHTheme() {
|
|
|
|
this.baseFolder = 'src';
|
|
|
|
return;
|
|
|
|
}
|
2016-01-27 10:29:26 +00:00
|
|
|
|
|
|
|
|
2016-02-11 16:48:44 +00:00
|
|
|
/* Open and parse the specified theme. */
|
2016-01-27 10:29:26 +00:00
|
|
|
|
|
|
|
FRESHTheme.prototype.open = function(themeFolder) {
|
|
|
|
var cached, formatsHash, pathInfo, that, themeFile, themeInfo;
|
|
|
|
this.folder = themeFolder;
|
|
|
|
pathInfo = parsePath(themeFolder);
|
|
|
|
formatsHash = {};
|
|
|
|
themeFile = PATH.join(themeFolder, 'theme.json');
|
|
|
|
themeInfo = loadSafeJson(themeFile);
|
|
|
|
if (themeInfo.ex) {
|
|
|
|
throw {
|
2018-01-29 07:04:00 +00:00
|
|
|
fluenterror: themeInfo.ex.op === 'parse' ? HMSTATUS.parseError : HMSTATUS.readError,
|
2016-01-27 10:29:26 +00:00
|
|
|
inner: themeInfo.ex.inner
|
|
|
|
};
|
|
|
|
}
|
|
|
|
that = this;
|
|
|
|
EXTEND(true, this, themeInfo.json);
|
|
|
|
if (this.inherits) {
|
|
|
|
cached = {};
|
|
|
|
_.each(this.inherits, function(th, key) {
|
|
|
|
var d, themePath, themesFolder;
|
|
|
|
themesFolder = require.resolve('fresh-themes');
|
|
|
|
d = parsePath(themeFolder).dirname;
|
|
|
|
themePath = PATH.join(d, th);
|
|
|
|
cached[th] = cached[th] || new FRESHTheme().open(themePath);
|
|
|
|
return formatsHash[key] = cached[th].getFormat(key);
|
|
|
|
});
|
|
|
|
}
|
2016-02-09 20:27:34 +00:00
|
|
|
formatsHash = _load.call(this, formatsHash);
|
2016-01-27 10:29:26 +00:00
|
|
|
this.formats = formatsHash;
|
|
|
|
this.name = parsePath(this.folder).name;
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Determine if the theme supports the specified output format. */
|
|
|
|
|
|
|
|
FRESHTheme.prototype.hasFormat = function(fmt) {
|
|
|
|
return _.has(this.formats, fmt);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Determine if the theme supports the specified output format. */
|
|
|
|
|
|
|
|
FRESHTheme.prototype.getFormat = function(fmt) {
|
|
|
|
return this.formats[fmt];
|
|
|
|
};
|
|
|
|
|
|
|
|
return FRESHTheme;
|
|
|
|
|
|
|
|
})();
|
|
|
|
|
|
|
|
|
2016-02-11 16:48:44 +00:00
|
|
|
/* Load and parse theme source files. */
|
2016-01-27 10:29:26 +00:00
|
|
|
|
2016-02-09 20:27:34 +00:00
|
|
|
_load = function(formatsHash) {
|
2017-01-21 03:53:16 +00:00
|
|
|
var copyOnly, fmts, jsFiles, major, that, tplFolder;
|
2016-01-27 10:29:26 +00:00
|
|
|
that = this;
|
|
|
|
major = false;
|
2018-02-01 11:52:06 +00:00
|
|
|
tplFolder = PATH.join(this.folder, this.baseFolder);
|
2016-02-09 20:27:34 +00:00
|
|
|
copyOnly = ['.ttf', '.otf', '.png', '.jpg', '.jpeg', '.pdf'];
|
2016-01-27 10:29:26 +00:00
|
|
|
fmts = READFILES(tplFolder).map(function(absPath) {
|
2016-02-11 16:48:44 +00:00
|
|
|
return _loadOne.call(this, absPath, formatsHash, tplFolder);
|
|
|
|
}, this);
|
2016-01-27 10:29:26 +00:00
|
|
|
this.cssFiles = fmts.filter(function(fmt) {
|
|
|
|
return fmt && (fmt.ext === 'css');
|
|
|
|
});
|
|
|
|
this.cssFiles.forEach(function(cssf) {
|
|
|
|
var idx;
|
|
|
|
idx = _.findIndex(fmts, function(fmt) {
|
|
|
|
return fmt && fmt.pre === cssf.pre && fmt.ext === 'html';
|
|
|
|
});
|
|
|
|
cssf.major = false;
|
|
|
|
if (idx > -1) {
|
|
|
|
fmts[idx].css = cssf.data;
|
|
|
|
return fmts[idx].cssPath = cssf.path;
|
|
|
|
} else {
|
|
|
|
if (that.inherits) {
|
|
|
|
return that.overrides = {
|
|
|
|
file: cssf.path,
|
|
|
|
data: cssf.data
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2017-01-21 03:53:16 +00:00
|
|
|
jsFiles = fmts.filter(function(fmt) {
|
|
|
|
return fmt && (fmt.ext === 'js');
|
|
|
|
});
|
|
|
|
this.jsFiles = jsFiles.map(function(jsf) {
|
|
|
|
return jsf['path'];
|
|
|
|
});
|
2016-01-27 10:29:26 +00:00
|
|
|
return formatsHash;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-02-11 16:48:44 +00:00
|
|
|
/* Load a single theme file. */
|
|
|
|
|
|
|
|
_loadOne = function(absPath, formatsHash, tplFolder) {
|
2016-02-13 08:27:11 +00:00
|
|
|
var absPathSafe, act, defFormats, idx, isPrimary, obj, outFmt, pathInfo, portion, ref, ref1, reg, res;
|
2016-02-11 16:48:44 +00:00
|
|
|
pathInfo = parsePath(absPath);
|
2018-02-01 22:56:43 +00:00
|
|
|
if (pathInfo.basename.toLowerCase() === 'theme.json') {
|
|
|
|
return;
|
|
|
|
}
|
2016-02-11 16:48:44 +00:00
|
|
|
absPathSafe = absPath.trim().toLowerCase();
|
|
|
|
outFmt = '';
|
2016-02-12 03:04:11 +00:00
|
|
|
act = 'copy';
|
2016-02-13 08:27:11 +00:00
|
|
|
isPrimary = false;
|
2016-02-11 16:48:44 +00:00
|
|
|
if (this.explicit) {
|
|
|
|
outFmt = _.find(Object.keys(this.formats), function(fmtKey) {
|
|
|
|
var fmtVal;
|
|
|
|
fmtVal = this.formats[fmtKey];
|
|
|
|
return _.some(fmtVal.transform, function(fpath) {
|
|
|
|
var absPathB;
|
|
|
|
absPathB = PATH.join(this.folder, fpath).trim().toLowerCase();
|
|
|
|
return absPathB === absPathSafe;
|
|
|
|
}, this);
|
|
|
|
}, this);
|
|
|
|
if (outFmt) {
|
|
|
|
act = 'transform';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!outFmt) {
|
|
|
|
portion = pathInfo.dirname.replace(tplFolder, '');
|
|
|
|
if (portion && portion.trim()) {
|
|
|
|
if (portion[1] === '_') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
reg = /^(?:\/|\\)(html|latex|doc|pdf|png|partials)(?:\/|\\)?/ig;
|
|
|
|
res = reg.exec(portion);
|
|
|
|
if (res) {
|
|
|
|
if (res[1] !== 'partials') {
|
|
|
|
outFmt = res[1];
|
|
|
|
if (!this.explicit) {
|
|
|
|
act = 'transform';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.partials = this.partials || [];
|
|
|
|
this.partials.push({
|
|
|
|
name: pathInfo.name,
|
|
|
|
path: absPath
|
|
|
|
});
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!outFmt) {
|
|
|
|
idx = pathInfo.name.lastIndexOf('-');
|
|
|
|
outFmt = idx === -1 ? pathInfo.name : pathInfo.name.substr(idx + 1);
|
|
|
|
if (!this.explicit) {
|
|
|
|
act = 'transform';
|
|
|
|
}
|
2016-02-13 08:27:11 +00:00
|
|
|
defFormats = require('./default-formats');
|
|
|
|
isPrimary = _.some(defFormats, function(form) {
|
|
|
|
return form.name === outFmt && pathInfo.extname !== '.css';
|
|
|
|
});
|
2016-02-11 16:48:44 +00:00
|
|
|
}
|
|
|
|
formatsHash[outFmt] = formatsHash[outFmt] || {
|
|
|
|
outFormat: outFmt,
|
|
|
|
files: []
|
|
|
|
};
|
|
|
|
if ((ref = this.formats) != null ? (ref1 = ref[outFmt]) != null ? ref1.symLinks : void 0 : void 0) {
|
|
|
|
formatsHash[outFmt].symLinks = this.formats[outFmt].symLinks;
|
|
|
|
}
|
|
|
|
obj = {
|
|
|
|
action: act,
|
2016-02-13 08:27:11 +00:00
|
|
|
primary: isPrimary,
|
2016-02-11 16:48:44 +00:00
|
|
|
path: absPath,
|
|
|
|
orgPath: PATH.relative(tplFolder, absPath),
|
|
|
|
ext: pathInfo.extname.slice(1),
|
|
|
|
title: friendlyName(outFmt),
|
|
|
|
pre: outFmt,
|
|
|
|
data: FS.readFileSync(absPath, 'utf8'),
|
|
|
|
css: null
|
|
|
|
};
|
|
|
|
formatsHash[outFmt].files.push(obj);
|
|
|
|
return obj;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/* Return a more friendly name for certain formats. */
|
2016-01-27 10:29:26 +00:00
|
|
|
|
|
|
|
friendlyName = function(val) {
|
|
|
|
var friendly;
|
2016-02-11 16:48:44 +00:00
|
|
|
val = (val && val.trim().toLowerCase()) || '';
|
2016-01-27 10:29:26 +00:00
|
|
|
friendly = {
|
|
|
|
yml: 'yaml',
|
|
|
|
md: 'markdown',
|
|
|
|
txt: 'text'
|
|
|
|
};
|
|
|
|
return friendly[val] || val;
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = FRESHTheme;
|
|
|
|
|
|
|
|
}).call(this);
|
2016-02-02 02:14:36 +00:00
|
|
|
|
|
|
|
//# sourceMappingURL=fresh-theme.js.map
|