Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.

Studio: Add "raw HTML" editor so that authors can write HTML that will not be
changed in any way. STUD-1562

Blades: Show the HD button only if there is an HD version available. BLD-937.

Studio: Add edit button to leaf xblocks on the container page. STUD-1306.
Expand Down
2 changes: 2 additions & 0 deletions cms/djangoapps/contentstore/features/component.feature
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,13 @@ Feature: CMS.Component Adding
| Text |
| Announcement |
| Zooming Image |
| Raw HTML |
Then I see HTML components in this order:
| Component |
| Text |
| Announcement |
| Zooming Image |
| Raw HTML |

Scenario: I can add Latex HTML components
Given I am in Studio editing a new unit
Expand Down
2 changes: 2 additions & 0 deletions cms/djangoapps/contentstore/features/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ def see_a_multi_step_component(step, category):
'<h2>ZOOMING DIAGRAMS</h2>',
'E-text Written in LaTeX':
'<h2>Example: E-text page</h2>',
'Raw HTML':
'<p>This template is similar to the Text template. The only difference is',
}
actual_html = world.css_html(selector, index=idx)
assert_in(html_matcher[step_hash['Component']], actual_html)
Expand Down
63 changes: 61 additions & 2 deletions cms/djangoapps/contentstore/features/html-editor.feature
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Feature: CMS.HTML Editor
Scenario: User can view metadata
Given I have created a Blank HTML Page
And I edit and select Settings
Then I see only the HTML display name setting
Then I see the HTML component settings

