views-morph
Version:
Views language morpher
1,873 lines (1,518 loc) • 82.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var path = require('path');
var buble = _interopDefault(require('buble'));
var toCamelCase = _interopDefault(require('to-camel-case'));
var toSlugCase = _interopDefault(require('to-slug-case'));
var list = _interopDefault(require('google-fonts-complete/api-response.json'));
var cssProperties = _interopDefault(require('css-properties'));
var toPascalCase = _interopDefault(require('to-pascal-case'));
var getColor = _interopDefault(require('color'));
var prettier = _interopDefault(require('prettier'));
var wrap = (function (s) {
return isCodeExplicit(s) ? s : '{' + s + '}';
});
var safe = (function (value) {
return typeof value === 'string' && !isCode(value) ? JSON.stringify(value) : wrap(value);
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var objectWithoutProperties = function (obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var toArray = function (arr) {
return Array.isArray(arr) ? arr : Array.from(arr);
};
var toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
var safeScope = function safeScope(value) {
return typeof value === 'string' && !isCode(value) ? JSON.stringify(value) : value;
};
var checkParentStem = function checkParentStem(node, styleKey) {
if (styleKey !== 'hover' || styleKey !== 'disabled' || !node.parent) return false;
var matchingParentStem = node.parent.scopes.some(function (scope) {
return scope.value === styleKey;
});
return matchingParentStem && (node.parent.is || node.parent.name);
};
var INTERPOLATION = /\${(.+)}/;
var isInterpolation = function isInterpolation(str) {
return INTERPOLATION.test(str);
};
var deinterpolate = function deinterpolate(str) {
var match = str.match(INTERPOLATION);
return match ? match[1] : str;
};
var getObjectAsString = function getObjectAsString(obj) {
return wrap(Object.keys(obj).map(function (k) {
var v = _typeof(obj[k]) === 'object' && hasKeys(obj[k]) ? getObjectAsString(obj[k]) : obj[k];
return JSON.stringify(k) + ': ' + v;
}).join(','));
};
var getPropertiesAsObject = function getPropertiesAsObject(list$$1) {
var obj = {};
list$$1.forEach(function (prop) {
obj[prop.name] = safeScope(prop.value);
});
return getObjectAsString(obj);
};
var getProp = function getProp(node, key) {
var finder = typeof key === 'string' ? function (p) {
return p.name === key;
} : function (p) {
return key.test(p.name);
};
return node.properties && node.properties.find(finder);
};
var maybeSafe = function maybeSafe(node) {
return node.tags.code ? node.value : typeof node.value === 'string' ? safe(node.value) : node.value;
};
var getScopedProps = function getScopedProps(propNode, blockNode) {
var scopes = blockNode.scopes.filter(function (scope) {
return !scope.isSystem;
}).map(function (scope) {
var prop = scope.properties.find(function (prop) {
return prop.name === propNode.name;
});
return prop && { prop: prop, when: scope.value };
}).filter(Boolean).reverse();
if (isEmpty(scopes)) return false;
return scopes;
};
var getScopedCondition = function getScopedCondition(propNode, blockNode) {
var conditional = maybeSafe(propNode);
if (!getScopedProps(propNode, blockNode)) return false;
getScopedProps(propNode, blockNode).forEach(function (scope) {
conditional = scope.when + ' ? ' + maybeSafe(scope.prop) + ' : ' + conditional;
});
return conditional;
};
var getScopedImageCondition = function getScopedImageCondition(scopes, scopedNames, defaultName) {
var conditional = defaultName;
scopes.forEach(function (scope, index) {
conditional = scope.when + ' ? ' + scopedNames[index] + ' : ' + conditional;
});
return conditional;
};
var getScopedRequireCondition = function getScopedRequireCondition(scopes, paths, defaultName) {
var conditional = 'requireImage(\'' + defaultName + '\')';
scopes.forEach(function (scope, index) {
conditional = scope.when + ' ? requireImage(\'' + paths[index] + '\') : ' + conditional;
});
return conditional;
};
var styleStems = ['hover', 'focus', 'placeholder', 'disabled', 'print'];
var getStyleType = function getStyleType(node) {
return styleStems.find(function (tag) {
return isTag(node, tag);
}) || 'base';
};
var hasKeys = function hasKeys(obj) {
return Object.keys(obj).length > 0;
};
var hasKeysInChildren = function hasKeysInChildren(obj) {
return Object.keys(obj).some(function (k) {
return hasKeys(obj[k]);
});
};
var hasProp = function hasProp(node, key, match) {
var prop = getProp(node, key);
if (!prop) return false;
return typeof match === 'function' ? match(prop.value) : true;
};
var CODE_EXPLICIT = /^{.+}$/;
var isCodeExplicit = function isCodeExplicit(str) {
return CODE_EXPLICIT.test(str);
};
var isCode = function isCode(node) {
return typeof node === 'string' ? /props|item|index/.test(node) || isCodeExplicit(node) : isTag(node, 'code');
};
var isStyle = function isStyle(node) {
return isTag(node, 'style');
};
var isTag = function isTag(node, tag) {
return node.tags[tag];
};
var getActionableParent = function getActionableParent(node) {
if (!node.parent) return false;
if (node.parent.action) return node.parent;
return getActionableParent(node.parent);
};
var getAllowedStyleKeys = function getAllowedStyleKeys(node) {
if (node.isCapture) {
return ['base', 'focus', 'hover', 'disabled', 'placeholder', 'print'];
} else if (node.action || getActionableParent(node)) {
return ['base', 'focus', 'hover', 'disabled', 'print'];
}
return ['base', 'focus', 'print'];
};
var isList = function isList(node) {
return node && node.type === 'Block' && node.name === 'List';
};
var isEmpty = function isEmpty(list$$1) {
return list$$1.length === 0;
};
var isValidImgSrc = function isValidImgSrc(node, parent) {
return node.name === 'source' && parent.name === 'Image' && parent.isBasic;
};
var pushImageToState = function pushImageToState(state, scopedNames, paths) {
return scopedNames.forEach(function (name) {
var path$$1 = paths[scopedNames.findIndex(function (item) {
return item === name;
})];
if (!state.images.includes(path$$1)) {
state.images.push({
name: name,
file: path$$1
});
}
});
};
var getScopes = function getScopes(node, parent) {
var scopedProps = getScopedProps(node, parent);
if (!scopedProps) return false;
var paths = scopedProps.map(function (scope) {
return scope.prop.value;
});
var scopedNames = paths.map(function (path$$1) {
return toCamelCase(path$$1);
});
return { scopedProps: scopedProps, paths: paths, scopedNames: scopedNames };
};
var isSvg = function isSvg(node) {
return (/^Svg/.test(node.name) && node.isBasic
);
};
var getScopeDescription = function getScopeDescription(scope) {
var dictionary = {};
var re = /(?:^|\W)props.(\w+)(?!\w)/g;
var match = re.exec(scope);
while (match) {
dictionary[match[1]] = toSlugCase(match[1]);
match = re.exec(scope);
}
for (var key in dictionary) {
scope = scope.replace(new RegExp(key, 'g'), dictionary[key]);
}
return toCamelCase(scope.replace(/\|\|/g, '-or-').replace(/!/g, 'not-').replace(/&&/g, '-and-').replace(/props\./g, '').replace(/\s/g, ''));
};
var makeOnClickTracker = function makeOnClickTracker(node, state) {
var block = node.testId ? '"' + state.name + '.' + node.testId + '"' : 'props["' + state.testIdKey + '"] || "' + state.name + '"';
var track = 'context.track({ block: ' + block + ', action: "click" })';
state.isTracking = true;
return 'event => { ' + track + '; (' + node.value + ')(event); }';
};
var enter$1 = function enter(node, parent, state) {
if (node.name === 'Proxy') return;
var scopes = node.scopes.filter(function (scope) {
return !scope.isSystem;
}).map(function (scope) {
return scope.value;
}).filter(Boolean).reverse();
var conditional = scopes.reduce(function (prev, scope) {
return scope + ' ? \'' + getScopeDescription(scope) + '\' : ' + prev;
}, "''");
conditional = scopes.length > 0 ? '${' + conditional + '}' : '';
var value = void 0;
if (node.isBasic && parent) {
value = '{`' + state.name + '.' + node.testId + '|' + conditional + '`}';
} else if (node.isBasic) {
value = '{`${props[\'' + state.testIdKey + '\'] || \'' + node.testId + '\'}|' + conditional + '`}';
} else if (parent) {
value = '"' + state.name + '.' + node.testId + '"';
} else {
value = '{props["' + state.testIdKey + '"] || "' + node.testId + '"}';
}
state.render.push(' ' + state.testIdKey + '=' + value);
};
var typesMap = {
CaptureEmail: 'email',
CaptureText: 'text',
CaptureNumber: 'number',
CapturePhone: 'tel',
CaptureSecure: 'password'
};
var enter$2 = function enter(node, parent, state) {
var blockType = node.name;
if (!/Capture/.test(blockType)) return;
node.isCapture = true;
var name = toCamelCase(node.is || blockType);
state.captures.push(name);
if (typesMap[blockType]) {
state.render.push(' type=\'' + typesMap[blockType] + '\'');
}
// if you specify a value, then you're supposed to manage the input from
// outside the view
if (getProp(node, 'value')) return;
state.render.push(' onChange={event => this.setState({ ' + name + ': event.target.value })}');
state.render.push(' value={state.' + name + '}');
if (state.debug) {
state.render.push(' tabIndex={-1}');
}
};
function leave$1(node, parent, state) {
if (node.explicitChildren) {
state.render.push('>');
state.render.push(node.explicitChildren);
}
}
var enter$3 = function enter(node, parent, state) {
if (node.goTo) {
var goTo = getProp(node, 'goTo');
state.render.push(' href=' + safe(goTo.value, goTo) + ' rel=\'noopener noreferrer\' target=\'_blank\'');
}
};
function enter$4(node, parent, state) {
if (node.isGroup && node.children.length > 0) {
state.render.push('>');
}
}
function enter$5(node, parent, state) {
if (isList(parent)) {
state.render.push(' {...item} key={item.id || index}');
}
}
function enter$6(node, parent, state) {
if (isList(node)) {
var from = getProp(node, 'from');
if (!from) return;
state.render.push('{Array.isArray(' + from.value + ') && ' + from.value + '.map((item, index) => ');
}
}
function leave$2(node, parent, state) {
if (isList(node)) {
state.render.push(')}');
}
}
function leave$3(node, parent, state) {
if (!parent && node.isGroup || node.explicitChildren || node.isGroup && node.children.length > 0) {
if (!parent && node.isGroup) {
if (node.children.length === 0) {
state.render.push('>');
}
if (!node.usesProxy) {
state.render.push('{props.children}');
}
}
state.render.push('</' + node.nameFinal + '>');
} else {
state.render.push('/>');
}
}
var getBlockName = (function (node, parent, state) {
var name = node.name;
switch (node.name) {
case 'CaptureEmail':
case 'CaptureFile':
case 'CaptureNumber':
case 'CapturePhone':
case 'CaptureSecure':
case 'CaptureText':
name = 'input';
break;
case 'CaptureTextArea':
name = 'textarea';
break;
case 'Horizontal':
case 'Vertical':
name = getGroupBlockName(node, parent, state);
break;
case 'Image':
name = 'img';
break;
case 'Text':
return 'span';
case 'List':
name = 'div';
break;
case 'Proxy':
return null;
case 'Svg':
name = 'svg';
break;
case 'SvgGroup':
name = 'g';
break;
case 'SvgCircle':
case 'SvgEllipse':
case 'SvgLinearGradient':
case 'SvgRadialGradient':
case 'SvgLine':
case 'SvgText':
case 'SvgPath':
case 'SvgPolygon':
case 'SvgPolyline':
case 'SvgRect':
case 'SvgSymbol':
case 'SvgUse':
case 'SvgDefs':
case 'SvgStop':
name = toCamelCase(node.name.replace('Svg', ''));
break;
default:
break;
}
return name;
});
var getGroupBlockName = function getGroupBlockName(node, parent, state) {
var name = 'div';
if (hasProp(node, 'teleportTo')) {
name = 'Link';
node.teleport = true;
} else if (hasProp(node, 'goTo')) {
name = 'a';
node.goTo = true;
} else if (hasProp(node, 'onClick')) {
var propNode = getProp(node, 'onClick');
var prevParent = parent;
var canBeButton = true;
while (prevParent && canBeButton) {
if (prevParent.type === 'Block') {
canBeButton = !hasProp(prevParent, 'onClick');
}
prevParent = prevParent.parent;
}
if (canBeButton) {
name = 'button';
node.action = propNode.value;
}
} else if (hasProp(node, 'overflowY', function (v) {
return v === 'auto' || v === 'scroll';
})) {
name = 'div';
} else if (hasProp(node, 'onSubmit')) {
name = 'form';
}
return name;
};
function enter$7(node, parent, state) {
var name = getBlockName(node, parent, state);
if (name === null) return true;
node.nameFinal = name;
node.nameTag = name;
state.use(name);
if (node.isBasic) {
var hasDynamicStyles = node.properties.some(function (prop) {
return prop.tags.style && prop.tags.code;
});
var hasDynamicScopedStyles = node.scopes.some(function (scope) {
return scope.isSystem ? scope.properties.some(function (prop) {
return prop.tags.style && prop.tags.code;
}) : scope.properties.some(function (prop) {
return prop.tags.style;
});
});
// TODO expand to active, focus, etc
var hasHoverStem = node.scopes.some(function (scope) {
return scope.value === 'hover';
});
var hasMatchingParentWithHover = hasHoverStem && checkParentStem(node, 'hover');
node.isDynamic = hasDynamicStyles || hasDynamicScopedStyles || hasMatchingParentWithHover;
if (node.isDynamic) {
// we need to reset it to the block's name or value
var finalValue = node.is || node.name;
// count repeatead ones
if (state.usedBlockNames[finalValue]) {
finalValue = '' + finalValue + state.usedBlockNames[finalValue]++;
} else {
state.usedBlockNames[finalValue] = 1;
}
node.nameFinal = finalValue;
}
}
state.render.push('<' + node.nameFinal);
}
function enter$8(node, parent, state) {
// onWhen lets you show/hide blocks depending on props
var onWhen = getProp(node, 'onWhen');
if (onWhen) {
node.onWhen = true;
if (parent && !isList(parent)) state.render.push('{');
state.render.push(onWhen.value + ' ? ');
}
}
function leave$4(node, parent, state) {
if (node.onWhen) {
state.render.push(' : null');
if (parent && !isList(parent)) state.render.push('}');
}
}
function leave$5(node, parent, state) {
if (node.childrenProxyMap) {
state.render.push(' childrenProxyMap={' + getObjectAsString(node.childrenProxyMap) + '}');
}
}
var enter$10 = function enter(node, parent, state) {
node.className = ['views-block'];
var className = getProp(node, 'className');
if (className) {
node.className.push(className.tags.code ? '${' + className.value + '}' : className.value);
}
if (state.debug && node.isCapture) {
node.className.push('mousetrap');
}
};
var leave$6 = function leave(node, parent, state) {
if (node.className.length === 1) {
var className = node.className[0];
var shouldWrap = true;
if (isInterpolation(className)) {
className = deinterpolate(className);
} else if (!isCode(className)) {
className = '"' + className + '"';
shouldWrap = false;
}
state.render.push(' className=' + (shouldWrap ? wrap(className) : className));
} else if (node.className.length > 1) {
var _className = '`' + node.className.join(' ') + '`';
state.render.push(' className=' + wrap(_className));
}
};
function leave$7(node, parent, state) {
if (node.isRoute) {
state.render.push(' {...routeProps}');
}
}
function enter$11(node, parent, state) {
node.style = {
dynamic: {
base: {},
hover: {},
focus: {},
disabled: {},
placeholder: {},
print: {}
},
static: {
base: {},
hover: {},
focus: {},
disabled: {},
placeholder: {},
print: {}
}
// TODO use this directly in styles without having to go through this
};node.scopes.filter(function (scope) {
return scope.isSystem;
}).forEach(function (scope) {
scope.properties.forEach(function (propNode) {
if (propNode.name === 'when') return;
var _state$getStyleForPro = state.getStyleForProperty(propNode, node, isCode(propNode)),
_isProp = _state$getStyleForPro._isProp,
styleForProperty = objectWithoutProperties(_state$getStyleForPro, ['_isProp']);
if (_isProp) {
Object.keys(styleForProperty).forEach(function (k) {
return state.render.push(' ' + k + '=' + safe(styleForProperty[k], node));
});
} else {
var hasMatchingParent = parent && node.isDynamic ? checkParentStem(node, scope.value) : false;
var target = isCode(propNode) || hasMatchingParent ? node.style.dynamic : node.style.static;
Object.assign(target[scope.value], styleForProperty);
}
});
});
// ensure flex-direction in Horizontals
if (node.isGroup && node.name === 'Horizontal') {
node.style.static.base.flexDirection = 'row';
}
}
// https://raw.githubusercontent.com/threepointone/glam/master/src/hash.js
// murmurhash2 via https://gist.github.com/raycmorgan/588423
var hash = (function (arr) {
return 'h' + hash$1(arr);
});
function hash$1(arr) {
var str = (Array.isArray(arr) ? arr : Object.keys(arr).map(function (k) {
return k + ':' + JSON.stringify(arr[k]);
})).join(',');
return murmur2(str, str.length).toString(36);
}
function murmur2(str, seed) {
var m = 0x5bd1e995;
var r = 24;
var h = seed ^ str.length;
var length = str.length;
var currentIndex = 0;
while (length >= 4) {
var k = UInt32(str, currentIndex);
k = Umul32(k, m);
k ^= k >>> r;
k = Umul32(k, m);
h = Umul32(h, m);
h ^= k;
currentIndex += 4;
length -= 4;
}
switch (length) {
case 3:
h ^= UInt16(str, currentIndex);
h ^= str.charCodeAt(currentIndex + 2) << 16;
h = Umul32(h, m);
break;
case 2:
h ^= UInt16(str, currentIndex);
h = Umul32(h, m);
break;
case 1:
h ^= str.charCodeAt(currentIndex);
h = Umul32(h, m);
break;
}
h ^= h >>> 13;
h = Umul32(h, m);
h ^= h >>> 15;
return h >>> 0;
}
function UInt32(str, pos) {
return str.charCodeAt(pos++) + (str.charCodeAt(pos++) << 8) + (str.charCodeAt(pos++) << 16) + (str.charCodeAt(pos) << 24);
}
function UInt16(str, pos) {
return str.charCodeAt(pos++) + (str.charCodeAt(pos++) << 8);
}
function Umul32(n, m) {
n = n | 0;
m = m | 0;
var nlo = n & 0xffff;
var nhi = n >>> 16;
var res = nlo * m + ((nhi * m & 0xffff) << 16) | 0;
return res;
}
function leave$8(node, parent, state) {
var _node$style = node.style,
dynamic = _node$style.dynamic,
staticStyle = _node$style.static;
var allowedStyleKeys = getAllowedStyleKeys(node);
var scopedUnderParent = !node.isCapture && !node.action && getActionableParent(node);
if (scopedUnderParent) {
scopedUnderParent = scopedUnderParent.styleName;
}
// dynamic merges static styles
if (hasKeysInChildren(dynamic)) {
state.cssDynamic = true;
node.styleName = node.nameFinal;
var cssStatic = Object.keys(staticStyle).filter(function (key) {
return allowedStyleKeys.includes(key) && hasKeys(staticStyle[key]);
}).map(function (key) {
return asCss(asStaticCss(staticStyle[key], Object.keys(dynamic[key])), key, scopedUnderParent).join('\n');
}).join(',\n');
var cssDynamic = ['({ props }) => ({'];
cssDynamic = cssDynamic.concat(Object.keys(dynamic).filter(function (key) {
return allowedStyleKeys.includes(key) && hasKeys(dynamic[key]);
}).map(function (key) {
return asCss(asDynamicCss(dynamic[key]), key, scopedUnderParent).join('\n');
}).join(',\n'));
cssDynamic.push('})');
cssDynamic = cssDynamic.join('\n');
if (cssStatic || cssDynamic) {
state.styles[node.nameFinal] = 'const ' + node.nameFinal + ' = styled(\'' + node.nameTag + '\')(' + (cssStatic ? '{' + cssStatic + '}, ' : '') + cssDynamic + ')';
// TODO we may want to be smarter here and only pass what's needed
state.render.push(' props={props}');
}
} else if (hasKeysInChildren(staticStyle)) {
state.cssStatic = true;
var id = (node.is || node.name) + '_' + hash(staticStyle);
node.styleName = id;
node.className.push('${' + id + '}');
var css = Object.keys(staticStyle).filter(function (key) {
return allowedStyleKeys.includes(key) && hasKeys(staticStyle[key]);
}).map(function (key) {
return asCss(asStaticCss(staticStyle[key]), key, scopedUnderParent).join('\n');
}).join(',\n');
if (css) {
state.styles[id] = 'const ' + id + ' = css({' + css + '})';
}
}
}
var asDynamicCss = function asDynamicCss(styles) {
return Object.keys(styles).map(function (prop) {
return prop + ': ' + styles[prop];
});
};
var safe$1 = function safe(str) {
return typeof str === 'string' ? '"' + str.replace(/"/g, "'") + '"' : str;
};
var asStaticCss = function asStaticCss(styles) {
var dynamicStyles = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
return Object.keys(styles).filter(function (prop) {
return !dynamicStyles.includes(prop);
}).map(function (prop) {
return prop + ': ' + safe$1(styles[prop]);
});
};
var asCss = function asCss(styles, key, scopedUnderParent) {
var css = [];
if (key !== 'base') {
if (scopedUnderParent) {
var parent = '${' + scopedUnderParent + '}';
if (/_/.test(scopedUnderParent)) {
parent = '.' + parent;
}
css.push('[`' + parent + ':' + key + ' &, ' + parent + '.' + key + ' &`]: {');
} else if (key === 'hover' || key === 'disabled' || key === 'focus' || key === 'placeholder') {
css.push('"&:' + key + ', &.' + key + '": {');
} else if (key === 'print') {
// TODO can we use this to support all media queries?
css.push('"@media print": {');
}
}
css.push(styles.join(',\n'));
if (key !== 'base') css.push('}');
return css;
};
function enter$12(node, parent, state) {
if (node.name === 'ref') {
state.render.push(' ' + (parent.isDynamic ? 'innerRef' : 'ref') + '=' + wrap(node.value));
return true;
}
}
function enter$13(node, parent, state) {
var value = state.getValueForProperty(node, parent, state);
if (value) {
Object.keys(value).forEach(function (k) {
return state.render.push(" " + k + "=" + value[k]);
});
}
}
function enter$14(node, parent, state) {
if (!isStyle(node) || !parent.isBasic || isSvg(parent) && state.isReactNative || parent.name === 'SvgGroup') return;
var styleForProperty = void 0,
isScopedVal = void 0,
_isProp = void 0;
var code = isCode(node);
// TODO refactor
if (getScopedCondition(node, parent)) {
isScopedVal = true;
styleForProperty = defineProperty({}, node.name, getScopedCondition(node, parent));
} else {
var _state$getStyleForPro = state.getStyleForProperty(node, parent, code);
_isProp = _state$getStyleForPro._isProp;
styleForProperty = objectWithoutProperties(_state$getStyleForPro, ['_isProp']);
}
if (_isProp) {
Object.keys(styleForProperty).forEach(function (k) {
return state.render.push(' ' + k + '=' + safe(styleForProperty[k], node));
});
} else {
var hasMatchingParent = parent && node.isDynamic ? checkParentStem(node, getStyleType(node)) : false;
var target = code || isScopedVal || hasMatchingParent ? parent.style.dynamic : parent.style.static;
Object.assign(target[getStyleType(node)], styleForProperty);
}
return true;
}
function enter$15(node, parent, state) {
if (node.name === 'text' && parent.name === 'Text') {
if (getScopedCondition(node, parent)) {
parent.explicitChildren = wrap(getScopedCondition(node, parent));
} else {
parent.explicitChildren = isCode(node) ? wrap(node.value) : node.value;
}
return true;
}
}
var blacklist = ['classname', 'teleportto', 'goto'];
var blacklistDebug = ['autofocus', 'tabindex'];
var isValidPropertyForBlock = (function (node, parent, state) {
var name = node.name.toLowerCase();
return !(blacklist.includes(name) || state.debug && blacklistDebug.includes(name));
});
// import { hasDefaultProp } from '../utils.js'
function enter$9(node, parent, state) {
enter$11(node, parent, state);
enter$10(node, parent, state);
node.properties.forEach(function (propNode) {
if (propNode.name === 'at' || propNode.name === 'when' || propNode.name === 'onWhen' || propNode.name === 'ref' && state.debug || !isValidPropertyForBlock(propNode, node, state) && node.isBasic || propNode.name === 'from' && node.name === 'List') return;
!enter$12(propNode, node, state) && !enter$14(propNode, node, state) && !enter$15(propNode, node, state) && enter$13(propNode, node, state);
});
leave$8(node, parent, state);
leave$7(node, parent, state);
leave$5(node, parent, state);
leave$6(node, parent, state);
}
function enter$16(node, parent, state) {
if (node.name !== 'Proxy') return;
var prevParent = parent;
while (prevParent) {
if (prevParent.type === 'Block' && !prevParent.parent) {
prevParent.usesProxy = true;
}
prevParent = prevParent.parent;
}
var proxied = node.properties.find(function (p) {
return p.name === 'from';
});
if (!proxied) return;
proxied = proxied.value;
var otherProperties = node.properties.filter(function (p) {
return p.name !== 'from' && p.name !== 'onWhen' && p.name !== 'when';
});
if (!node.onWhen) {
state.render.push('{');
}
if (proxied === 'all') {
var childContent = otherProperties.length > 0 ? 'React.Children.map(props.children, child => React.cloneElement(child, ' + getPropertiesAsObject(otherProperties) + '))' : 'props.children';
state.render.push(childContent);
} else {
if (!node.onWhen) {
state.render.push('props.childrenProxyMap && ');
}
var child = 'childrenArray[props.childrenProxyMap[\'' + proxied + '\']]';
if (otherProperties.length > 0) {
if (node.onWhen) {
if (state.render[state.render.length - 1].endsWith(' ? ')) {
state.render[state.render.length - 1] = state.render[state.render.length - 1].replace(' ? ', ' && ');
}
}
state.render.push(' ' + child + ' ? React.cloneElement(' + child + ', ' + getPropertiesAsObject(otherProperties) + ') : null');
} else {
state.render.push(child);
}
state.usesChildrenArray = true;
}
state.render.push('}');
// skip next
return true;
}
function enter$17(node, parent, state) {
var at = getProp(node, 'at');
if (at) {
var _at$value$split = at.value.split(' '),
_at$value$split2 = slicedToArray(_at$value$split, 2),
path$$1 = _at$value$split2[0],
_at$value$split2$ = _at$value$split2[1],
isExact = _at$value$split2$ === undefined ? false : _at$value$split2$;
state.use('Route');
if (path$$1 === '/') state.use('Router');
if (!path$$1.startsWith('/')) {
path$$1 = isCode(path$$1) ? '`${' + path$$1 + '}`' : path$$1;
// path = `\`\${props.match.url}/${to}\``
}
node.isRoute = true;
state.render.push('<Route path=' + safe(path$$1) + ' ' + (isExact ? 'exact' : '') + ' render={routeProps => ');
}
}
function leave$9(node, parent, state) {
if (node.isRoute) {
state.render.push('} />');
}
}
var enter$18 = function enter(node, parent, state) {
if (node.name === 'Proxy') return;
var blockName = node.is || node.name;
if (typeof state.testIds[blockName] === 'number') {
state.testIds[blockName]++;
blockName = blockName + ':' + state.testIds[blockName];
} else {
state.testIds[blockName] = 0;
}
node.testId = blockName;
};
var enter$19 = function enter(node, parent, state) {
if (node.teleport) {
var to = getProp(node, 'teleportTo').value;
if (to.startsWith('/') || to === '..') {
to = safe(to);
} else {
to = isCode(to) ? '${' + to + '}' : to;
to = '{`${props.match.url === \'/\' ? \'\' : props.match.url}/' + to + '`}';
state.withRouter = true;
}
state.render.push(' to=' + to);
}
};
var enter = [enter$18, enter$8, enter$16, enter$17, enter$7, enter$2, enter$19, enter$3, enter$5, enter$1, enter$9, enter$4, enter$6];
var leave = [leave$2, leave$1, leave$3, leave$9, leave$4];
var visitor = Object.freeze({
enter: enter,
leave: leave
});
var getWeights = function getWeights(variants) {
return variants.filter(function (v) {
return !v.includes('italic');
}).map(function (v) {
return v === 'regular' ? 400 : v;
});
};
var all = list.map(function (font) {
return {
category: font.category,
value: font.family,
weights: getWeights(font.variants)
};
});
var byName = {};
all.forEach(function (f) {
return byName[f.value] = f;
});
var fontFamily = all.map(function (f) {
return f.value;
});
var isGoogleFont = function isGoogleFont(family) {
return !!byName[family];
};
var maybeAddFallbackFont = function maybeAddFallbackFont(f) {
var font = byName[f];
return font && font.category ? f + ', ' + font.category : f;
};
var getStyleForProperty = (function (node, parent, code) {
switch (node.name) {
case 'appRegion':
return {
WebkitAppRegion: node.value
};
case 'backgroundImage':
return {
backgroundImage: code ? '`url(${' + node.value + '})`' : 'url("' + node.value + '")'
};
case 'fontFamily':
return {
fontFamily: code ? node.value : maybeAddFallbackFont(node.value)
};
case 'userSelect':
return {
WebkitUserSelect: node.value
};
case 'zIndex':
return {
zIndex: code ? node.value : parseInt(node.value, 10)
};
default:
return defineProperty({}, node.name, node.value);
}
});
var getStyles = (function (_ref) {
var styles = _ref.styles;
return '\n' + Object.keys(styles).map(function (k) {
return styles[k];
}).join('\n');
});
var isUrl = function isUrl(str) {
return (/^https?:\/\//.test(str)
);
};
var getImageSource = function getImageSource(node, state, parent) {
var scopes = getScopes(node, parent);
if (scopes && (isUrl(node.value) || node.tags.code)) {
return wrap(getScopedCondition(node, parent));
} else if (isUrl(node.value) || node.tags.code) {
return safe(node.value);
} else {
if (scopes && state.debug) {
return wrap(getScopedRequireCondition(scopes.scopedProps, scopes.paths, node.value));
} else if (state.debug) {
return '{requireImage("' + node.value + '")}';
} else {
if (scopes) {
pushImageToState(state, scopes.scopedNames, scopes.paths);
}
var name = toCamelCase(node.value);
if (!state.images.includes(node.value)) {
state.images.push({
name: name,
file: node.value
});
}
return scopes ? wrap(getScopedImageCondition(scopes.scopedProps, scopes.scopedNames, name)) : '{' + name + '}';
}
}
};
var getValueForProperty = (function (node, parent, state) {
if (isValidImgSrc(node, parent)) {
return {
src: getImageSource(node, state, parent)
};
} else if (parent.isBasic && node.name === 'isDisabled') {
return {
disabled: safe(node.value, node)
};
} else if (getScopedCondition(node, parent)) {
return defineProperty({}, node.name, safe(getScopedCondition(node, parent)));
} else if (parent.isBasic && node.name === 'onClick' && state.track && !state.debug) {
return {
onClick: wrap(makeOnClickTracker(node, state))
};
} else {
return defineProperty({}, node.name, safe(node.value, node));
}
});
var maybeUsesRouter = (function (state) {
if (state.uses.includes('Router')) {
state.render = ['<Router>'].concat(toConsumableArray(state.render), ['</Router>']);
}
});
var BASIC = /^(CaptureEmail|CaptureFile|CaptureNumber|CapturePhone|CaptureSecure|CaptureText|CaptureTextArea|G|Horizontal|Image|List|Svg|SvgCircle|SvgEllipse|SvgDefs|SvgGroup|SvgLinearGradient|SvgRadialGradient|SvgLine|SvgPath|SvgPolygon|SvgPolyline|SvgRect|SvgSymbol|SvgText|SvgUse|SvgStop|Text|Vertical|FakeProps)$/i;
var BLOCK = /^([A-Z][a-zA-Z0-9]*)(\s+([A-Z][a-zA-Z0-9]*))?$/;
var BOOL = /^(false|true)$/i;
var CAPTURE = /^(CaptureEmail|CaptureFile|CaptureNumber|CapturePhone|CaptureSecure|CaptureText|CaptureTextArea)$/i;
var CODE_EXPLICIT$1 = /^{.+}$/;
var CODE_IMPLICIT = /props\./;
var CODE_DEFAULT = /^props$/;
var COMMENT = /^#(.+)$/;
var INTERPOLATED_EXPRESSION = /\${.+}/;
var FLOAT = /^[0-9]+\.[0-9]+$/;
var FONTABLE = /^(CaptureEmail|CaptureNumber|CapturePhone|CaptureSecure|CaptureText|CaptureTextArea|Text)$/;
var INT = /^[0-9]+$/;
var NOT_GROUP = /^(Image|FakeProps|Text|Proxy|SvgCircle|SvgEllipse|SvgLine|SvgPath|SvgPolygon|SvgPolyline|SvgRect|SvgText|SvgStop)$/i;
var PROP = /^([a-z][a-zA-Z0-9]*)(\s+(.+))?$/;
var STYLE = new RegExp('^(' + cssProperties.map(toCamelCase).join('|') + '|pointerEvents|clipPath|appRegion|userSelect|hyphens|overflowWrap)$');
var TEMPLATE_LITERAL = /^`.+`$/;
var TRUE = /^true$/i;
var USER_COMMENT = /^##(.*)$/;
var is = function is(thing, line) {
return thing.test(line);
};
var isBasic = function isBasic(line) {
return is(BASIC, line);
};
var isBlock = function isBlock(line) {
return is(BLOCK, line);
};
var isBool = function isBool(line) {
return is(BOOL, line);
};
var isCapture = function isCapture(line) {
return is(CAPTURE, line);
};
var isCode$1 = function isCode(line) {
return is(CODE_EXPLICIT$1, line) || is(CODE_IMPLICIT, line) || isCodeDefault(line);
};
var isCodeDefault = function isCodeDefault(line) {
return is(CODE_DEFAULT, line);
};
// TODO
var isCodeInvalid = function isCodeInvalid(line) {
return getCodeData(line).find(function (l) {
return (/\. /.test(l) || // props. x
/ \./.test(l) || // props .
/ \[/.test(l) || // props[
/\]/.test(l)
);
} // props]
);
};
var isComment = function isComment(line) {
return is(COMMENT, line);
};
var isEmptyText = function isEmptyText(line) {
return line === '';
};
var isEnd = function isEnd(line) {
return line === '';
};
var isInterpolatedExpression = function isInterpolatedExpression(line) {
return is(INTERPOLATED_EXPRESSION, line);
};
var isFloat = function isFloat(line) {
return is(FLOAT, line);
};
var isFontable = function isFontable(line) {
return is(FONTABLE, line);
};
var isGroup = function isGroup(line) {
return !is(NOT_GROUP, line) && !isCapture(line);
};
var isList$1 = function isList(line) {
return line === 'List';
};
var isInt = function isInt(line) {
return is(INT, line);
};
var isProp = function isProp(line) {
return is(PROP, line);
};
var isTemplateLiteral = function isTemplateLiteral(line) {
return is(TEMPLATE_LITERAL, line);
};
var isStyle$1 = function isStyle(line) {
return is(STYLE, line);
};
var isTrue = function isTrue(line) {
return is(TRUE, line);
};
var isUserComment = function isUserComment(line) {
return is(USER_COMMENT, line);
};
var get$1 = function get$$1(regex, line) {
return line.match(regex);
};
var getBlock = function getBlock(line) {
// eslint-disable-next-line
var _get = get$1(BLOCK, line),
_get2 = slicedToArray(_get, 4),
_ = _get2[0],
is = _get2[1],
_1 = _get2[2],
block = _get2[3];
return {
block: block || is,
is: block ? is : null
};
};
var getCodeData = function getCodeData(line) {
return line.replace(/^{/, '').replace(/}$/, '').split(' ').filter(function (l) {
return (/[.[]/.test(l)
);
});
};
var getComment = function getComment(line) {
try {
return get$1(COMMENT, line).slice(1);
} catch (err) {
return '';
}
};
var getMainFont = function getMainFont(line) {
return line ? line.split(',')[0].replace(/['"]/g, '') : '';
};
var getProp$1 = function getProp(line) {
// eslint-disable-next-line
var _get3 = get$1(PROP, line),
_get4 = slicedToArray(_get3, 4),
_ = _get4[0],
prop = _get4[1],
_1 = _get4[2],
_get4$ = _get4[3],
value = _get4$ === undefined ? '' : _get4$;
if (isCodeDefault(value)) {
value = 'props.' + prop;
}
return [prop, value];
};
var getValue = function getValue(value) {
if (isFloat(value)) {
return parseFloat(value, 10);
} else if (isInt(value)) {
return parseInt(value, 10);
} else if (isEmptyText(value)) {
return '';
} else if (isBool(value)) {
return isTrue(value);
} else if (isInterpolatedExpression(value)) {
return fixBackticks(value);
} else {
return value;
}
};
var fixBackticks = function fixBackticks(value) {
return isTemplateLiteral(value) ? value : '`' + value + '`';
};
var warn = function warn(message, block) {
if (!Array.isArray(block.warnings)) {
block.warnings = [];
}
block.warnings.push(message);
};
var SYSTEM_SCOPES = ['active',
// TODO disabled should be a prop instead I think
'disabled', 'focus', 'hover', 'placeholder', 'print'];
var isSystemScope = function isSystemScope(name) {
return SYSTEM_SCOPES.includes(name);
};
var getLoc = (function (line, scolumn, ecolumn) {
return {
start: {
line: line,
column: scolumn
},
end: {
line: line,
column: ecolumn
}
};
});
var getMeta = (function (value, line, startLine) {
if (!isCode$1(value)) return [];
return getCodeData(value).map(function (value) {
return {
tag: 'code',
value: value
};
});
});
var isNumber = {
width: true,
maxWidth: true,
minWidth: true,
height: true,
maxHeight: true,
minHeight: true,
margin: true,
marginBottom: true,
marginLeft: true,
marginRight: true,
marginTop: true,
padding: true,
paddingBottom: true,
paddingLeft: true,
paddingRight: true,
paddingTop: true,
bottom: true,
left: true,
right: true,
top: true,
outline: true,
opacity: true,
zIndex: true,
scale: true,
translateX: true,
translateY: true,
borderBottomLeftRadius: true,
borderBottomRightRadius: true,
borderBottomWidth: true,
borderLeftWidth: true,
borderRadius: true,
borderRightWidth: true,
borderTopLeftRadius: true,
borderTopRightRadius: true,
borderTopWidth: true,
borderWidth: true,
fontSize: true,
fontWeight: true,
letterSpacing: true,
lineHeight: true,
wordSpacing: true
};
var isActionable = function isActionable(item) {
return (
// (item.type === 'Horizontal' ||
// item.type === 'Vertical' ||
// /^Capture/.test(item.type)) &&
item.name !== 'onWhen' && /^on[A-Z]/.test(item.name)
);
};
var extractPropsAndItems = function extractPropsAndItems(item) {
var props = [];
var regex = /(props|item)\.([a-zA-Z][a-zA-Z0-9.]*[a-zA-Z0-9]+)(.)?/g;
var matches = regex.exec(item.value);
while (matches !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (matches.index === regex.lastIndex) {
regex.lastIndex++;
}
var isExplicitFunctionCall = matches[3] === '(';
props.push({
isItem: matches[1] === 'item',
path: matches[2],
type: isActionable(item) || isExplicitFunctionCall ? 'function' : isNumber[item.name] ? 'number' : 'string'
});
matches = regex.exec(item.value);
}
return props;
};
var isList$2 = function isList(item) {
return item.type === 'List';
};
var isListFrom = function isListFrom(item) {
return item.name === 'from' && isList$2(item);
};
var getPropTypes = (function (list$$1) {
var flatProps = {};
var listFromPath = void 0;
list$$1.forEach(function (item, index) {
extractPropsAndItems(item).forEach(function (propOrItem) {
if (isListFrom(item)) {
// store the list prop path for later
listFromPath = propOrItem.path;
} else if (isList$2(item) && propOrItem.path.endsWith('.length')) {
// skip array length checks in list
return;
}
if (propOrItem.isItem) {
// if we didn't find a list, don't include item props
if (!listFromPath) return;
propOrItem.path = listFromPath + '.' + propOrItem.path;
}
flatProps[propOrItem.path] = propOrItem;
});
});
var props = {};
Object.keys(flatProps).sort().forEach(function (key) {
var prop = flatProps[key];
if (key.includes('.')) {
var _key$split = key.split('.'),
_key$split2 = toArray(_key$split),
main = _key$split2[0],
rest = _key$split2.slice(1);
var ref = props[main];
if (!ref || typeof ref === 'string') {
ref = props[main] = {
type: prop.isItem ? 'array' : 'object',
shape: {}
};
}
// TODO support any nesting
rest.forEach(function (part) {
ref.shape[part] = prop.type;
});
} else {
props[key] = prop.type;
}
});
return props;
});
var getTags = (function (prop, value) {
var tags = {};
if (isCode$1(value)) tags.code = isCodeInvalid(value) ? 'invalid' : true;
if (isStyle$1(prop)) tags.style = true;
return tags;
});
var parse = (function (rtext) {
var skipComments = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
// convert crlf to lf
var text = rtext.replace(/\r\n/g, '\n');
var fonts = [];
var lines = text.split('\n').map(function (line) {
return line.trim();
});
var props = [];
var stack = [];
var views = [];
var lastCapture = void 0;
var getChildrenProxyMap = function getChildrenProxyMap(block) {
var childrenProxyMap = {};
block.children.forEach(function (child, i) {
var maybeName = child.is || child.name;
var name = maybeName;
var next = 1;
while (name in childrenProxyMap) {
name = '' + maybeName + next;
next++;
}
childrenProxyMap[name] = i;
});
return Object.keys(childrenProxyMap).length === 0 ? null : childrenProxyMap;
};
var lookForFonts = function lookForFonts(block) {
if (block.properties && (isFontable(block.name) || !block.isBasic)) {
var fontFamilyProp = block.properties.find(function (p) {
return p.name === 'fontFamily';
});
if (fontFamilyProp) {
var fontFamily = getMainFont(fontFamilyProp.value);
var fontWeightProp = block.properties.find(function (p) {
return p.name === 'fontWeight';
});
var fontStyleProp = block.properties.find(function (p) {
return p.name === 'fontStyle';
});
var fontWeight = fontWeightProp ? fontWeightProp.value.toString() : '400';
var fontStyle = fontStyleProp ? fontStyleProp.value.toString() : 'normal';
if (!fonts.find(function (font) {
return font.family === fontFamily && font.weight === fontWeight && font.style === fontStyle;
})) {
fonts.push({
id: fontFamily + '-' + fontWeight + (fontStyle === 'italic' ? '-italic' : ''),
family: fontFamily,
weight: fontWeight,
style: fontStyle
});
}
}
}
};
var end = function end(block, endLine) {
block.loc.end = {
line: endLine,
column: Math.max(0, lines[endLine].length - 1)
};
if (block.isGroup && !block.isBasic) {
block.childrenProxyMap = getChildrenProxyMap(block);
}
if (!block.properties) {
block.properties = [];
}
if (stack.length === 0) {
// if we're the last block on the stack, then this is the view!
views.push(block);
return true;
}
return false;
};
var parseBlock = function parseBlock(line, i) {
var _getBlock = getBlock(line),
name = _getBlock.block,
is$$1 = _getBlock.is;
var shouldPushToStack = false;
var block = {
type: 'Block',
name: name,
isBasic: isBasic(name),
isGroup: false,
loc: getLoc(i, 0),
properties: [],
scopes: []
};
if (is$$1) {
block.is = is$$1;
if (isCapture(name)) {
if (lastCapture) {
lastCapture.captureNext = is$$1;
}
lastCapture = block;
}
}
var last = stack[stack.length - 1];
if (last) {
if (last.isGroup) {
if (last.isList) {
if (block.isBasic) {
warn('A basic block can\'t be inside a List.\nPut 1 empty line before', block);
shouldPushToStack = true;
} else if (last.children.length > 0) {
warn('A List can only have one view inside. This block is outside of it.\nPut 1 empty line before.', block);
shouldPushToStack = true;
} else {
last.children.push(block);
}
} else {
last.children.push(block);
}
} else {
// the block is inside a block that isn't a group
end(stack.pop(), i);
if (views[0].isGroup) {
warn(lines[i - 1] === '' ? 'put 1 empty line before' : 'put 2 empty lines before', block);
} else {
warn('add Vertical at the top', block);
}
shouldPushToStack = true;
}
} else if (views.length > 0) {
// the block is outside the top level block
var newLinesBeforePreviousBlock = 1;
while (isEnd(lines[i - newLinesBeforePreviousBlock])) {
newLinesBeforePreviousBlock++;
}
var help = [];
if (!views[0].isGroup) {
help.push('add Vertical at the top');
}
if (newLinesBeforePreviousBlock > 2) {
var linesToRemove = newLinesBeforePreviousBlock - 2;
help.push('remove ' + linesToRemove + ' empty line' + (linesToRemove > 1 ? 's' : '') + ' before');
}
warn(help.join(', '), block);
}
if (isGroup(name)) {
block.isGroup = true;
block.isList = isList$1(name);
block.children = [];
shouldPushToStack = true;
}
if (shouldPushToStack || stack.length === 0) {
stack.push(block);
}
parseProps(i, block);
lookForFonts(block);
};
var parseProps = function parseProps(i, block) {
var endOfBlockIndex = i;
while (endOfBlockIndex < lines.length - 1 && !isBlock(lines[endOfBlockIndex + 1])) {
endOfBlockIndex++;
}
var properties = [];
var scopes = [];
var scope = void 0;
var inScope = false;
for (var j = i; j <= endOfBlockIndex; j++) {
var line = lines[j];
var propNode = null;
if (isProp(line)) {
var _getProp = getProp$1(line),
_getProp2 = slicedToArray(_getProp, 2),
name = _getProp2[0],
value = _getProp2[1];
var tags = getTags(name, value);
if (tags.code) {
props.push({ type: block.name, name: name, value: value });
}
if (tags.style && tags.code) {
block.maybeAnimated = true;
}
if (name === 'when') {
tags.scope = value;
inScope = value;
scope = { isSystem: isSystemScope(value), value: value, properties: [] };
scopes.push(scope);
}
propNode = {
type: 'Property',
loc: getLoc(j, line.indexOf(name), line.length - 1),
name: name,
tags: tags,
meta: getMeta(value, line, j),
value: getValue(value)
};
} else if (isComment(line) && !skipComments) {
var _getComment = getComment(line),
_getComment2 = slicedToArray(_getComment, 1),
_value = _getComment2[0];
var userComment = isUserComment(line);
if (userComment) {
_value = getComment(_value);
}
propNode = {
type: 'Property',
loc: getLoc(j, 0, line.length - 1),
value: _value