Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
ca9e033
Add AST checkbox in options and set state in url
sujinleeme Aug 27, 2018
d2dad33
Updates to old posts (#1758)
hzoo Aug 23, 2018
74f64d9
fix headings
hzoo Aug 23, 2018
59d8ffc
Fix some broken links (#1752)
notlmn Aug 24, 2018
732c99e
rename 6.x to 6.26.3 (#1759) [skip ci]
hzoo Aug 24, 2018
6122e99
Remove outdated reference to Makefile from readme (#1761) [skip ci]
suchipi Aug 24, 2018
7aa44ae
Upgrade prettier (#1760)
suchipi Aug 24, 2018
8fb71e6
Hide docs version on repl page (#1762)
suchipi Aug 24, 2018
673e1ba
[email protected] (#1765)
existentialism Aug 24, 2018
0bcd398
add browserslist config
existentialism Aug 24, 2018
e3a0160
Update v7-migration.md
hzoo Aug 24, 2018
565f2f6
Rewrite env docs (#1766)
existentialism Aug 24, 2018
0397c4f
match css custom class names to hljs class names
vikr01 Aug 25, 2018
d297059
Change package titles to be scoped (#1770)
notlmn Aug 25, 2018
f176b63
add css style for JSX
vikr01 Aug 26, 2018
924a505
Add AST Panel in Repl
ianchobuilds Aug 27, 2018
dfbd537
Complie AST ouput and add astContexxt in Relp's state
sujinleeme Aug 27, 2018
5d36491
Merge branch 'AST_worker' into AST
sujinleeme Aug 27, 2018
6feafb1
Persist AST context state when its compiled
sujinleeme Aug 27, 2018
f780507
Use decodeURI() instead of deprecated unescape()
sujinleeme Aug 29, 2018
8750cf8
Remove duplicate compiled AST variable
sujinleeme Aug 29, 2018
6cd3d4c
Collapse most nodes and fix scroll
ianchobuilds Aug 29, 2018
543e4e1
Sync upstream repo
Oct 4, 2018
7c18a63
Sync upstream repo
sujinleeme Oct 4, 2018
ed92794
wip
sujinleeme Oct 4, 2018
7df9280
Install react-json-view
sujinleeme Oct 4, 2018
0380002
Create ASTPanel component
sujinleeme Oct 4, 2018
1593578
Create flatten, unflatten funcs to control AST source
sujinleeme Oct 5, 2018
262c531
Create deleteFlatten, mergeFlatten funcs
sujinleeme Oct 5, 2018
c975379
Trigger show/hide type keys in AST ouput object
sujinleeme Oct 5, 2018
2d8aba1
code review by @benevbright
sujinleeme Oct 6, 2018
5f4ac6c
fix popup error msg while ast code is compiling
sujinleeme Oct 6, 2018
3c6e1a6
filter location, null value in AST options
sujinleeme Oct 6, 2018
5f236b6
if-else shorthand in getDerivedStateFromProps
sujinleeme Oct 8, 2018
e0ee4c8
Add default in triggerAstOutput func
sujinleeme Oct 9, 2018
02d8e83
Update ASTOption and ASTpanel styling
sujinleeme Dec 31, 2018
d534988
Update ReactJson styling
sujinleeme Dec 31, 2018
c5f8d84
Sync upstream repo
sujinleeme Jan 1, 2019
8256bd0
remove _fromTemplate, _letDone props in AST
sujinleeme Jan 17, 2019
03067db
Merge branch 'master' into AST
sujinleeme Jan 17, 2019
1d08d6d
Fix conflict on yarn.lock
sujinleeme Jan 17, 2019
0828e25
Update yarn.lock
sujinleeme Jan 17, 2019
00da94b
Remove '_' props in AST
sujinleeme Jan 18, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 192 additions & 0 deletions js/repl/ASTPanel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// @flow

import { css } from "emotion";
import { colors } from "./styles";
import React from "react";
import ReactJson from "react-json-view";
import {
flatten,
filterFlatten,
unflatten,
deleteFlatten,
mergeFlatten,
reject,
} from "./ASTUtils";

type Props = {
className?: string,
src: Object,
};

type State = {
src: Object,
flattenEmpty: Object,
flattenSrc: Object,
flattenType: Object,
flattenLocation: Object,
astOption: {
location: boolean,
empty: boolean,
type: boolean,
},
};

const OPTION_ORDER = ["location", "empty", "type"];

export default class ASTPanel extends React.Component<Props, State> {
state = {
src: {},
flattenEmpty: {},
flattenSrc: {},
flattenType: {},
flattenLocation: {},
astOption: {
autofocus: true,
location: true,
empty: true,
type: true,
},
};

static getDerivedStateFromProps(nextProps: Props, prevState: State) {
if (nextProps.src && nextProps.src !== prevState.src) {
let flattenSrc = flatten(nextProps.src);
flattenSrc = reject(flattenSrc, "_");
const src = unflatten(flattenSrc);

return {
src: src,
Copy link
Member

@danez danez Feb 9, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the input is changed (props.src) the options here are ignored. So I disabled location but as soon as I change the input the locations are back. I have to enable and then disable the locations option again to remove locations.

flattenSrc: flattenSrc,
flattenType: filterFlatten(flattenSrc, "type"),
flattenLocation: {
...filterFlatten(flattenSrc, "start"),
...filterFlatten(flattenSrc, "end"),
},
flattenEmpty: filterFlatten(flattenSrc, null, "null"),
};
}
}

_onOptionSettingCheck(option: string) {
this.setState(prevState => ({
astOption: {
...prevState.astOption,
[option]: !prevState.astOption[option],
},
}));
this._onChangeJson(option);
}

_onChangeJson(option: string) {
const {
astOption,
flattenEmpty,
flattenSrc,
flattenType,
flattenLocation,
} = this.state;

function triggerAstOutput(type) {
const isShow = astOption[type];
let newSrc = {};
const types = {
empty: () => {
newSrc = isShow
? deleteFlatten(flattenSrc, flattenEmpty)
: mergeFlatten(flattenSrc, flattenEmpty);
return newSrc;
},
type: () => {
newSrc = isShow
? deleteFlatten(flattenSrc, flattenType)
: mergeFlatten(flattenSrc, flattenType);
return newSrc;
},
location: () => {
newSrc = isShow
? deleteFlatten(flattenSrc, flattenLocation)
: mergeFlatten(flattenSrc, flattenLocation);
return newSrc;
},
default: () => flattenSrc,
};
return (types[type] || types["default"])();
}

const result = triggerAstOutput(option);
this.setState({ flattenSrc: result, src: unflatten(result) });
}

render() {
const { src, astOption } = this.state;
const { className = "" } = this.props;

return (
<div className={`${styles.astWrapper} ${className}`}>
{src && (
<div className={styles.optionWrapper}>
{OPTION_ORDER.map(option => (
<label className={styles.settingsLabel}>
<input
checked={astOption[option]}
type="checkbox"
className={styles.inputCheckboxLeft}
onChange={() => this._onOptionSettingCheck(option)}
/>
{option}
</label>
))}
</div>
)}
<ReactJson
src={src}
style={styles.reactJson}
sortKeys={true}
name={false}
enableClipboard={false}
displayObjectSize={true}
displayDataTypes={false}
/>
</div>
);
}
}

const styles = {
astWrapper: css({
height: "100%",
}),
optionWrapper: css({
display: "flex",
flexDirection: "row",
width: "100%",
justifyContent: "stretch",
color: colors.inverseForegroundLight,
backgroundColor: colors.inverseBackgroundLight,
}),
settingsLabel: css({
alignItems: "center",
display: "flex",
flexDirection: "colum",
fontSize: "0.875rem",
fontWeight: "normal",
padding: "0.19rem 1rem",
transition: "background-color 250ms ease-in-out, color 250ms ease-in-out",
"&:hover": {
backgroundColor: colors.inverseBackgroundDark,
color: colors.inverseForeground,
},
}),
inputCheckboxLeft: css({
margin: "0 0.75rem 0 0 !important", // TODO (bvaughn) Override input[type="checkbox"] style in main.css
"&:disabled": {
opacity: 0.5,
},
}),
reactJson: {
overflowY: "scroll",
overflow: "show",
width: "100%",
height: "100%",
},
};
164 changes: 164 additions & 0 deletions js/repl/ASTUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// https://github.com/hughsk/flat/blob/master/index.js

function isBuffer(obj) {
return (
obj != null &&
obj.constructor != null &&
typeof obj.constructor.isBuffer === "function" &&
obj.constructor.isBuffer(obj)
);
}

function flatten(target, opts) {
opts = opts || {};

const delimiter = opts.delimiter || ".";
const maxDepth = opts.maxDepth;
const output = {};

function step(object, prev, currentDepth) {
currentDepth = currentDepth || 1;
Object.keys(object).forEach(function(key) {
const value = object[key];
const isarray = opts.safe && Array.isArray(value);
const type = Object.prototype.toString.call(value);
const isbuffer = isBuffer(value);
const isobject = type === "[object Object]" || type === "[object Array]";
const newKey = prev ? prev + delimiter + key : key;
if (
!isarray &&
!isbuffer &&
isobject &&
Object.keys(value).length &&
(!opts.maxDepth || currentDepth < maxDepth)
) {
return step(value, newKey, currentDepth + 1);
}
output[newKey] = value;
});
}
step(target);
return output;
}

function unflatten(target, opts) {
opts = opts || {};
const delimiter = opts.delimiter || ".";
const overwrite = opts.overwrite || false;
const result = {};
const isbuffer = isBuffer(target);
if (
isbuffer ||
Object.prototype.toString.call(target) !== "[object Object]"
) {
return target;
}

// safely ensure that the key is
// an integer.
function getkey(key) {
const parsedKey = Number(key);
return isNaN(parsedKey) || key.indexOf(".") !== -1 || opts.object
? key
: parsedKey;
}

const sortedKeys = Object.keys(target).sort(function(keyA, keyB) {
return keyA.length - keyB.length;
});

sortedKeys.forEach(function(key) {
const split = key.split(delimiter);
let key1 = getkey(split.shift());
let key2 = getkey(split[0]);
let recipient = result;

while (key2 !== undefined) {
const type = Object.prototype.toString.call(recipient[key1]);
const isobject = type === "[object Object]" || type === "[object Array]";

// do not write over falsey, non-undefined values if overwrite is false
if (!overwrite && !isobject && typeof recipient[key1] !== "undefined") {
return;
}

if ((overwrite && !isobject) || (!overwrite && recipient[key1] == null)) {
recipient[key1] = typeof key2 === "number" && !opts.object ? [] : {};
}

recipient = recipient[key1];
if (split.length > 0) {
key1 = getkey(split.shift());
key2 = getkey(split[0]);
}
}

// unflatten again for 'messy objects'
recipient[key1] = unflatten(target[key], opts);
});

return result;
}

function filterFlatten(flattenSrc, type = "", value) {
const result = Object.keys(flattenSrc)
.filter(key => {
if (type) {
const keys = key.split(".");
return keys.includes(type);
}
if (value) {
const v = value === "null" || value === "undefined" ? null : value;
return flattenSrc[key] === v;
}
})
.reduce((object, key) => {
object[key] = flattenSrc[key];
return object;
}, {});
return result;
}

function deleteFlatten(currentSrc, deletedSrc) {
const deletedKeys = Object.keys(deletedSrc);
const result = Object.keys(currentSrc).reduce((object, key) => {
!deletedKeys.includes(key) ? (object[key] = currentSrc[key]) : null;
return object;
}, {});
return result;
}

function mergeFlatten(currentSrc, nextSrc) {
return {
...currentSrc,
...nextSrc,
};
}

function reject(obj, char) {
return Object.keys(obj)
.filter(key => !key.includes(char))
.reduce((o, key) => {
return {
...o,
[key]: obj[key],
};
}, {});
}

// function reject(obj, keys) {
// const result = Object.keys(obj)
// .filter(k => !keys.includes(k))
// .map(k => Object.assign({}, { [k]: obj[k] }))
// .reduce((res, o) => Object.assign(res, o), {});
// return result;
// }

export {
flatten,
unflatten,
filterFlatten,
deleteFlatten,
mergeFlatten,
reject,
};
2 changes: 2 additions & 0 deletions js/repl/PluginConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ const pluginConfigs: Array<PluginConfig> = [
];

const replDefaults: ReplState = {
ast: false,
astContext: {},
babili: false,
browsers: "",
build: "",
Expand Down
Loading