componentize the code-editor with beautyfier will reuse it for mango
Project: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/commit/18c96098 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/tree/18c96098 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/diff/18c96098 Branch: refs/heads/master Commit: 18c96098b1da0a44dff93ea1dee5dfce84a6d48b Parents: f9b0ee0 Author: Robert Kowalski <[email protected]> Authored: Tue Mar 3 13:50:06 2015 +0100 Committer: Robert Kowalski <[email protected]> Committed: Wed Mar 4 16:17:52 2015 +0100 ---------------------------------------------------------------------- .../components/react-components.react.jsx | 127 ++++++++++++++++++- .../components/tests/beautifySpec.react.jsx | 69 ++++++++++ .../documents/index-editor/components.react.jsx | 108 +--------------- .../tests/viewIndex.componentsSpec.react.jsx | 39 ------ 4 files changed, 192 insertions(+), 151 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/18c96098/app/addons/components/react-components.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/components/react-components.react.jsx b/app/addons/components/react-components.react.jsx index b78646c..7645c17 100644 --- a/app/addons/components/react-components.react.jsx +++ b/app/addons/components/react-components.react.jsx @@ -13,11 +13,12 @@ define([ 'app', 'api', - 'react', + 'addons/fauxton/components', + 'plugins/beautify' ], -function (app, FauxtonAPI, React) { +function (app, FauxtonAPI, React, Components, beautifyHelper) { var ToggleHeaderButton = React.createClass({ render: function () { @@ -41,7 +42,6 @@ function (app, FauxtonAPI, React) { } }); - // global component var StyledSelect = React.createClass({ render: function () { return ( @@ -62,12 +62,127 @@ function (app, FauxtonAPI, React) { } }); + var CodeEditor = React.createClass({ + render: function () { + var code = this.aceEditor ? this.aceEditor.getValue() : this.props.code; + var docsLink; + if (this.props.docs) { + docsLink = <a + className="help-link" + data-bypass="true" + href={this.props.docs} + target="_blank" + > + <i className="icon-question-sign"></i> + </a>; + + } + return ( + <div className="control-group"> + <label htmlFor="ace-function"> + <strong>{this.props.title}</strong> + {docsLink} + </label> + <div className="js-editor" id={this.props.id}>{this.props.code}</div> + <Beautify code={code} beautifiedCode={this.setEditorValue} /> + </div> + ); + }, + + setEditorValue: function (code) { + this.aceEditor.setValue(code); + //this is not a good practice normally but because we working with a backbone view as the mapeditor + //that keeps the map code state this is the best way to force a render so that the beautify button will hide + this.forceUpdate(); + }, + + getValue: function () { + return this.aceEditor.getValue(); + }, + + getEditor: function () { + return this.aceEditor; + }, + + componentDidMount: function () { + this.aceEditor = new Components.Editor({ + editorId: this.props.id, + mode: 'javascript', + couchJSHINT: true + }); + this.aceEditor.render(); + }, + + shouldComponentUpdate: function () { + //we don't want to re-render the map editor as we are using backbone underneath + //which will cause the editor to break + this.aceEditor.editSaved(); + + return false; + }, + + componentWillUnmount: function () { + this.aceEditor.remove(); + } + + }); + + var Beautify = React.createClass({ + noOfLines: function () { + return this.props.code.split(/\r\n|\r|\n/).length; + }, + + canBeautify: function () { + if (this.noOfLines() === 1) { + return true; + } + + return false; + }, + + addTooltip: function () { + if (this.canBeautify) { + $('.beautify-tooltip').tooltip(); + } + }, + + componentDidMount: function () { + this.addTooltip(); + }, + + beautify: function (event) { + event.preventDefault(); + var beautifiedCode = beautifyHelper(this.props.code); + this.props.beautifiedCode(beautifiedCode); + + }, + + render: function () { + if (!this.canBeautify()) { + return null; + } + + return ( + <button + onClick={this.beautify} + className="beautify beautify_map btn btn-primary btn-large beautify-tooltip" + type="button" + data-toggle="tooltip" + title="Reformat your minified code to make edits to it." + > + beautify this code + </button> + ); + } + }); - var Components = { + var ReactComponents = { ToggleHeaderButton: ToggleHeaderButton, - StyledSelect: StyledSelect + StyledSelect: StyledSelect, + CodeEditor: CodeEditor, + Beautify: Beautify }; - return Components; + return ReactComponents; }); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/18c96098/app/addons/components/tests/beautifySpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/components/tests/beautifySpec.react.jsx b/app/addons/components/tests/beautifySpec.react.jsx new file mode 100644 index 0000000..7315986 --- /dev/null +++ b/app/addons/components/tests/beautifySpec.react.jsx @@ -0,0 +1,69 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +define([ + 'api', + 'addons/components/react-components.react', + + 'testUtils', + 'react' +], function (FauxtonAPI, ReactComponents, utils, React) { + + var assert = utils.assert; + var TestUtils = React.addons.TestUtils; + + describe('Beautify', function () { + var container, beautifyEl, reduceStub; + + beforeEach(function () { + container = document.createElement('div'); + }); + + afterEach(function () { + React.unmountComponentAtNode(container); + }); + + it('should be empty for multi-lined code', function () { + var correctCode = 'function() {\n console.log("hello");\n}'; + beautifyEl = TestUtils.renderIntoDocument( + <ReactComponents.Beautify code={correctCode}/>, + container + ); + assert.ok(_.isNull(beautifyEl.getDOMNode())); + }); + + it('should have button to beautify for single line code', function () { + var badCode = 'function () { console.log("hello"); }'; + beautifyEl = TestUtils.renderIntoDocument(<ReactComponents.Beautify code={badCode}/>, container); + assert.ok($(beautifyEl.getDOMNode()).hasClass('beautify')); + }); + + it('on click beautifies code', function () { + var fixedCode; + var correctCode = 'function() {\n console.log("hello");\n}'; + + var beautifiedCode = function (code) { + fixedCode = code; + }; + + beautifyEl = TestUtils.renderIntoDocument( + <ReactComponents.Beautify + beautifiedCode={beautifiedCode} + code={'function () { console.log("hello"); }'} + noOfLines={1}/>, + container + ); + TestUtils.Simulate.click(beautifyEl.getDOMNode()); + assert.equal(fixedCode, correctCode); + + }); + }); +}); http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/18c96098/app/addons/documents/index-editor/components.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/index-editor/components.react.jsx b/app/addons/documents/index-editor/components.react.jsx index 83d4279..63c60f8 100644 --- a/app/addons/documents/index-editor/components.react.jsx +++ b/app/addons/documents/index-editor/components.react.jsx @@ -25,7 +25,7 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, ReactComponents, var indexEditorStore = Stores.indexEditorStore; var getDocUrl = app.helpers.getDocUrl; var StyledSelect = ReactComponents.StyledSelect; - + var CodeEditor = ReactComponents.CodeEditor; var DesignDocSelector = React.createClass({ @@ -134,109 +134,6 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, ReactComponents, }); - var Beautify = React.createClass({ - noOfLines: function () { - return this.props.code.split(/\r\n|\r|\n/).length; - }, - - canBeautify: function () { - if (this.noOfLines() === 1) { - return true; - } - - return false; - }, - - addTooltip: function () { - if (this.canBeautify) { - $('.beautify-tooltip').tooltip(); - } - }, - - componentDidMount: function () { - this.addTooltip(); - }, - - beautify: function (event) { - event.preventDefault(); - var beautifiedCode = beautifyHelper(this.props.code); - this.props.beautifiedCode(beautifiedCode); - - }, - - render: function () { - if(!this.canBeautify()) { - return null; - } - - return ( - <button onClick={this.beautify} className="beautify beautify_map btn btn-primary btn-large beautify-tooltip" type="button" data-toggle="tooltip" title="Reformat your minified code to make edits to it."> - beautify this code - </button> - ); - } - }); - - var CodeEditor = React.createClass({ - render: function () { - var code = this.aceEditor ? this.aceEditor.getValue() : this.props.code; - var docsLink; - if (this.props.docs) { - docsLink = <a className="help-link" data-bypass="true" href={getDocUrl(this.props.docs)} target="_blank"> - <i className="icon-question-sign"></i> - </a>; - - } - return ( - <div className="control-group"> - <label htmlFor="ace-function"> - <strong>{this.props.title}</strong> - {docsLink} - </label> - <div className="js-editor" id={this.props.id}>{this.props.code}</div> - <Beautify code={code} beautifiedCode={this.setEditorValue} /> - </div> - ); - }, - - setEditorValue: function (code) { - this.aceEditor.setValue(code); - //this is not a good practice normally but because we working with a backbone view as the mapeditor - //that keeps the map code state this is the best way to force a render so that the beautify button will hide - this.forceUpdate(); - }, - - getValue: function () { - return this.aceEditor.getValue(); - }, - - getEditor: function () { - return this.aceEditor; - }, - - componentDidMount: function () { - this.aceEditor = new Components.Editor({ - editorId: this.props.id, - mode: 'javascript', - couchJSHINT: true - }); - this.aceEditor.render(); - }, - - shouldComponentUpdate: function () { - //we don't want to re-render the map editor as we are using backbone underneath - //which will cause the editor to break - this.aceEditor.editSaved(); - - return false; - }, - - componentWillUnmount: function () { - this.aceEditor.remove(); - }, - - }); - var ReduceEditor = React.createClass({ getStoreState: function () { @@ -499,7 +396,7 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, ReactComponents, id={'map-function'} ref="mapEditor" title={"Map function"} - docs={'MAP_FUNCS'} + docs={getDocUrl('MAP_FUNCS')} code={this.state.map} /> </div> </div> @@ -564,7 +461,6 @@ function (app, FauxtonAPI, React, Stores, Actions, Components, ReactComponents, ReduceEditor: ReduceEditor, Editor: Editor, DesignDocSelector: DesignDocSelector, - Beautify: Beautify, StyledSelect: StyledSelect }; http://git-wip-us.apache.org/repos/asf/couchdb-fauxton/blob/18c96098/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx ---------------------------------------------------------------------- diff --git a/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx b/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx index 4bad4a6..659cc8e 100644 --- a/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx +++ b/app/addons/documents/tests/viewIndex.componentsSpec.react.jsx @@ -198,43 +198,4 @@ define([ }); }); - - describe('Beautify', function () { - var container, beautifyEl, reduceStub; - - beforeEach(function () { - container = document.createElement('div'); - }); - - afterEach(function () { - React.unmountComponentAtNode(container); - }); - - it('should be empty for multi-lined code', function () { - var correctCode = 'function() {\n console.log("hello");\n}'; - beautifyEl = TestUtils.renderIntoDocument(<Views.Beautify code={correctCode}/>, container); - assert.ok(_.isNull(beautifyEl.getDOMNode())); - }); - - it('should have button to beautify for single line code', function () { - var badCode = 'function () { console.log("hello"); }'; - beautifyEl = TestUtils.renderIntoDocument(<Views.Beautify code={badCode}/>, container); - assert.ok($(beautifyEl.getDOMNode()).hasClass('beautify')); - }); - - it('on click beautifies code', function () { - var fixedCode; - var correctCode = 'function() {\n console.log("hello");\n}'; - - var beautifiedCode = function (code) { - fixedCode = code; - }; - - beautifyEl = TestUtils.renderIntoDocument(<Views.Beautify beautifiedCode={beautifiedCode} code={'function () { console.log("hello"); }'} noOfLines={1}/>, container); - TestUtils.Simulate.click(beautifyEl.getDOMNode()); - assert.equal(fixedCode, correctCode); - - }); - - }); });
