From d7b05e485d0ac1858297bfb3a06b5164d621faad Mon Sep 17 00:00:00 2001 From: cahrens Date: Mon, 7 Jan 2013 15:32:11 -0500 Subject: [PATCH] Add insertion of problem types. --- .../xmodule/js/spec/problem/edit_spec.coffee | 48 ++++++++++ .../xmodule/js/src/problem/edit.coffee | 90 ++++++++++++++++--- 2 files changed, 124 insertions(+), 14 deletions(-) diff --git a/common/lib/xmodule/xmodule/js/spec/problem/edit_spec.coffee b/common/lib/xmodule/xmodule/js/spec/problem/edit_spec.coffee index 906a228335..6a9f6b6209 100644 --- a/common/lib/xmodule/xmodule/js/spec/problem/edit_spec.coffee +++ b/common/lib/xmodule/xmodule/js/spec/problem/edit_spec.coffee @@ -1,4 +1,52 @@ describe 'MarkdownEditingDescriptor', -> + + describe 'insertMultipleChoice', -> + it 'inserts the template if selection is empty', -> + revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('') + expect(revisedSelection).toEqual(MarkdownEditingDescriptor.multipleChoiceTemplate) + it 'wraps existing text', -> + revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('foo\nbar') + expect(revisedSelection).toEqual('( ) foo\n( ) bar\n') + it 'recognizes x as a selection if there is non-whitespace after x', -> + revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('a\nx b\nc\nx \nd\n x e') + expect(revisedSelection).toEqual('( ) a\n(x) b\n( ) c\n( ) x \n( ) d\n(x) e\n') + it 'removes multiple newlines', -> + revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice('a\nx b\n\n\nc') + expect(revisedSelection).toEqual('( ) a\n(x) b\n( ) c\n') + + describe 'insertCheckboxChoice', -> + # Note, shares code with insertMultipleChoice. Therefore only doing smoke test. + it 'inserts the template if selection is empty', -> + revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice('') + expect(revisedSelection).toEqual(MarkdownEditingDescriptor.checkboxChoiceTemplate) + it 'wraps existing text', -> + revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice('foo\nbar') + expect(revisedSelection).toEqual('[ ] foo\n[ ] bar\n') + + describe 'insertStringInput', -> + it 'inserts the template if selection is empty', -> + revisedSelection = MarkdownEditingDescriptor.insertStringInput('') + expect(revisedSelection).toEqual(MarkdownEditingDescriptor.stringInputTemplate) + it 'wraps existing text', -> + revisedSelection = MarkdownEditingDescriptor.insertStringInput('my text') + expect(revisedSelection).toEqual('= my text') + + describe 'insertNumberInput', -> + it 'inserts the template if selection is empty', -> + revisedSelection = MarkdownEditingDescriptor.insertNumberInput('') + expect(revisedSelection).toEqual(MarkdownEditingDescriptor.numberInputTemplate) + it 'wraps existing text', -> + revisedSelection = MarkdownEditingDescriptor.insertNumberInput('my text') + expect(revisedSelection).toEqual('= my text') + + describe 'insertSelect', -> + it 'inserts the template if selection is empty', -> + revisedSelection = MarkdownEditingDescriptor.insertSelect('') + expect(revisedSelection).toEqual(MarkdownEditingDescriptor.selectTemplate) + it 'wraps existing text', -> + revisedSelection = MarkdownEditingDescriptor.insertSelect('my text') + expect(revisedSelection).toEqual('[[my text]]') + describe 'markdownToXml', -> it 'converts raw text to paragraph', -> data = MarkdownEditingDescriptor.markdownToXml('foo') diff --git a/common/lib/xmodule/xmodule/js/src/problem/edit.coffee b/common/lib/xmodule/xmodule/js/src/problem/edit.coffee index b869bde966..4e636d3de9 100644 --- a/common/lib/xmodule/xmodule/js/src/problem/edit.coffee +++ b/common/lib/xmodule/xmodule/js/src/problem/edit.coffee @@ -1,4 +1,10 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor + @multipleChoiceTemplate : "( ) incorrect\n( ) incorrect\n(x) correct\n" + @checkboxChoiceTemplate: "[x] correct\n[ ] incorrect\n[x] correct\n" + @stringInputTemplate: "= answer\n" + @numberInputTemplate: "= answer +- x%\n" + @selectTemplate: "[[incorrect, (correct), incorrect]]\n" + constructor: (element) -> $body.on('click', '.editor-tabs .tab', @changeEditor) $body.on('click', '.editor-bar a', @onToolbarButton); @@ -19,24 +25,32 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor changeEditor: (e) => e.preventDefault(); - $('.editor-tabs .current').removeClass('current') - $(e.currentTarget).addClass('current') - if (@current_editor == @xml_editor) - @setCurrentEditor(@markdown_editor) - # onMarkdownEditorUpdate(); - else - @setCurrentEditor(@xml_editor) - @xml_editor.setValue(MarkdownEditingDescriptor.markdownToXml(@markdown_editor.getValue())) + if not $(e.currentTarget).hasClass('current') + $('.editor-tabs .current').removeClass('current') + $(e.currentTarget).addClass('current') + if (@current_editor == @xml_editor) + @setCurrentEditor(@markdown_editor) + else + @setCurrentEditor(@xml_editor) + @xml_editor.setValue(MarkdownEditingDescriptor.markdownToXml(@markdown_editor.getValue())) onToolbarButton: (e) => e.preventDefault(); + selection = @markdown_editor.getSelection() + + revisedSelection = null switch $(e.currentTarget).attr('class') - when "multiple-choice-button" then console.log("multiple choice") - when "string-button" then console.log("string-button") - when "number-button" then console.log("number-button") - when "checks-button" then console.log("checks-button") - when "dropdown-button" then console.log("dropdown-button") - else console.log("unknown option") + when "multiple-choice-button" then revisedSelection = MarkdownEditingDescriptor.insertMultipleChoice(selection) + when "string-button" then revisedSelection = MarkdownEditingDescriptor.insertStringInput(selection) + when "number-button" then revisedSelection = MarkdownEditingDescriptor.insertNumberInput(selection) + when "checks-button" then revisedSelection = MarkdownEditingDescriptor.insertCheckboxChoice(selection) + when "dropdown-button" then revisedSelection = MarkdownEditingDescriptor.insertSelect(selection) + else # do nothing + + if revisedSelection != null + @markdown_editor.replaceSelection(revisedSelection) + @markdown_editor.focus() + setCurrentEditor: (editor) -> $(@current_editor.getWrapperElement()).hide() @@ -49,6 +63,54 @@ class @MarkdownEditingDescriptor extends XModule.Descriptor $body.off('click', '.editor-bar a', @onToolbarButton); data: @xml_editor.getValue() + @insertMultipleChoice: (selectedText) -> + return MarkdownEditingDescriptor.insertGenericChoice(selectedText, '(', ')', MarkdownEditingDescriptor.multipleChoiceTemplate) + + @insertCheckboxChoice: (selectedText) -> + return MarkdownEditingDescriptor.insertGenericChoice(selectedText, '[', ']', MarkdownEditingDescriptor.checkboxChoiceTemplate) + + @insertGenericChoice: (selectedText, choiceStart, choiceEnd, template) -> + if selectedText.length > 0 + # Replace adjacent newlines with a single newline + cleanSelectedText = selectedText.replace(/\n+/g, '\n') + lines = cleanSelectedText.split('\n') + revisedLines = '' + for line in lines + revisedLines += choiceStart + # This is looking for a x before text to mark as selected. + if /x\s/i.test(line) + # Remove the x and any initial whitespace + lineWithoutX = line.replace(/^(\s+)?x/i, '') + # Check if any non-whitespace chars remain on the line + if not /^\s+$/.test(lineWithoutX) + # Remove initial whitespace, x, and space immediately after + line = line.replace(/^(\s+)?x\s/i, '') + revisedLines += 'x' + else + revisedLines += ' ' + else + revisedLines += ' ' + revisedLines += choiceEnd + ' ' + line + '\n' + return revisedLines + else + return template + + @insertStringInput: (selectedText) -> + return MarkdownEditingDescriptor.insertGenericInput(selectedText, '= ', '', MarkdownEditingDescriptor.stringInputTemplate) + + @insertNumberInput: (selectedText) -> + return MarkdownEditingDescriptor.insertGenericInput(selectedText, '= ', '', MarkdownEditingDescriptor.numberInputTemplate) + + @insertSelect: (selectedText) -> + return MarkdownEditingDescriptor.insertGenericInput(selectedText, '[[', ']]', MarkdownEditingDescriptor.selectTemplate) + + @insertGenericInput: (selectedText, lineStart, lineEnd, template) -> + if selectedText.length > 0 + # TODO: should this insert a newline afterwards? + return lineStart + selectedText + lineEnd + else + return template + @markdownToXml: (markdown)-> toXml = `function(markdown) { var xml = markdown;