UNPKG

views-morph

Version:
1,873 lines (1,518 loc) 82.3 kB
'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