diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 86378036d65..acf41b0a510 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1257,21 +1257,66 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge // Children if (children) { - // build list of valid emittable jsx children - const emittableChildren = children.filter(isJsxChildEmittable); - if (emittableChildren.length > 0) { - // If the only child is non-jsx element, don't put it on a new line - if (emittableChildren.length == 1 && emittableChildren[0].kind !== SyntaxKind.JsxElement && emittableChildren[0].kind !== SyntaxKind.JsxSelfClosingElement) { - write(", "); - emit(emittableChildren[0]); + let firstChild:JsxChild; + let multipleEmittableChildren = false; + + for (let i = 0, n = children.length; i < n; ++i) { + let jsxChild = children[i]; + + if (isJsxChildEmittable(jsxChild)) { + // we need to decide whether to emit in single line or multiple lines as indented list + // store firstChild reference, if we see another emittable child, then emit accordingly + if (!firstChild) { + write(", "); + firstChild = jsxChild; + } + else { + // more than one emittable child, emit indented list + if(!multipleEmittableChildren){ + multipleEmittableChildren = true; + increaseIndent(); + writeLine(); + emit(firstChild); + } + + write(", "); + writeLine(); + emit(jsxChild); + } + } + } + + if (multipleEmittableChildren) { + decreaseIndent(); + } + else if (firstChild) { + if (firstChild.kind !== SyntaxKind.JsxElement && firstChild.kind !== SyntaxKind.JsxSelfClosingElement) { + emit(firstChild); } - // Otherwise build a indented comma separated list else { + // If the only child is jsx element, put it on a new indented line increaseIndent(); - emitList(emittableChildren, 0, emittableChildren.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ true); + writeLine(); + emit(firstChild); + writeLine(); decreaseIndent(); } } + + // const emittableChildren = children.filter(isJsxChildEmittable); + // if (emittableChildren.length > 0) { + // // If the only child is non-jsx element, don't put it on a new line + // if (emittableChildren.length == 1 && emittableChildren[0].kind !== SyntaxKind.JsxElement && emittableChildren[0].kind !== SyntaxKind.JsxSelfClosingElement) { + // write(", "); + // emit(emittableChildren[0]); + // } + // // Otherwise build a indented comma separated list + // else { + // increaseIndent(); + // emitList(emittableChildren, 0, emittableChildren.length, /*multiLine*/ true, /*trailingComma*/ false, /*leadingComma*/ true); + // decreaseIndent(); + // } + // } } // Closing paren diff --git a/tests/baselines/reference/tsxReactEmit1.js b/tests/baselines/reference/tsxReactEmit1.js index a6eac7f4824..f62a7bdc47d 100644 --- a/tests/baselines/reference/tsxReactEmit1.js +++ b/tests/baselines/reference/tsxReactEmit1.js @@ -70,9 +70,8 @@ var SomeClass = (function () { return SomeClass; }()); var whitespace1 = React.createElement("div", null, " "); -var whitespace2 = React.createElement("div", null, - " ", - p, - " " -); +var whitespace2 = React.createElement("div", null, + " ", + p, + " "); var whitespace3 = React.createElement("div", null, p); diff --git a/tests/baselines/reference/tsxReactEmit3.js b/tests/baselines/reference/tsxReactEmit3.js index 2163a310fc8..07a8f22761f 100644 --- a/tests/baselines/reference/tsxReactEmit3.js +++ b/tests/baselines/reference/tsxReactEmit3.js @@ -8,12 +8,11 @@ declare var Foo, Bar, baz; q s ; //// [test.js] -React.createElement(Foo, null, - " ", - React.createElement(Bar, null, " q "), - " ", - React.createElement(Bar, null), - " s ", - React.createElement(Bar, null), - React.createElement(Bar, null) -); +React.createElement(Foo, null, + " ", + React.createElement(Bar, null, " q "), + " ", + React.createElement(Bar, null), + " s ", + React.createElement(Bar, null), + React.createElement(Bar, null)); diff --git a/tests/baselines/reference/tsxReactEmitNesting.js b/tests/baselines/reference/tsxReactEmitNesting.js index 3f12715b98c..53abc04aa9b 100644 --- a/tests/baselines/reference/tsxReactEmitNesting.js +++ b/tests/baselines/reference/tsxReactEmitNesting.js @@ -38,27 +38,23 @@ let render = (ctrl, model) => //// [file.js] // A simple render function with nesting and control statements var render = function (ctrl, model) { - return vdom.createElement("section", {class: "todoapp"}, - vdom.createElement("header", {class: "header"}, - vdom.createElement("h1", null, "todos "), - vdom.createElement("input", {class: "new-todo", autofocus: true, autocomplete: "off", placeholder: "What needs to be done?", value: model.newTodo, onKeyup: ctrl.addTodo.bind(ctrl, model)}) - ), - vdom.createElement("section", {class: "main", style: { display: (model.todos && model.todos.length) ? "block" : "none" }}, - vdom.createElement("input", {class: "toggle-all", type: "checkbox", onChange: ctrl.toggleAll.bind(ctrl)}), + return vdom.createElement("section", {class: "todoapp"}, + vdom.createElement("header", {class: "header"}, + vdom.createElement("h1", null, "todos "), + vdom.createElement("input", {class: "new-todo", autofocus: true, autocomplete: "off", placeholder: "What needs to be done?", value: model.newTodo, onKeyup: ctrl.addTodo.bind(ctrl, model)})), + vdom.createElement("section", {class: "main", style: { display: (model.todos && model.todos.length) ? "block" : "none" }}, + vdom.createElement("input", {class: "toggle-all", type: "checkbox", onChange: ctrl.toggleAll.bind(ctrl)}), vdom.createElement("ul", {class: "todo-list"}, model.filteredTodos.map(function (todo) { - return vdom.createElement("li", {class: { todo: true, completed: todo.completed, editing: todo == model.editedTodo }}, - vdom.createElement("div", {class: "view"}, + return vdom.createElement("li", {class: { todo: true, completed: todo.completed, editing: todo == model.editedTodo }}, + vdom.createElement("div", {class: "view"}, (!todo.editable) ? vdom.createElement("input", {class: "toggle", type: "checkbox"}) - : null, - vdom.createElement("label", {onDoubleClick: function () { ctrl.editTodo(todo); }}, todo.title), - vdom.createElement("button", {class: "destroy", onClick: ctrl.removeTodo.bind(ctrl, todo)}), - vdom.createElement("div", {class: "iconBorder"}, + : null, + vdom.createElement("label", {onDoubleClick: function () { ctrl.editTodo(todo); }}, todo.title), + vdom.createElement("button", {class: "destroy", onClick: ctrl.removeTodo.bind(ctrl, todo)}), + vdom.createElement("div", {class: "iconBorder"}, vdom.createElement("div", {class: "icon"}) - ) - ) + )) ); - })) - ) - ); + })))); }; diff --git a/tests/baselines/reference/tsxReactEmitWhitespace.js b/tests/baselines/reference/tsxReactEmitWhitespace.js index 5db92bb33a4..9a157d242e3 100644 --- a/tests/baselines/reference/tsxReactEmitWhitespace.js +++ b/tests/baselines/reference/tsxReactEmitWhitespace.js @@ -59,11 +59,10 @@ var p = 0; // Emit " " React.createElement("div", null, " "); // Emit " ", p, " " -React.createElement("div", null, - " ", - p, - " " -); +React.createElement("div", null, + " ", + p, + " "); // Emit only p React.createElement("div", null, p); // Emit only p diff --git a/tests/baselines/reference/tsxReactEmitWhitespace2.js b/tests/baselines/reference/tsxReactEmitWhitespace2.js index 61e7805fb3d..152d869fc03 100644 --- a/tests/baselines/reference/tsxReactEmitWhitespace2.js +++ b/tests/baselines/reference/tsxReactEmitWhitespace2.js @@ -18,18 +18,15 @@ declare var React: any; //// [file.js] // Emit ' word' in the last string -React.createElement("div", null, - "word ", - React.createElement("code", null, "code"), - " word" -); +React.createElement("div", null, + "word ", + React.createElement("code", null, "code"), + " word"); // Same here -React.createElement("div", null, - React.createElement("code", null, "code"), - " word" -); +React.createElement("div", null, + React.createElement("code", null, "code"), + " word"); // And here -React.createElement("div", null, - React.createElement("code", null), - " word" -); +React.createElement("div", null, + React.createElement("code", null), + " word");