From 3ace76c4a1a59da630a2a41723ff0db6f7a4dc16 Mon Sep 17 00:00:00 2001 From: abe33 Date: Wed, 3 Feb 2016 01:04:10 +0100 Subject: [PATCH] Implement using default CSV config from table settings Closes #28 --- lib/csv-editor-element.coffee | 1 + lib/csv-editor-form-element.coffee | 67 ++++++++++++++++++------------ lib/tablr.coffee | 4 +- spec/csv-editor-spec.coffee | 57 ++++++++++++++++++++++++- 4 files changed, 100 insertions(+), 29 deletions(-) diff --git a/lib/csv-editor-element.coffee b/lib/csv-editor-element.coffee index 69964b4..638ede6 100644 --- a/lib/csv-editor-element.coffee +++ b/lib/csv-editor-element.coffee @@ -86,6 +86,7 @@ class CSVEditorElement extends HTMLElement @updatePreview(options) container.appendChild(@form) + @form.setModel(@model.options) if @model? @appendChild(container) updatePreview: (options) -> diff --git a/lib/csv-editor-form-element.coffee b/lib/csv-editor-form-element.coffee index 22f4f03..b1a6bb3 100644 --- a/lib/csv-editor-form-element.coffee +++ b/lib/csv-editor-form-element.coffee @@ -4,6 +4,24 @@ encodings = require('./encodings') nextId = 0 +labelFromValue = (value) -> + String(value) + .replace('\n','\\n') + .replace('\t','\\t') + .replace('\r','\\r') + +valueFromLabel = (value) -> + String(value) + .replace('\\n','\n') + .replace('\\t','\t') + .replace('\\r','\r') + +normalizeValue = (value) -> + labelFromValue(value?.replace('"','"')) + +denormalizeValue = (value) -> + valueFromLabel(value?.replace('"', '"')) + module.exports = class CSVEditorFormElement extends HTMLElement SpacePenDSL.includeInto(this) @@ -12,23 +30,13 @@ class CSVEditorFormElement extends HTMLElement @content: -> id = nextId++ - labelFromValue = (value) -> - String(value) - .replace('\n','\\n') - .replace('\t','\\t') - .replace('\r','\\r') - .replace('\t','\\t') - - normalizeValue = (value) -> - value?.replace('"','"') - radios = (options) => - {name, label, options, outlet, selected} = options + {name, label, options, outlet, output, selected} = options - @div class: 'controls btn-group', 'data-initial': selected, 'data-id': outlet, => + @div class: 'controls btn-group', 'data-initial': selected, 'data-id': outlet, 'data-output': output ? outlet, => for optionName, value of options inputOption = type: 'radio', value: normalizeValue(value), name: name, id: "#{optionName}-#{name}-#{id}", 'data-name': optionName - inputOption.checked = true if selected is optionName + inputOption.checked = true if optionName is value @input(inputOption) @label class: 'btn', for: "#{optionName}-#{name}-#{id}", labelFromValue(value) @@ -113,7 +121,8 @@ class CSVEditorFormElement extends HTMLElement radiosWithTextEditor { label: 'Column Delimiter' name: 'delimiter' - outlet: 'delimiter' + output: 'delimiter' + outlet: 'columnDelimiter' selected: 'comma' options: 'comma': ',' @@ -200,16 +209,26 @@ class CSVEditorFormElement extends HTMLElement @emitChangeEvent() initializeDefaults: (options) -> + @querySelector('[id^="header"]').checked = true if options.header + @querySelector('[id^="eof"]').checked = true if options.eof + @querySelector('[id^="quoted"]').checked = true if options.quoted + @querySelector('[id^="skip-empty-lines"]').checked = true if options.skip_empty_lines + + @querySelector('[id^="left-trim"]').checked = true if options.ltrim + @querySelector('[id^="right-trim"]').checked = true if options.rtrim + @querySelector('[id^="both-trim"]').checked = true if options.trim + radioGroups = @querySelectorAll('.with-text-editor .btn-group') Array::forEach.call radioGroups, (radioGroup) => outlet = radioGroup.dataset.id + output = radioGroup.dataset.output initial = radioGroup.dataset.initial radios = radioGroup.querySelectorAll('input[type="radio"]') radioOptions = {} - value = options[outlet] + value = labelFromValue(options[output] ? atom.config.get("tablr.csvEditor.#{outlet}")) if value? and radio = Array::filter.call(radios, (r) -> r.value is value)[0] radio.checked = true @@ -249,15 +268,6 @@ class CSVEditorFormElement extends HTMLElement @messagesContainer.innerHTML = '' setModel: (options={}) -> - @querySelector('[id^="header"]').checked = true if options.header - @querySelector('[id^="eof"]').checked = true if options.eof - @querySelector('[id^="quoted"]').checked = true if options.quoted - @querySelector('[id^="skip-empty-lines"]').checked = true if options.skip_empty_lines - - @querySelector('[id^="left-trim"]').checked = true if options.ltrim - @querySelector('[id^="right-trim"]').checked = true if options.rtrim - @querySelector('[id^="both-trim"]').checked = true if options.trim - requestAnimationFrame => @initializeDefaults(options) collectOptions: -> @@ -276,6 +286,9 @@ class CSVEditorFormElement extends HTMLElement delimiter = @querySelector('[name="delimiter"]:checked')?.value rowDelimiter = @querySelector('[name="row-delimiter"]:checked')?.value + if quote is '' or delimiter is '' or rowDelimiter is '' or comment is '' or escape is '' + throw new Error('It should not be empty') + if quote is 'custom' options.quote = @quoteTextEditor.getText() else @@ -294,14 +307,16 @@ class CSVEditorFormElement extends HTMLElement options.comment = comment if delimiter is 'custom' - options.delimiter = @delimiterTextEditor.getText() + options.delimiter = @columnDelimiterTextEditor.getText() else options.delimiter = delimiter if rowDelimiter is 'custom' options.rowDelimiter = @rowDelimiterTextEditor.getText() else unless rowDelimiter is 'auto' - options.rowDelimiter = rowDelimiter + options.rowDelimiter = denormalizeValue(rowDelimiter) + + console.log options switch trim when 'both' then options.trim = true diff --git a/lib/tablr.coffee b/lib/tablr.coffee index ccbc50b..a144729 100644 --- a/lib/tablr.coffee +++ b/lib/tablr.coffee @@ -106,7 +106,7 @@ module.exports = title: 'Default Row Delimiter' type: 'string' default: 'auto' - quotes: + quote: title: 'Default Quote Character' type: 'string' default: '"' @@ -114,7 +114,7 @@ module.exports = title: 'Default Espace Character' type: 'string' default: '"' - comments: + comment: title: 'Default Comment Character' type: 'string' default: '#' diff --git a/spec/csv-editor-spec.coffee b/spec/csv-editor-spec.coffee index 38a696f..5adb981 100644 --- a/spec/csv-editor-spec.coffee +++ b/spec/csv-editor-spec.coffee @@ -31,7 +31,8 @@ describe "CSVEditor", -> csvEditor = t csvEditorElement = atom.views.getView(csvEditor) - runs -> expect(csvEditor.file).toBeDefined() + runs -> + expect(csvEditor.file).toBeDefined() return @@ -74,6 +75,12 @@ describe "CSVEditor", -> beforeEach -> [csvEditor, csvEditorElement, csvDest, projectPath, tableEditor, tableEditorElement, openSpy, destroySpy, savedContent, spy] = [] + atom.config.set('tablr.csvEditor.rowDelimiter', 'auto') + atom.config.set('tablr.csvEditor.columnDelimiter', ',') + atom.config.set('tablr.csvEditor.quote', '"') + atom.config.set('tablr.csvEditor.escape', '"') + atom.config.set('tablr.csvEditor.comment', '#') + jasmineContent = document.body.querySelector('#jasmine-content') workspaceElement = atom.views.getView(atom.workspace) jasmineContent.appendChild(workspaceElement) @@ -101,6 +108,24 @@ describe "CSVEditor", -> runs -> expect(csvEditor instanceof CSVEditor).toBeTruthy() + it 'fills the form with the default values from the config', -> + atom.config.set('tablr.csvEditor.columnDelimiter', ';') + atom.config.set('tablr.csvEditor.rowDelimiter', '\\r') + atom.config.set('tablr.csvEditor.quote', '\'') + atom.config.set('tablr.csvEditor.escape', '\\') + atom.config.set('tablr.csvEditor.comment', '$') + + openFixture('sample.csv') + runs -> + nextAnimationFrame() + + expect(csvEditorElement.querySelector('[id^="semi-colon"]:checked')).toExist() + expect(csvEditorElement.querySelector('[id^="char-return"]:checked')).toExist() + expect(csvEditorElement.querySelector('[id^="custom-comment"]:checked')).toExist() + expect(csvEditorElement.form.commentTextEditor.getText()).toEqual('$') + expect(csvEditorElement.querySelector('[id^="single-quote-quote"]:checked')).toExist() + expect(csvEditorElement.querySelector('[id^="backslash-escape"]:checked')).toExist() + describe '::copy', -> it 'returns a CSVEditor in a pending state', -> openFixture('sample.csv') @@ -118,6 +143,7 @@ describe "CSVEditor", -> openFixture('sample.csv') runs -> + nextAnimationFrame() changeSpy = jasmine.createSpy('did-change') changeSubscription = csvEditor.file.onDidChange(changeSpy) @@ -231,6 +257,8 @@ describe "CSVEditor", -> describe 'and the csv setting is changed to a valid format', -> beforeEach -> + nextAnimationFrame() + tableEditor = null csvEditorElement.querySelector('[id^="semi-colon"]').checked = true @@ -259,6 +287,7 @@ describe "CSVEditor", -> openFixture('sample.csv', {}) runs -> + nextAnimationFrame() spy = jasmine.createSpy('did-change-path') spyTitle = jasmine.createSpy('did-change-title') csvEditor.onDidChangePath(spy) @@ -289,6 +318,7 @@ describe "CSVEditor", -> openFixture('sample.csv', {}) runs -> + nextAnimationFrame() deleteSpy = jasmine.createSpy('delete') csvEditor.file.onDidDelete(deleteSpy) @@ -333,6 +363,8 @@ describe "CSVEditor", -> openFixture('sample.csv') runs -> + nextAnimationFrame() + destroySpy = jasmine.createSpy('did-destroy') csvEditor.onDidDestroy(destroySpy) @@ -363,6 +395,8 @@ describe "CSVEditor", -> openFixture('sample.csv') runs -> + nextAnimationFrame() + csvEditorElement.querySelector('[id^="remember-choice"]').checked = true destroySpy = jasmine.createSpy('did-destroy') @@ -393,6 +427,8 @@ describe "CSVEditor", -> openFixture('sample.csv') runs -> + nextAnimationFrame() + csvEditor.onDidOpen ({editor}) -> tableEditor = editor @@ -480,6 +516,8 @@ describe "CSVEditor", -> secondCSVEditor = t secondCSVEditorElement = atom.views.getView(secondCSVEditor) + nextAnimationFrame() + tableEditorButton = secondCSVEditorElement.form.openTableEditorButton click(tableEditorButton) @@ -514,6 +552,8 @@ describe "CSVEditor", -> csvEditor = t csvEditorElement = atom.views.getView(csvEditor) + nextAnimationFrame() + csvEditor.onDidOpen ({editor}) -> tableEditor = editor @@ -601,6 +641,8 @@ describe "CSVEditor", -> openFixture('iso-8859-1.csv') runs -> + nextAnimationFrame() + csvEditor.onDidOpen ({editor}) -> tableEditor = editor encodingSelect = csvEditorElement.form.encodingSelect @@ -638,6 +680,8 @@ describe "CSVEditor", -> openFixture('invalid.csv') runs -> + nextAnimationFrame() + tableEditorButton = csvEditorElement.form.openTableEditorButton click(tableEditorButton) @@ -654,6 +698,8 @@ describe "CSVEditor", -> openFixture('semi-colon.csv') runs -> + nextAnimationFrame() + csvEditorElement.querySelector('[id^="semi-colon"]').checked = true csvEditor.onDidOpen ({editor}) -> tableEditor = editor @@ -693,6 +739,8 @@ describe "CSVEditor", -> openFixture('sample.csv') runs -> + nextAnimationFrame() + csvEditorElement.querySelector('[id^="header"]').checked = true csvEditor.onDidOpen ({editor}) -> tableEditor = editor @@ -735,6 +783,8 @@ describe "CSVEditor", -> openFixture('custom-row-delimiter.csv') runs -> + nextAnimationFrame() + csvEditorElement.querySelector('atom-text-editor').getModel().setText('::') csvEditorElement.querySelector('[id^="custom-row-delimiter"]').checked = true csvEditor.onDidOpen ({editor}) -> @@ -909,6 +959,8 @@ describe "CSVEditor", -> it 'serializes the csv editor', -> openFixture('sample.csv') runs -> + nextAnimationFrame() + expect(csvEditor.serialize()).toEqual({ deserializer: 'CSVEditor' filePath: csvDest @@ -919,6 +971,7 @@ describe "CSVEditor", -> describe 'when the editor has a choice', -> it 'serializes the user choice', -> openFixture('sample.csv') + runs -> nextAnimationFrame() waitsForPromise -> csvEditor.openTableEditor() runs -> expect(csvEditor.serialize()).toEqual({ @@ -934,6 +987,7 @@ describe "CSVEditor", -> describe 'when the table editor has a layout', -> it 'serializes the layout', -> openFixture('sample.csv') + runs -> nextAnimationFrame() waitsForPromise -> csvEditor.openTableEditor() runs -> {editor: tableEditor} = csvEditor @@ -967,6 +1021,7 @@ describe "CSVEditor", -> describe 'that has unsaved changes', -> it 'serializes the table editor and its children', -> openFixture('sample.csv') + runs -> nextAnimationFrame() waitsForPromise -> csvEditor.openTableEditor() runs -> csvEditor.editor.addRow()