Merge pull request #424 from 4ian/feature/clipboard-project-manager

Clipboard support for ProjectManager in newIDE
This commit is contained in:
Florian Rival
2017-12-16 16:17:14 +01:00
committed by GitHub
48 changed files with 593 additions and 226 deletions

View File

@@ -5,6 +5,7 @@ node_modules
# testing
coverage
flow-coverage
# production
build
@@ -23,3 +24,4 @@ public/res
public/CppPlatform
public/JsPlatform
resources/GDJS

10
newIDE/app/flow-typed/libGD.js vendored Normal file
View File

@@ -0,0 +1,10 @@
// @flow
//TODO: These types could be generated from GDevelop.js instead of being
//manually written here.
declare type gdProject = Object;
declare type gdLayout = Object;
declare type gdExternalLayout = Object;
//Represents all objects that have serializeTo and unserializeFrom methods.
declare type gdSerializable = Object;

View File

@@ -5,7 +5,8 @@
"license": "MIT",
"homepage": ".",
"devDependencies": {
"flow-bin": "^0.58.0",
"flow-bin": "^0.61.0",
"flow-coverage-report": "^0.4.0",
"follow-redirects": "^1.2.3",
"prettier": "1.7.0",
"react-scripts": "1.0.6",
@@ -49,18 +50,29 @@
"wait-promise": "^0.4.1"
},
"scripts": {
"postinstall": "npm run import-resources",
"import-resources": "cd scripts && node import-libGD.js && node import-res-folder.js && node import-GDJS-Runtime.js",
"start": "npm run import-resources && react-scripts start",
"build": "npm run import-resources && react-scripts build",
"postinstall": "npm run import-resources",
"format": "prettier --write \"src/**/*.js\"",
"test": "react-scripts test --env=jsdom",
"flow": "flow",
"analyze-source-map": "source-map-explorer build/static/js/main.*",
"storybook": "start-storybook -p 9009 -s public",
"build-storybook": "build-storybook -s public"
"analyze-test-coverage": "react-scripts test --env=jsdom --coverage",
"analyze-flow-coverage": "flow-coverage-report",
"analyze-source-map": "source-map-explorer build/static/js/main.*"
},
"eslintConfig": {
"extends": "react-app"
},
"flow-coverage-report": {
"includeGlob": [
"src/**/*.js"
],
"type": [
"text",
"html",
"json"
]
}
}

View File

