From 44fb9561e8afe99096416f4b0c7b6e8870a7c5cb Mon Sep 17 00:00:00 2001 From: Tom Giannattasio Date: Wed, 7 Nov 2012 17:21:20 -0500 Subject: [PATCH] added a ton of speed editor goodness --- cms/static/coffee/src/views/unit.coffee | 39 ++- cms/static/img/problem-editor-icons.png | Bin 0 -> 3309 bytes cms/static/js/speed-editor.js | 421 ++++++++++++++++++++++++ cms/static/sass/_base.scss | 26 ++ cms/static/sass/_graphics.scss | 38 +++ cms/static/sass/_unit.scss | 157 +++++++-- cms/templates/unit.html | 133 ++++++-- 7 files changed, 765 insertions(+), 49 deletions(-) create mode 100644 cms/static/img/problem-editor-icons.png create mode 100644 cms/static/js/speed-editor.js diff --git a/cms/static/coffee/src/views/unit.coffee b/cms/static/coffee/src/views/unit.coffee index a250925bf9..6c06c85400 100644 --- a/cms/static/coffee/src/views/unit.coffee +++ b/cms/static/coffee/src/views/unit.coffee @@ -1,6 +1,7 @@ class CMS.Views.UnitEdit extends Backbone.View events: - 'click .new-component .new-component-type a': 'showComponentTemplates' + # 'click .new-component .new-component-type a': 'showComponentTemplates' + 'click .new-component .new-component-type a': 'addNewComponent' 'click .new-component .cancel-button': 'closeNewComponent' 'click .new-component-templates .new-component-template a': 'saveNewComponent' 'click .new-component-templates .cancel-button': 'closeNewComponent' @@ -79,6 +80,42 @@ class CMS.Views.UnitEdit extends Backbone.View @$newComponentItem.find('.rendered-component').remove() @$newComponentItem.css('height', @$newComponentButton.outerHeight()) + addNewComponent: (event) => + event.preventDefault() + + @$componentItem = $('
  • ').addClass('editing') + $modalCover.show() + $modalCover.bind('click', @closeEditor) + type = $(event.currentTarget).data('type') + + switch type + when 'video' + @$editor = $($('#video-editor').html()) + $preview = $($('#video-preview').html()) + when 'problem' + @$editor = $($('#problem-editor').html()) + $preview = $($('#problem-preview').html()) + initProblemEditors(@$editor, $preview) + + @$editor.find('.save-button').bind('click', => + @$componentItem.removeClass('editing') + @closeEditor() + ) + + $componentActions = $($('#component-actions').html()); + + @$componentItem.append(@$editor) + @$componentItem.append($preview) + @$componentItem.append($componentActions); + @$newComponentItem.before(@$componentItem) + + closeEditor: (event) => + console.log('close') + $modalCover.hide() + $modalCover.unbind('click', @closeEditor) + @$editor.remove() + @$componentItem.removeClass('editing') + saveNewComponent: (event) => event.preventDefault() diff --git a/cms/static/img/problem-editor-icons.png b/cms/static/img/problem-editor-icons.png new file mode 100644 index 0000000000000000000000000000000000000000..62f078560fc47b5765e1d3c05e3b4077d7960ab4 GIT binary patch literal 3309 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 literal 0 HcmV?d00001 diff --git a/cms/static/js/speed-editor.js b/cms/static/js/speed-editor.js new file mode 100644 index 0000000000..7d6a37a6b2 --- /dev/null +++ b/cms/static/js/speed-editor.js @@ -0,0 +1,421 @@ +var $body; +var $preview; +var $tooltip; +var simpleEditor; +var xmlEditor; +var currentEditor; +var controlDown; +var commandDown; + + +function initProblemEditors($editor, $prev) { + simpleEditor = CodeMirror.fromTextArea($editor.find('.edit-box')[0], { + lineWrapping: true, + extraKeys: { + 'Ctrl-N': newUnit, + 'Ctrl-H': makeHeader, + 'Ctrl-V': makeVideo, + 'Ctrl-M': makeMultipleChoice, + 'Ctrl-C': makeCheckboxes, + 'Ctrl-S': makeStringInput, + 'Shift-Ctrl-3': makeNumberInput, + 'Shift-Ctrl-S': makeSelect + }, + mode: null, + onChange: onSimpleEditorUpdate + }); + + xmlEditor = CodeMirror.fromTextArea($editor.find('.xml-box')[0], { + lineWrapping: true, + mode: 'xml', + lineNumbers: true + }); + + currentEditor = simpleEditor; + + $(simpleEditor.getWrapperElement()).css('background', '#fff'); + $(xmlEditor.getWrapperElement()).css({ + 'background': '#fff' + }).hide(); + + $(simpleEditor.getWrapperElement()).bind('click', setFocus); + $preview = $prev.find('.problem'); + + $body.on('click', '.editor-bar a', onEditorButton); + $body.on('click', '.editor-tabs a', setEditorTab); + $(document).bind('keyup', onKeyboard); +} + +function setEditorTab(e) { + e.preventDefault(); + $('.editor-tabs .current').removeClass('current'); + $(this).addClass('current'); + if($(this).hasClass('simple-tab')) { + currentEditor = simpleEditor; + $(simpleEditor.getWrapperElement()).show(); + $(xmlEditor.getWrapperElement()).hide(); + $(simpleEditor).focus(); + } else { + currentEditor = xmlEditor; + $(simpleEditor.getWrapperElement()).hide(); + $(xmlEditor.getWrapperElement()).show(); + $(xmlEditor).focus(); + } + onSimpleEditorUpdate(); +} + +function setFocus(e) { + $(simpleEditor).focus(); +} + +function onSimpleEditorUpdate() { + updatePreview(); + updateXML(); +} + +function updateXML() { + var val = simpleEditor.getValue(); + var xml = val; + + // replace headers + xml = xml.replace(/(^.*)\n(?=\=\=+)/g, '

    $1

    '); + xml = xml.replace(/\=\=+/g, ''); + + // group multiple choice answers + xml = xml.replace(/(\(.?\).*\n*)+/g, function(match, p) { + var groupString = '\n'; + groupString += ' \n'; + var options = match.split('\n'); + for(var i = 0; i < options.length; i++) { + if(options[i].length > 0) { + var value = options[i].split(/\)\s*/)[1]; + var correct = /\(x\)/i.test(options[i]); + groupString += ' ' + value + '\n'; + } + } + groupString += ' \n'; + groupString += '\n\n'; + return groupString; + }); + + // group check answers + xml = xml.replace(/(\[.?\].*\n*)+/g, function(match, p) { + var groupString = '\n'; + groupString += ' \n'; + var options = match.split('\n'); + for(var i = 0; i < options.length; i++) { + if(options[i].length > 0) { + var value = options[i].split(/\]\s*/)[1]; + var correct = /\[x\]/i.test(options[i]); + groupString += ' ' + value + '\n'; + } + } + groupString += ' \n'; + groupString += '\n\n'; + return groupString; + }); + + // replace videos + xml = xml.replace(/\{\{video\s(.*)\}\}/g, '
  • % endfor -
  • - - New Component - +
  • -
    Select Component Type
    +
    Add New Component
      % for type in sorted(component_templates.keys()):
    • @@ -48,22 +154,7 @@
    • % endfor
    - Cancel -
    - % for type, templates in sorted(component_templates.items()): -
    -
      - % for name, location in templates: -
    • - - ${name} - -
    • - % endfor -
    - Cancel -
    - % endfor +