# Safari doesn't save the name properly
@skip_safari
Expand Down Expand Up @@ -47,6 +47,26 @@ Feature: CMS.HTML Editor
--></style>
"""

Scenario: TinyMCE and CodeMirror preserve span tags
Given I have created a Blank HTML Page
When I edit the page
And type "<span>Test</span>" in the code editor and press OK
And I save the page
Then the page text contains:
"""
<span>Test</span>
"""

Scenario: TinyMCE and CodeMirror preserve math tags
Given I have created a Blank HTML Page
When I edit the page
And type "<math><msup><mi>x</mi><mn>2</mn></msup></math>" in the code editor and press OK
And I save the page
Then the page text contains:
"""
<math><msup><mi>x</mi><mn>2</mn></msup></math>
"""

Scenario: TinyMCE toolbar buttons are as expected
Given I have created a Blank HTML Page
When I edit the page
Expand All @@ -57,7 +77,7 @@ Feature: CMS.HTML Editor
When I edit the page
And type "<img src="/static/image.jpg">" in the code editor and press OK
Then the src link is rewritten to "c4x/MITx/999/asset/image.jpg"
And the code editor displays "<p><img src="/static/image.jpg" alt="" /></p>"
And the code editor displays "<p><img src="/static/image.jpg" /></p>"

Scenario: Code format toolbar button wraps text with code tags
Given I have created a Blank HTML Page
Expand All @@ -69,3 +89,42 @@ Feature: CMS.HTML Editor
"""
<p><code>display as code</code></p>
"""

Scenario: Raw HTML component does not change text
Given I have created a raw HTML component
When I edit the page
And type "<li>zzzz<ol>" into the Raw Editor
And I save the page
Then the page text contains:
"""
<li>zzzz<ol>
"""
And I edit the page
Then the Raw Editor contains exactly:
"""
<li>zzzz<ol>
"""

Scenario: Can switch from Visual Editor to Raw
Given I have created a Blank HTML Page
When I edit the component and select the Raw Editor
And I save the page
When I edit the page
And type "fancy html" into the Raw Editor
And I save the page
Then the page text contains:
"""
fancy html
"""

Scenario: Can switch from Raw Editor to Visual
Given I have created a raw HTML component
And I edit the component and select the Visual Editor
And I save the page
When I edit the page
And type "less fancy html" in the code editor and press OK
And I save the page
Then the page text contains:
"""
less fancy html
"""
45 changes: 42 additions & 3 deletions cms/djangoapps/contentstore/features/html-editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# pylint: disable=C0111

from lettuce import world, step
from nose.tools import assert_in, assert_equal # pylint: disable=no-name-in-module
from nose.tools import assert_in, assert_false, assert_true, assert_equal # pylint: disable=no-name-in-module
from common import type_in_codemirror, get_codemirror_value

CODEMIRROR_SELECTOR_PREFIX = "$('iframe').contents().find"
Expand All @@ -18,9 +18,24 @@ def i_created_blank_html_page(step):
)


@step('I see only the HTML display name setting$')
@step('I have created a raw HTML component')
def i_created_raw_html(step):
world.create_course_with_unit()
world.create_component_instance(
step=step,
category='html',
component_type='Raw HTML'
)


@step('I see the HTML component settings$')
def i_see_only_the_html_display_name(step):
world.verify_all_setting_entries([['Display Name', "Text", False]])
world.verify_all_setting_entries(
[
['Display Name', "Text", False],
['Editor', "Visual", False]
]
)


@step('I have created an E-text Written in LaTeX$')
Expand Down Expand Up @@ -81,6 +96,10 @@ def check_link_in_link_plugin(step, path):

@step('type "(.*)" in the code editor and press OK$')
def type_in_codemirror_plugin(step, text):
# Verify that raw code editor is not visible.
assert_true(world.css_has_class('.CodeMirror', 'is-inactive'))
# Verify that TinyMCE editor is present
assert_true(world.is_css_present('.tiny-mce'))
use_code_editor(
lambda: type_in_codemirror(0, text, CODEMIRROR_SELECTOR_PREFIX)
)
Expand Down Expand Up @@ -131,6 +150,11 @@ def check_page_text(step):
assert_in(step.multiline, world.css_find('.xmodule_HtmlModule').html)


@step('the Raw Editor contains exactly:')
def check_raw_editor_text(step):
assert_equal(step.multiline, get_codemirror_value(0))


@step('the src link is rewritten to "(.*)"$')
def image_static_link_is_rewritten(step, path):
# Find the TinyMCE iframe within the main window
Expand Down Expand Up @@ -199,3 +223,18 @@ def set_text_and_select(step, text):
def select_code_button(step):
# This is our custom "code style" button. It uses an image instead of a class.
world.css_click(".mce-i-none")


@step('type "(.*)" into the Raw Editor$')
def type_in_raw_editor(step, text):
# Verify that CodeMirror editor is not hidden
assert_false(world.css_has_class('.CodeMirror', 'is-inactive'))
# Verify that TinyMCE Editor is not present
assert_true(world.is_css_not_present('.tiny-mce'))
type_in_codemirror(0, text)


@step('I edit the component and select the (Raw|Visual) Editor$')
def select_editor(step, editor):
world.edit_component_and_select_settings()
world.browser.select('Editor', editor)
7 changes: 5 additions & 2 deletions cms/templates/widgets/html-edit.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
<%! from django.utils.translation import ugettext as _ %>

<div class="wrapper-comp-editor" id="editor-tab" data-base-asset-url="${base_asset_url}">
<div class="wrapper-comp-editor" id="editor-tab" data-base-asset-url="${base_asset_url}" data-editor="${editor}">
<section class="html-editor editor">
<div class="row">
<textarea class="tiny-mce">${data | h}</textarea>
% if editor == 'visual':
<textarea class="tiny-mce">${data | h}</textarea>
% endif
<textarea name="" class="edit-box">${data | h}</textarea>
</div>
</section>
</div>
Expand Down
23 changes: 3 additions & 20 deletions common/lib/xmodule/xmodule/css/html/edit.scss
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
// HTML component editor:
// HTML component editor:
.html-editor {
@include clearfix();

.CodeMirror {
@include box-sizing(border-box);
position: absolute;
top: 46px;
width: 100%;
height: 379px;
border: 1px solid #3c3c3c;
border-top: 1px solid #8891a1;
background: #fff;
color: #3c3c3c;
}

.CodeMirror-scroll {
height: 100%;
}

.editor-tabs {
top: 0 !important;
right: 10px;
z-index: 99;
height: 435px;
}

.is-inactive {
display: none;
}
}
}
11 changes: 11 additions & 0 deletions common/lib/xmodule/xmodule/html_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,16 @@ class HtmlFields(object):
default=False,
scope=Scope.settings
)
editor = String(
help="Select Visual to enter content and have the editor automatically create the HTML. Select Raw to edit HTML directly. If you change this setting, you must save the component and then re-open it for editing.",
display_name="Editor",
default="visual",
values=[
{"display_name": "Visual", "value": "visual"},
{"display_name": "Raw", "value": "raw"}
],
scope=Scope.settings
)


class HtmlModule(HtmlFields, XModule):
Expand Down Expand Up @@ -113,6 +123,7 @@ def get_context(self):
_context.update({
'base_asset_url': StaticContent.get_base_url_path_for_course_assets(self.location) + '/',
'enable_latex_compiler': self.use_latex_compiler,
'editor': self.editor
})
return _context

Expand Down
10 changes: 10 additions & 0 deletions common/lib/xmodule/xmodule/js/fixtures/html-edit-visual.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<div class="test-component">
<div class="wrapper-comp-editor" id="editor-tab" data-base-asset-url="/c4x/foo/bar/asset/" data-editor="visual">
<section class="html-editor editor">
<div class="row">
<textarea class="tiny-mce"><p>original visual text</p></textarea>
<textarea name="" class="edit-box">raw text</textarea>
</div>
</section>
</div>
</div>
3 changes: 0 additions & 3 deletions common/lib/xmodule/xmodule/js/fixtures/html-edit.html

This file was deleted.

9 changes: 9 additions & 0 deletions common/lib/xmodule/xmodule/js/fixtures/html-editor-raw.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div class="test-component">
<div class="wrapper-comp-editor" id="editor-tab" data-editor="raw">
<section class="html-editor editor">
<div class="row">
<textarea name="" class="edit-box">raw text</textarea>
</div>
</section>
</div>
</div>
28 changes: 14 additions & 14 deletions common/lib/xmodule/xmodule/js/spec/html/edit_spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,32 @@ describe 'HTMLEditingDescriptor', ->
window.baseUrl = "/static/deadbeef"
afterEach ->
delete window.baseUrl
describe 'HTML Editor', ->
describe 'Visual HTML Editor', ->
beforeEach ->
loadFixtures 'html-edit.html'
@descriptor = new HTMLEditingDescriptor($('.html-edit'))
it 'Returns data from Visual Editor if Visual Editor is dirty', ->
loadFixtures 'html-edit-visual.html'
@descriptor = new HTMLEditingDescriptor($('.test-component'))
it 'Returns data from Visual Editor if text has changed', ->
visualEditorStub =
isDirty: () -> true
getContent: () -> 'from visual editor'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor')
it 'Returns data from Visual Editor even if Visual Editor is not dirty', ->
it 'Returns data from Raw Editor if text has not changed', ->
visualEditorStub =
isDirty: () -> false
getContent: () -> 'from visual editor'
getContent: () -> '<p>original visual text</p>'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
visualEditorStub
data = @descriptor.save().data
expect(data).toEqual('from visual editor')
expect(data).toEqual('raw text')
it 'Performs link rewriting for static assets when saving', ->
visualEditorStub =
isDirty: () -> true
getContent: () -> 'from visual editor with /c4x/foo/bar/asset/image.jpg'
spyOn(@descriptor, 'getVisualEditor').andCallFake () ->
visualEditorStub
@descriptor.base_asset_url = '/c4x/foo/bar/asset/'
data = @descriptor.save().data
expect(data).toEqual('from visual editor with /static/image.jpg')
it 'When showing visual editor links are rewritten to c4x format', ->
@descriptor = new HTMLEditingDescriptor($('.html-edit'))
@descriptor.base_asset_url = '/c4x/foo/bar/asset/'

visualEditorStub =
content: 'text /static/image.jpg'
startContent: 'text /static/image.jpg'
Expand All @@ -45,3 +38,10 @@ describe 'HTMLEditingDescriptor', ->

@descriptor.initInstanceCallback(visualEditorStub)
expect(visualEditorStub.getContent()).toEqual('text /c4x/foo/bar/asset/image.jpg')
describe 'Raw HTML Editor', ->
beforeEach ->
loadFixtures 'html-editor-raw.html'
@descriptor = new HTMLEditingDescriptor($('.test-component'))
it 'Returns data from raw editor', ->
data = @descriptor.save().data
expect(data).toEqual('raw text')
Loading