@@ -65,7 +65,12 @@ export default class NewBehaviorDialog extends Component {
if (!open || !project) return null;
const actions = [
<FlatButton key="close" label="Close" primary={false} onClick={onClose} />,
<FlatButton
key="close"
label="Close"
primary={false}
onClick={onClose}
/>,
];
return (

View File

@@ -15,19 +15,21 @@ export const createTree = (
allExpressions: Array<InstructionOrExpressionInformation>
): InstructionOrExpressionTreeNode => {
const tree = {};
allExpressions.forEach((expressionInfo: InstructionOrExpressionInformation) => {
update(
tree,
compact(expressionInfo.fullGroupName.split(GROUP_DELIMITER)),
groupInfo => {
const existingGroupInfo = groupInfo || {};
return {
...existingGroupInfo,
[expressionInfo.displayedName]: expressionInfo,
};
}
);
});
allExpressions.forEach(
(expressionInfo: InstructionOrExpressionInformation) => {
update(
tree,
compact(expressionInfo.fullGroupName.split(GROUP_DELIMITER)),
groupInfo => {
const existingGroupInfo = groupInfo || {};
return {
...existingGroupInfo,
[expressionInfo.displayedName]: expressionInfo,
};
}
);
}
);
return tree;
};

View File

@@ -50,7 +50,7 @@ const enumerateExtensionExpressions = (
return allExpressions;
};
export const enumerateExpressions = (type) => {
export const enumerateExpressions = type => {
const freeExpressions = [];
const objectsExpressions = [];
const behaviorsExpressions = [];
@@ -85,7 +85,10 @@ export const enumerateExpressions = (type) => {
//Free expressions
freeExpressions.push.apply(
freeExpressions,
enumerateExtensionExpressions(prefix, allFreeExpressionsGetter.call(extension))
enumerateExtensionExpressions(
prefix,
allFreeExpressionsGetter.call(extension)
)
);
//Objects expressions:
@@ -134,14 +137,13 @@ export const enumerateExpressions = (type) => {
};
export const filterExpressions = (list, searchText) => {
if (!searchText) return list;
const lowercaseSearchText = searchText.toLowerCase();
if (!searchText) return list;
const lowercaseSearchText = searchText.toLowerCase();
return list.filter(enumeratedExpression => {
return (
enumeratedExpression.type
.toLowerCase()
.indexOf(lowercaseSearchText) !== -1
);
});
}
return list.filter(enumeratedExpression => {
return (
enumeratedExpression.type.toLowerCase().indexOf(lowercaseSearchText) !==
-1
);
});
};

View File

@@ -15,5 +15,5 @@ describe('EnumerateInstructions', () => {
it('can create the tree of instructions', () => {
const instructions = enumerateInstructions('number');
expect(createTree(instructions)).toMatchSnapshot();
})
});
});

View File

@@ -8,7 +8,7 @@ import { type InstructionOrExpressionInformation } from './InstructionOrExpressi
export default class ExpressionSelector extends Component<*, *> {
_selector: any = null;
instructionsInfo: Array<InstructionOrExpressionInformation> = [];
instructionsInfoTree: InstructionOrExpressionTreeNode = null;
instructionsInfoTree: ?InstructionOrExpressionTreeNode = null;
static defaultProps = {
expressionType: 'number',

View File

@@ -1,3 +1,5 @@
//@flow
export type InstructionOrExpressionInformation = {
type: string,
name?: string, //For expressions

View File

@@ -13,7 +13,7 @@ type Props = {
export default class InstructionSelector extends Component<Props, *> {
_selector: any = null;
instructionsInfo: Array<InstructionOrExpressionInformation> = [];
instructionsInfoTree: InstructionOrExpressionTreeNode = null;
instructionsInfoTree: ?InstructionOrExpressionTreeNode = null;
componentWillMount() {
const allInstructions = enumerateInstructions(this.props.isCondition);

View File

@@ -133,6 +133,11 @@ Object {
"fullGroupName": "Common conditions for all objects/Collision",
"type": "CollisionNP",
},
"Point inside object": Object {
"displayedName": "Point inside object",
"fullGroupName": "Common conditions for all objects/Collision",
"type": "CollisionPoint",
},
},
"Layer": Object {
"Compare layer": Object {
@@ -1763,6 +1768,11 @@ Array [
"fullGroupName": "Common conditions for all objects/Behaviors",
"type": "BehaviorActivated",
},
Object {
"displayedName": "Point inside object",
"fullGroupName": "Common conditions for all objects/Collision",
"type": "CollisionPoint",
},
Object {
"displayedName": "Compare layer",
"fullGroupName": "Common conditions for all objects/Layer",

View File

@@ -121,9 +121,7 @@ export class InstructionOrExpressionSelector extends Component {
style={styles.searchBar}
ref={searchBar => (this._searchBar = searchBar)}
/>
<SelectableList
value={this.props.selectedType}
>
<SelectableList value={this.props.selectedType}>
{this.state.search
? this._renderSearchResults()
: this._renderTree(this.props.instructionsInfoTree)}

View File

@@ -37,7 +37,12 @@ export default class ExpressionParametersEditorDialog extends Component<
}
render() {
const { project, layout, expressionMetadata, parameterRenderingService } = this.props;
const {
project,
layout,
expressionMetadata,
parameterRenderingService,
} = this.props;
return (
<Dialog

View File

@@ -20,6 +20,8 @@ export const formatExpressionCall = (
expressionInfo: InstructionOrExpressionInformation,
parameterValues: ParameterValues
): string => {
const functionName = expressionInfo.name || '';
if (expressionInfo.objectMetadata) {
const [objectName, ...otherParameters] = parameterValues;
@@ -27,7 +29,7 @@ export const formatExpressionCall = (
otherParameters,
expressionInfo.metadata
).join(', ');
return `${objectName}.${expressionInfo.name}(${functionArgs})`;
return `${objectName}.${functionName}(${functionArgs})`;
} else if (expressionInfo.behaviorMetadata) {
const [objectName, behaviorName, ...otherParameters] = parameterValues;
@@ -35,12 +37,12 @@ export const formatExpressionCall = (
otherParameters,
expressionInfo.metadata
).join(', ');
return `${objectName}.${behaviorName}::${expressionInfo.name}(${functionArgs})`;
return `${objectName}.${behaviorName}::${functionName}(${functionArgs})`;
} else {
const functionArgs = filterOutCodeOnlyParameters(
parameterValues,
expressionInfo.metadata
).join(', ');
return `${expressionInfo.name}(${functionArgs})`;
return `${functionName}(${functionArgs})`;
}
};

View File

@@ -25,10 +25,13 @@ describe('HelpButton', () => {
});
it('properly format a free function, with "code-only" parameters', () => {
const cameraHeightExpression = filterExpressions(freeExpressions, 'CameraHeight')[0];
expect(formatExpressionCall(cameraHeightExpression, ['', '"My layer"', "0"])).toBe(
'CameraHeight("My layer", 0)'
);
const cameraHeightExpression = filterExpressions(
freeExpressions,
'CameraHeight'
)[0];
expect(
formatExpressionCall(cameraHeightExpression, ['', '"My layer"', '0'])
).toBe('CameraHeight("My layer", 0)');
});
it('properly format an object function', () => {

View File

@@ -39,12 +39,15 @@ export default class LinkEvent extends Component {
}
edit = domEvent => {
this.setState({
editing: true,
anchorEl: domEvent.currentTarget,
}, () => {
if (this._externalEventsField) this._externalEventsField.focus();
});
this.setState(
{
editing: true,
anchorEl: domEvent.currentTarget,
},
() => {
if (this._externalEventsField) this._externalEventsField.focus();
}
);
};
endEditing = () => {
@@ -90,7 +93,8 @@ export default class LinkEvent extends Component {
this.props.onUpdate();
}}
isInline
ref={externalEventsField => this._externalEventsField = externalEventsField}
ref={externalEventsField =>
(this._externalEventsField = externalEventsField)}
/>
</InlinePopover>
</div>

View File

@@ -190,17 +190,20 @@ export default class EventsSheet extends Component {
this.state.editedInstruction.instruction.delete();
}
this.setState({
editedInstruction: {
isCondition: true,
instruction: null,
instrsList: null,
this.setState(
{
editedInstruction: {
isCondition: true,
instruction: null,
instrsList: null,
},
},
}, () => {
if (saveChanges) {
this._saveChangesToHistory();
() => {
if (saveChanges) {
this._saveChangesToHistory();
}
}
});
);
}
selectEvent = eventContext => {

View File

@@ -29,7 +29,7 @@ const awsS3Client = new awsS3({
});
export default class BrowserS3PreviewLauncher {
static _openPreviewWindow = (project, url): any => {
static _openPreviewWindow = (project: gdProject, url: string): any => {
const windowObjectReference = window.open(url, `_blank`);
return {
url,
@@ -73,7 +73,10 @@ export default class BrowserS3PreviewLauncher {
});
};
static launchLayoutPreview = (project, layout): Promise<any> => {
static launchLayoutPreview = (
project: gdProject,
layout: gdLayout
): Promise<any> => {
if (!project || !layout) return Promise.reject();
return BrowserS3PreviewLauncher._prepareExporter().then(
@@ -99,9 +102,9 @@ export default class BrowserS3PreviewLauncher {
};
static launchExternalLayoutPreview = (
project,
layout,
externalLayout
project: gdProject,
layout: gdLayout,
externalLayout: gdExternalLayout
): Promise<any> => {
return Promise.reject('Not implemented');
};

View File

@@ -11,7 +11,7 @@ const BrowserWindow = electron ? electron.remote.BrowserWindow : null;
const gd = global.gd;
export default class LocalPreviewLauncher {
static _openPreviewWindow = (project, gamePath): void => {
static _openPreviewWindow = (project: gdProject, gamePath: string): void => {
if (!BrowserWindow) return;
const win = new BrowserWindow({
@@ -47,7 +47,10 @@ export default class LocalPreviewLauncher {
});
};
static launchLayoutPreview = (project, layout): Promise<any> => {
static launchLayoutPreview = (
project: gdProject,
layout: gdLayout
): Promise<any> => {
if (!project || !layout) return Promise.reject();
return LocalPreviewLauncher._prepareExporter().then(
@@ -65,9 +68,9 @@ export default class LocalPreviewLauncher {
};
static launchExternalLayoutPreview = (
project,
layout,
externalLayout
project: gdProject,
layout: gdLayout,
externalLayout: gdExternalLayout
): Promise<any> => {
if (!project || !externalLayout) return Promise.reject();

View File

@@ -99,7 +99,13 @@ export const addScrollbars = (WrappedComponent: any) => {
);
};
_setAndAdjust = ({ xValue, yValue }: {xValue: number, yValue: number}) => {
_setAndAdjust = ({
xValue,
yValue,
}: {
xValue: number,
yValue: number,
}) => {
const xMax = Math.max(Math.abs(xValue) + 100, this.state.xMax);
const yMax = Math.max(Math.abs(yValue) + 100, this.state.yMax);

View File

@@ -87,7 +87,12 @@ export default class InstancesEditorContainer extends Component {
this._onMouseMove(event.data.global.x, event.data.global.y)
);
this.backgroundArea.on('panmove', event =>
this._onPanMove(event.deltaX, event.deltaY, event.data.global.x, event.data.global.y)
this._onPanMove(
event.deltaX,
event.deltaY,
event.data.global.x,
event.data.global.y
)
);
this.backgroundArea.on('panend', event => this._onEndSelectionRectangle());
this.pixiContainer.addChild(this.backgroundArea);
@@ -460,7 +465,7 @@ export default class InstancesEditorContainer extends Component {
getViewPosition = () => {
return this.viewPosition;
}
};
_renderScene = () => {
// Protect against rendering scheduled after the component is unmounted.

View File

@@ -1,3 +1,4 @@
//TODO: Factor with styles.js from PointsEditor.
export default {
handleColumn: {
width: 24,

View File

@@ -34,10 +34,7 @@ export default class ConfirmCloseDialog extends Component {
render() {
const actions = [
<FlatButton
label="Cancel"
onTouchTap={this.handleCancel}
/>,
<FlatButton label="Cancel" onTouchTap={this.handleCancel} />,
<FlatButton
label="Close project"
primary={true}

View File

@@ -31,7 +31,7 @@ export const openEditorTab = (
editorRef: null,
name,
key,
closable: typeof closable === "undefined" ? true : !!closable,
closable: typeof closable === 'undefined' ? true : !!closable,
};
return {

View File

@@ -66,7 +66,14 @@ export default class StartPage extends BaseEditor {
};
render() {
const { project, canOpen, onOpen, onCreate, onOpenProjectManager, onCloseProject } = this.props;
const {
project,
canOpen,
onOpen,
onCreate,
onOpenProjectManager,
onCloseProject,
} = this.props;
return (
<div style={styles.scrollContainer}>
@@ -81,28 +88,35 @@ export default class StartPage extends BaseEditor {
</p>
</Paper>
<Paper zDepth={1} style={styles.buttonsPaper}>
{!project && canOpen && (
{!project &&
canOpen && (
<FlatButton
label="Open a project"
fullWidth
onClick={onOpen}
/>
)}
{!project && (
<FlatButton
label="Open a project"
label="Create a new project"
fullWidth
onClick={onOpen}
onClick={onCreate}
/>
)}
{!!project && (
<FlatButton
label="Open Project Manager"
fullWidth
onClick={onOpenProjectManager}
/>
)}
{!!project && (
<FlatButton
label="Close project"
fullWidth
onClick={onCloseProject}
/>
)}
{!project && (<FlatButton
label="Create a new project"
fullWidth
onClick={onCreate}
/>)}
{!!project && (<FlatButton
label="Open Project Manager"
fullWidth
onClick={onOpenProjectManager}
/>)}
{!!project && (<FlatButton
label="Close project"
fullWidth
onClick={onCloseProject}
/>)}
</Paper>
</div>
</Line>

View File

@@ -174,13 +174,13 @@ export default class PointsEditor extends Component {
return (
<div>
<ImagePreview
resourceName={hasValidSprite ? sprite.getImageName() : ''}
resourcesLoader={resourcesLoader}
project={project}
>
{hasValidSprite && <PointsPreview pointsContainer={sprite} />}
</ImagePreview>
<ImagePreview
resourceName={hasValidSprite ? sprite.getImageName() : ''}
resourcesLoader={resourcesLoader}
project={project}
>
{hasValidSprite && <PointsPreview pointsContainer={sprite} />}
</ImagePreview>
<Line>
<Column expand>
<Toggle
@@ -237,7 +237,11 @@ export default class PointsEditor extends Component {
>
{mapFor(0, direction.getSpritesCount(), i => {
return (
<MenuItem value={i} key={i} primaryText={`Frame #${i}`} />
<MenuItem
value={i}
key={i}
primaryText={`Frame #${i}`}
/>
);
})}
</SelectField>
@@ -247,7 +251,8 @@ export default class PointsEditor extends Component {
label="Share same points for all sprites of the animation"
labelPosition="right"
toggled={samePointsForSprites}
onToggle={(e, checked) => this._onToggleSamePointsForSprites(checked)}
onToggle={(e, checked) =>
this._onToggleSamePointsForSprites(checked)}
/>
</Column>
</Line>

View File

@@ -1,17 +1,17 @@
//TODO: Factor with styles.js from LayersList.
export default {
handleColumn: {
width: 24,
paddingLeft: 8,
paddingRight: 0,
},
coordinateColumn: {
width: 48,
},
toolColumn: {
width: 48,
},
pointRow: {
backgroundColor: 'white',
}
};
handleColumn: {
width: 24,
paddingLeft: 8,
paddingRight: 0,
},
coordinateColumn: {
width: 48,
},
toolColumn: {
width: 48,
},
pointRow: {
backgroundColor: 'white',
},
};

View File

@@ -31,7 +31,11 @@ export class ObjectEditorDialog extends Component<*, StateType> {
render() {
const actions = [
<FlatButton key="cancel" label="Cancel" onTouchTap={this.props.onCancel} />,
<FlatButton
key="cancel"
label="Cancel"
onTouchTap={this.props.onCancel}
/>,
<FlatButton
key="apply"
label="Apply"

View File

@@ -19,13 +19,13 @@ export default {
component: SpriteEditor,
newObjectCreator: () => new gd.SpriteObject(''),
castToObjectType: object => gd.asSpriteObject(object),
helpPagePath: "/objects/sprite",
helpPagePath: '/objects/sprite',
},
'TiledSpriteObject::TiledSprite': {
component: TiledSpriteEditor,
newObjectCreator: () => new gd.TiledSpriteObject(''),
castToObjectType: object => gd.asTiledSpriteObject(object),
helpPagePath: "/objects/tiled_sprite",
helpPagePath: '/objects/tiled_sprite',
},
'PanelSpriteObject::PanelSprite': {
component: PanelSpriteEditor,
@@ -41,19 +41,19 @@ export default {
component: TextEditor,
newObjectCreator: () => new gd.TextObject(''),
castToObjectType: object => gd.asTextObject(object),
helpPagePath: "/objects/text",
helpPagePath: '/objects/text',
},
'PrimitiveDrawing::Drawer': {
component: ShapePainterEditor,
newObjectCreator: () => new gd.ShapePainterObject(''),
castToObjectType: object => gd.asShapePainterObject(object),
helpPagePath: "/objects/shape_painter",
helpPagePath: '/objects/shape_painter',
},
'TextEntryObject::TextEntry': {
component: EmptyEditor,
newObjectCreator: () => new gd.TextEntryObject(''),
castToObjectType: object => gd.asTextEntryObject(object),
helpPagePath: "/objects/text_entry",
helpPagePath: '/objects/text_entry',
},
},
};

View File

@@ -45,7 +45,6 @@ export class ObjectsGroupEditorDialog extends Component {
}
}
export default withSerializableObject(ObjectsGroupEditorDialog, {
newObjectCreator: () => new gd.ObjectGroup(),
propName: 'group',

View File

@@ -13,7 +13,10 @@ import {
enumerateObjectsAndGroups,
filterGroupsList,
} from '../ObjectsList/EnumerateObjects';
import type { GroupWithContextList, GroupWithContext } from '../ObjectsList/EnumerateObjects';
import type {
GroupWithContextList,
GroupWithContext,
} from '../ObjectsList/EnumerateObjects';
const listItemHeight = 48;
const styles = {
@@ -43,7 +46,7 @@ const SortableAddGroupRow = SortableElement(props => {
return <AddGroupRow {...props} />;
});
class GroupsList extends Component<*,*> {
class GroupsList extends Component<*, *> {
list: any;
forceUpdateGrid() {
@@ -60,8 +63,8 @@ class GroupsList extends Component<*,*> {
rowCount={fullList.length}
rowHeight={listItemHeight}
rowRenderer={({ index, key, style }) => {
const groupWithScope = fullList[index];
if (groupWithScope.key === 'add-groups-row') {
const groupWithContext = fullList[index];
if (groupWithContext.key === 'add-groups-row') {
return (
<SortableAddGroupRow
index={fullList.length}
@@ -76,24 +79,25 @@ class GroupsList extends Component<*,*> {
const nameBeingEdited =
this.props.renamedGroupWithScope &&
this.props.renamedGroupWithScope.group === groupWithScope.group &&
this.props.renamedGroupWithScope.global === groupWithScope.global;
this.props.renamedGroupWithScope.group === groupWithContext.group &&
this.props.renamedGroupWithScope.global === groupWithContext.global;
return (
<SortableGroupRow
index={index}
key={groupWithScope.group.ptr}
key={groupWithContext.group.ptr}
project={project}
group={groupWithScope.group}
group={groupWithContext.group}
style={style}
onEdit={
this.props.onEditGroup
? () => this.props.onEditGroup(groupWithScope.group)
? () => this.props.onEditGroup(groupWithContext.group)
: undefined
}
onEditName={() => this.props.onEditName(groupWithScope)}
onDelete={() => this.props.onDelete(groupWithScope)}
onRename={newName => this.props.onRename(groupWithScope, newName)}
onEditName={() => this.props.onEditName(groupWithContext)}
onDelete={() => this.props.onDelete(groupWithContext)}
onRename={newName =>
this.props.onRename(groupWithContext, newName)}
editingName={nameBeingEdited}
/>
);
@@ -113,8 +117,13 @@ type StateType = {|
export default class GroupsListContainer extends React.Component<*, StateType> {
static defaultProps = {
onDeleteGroup: (groupWithScope, cb) => cb(true),
onRenameGroup: (groupWithScope, newName, cb) => cb(true),
onDeleteGroup: (groupWithContext: GroupWithContext, cb: Function) =>
cb(true),
onRenameGroup: (
groupWithContext: GroupWithContext,
newName: string,
cb: Function
) => cb(true),
};
sortableList: any;
@@ -133,8 +142,10 @@ export default class GroupsListContainer extends React.Component<*, StateType> {
// If a change is made, the component won't notice it: you have to manually
// call forceUpdate.
if (this.state.renamedGroupWithScope !== nextState.renamedGroupWithScope ||
this.state.searchText !== nextState.searchText)
if (
this.state.renamedGroupWithScope !== nextState.renamedGroupWithScope ||
this.state.searchText !== nextState.searchText
)
return true;
if (
@@ -160,8 +171,8 @@ export default class GroupsListContainer extends React.Component<*, StateType> {
this.forceUpdate();
};
_onDelete = (groupWithScope: GroupWithContext) => {
const { group, global } = groupWithScope;
_onDelete = (groupWithContext: GroupWithContext) => {
const { group, global } = groupWithContext;
const { project, objectsContainer } = this.props;
//eslint-disable-next-line
@@ -170,7 +181,7 @@ export default class GroupsListContainer extends React.Component<*, StateType> {
);
if (!answer) return;
this.props.onDeleteGroup(groupWithScope, doRemove => {
this.props.onDeleteGroup(groupWithContext, doRemove => {
if (!doRemove) return;
if (global) {
@@ -183,17 +194,17 @@ export default class GroupsListContainer extends React.Component<*, StateType> {
});
};
_onEditName = (groupWithScope: GroupWithContext) => {
_onEditName = (groupWithContext: GroupWithContext) => {
this.setState(
{
renamedGroupWithScope: groupWithScope,
renamedGroupWithScope: groupWithContext,
},
() => this.sortableList.getWrappedInstance().forceUpdateGrid()
);
};
_onRename = (groupWithScope: GroupWithContext, newName: string) => {
const { group } = groupWithScope;
_onRename = (groupWithContext: GroupWithContext, newName: string) => {
const { group } = groupWithContext;
const { project, objectsContainer } = this.props;
this.setState({
@@ -210,7 +221,7 @@ export default class GroupsListContainer extends React.Component<*, StateType> {
return;
}
this.props.onRenameGroup(groupWithScope, newName, doRename => {
this.props.onRenameGroup(groupWithContext, newName, doRename => {
if (!doRename) return;
group.setName(newName);
@@ -250,8 +261,14 @@ export default class GroupsListContainer extends React.Component<*, StateType> {
const { searchText } = this.state;
const lists = enumerateObjectsAndGroups(project, objectsContainer);
this.containerGroupsList = filterGroupsList(lists.containerGroupsList, searchText);
this.projectGroupsList = filterGroupsList(lists.projectGroupsList, searchText);
this.containerGroupsList = filterGroupsList(
lists.containerGroupsList,
searchText
);
this.projectGroupsList = filterGroupsList(
lists.projectGroupsList,
searchText
);
const allGroupsList = filterGroupsList(lists.allGroupsList, searchText);
const fullList = allGroupsList.concat({
key: 'add-groups-row',

View File

@@ -24,8 +24,14 @@ describe('EnumerateObjects', () => {
allObjectsList,
} = enumerateObjects(project, testLayout);
expect(filterObjectsList(containerObjectsList, "myshapepainterobject")).toHaveLength(1);
expect(filterObjectsList(projectObjectsList, "myshapepainterobject")).toHaveLength(0);
expect(filterObjectsList(allObjectsList, "myshapepainterobject")).toHaveLength(1);
expect(
filterObjectsList(containerObjectsList, 'myshapepainterobject')
).toHaveLength(1);
expect(
filterObjectsList(projectObjectsList, 'myshapepainterobject')
).toHaveLength(0);
expect(
filterObjectsList(allObjectsList, 'myshapepainterobject')
).toHaveLength(1);
});
});

View File

@@ -198,6 +198,76 @@ export default class ProjectManager extends React.Component {
'unserializeFrom',
project
);
newLayout.setName(newName);
this.forceUpdate();
};
_copyExternalEvents = externalEvents => {
Clipboard.set(EXTERNAL_EVENTS_CLIPBOARD_KIND, {
externalEvents: serializeToJSObject(externalEvents),
name: externalEvents.getName(),
});
};
_cutExternalEvents = externalEvents => {
this._copyExternalEvents(externalEvents);
this.props.onDeleteExternalEvents(externalEvents);
};
_pasteExternalEvents = index => {
if (!Clipboard.has(EXTERNAL_EVENTS_CLIPBOARD_KIND)) return;
const { externalEvents: copiedExternalEvents, name } = Clipboard.get(
EXTERNAL_EVENTS_CLIPBOARD_KIND
);
const { project } = this.props;
const newName = newNameGenerator('CopyOf' + name, name =>
project.hasExternalEventsNamed(name)
);
const newExternalEvents = project.insertNewExternalEvents(newName, index);
unserializeFromJSObject(
newExternalEvents,
copiedExternalEvents,
'unserializeFrom',
project
);
newExternalEvents.setName(newName);
this.forceUpdate();
};
_copyExternalLayout = externalLayout => {
Clipboard.set(EXTERNAL_LAYOUT_CLIPBOARD_KIND, {
externalLayout: serializeToJSObject(externalLayout),
name: externalLayout.getName(),
});
};
_cutExternalLayout = externalLayout => {
this._copyExternalLayout(externalLayout);
this.props.onDeleteExternalLayout(externalLayout);
};
_pasteExternalLayout = index => {
if (!Clipboard.has(EXTERNAL_LAYOUT_CLIPBOARD_KIND)) return;
const { externalLayout: copiedExternalLayout, name } = Clipboard.get(
EXTERNAL_LAYOUT_CLIPBOARD_KIND
);
const { project } = this.props;
const newName = newNameGenerator('CopyOf' + name, name =>
project.hasExternalLayoutNamed(name)
);
const newExternalLayout = project.insertNewExternalLayout(newName, index);
unserializeFromJSObject(newExternalLayout, copiedExternalLayout);
newExternalLayout.setName(newName);
this.forceUpdate();
};
@@ -348,6 +418,9 @@ export default class ProjectManager extends React.Component {
this._onEditName(null, '');
}}
onEditName={() => this._onEditName('external-events', name)}
onCopy={() => this._copyExternalEvents(externalEvents)}
onCut={() => this._cutExternalEvents(externalEvents)}
onPaste={() => this._pasteExternalEvents(i)}
/>
);
})
@@ -390,6 +463,9 @@ export default class ProjectManager extends React.Component {
this._onEditName(null, '');
}}
onEditName={() => this._onEditName('external-layout', name)}
onCopy={() => this._copyExternalLayout(externalLayout)}
onCut={() => this._cutExternalLayout(externalLayout)}
onPaste={() => this._pasteExternalLayout(i)}
/>
);
})

View File

@@ -11,7 +11,7 @@ const styles = {
explanations: {
textAlign: 'center',
margin: 20,
}
},
};
const publicImageUrls = [
@@ -76,11 +76,8 @@ const publicImageUrls = [
const nameFromUrl = (url: string): string => {
const urlParts = url.split('/');
return urlParts[urlParts.length - 1].replace(
'.png',
''
);
}
return urlParts[urlParts.length - 1].replace('.png', '');
};
export default [
{
@@ -108,7 +105,7 @@ export default [
leftAvatar={<ListIcon src={url} />}
/>
);
})
});
}
chooseResources = (
@@ -178,7 +175,10 @@ export default [
autoScrollBodyContent
>
<div style={styles.explanations}>
<p>Adding images from Dropbox, Google Drive... is coming soon! Download GDevelop desktop version to use your own assets.</p>
<p>
Adding images from Dropbox, Google Drive... is coming soon!
Download GDevelop desktop version to use your own assets.
</p>
</div>
<SelectableList
value={this.state.chosenImageUrl}

View File

@@ -27,7 +27,9 @@ export default class ResourceSelector extends Component {
.filter(source => source.kind === this.props.resourceKind)
.map(source => ({
text: '',
value: <MenuItem primaryText={source.displayName} rightIcon={<Add />} />,
value: (
<MenuItem primaryText={source.displayName} rightIcon={<Add />} />
),
onClick: () => this._addFrom(source),
})),
{

View File

@@ -476,10 +476,16 @@ export default class InstancesFullEditor extends Component {
forceUpdatePropertiesEditor = () => {
if (this._propertiesEditor) this._propertiesEditor.forceUpdate();
}
};
render() {
const { project, layout, initialInstances, resourceSources, onChooseResource } = this.props;
const {
project,
layout,
initialInstances,
resourceSources,
onChooseResource,
} = this.props;
const selectedInstances = this.instancesSelection.getSelectedInstances();
const editors = {
@@ -491,7 +497,8 @@ export default class InstancesFullEditor extends Component {
instances={selectedInstances}
onInstancesModified={this._onInstancesModified}
editInstanceVariables={this.editInstanceVariables}
ref={propertiesEditor => (this._propertiesEditor = propertiesEditor)}
ref={propertiesEditor =>
(this._propertiesEditor = propertiesEditor)}
/>
</MosaicWindow>
),

View File

@@ -71,7 +71,8 @@ class EditorMosaic extends Component {
render() {
return (
<MosaicWithoutDragDropContext
renderTile={(editorName, path) => React.cloneElement(this.props.editors[editorName], { path })}
renderTile={(editorName, path) =>
React.cloneElement(this.props.editors[editorName], { path })}
className="mosaic-blueprint-theme mosaic-gd-theme"
value={this.state.mosaicNode}
onChange={this._onChange}

View File

@@ -16,9 +16,7 @@ export default (props: PropsType) => {
if (!helpPagePath) return null;
return (
<IconButton
onClick={() => window.open(getHelpLink(helpPagePath), 'blank') }
>
<IconButton onClick={() => window.open(getHelpLink(helpPagePath), 'blank')}>
<HelpOutline />
</IconButton>
);

View File

@@ -21,7 +21,7 @@ const styles = {
},
};
export default class LocalFolderPicker extends Component<*,*> {
export default class LocalFolderPicker extends Component<*, *> {
onChooseFolder = () => {
if (!dialog || !electron) return;

View File

@@ -15,13 +15,7 @@ export default class ToolbarIcon extends Component {
filter: this.props.disabled ? 'grayscale(100%)' : undefined,
}}
>
<img
title={tooltip}
alt={tooltip}
src={src}
width={32}
height={32}
/>
<img title={tooltip} alt={tooltip} src={src} width={32} height={32} />
</IconButton>
);
}

View File

@@ -32,7 +32,7 @@ export default class Clipboard {
return text.indexOf(kind) === 12; /// 12 is the position of '000kind' value
}
static get(kind: ClipboardKind): ?any {
static get(kind: ClipboardKind): any {
if (!Clipboard.has(kind)) return null;
let text = '';

View File

@@ -7,5 +7,5 @@ import AutoComplete from 'material-ui/AutoComplete';
* @param {*} key
*/
export const fuzzyOrEmptyFilter = (searchText, key) => {
return !key || AutoComplete.fuzzyFilter(searchText, key);
return !key || AutoComplete.fuzzyFilter(searchText, key);
};

View File

@@ -1,7 +1,4 @@
import {
serializeToJSObject,
unserializeFromJSObject,
} from './Serializer';
import { serializeToJSObject, unserializeFromJSObject } from './Serializer';
// Tools function to keep track of the history of changes made
// on a serializable object from libGD.js
@@ -63,7 +60,12 @@ export const undo = (history, serializableObject, project = undefined) => {
}
const newCurrent = history.undoHistory[history.undoHistory.length - 1];
unserializeFromJSObject(serializableObject, newCurrent, 'unserializeFrom', project);
unserializeFromJSObject(
serializableObject,
newCurrent,
'unserializeFrom',
project
);
return {
undoHistory: history.undoHistory.slice(0, -1),
@@ -86,7 +88,12 @@ export const redo = (history, serializableObject, project = undefined) => {
}
const newCurrent = history.redoHistory[history.redoHistory.length - 1];
unserializeFromJSObject(serializableObject, newCurrent, 'unserializeFrom', project);
unserializeFromJSObject(
serializableObject,
newCurrent,
'unserializeFrom',
project
);
return {
undoHistory: [...history.undoHistory, history.current],

View File

@@ -2,9 +2,6 @@
const gd = global.gd;
type gdProject = Object;
type gdSerializable = Object;
/**
* Tool function to save a serializable object to a JS object.
* Most gd.* objects are "serializable", meaning they have a serializeTo

View File

@@ -31,17 +31,11 @@ export const makeTestProject = gd => {
project.getResourcesManager().addResource(audioResource1);
// Create and expose some objects
const shapePainterObject = new gd.ShapePainterObject(
'MyShapePainterObject'
);
const shapePainterObject = new gd.ShapePainterObject('MyShapePainterObject');
const adMobObject = new gd.AdMobObject('MyAdMobObject');
const textObject = new gd.TextObject('MyTextObject');
const tiledSpriteObject = new gd.TiledSpriteObject(
'MyTiledSpriteObject'
);
const panelSpriteObject = new gd.PanelSpriteObject(
'MyPanelSpriteObject'
);
const tiledSpriteObject = new gd.TiledSpriteObject('MyTiledSpriteObject');
const panelSpriteObject = new gd.PanelSpriteObject('MyPanelSpriteObject');
const spriteObject = new gd.SpriteObject('MySpriteObject');
const spriteObjectWithBehaviors = new gd.SpriteObject(
'MySpriteObjectWithBehaviors'
@@ -62,7 +56,7 @@ export const makeTestProject = gd => {
sprite1.getOrigin().setY(20);
sprite1.getCenter().setX(100);
sprite1.getCenter().setY(200);
const headCustomPoint = new gd.Point("Head");
const headCustomPoint = new gd.Point('Head');
headCustomPoint.setX(40);
headCustomPoint.setY(50);
sprite1.addPoint(headCustomPoint);
@@ -136,13 +130,20 @@ export const makeTestProject = gd => {
//Add a few variables
const testLayoutVariables = testLayout.getVariables();
testLayoutVariables.insert("Variable1", new gd.Variable(), 0).setString("A multiline\nstr value");
testLayoutVariables.insert("Variable2", new gd.Variable(), 1).setString("123456");
testLayoutVariables
.insert('Variable1', new gd.Variable(), 0)
.setString('A multiline\nstr value');
testLayoutVariables
.insert('Variable2', new gd.Variable(), 1)
.setString('123456');
const variable3 = new gd.Variable();
variable3.getChild("Child1").setString("Child1 str value");
variable3.getChild("Child2").setString("7891011");
variable3.getChild("Child3").getChild("SubChild1").setString("Hello\nMultiline\nWorld");
testLayoutVariables.insert("Variable3", variable3, 2);
variable3.getChild('Child1').setString('Child1 str value');
variable3.getChild('Child2').setString('7891011');
variable3
.getChild('Child3')
.getChild('SubChild1')
.setString('Hello\nMultiline\nWorld');
testLayoutVariables.insert('Variable3', variable3, 2);
//Create a few events
//Add a new "standard" event to the scene:
@@ -236,8 +237,14 @@ export const makeTestProject = gd => {
project.insertObject(globalTiledSpriteObject, 0);
// External events
const testExternalEvents1 = project.insertNewExternalEvents('TestExternalEvents1', 0);
const testExternalEvents2 = project.insertNewExternalEvents('TestExternalEvents2', 1);
const testExternalEvents1 = project.insertNewExternalEvents(
'TestExternalEvents1',
0
);
const testExternalEvents2 = project.insertNewExternalEvents(
'TestExternalEvents2',
1
);
return {
project,

View File

@@ -6,13 +6,13 @@ export default class ValueStateHolder extends Component {
this.state = {
value: props.initialValue,
}
};
}
render() {
return React.cloneElement(this.props.children, {
onChange: value => this.setState({value}),
onChange: value => this.setState({ value }),
value: this.state.value,
})
});
}
}

View File

@@ -131,7 +131,9 @@ storiesOf('ParameterFields', module)
</ValueStateHolder>
))
.add('StringField', () => (
<ValueStateHolder initialValue={'ToString(0) + "Test" + NewLine() + VariableString(MyVar)'}>
<ValueStateHolder
initialValue={'ToString(0) + "Test" + NewLine() + VariableString(MyVar)'}
>
<StringField
project={project}
layout={testLayout}
@@ -231,7 +233,8 @@ storiesOf('ExpressionSelector', module)
expressionType="number"
onChoose={action('Expression chosen')}
/>
)).add('string', () => (
))
.add('string', () => (
<ExpressionSelector
selectedType=""
expressionType="string"

View File

@@ -371,7 +371,7 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
argparse@^1.0.7, argparse@^1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
@@ -442,6 +442,13 @@ array-unique@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53"
array.prototype.find@2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.0.4.tgz#556a5c5362c08648323ddaeb9de9d14bc1864c90"
dependencies:
define-properties "^1.1.2"
es-abstract "^1.7.0"
array.prototype.flatmap@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.1.1.tgz#dbb6c44693c2a2a2fcab24e551dfbf47f67fde03"
@@ -1279,7 +1286,7 @@ babel-plugin-transform-minify-booleans@^6.8.3:
version "6.8.3"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.8.3.tgz#5906ed776d3718250519abf1bace44b0b613ddf9"
babel-plugin-transform-object-rest-spread@6.26.0, babel-plugin-transform-object-rest-spread@^6.22.0:
babel-plugin-transform-object-rest-spread@6.26.0, babel-plugin-transform-object-rest-spread@^6.20.2, babel-plugin-transform-object-rest-spread@^6.22.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06"
dependencies:
@@ -2076,7 +2083,7 @@ colormin@^1.0.5:
css-color-names "0.0.4"
has "^1.0.1"
colors@~1.1.2:
colors@^1.0.3, colors@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
@@ -2714,6 +2721,10 @@ earcut@^2.0.8:
version "2.1.2"
resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.1.2.tgz#542add0ca3a7b713452720e1d053937d3daf3784"
eastasianwidth@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.1.1.tgz#44d656de9da415694467335365fb3147b8572b7c"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
@@ -3161,6 +3172,12 @@ expand-range@^1.8.1:
dependencies:
fill-range "^2.1.0"
expand-tilde@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-1.2.2.tgz#0b81eba897e5a3d31d1c3d102f8f01441e559449"
dependencies:
os-homedir "^1.0.1"
expand-tilde@^2.0.0, expand-tilde@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
@@ -3395,6 +3412,19 @@ find-cache-dir@^1.0.0:
make-dir "^1.0.0"
pkg-dir "^2.0.0"
find-file-up@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/find-file-up/-/find-file-up-0.1.3.tgz#cf68091bcf9f300a40da411b37da5cce5a2fbea0"
dependencies:
fs-exists-sync "^0.1.0"
resolve-dir "^0.1.0"
find-pkg@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/find-pkg/-/find-pkg-0.1.2.tgz#1bdc22c06e36365532e2a248046854b9788da557"
dependencies:
find-file-up "^0.1.2"
find-root@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/find-root/-/find-root-0.1.2.tgz#98d2267cff1916ccaf2743b3a0eea81d79d7dcd1"
@@ -3431,9 +3461,36 @@ flatten@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
flow-bin@^0.58.0:
version "0.58.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.58.0.tgz#62d5a776589419e5656800a0e5230a5e585ca65e"
flow-annotation-check@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/flow-annotation-check/-/flow-annotation-check-1.3.1.tgz#6ee39747251431b1667039eeab807b6d2c297c8a"
dependencies:
argparse "^1.0.9"
babel-plugin-transform-object-rest-spread "^6.20.2"
glob "7.1.1"
load-pkg "^3.0.1"
flow-bin@^0.61.0:
version "0.61.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.61.0.tgz#d0473a8c35dbbf4de573823f4932124397d32d35"
flow-coverage-report@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/flow-coverage-report/-/flow-coverage-report-0.4.0.tgz#97c1a0a5493e9b4aabc7e4252a80030085c83365"
dependencies:
array.prototype.find "2.0.4"
babel-runtime "6.23.0"
flow-annotation-check "1.3.1"
glob "7.1.1"
minimatch "3.0.4"
mkdirp "0.5.1"
parse-json "2.2.0"
react "15.5.4"
react-dom "15.5.4"
strip-json-comments "2.0.1"
temp "0.8.3"
terminal-table "0.0.12"
yargs "8.0.1"
follow-redirects@^1.2.3:
version "1.2.6"
@@ -3487,6 +3544,10 @@ fresh@0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
fs-exists-sync@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add"
fs-extra@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-3.0.1.tgz#3794f378c58b342ea7dbbb23095109c4b3b62291"
@@ -3636,6 +3697,17 @@ glob-parent@^2.0.0:
dependencies:
is-glob "^2.0.0"
glob@7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.2"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
@@ -3655,6 +3727,22 @@ global-modules@1.0.0, global-modules@^1.0.0:
is-windows "^1.0.1"
resolve-dir "^1.0.0"
global-modules@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-0.2.3.tgz#ea5a3bed42c6d6ce995a4f8a1269b5dae223828d"
dependencies:
global-prefix "^0.1.4"
is-windows "^0.2.0"
global-prefix@^0.1.4:
version "0.1.5"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-0.1.5.tgz#8d3bc6b8da3ca8112a160d8d496ff0462bfef78f"
dependencies:
homedir-polyfill "^1.0.0"
ini "^1.3.4"
is-windows "^0.2.0"
which "^1.2.12"
global-prefix@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
@@ -3854,7 +3942,7 @@ home-or-tmp@^2.0.0:
os-homedir "^1.0.0"
os-tmpdir "^1.0.1"
homedir-polyfill@^1.0.1:
homedir-polyfill@^1.0.0, homedir-polyfill@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
dependencies:
@@ -4368,6 +4456,10 @@ is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
is-windows@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c"
is-windows@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.1.tgz#310db70f742d259a16a369202b51af84233310d9"
@@ -4898,6 +4990,12 @@ load-json-file@^2.0.0:
pify "^2.0.0"
strip-bom "^3.0.0"
load-pkg@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/load-pkg/-/load-pkg-3.0.1.tgz#9230b37ec04e569003060bc58951e3ed508d594f"
dependencies:
find-pkg "^0.1.0"
loader-fs-cache@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/loader-fs-cache/-/loader-fs-cache-1.0.1.tgz#56e0bf08bd9708b26a765b68509840c8dec9fdbc"
@@ -5246,7 +5344,7 @@ minimatch@3.0.3:
dependencies:
brace-expansion "^1.0.0"
minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
@@ -5670,7 +5768,7 @@ parse-glob@^3.0.4:
is-extglob "^1.0.0"
is-glob "^2.0.0"
parse-json@^2.1.0, parse-json@^2.2.0:
parse-json@2.2.0, parse-json@^2.1.0, parse-json@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
dependencies:
@@ -6216,6 +6314,13 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.6, prop-types@^15.5.7,
loose-envify "^1.3.1"
object-assign "^4.1.1"
prop-types@~15.5.7:
version "15.5.10"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.5.10.tgz#2797dfc3126182e3a95e3dfbb2e893ddd7456154"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.3.1"
proxy-addr@~2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
@@ -6497,6 +6602,15 @@ react-dom@15.4.2:
loose-envify "^1.1.0"
object-assign "^4.1.0"
react-dom@15.5.4:
version "15.5.4"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.5.4.tgz#ba0c28786fd52ed7e4f2135fe0288d462aef93da"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.1.0"
object-assign "^4.1.0"
prop-types "~15.5.7"
react-error-overlay@^1.0.6:
version "1.0.10"
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-1.0.10.tgz#da8cd1eafac41afdca2a33792b23694ef6c528f1"
@@ -6722,6 +6836,15 @@ react@15.4.2:
loose-envify "^1.1.0"
object-assign "^4.1.0"
react@15.5.4:
version "15.5.4"
resolved "https://registry.yarnpkg.com/react/-/react-15.5.4.tgz#fa83eb01506ab237cdc1c8c3b1cea8de012bf047"
dependencies:
fbjs "^0.8.9"
loose-envify "^1.1.0"
object-assign "^4.1.0"
prop-types "^15.5.7"
reactcss@^1.2.0:
version "1.2.3"
resolved "https://registry.yarnpkg.com/reactcss/-/reactcss-1.2.3.tgz#c00013875e557b1cf0dfd9a368a1c3dab3b548dd"
@@ -7051,6 +7174,13 @@ resize-observer-polyfill@^1.4.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.0.tgz#660ff1d9712a2382baa2cad450a4716209f9ca69"
resolve-dir@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-0.1.1.tgz#b219259a5602fac5c5c496ad894a6e8cc430261e"
dependencies:
expand-tilde "^1.2.2"
global-modules "^0.2.3"
resolve-dir@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
@@ -7638,7 +7768,7 @@ strip-indent@^1.0.1:
dependencies:
get-stdin "^4.0.1"
strip-json-comments@~2.0.1:
strip-json-comments@2.0.1, strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
@@ -7761,13 +7891,20 @@ tar@^2.2.1:
fstream "^1.0.2"
inherits "2"
temp@^0.8.3:
temp@0.8.3, temp@^0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59"
dependencies:
os-tmpdir "^1.0.0"
rimraf "~2.2.6"
terminal-table@0.0.12:
version "0.0.12"
resolved "https://registry.yarnpkg.com/terminal-table/-/terminal-table-0.0.12.tgz#7b56d009aa6828dfdd10f11b654e79c062965fa2"
dependencies:
colors "^1.0.3"
eastasianwidth "^0.1.0"
test-exclude@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.1.1.tgz#4d84964b0966b0087ecc334a2ce002d3d9341e26"
@@ -8473,6 +8610,24 @@ yargs-parser@^7.0.0:
dependencies:
camelcase "^4.1.0"
yargs@8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.1.tgz#420ef75e840c1457a80adcca9bc6fa3849de51aa"
dependencies:
camelcase "^4.1.0"
cliui "^3.2.0"
decamelize "^1.1.1"
get-caller-file "^1.0.1"
os-locale "^2.0.0"
read-pkg-up "^2.0.0"
require-directory "^2.1.1"
require-main-filename "^1.0.1"
set-blocking "^2.0.0"
string-width "^2.0.0"
which-module "^2.0.0"
y18n "^3.2.1"
yargs-parser "^7.0.0"
yargs@^6.0.0:
version "6.6.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"