diff --git a/README.rst b/README.rst index 76cd6aa..3d58ed1 100644 --- a/README.rst +++ b/README.rst @@ -142,8 +142,7 @@ If you prefer to link CSS and Javascript from different locations, the ``markitup_media`` tag can be replaced with two separate tags, ``markitup_css`` and ``markitup_js``. ``markitup_js`` accepts a parameter to suppress jQuery inclusion, just like -``markitup_media``. (Note that jQuery must be included in your -template before the ``markitup_editor`` tag is used). +``markitup_media``. Last, use the ``markitup_editor`` template tag to apply the MarkItUp! editor to a textarea in your page. It accepts one argument, the HTML diff --git a/markitup/static/markitup/ajax_csrf.js b/markitup/static/markitup/ajax_csrf.js index 863187e..2534625 100644 --- a/markitup/static/markitup/ajax_csrf.js +++ b/markitup/static/markitup/ajax_csrf.js @@ -29,4 +29,4 @@ } } }); - })(jQuery); + })(jQuery || django.jQuery); diff --git a/markitup/static/markitup/django-markitup.js b/markitup/static/markitup/django-markitup.js new file mode 100644 index 0000000..07b62f1 --- /dev/null +++ b/markitup/static/markitup/django-markitup.js @@ -0,0 +1,31 @@ +'use strict'; +(function($) { + // Configure a MarkItUp editor on element + // Config comes from data attributes on config + function configure_markitup_editor(element, config) { + var preview_url = config.attr('data-preview-url'); + var auto_preview = config.attr('data-auto-preview') == '1'; + if (!element.hasClass("markItUpEditor")) { + if (preview_url) { + mySettings["previewParserPath"] = preview_url; + } + element.markItUp(mySettings); + } + if (auto_preview) { + $('a[title="Preview"]').trigger('mouseup'); + } + }; + + $(function() { + $('.django-markitup-widget').each(function(index) { + var element = $(this); + configure_markitup_editor(element, element); + }); + + $('.django-markitup-editor-config').each(function(index) { + var config = $(this); + var element = $(config.attr('data-element')); + configure_markitup_editor(element, config); + }); + }); +})(jQuery || django.jQuery); diff --git a/markitup/static/markitup/jquery.markitup.js b/markitup/static/markitup/jquery.markitup.js index b7e2d03..7b5adf1 100644 --- a/markitup/static/markitup/jquery.markitup.js +++ b/markitup/static/markitup/jquery.markitup.js @@ -662,4 +662,4 @@ $('textarea').trigger('insertion', [options]); } }; -})(jQuery); +})(jQuery || django.jQuery); diff --git a/markitup/templates/markitup/editor.html b/markitup/templates/markitup/editor.html index ce44c5f..deeb5eb 100644 --- a/markitup/templates/markitup/editor.html +++ b/markitup/templates/markitup/editor.html @@ -1,12 +1,4 @@ - + diff --git a/markitup/templates/markitup/include_js.html b/markitup/templates/markitup/include_js.html index bbed9b8..a08289e 100644 --- a/markitup/templates/markitup/include_js.html +++ b/markitup/templates/markitup/include_js.html @@ -4,3 +4,4 @@ + diff --git a/markitup/templatetags/markitup_tags.py b/markitup/templatetags/markitup_tags.py index bb9bd44..54e2815 100644 --- a/markitup/templatetags/markitup_tags.py +++ b/markitup/templatetags/markitup_tags.py @@ -27,6 +27,7 @@ def _get_markitup_context(): 'MARKITUP_SKIN': absolute_url(settings.MARKITUP_SKIN).rstrip('/'), 'MARKITUP_JS': absolute_url('markitup/jquery.markitup.js'), 'AJAXCSRF_JS': absolute_url('markitup/ajax_csrf.js'), + 'DJANGO_MARKITUP_JS': absolute_url('markitup/django-markitup.js'), } if settings.JQUERY_URL is not None: context['JQUERY_URL'] = absolute_url(settings.JQUERY_URL) diff --git a/markitup/widgets.py b/markitup/widgets.py index fae1f13..accf002 100644 --- a/markitup/widgets.py +++ b/markitup/widgets.py @@ -5,9 +5,9 @@ from django.contrib.admin.widgets import AdminTextareaWidget from django.template.loader import render_to_string try: - from django.urls import NoReverseMatch, reverse + from django.urls import NoReverseMatch, reverse_lazy except ImportError: - from django.core.urlresolvers import reverse, NoReverseMatch + from django.core.urlresolvers import NoReverseMatch, reverse_lazy from django.utils.safestring import mark_safe from markitup import settings from markitup.util import absolute_url @@ -59,39 +59,33 @@ def __init__(self, attrs=None, if auto_preview is None: auto_preview = settings.MARKITUP_AUTO_PREVIEW self.auto_preview = auto_preview + + try: + preview_url = reverse_lazy('markitup_preview') + except NoReverseMatch: + preview_url = "" + + attrs = attrs or {} + classes = attrs.get('class', '').split() + attrs['class'] = ' '.join(classes + ['django-markitup-widget']) + attrs['data-preview-url'] = preview_url + if auto_preview: + attrs['data-auto-preview'] = '1' + super(MarkItUpWidget, self).__init__(attrs) def _media(self): js_media = [absolute_url(settings.JQUERY_URL)] if settings.JQUERY_URL is not None else [] js_media = js_media + [absolute_url('markitup/ajax_csrf.js'), absolute_url('markitup/jquery.markitup.js'), - posixpath.join(self.miu_set, 'set.js')] + posixpath.join(self.miu_set, 'set.js'), + absolute_url('markitup/django-markitup.js')] return forms.Media( css={'screen': (posixpath.join(self.miu_skin, 'style.css'), posixpath.join(self.miu_set, 'style.css'))}, js=js_media) media = property(_media) - def render(self, name, value, attrs=None, renderer=None): - html = super(MarkItUpWidget, self).render(name, value, attrs) - - # Passing base_attrs as a kwarg for compatibility with Django < 1.11 - # (where it will be treated as an innocuous attr named base_attrs) - final_attrs = self.build_attrs( - base_attrs=self.attrs, extra_attrs=attrs) - - try: - preview_url = reverse('markitup_preview') - except NoReverseMatch: - preview_url = "" - - html += render_to_string('markitup/editor.html', - {'textarea_id': final_attrs['id'], - 'AUTO_PREVIEW': self.auto_preview, - 'preview_url': preview_url}) - - return mark_safe(html) - class AdminMarkItUpWidget(MarkItUpWidget, AdminTextareaWidget): """ diff --git a/tests/tests.py b/tests/tests.py index 8d18883..800b020 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -239,68 +239,81 @@ def test_render_markup(self): 'replace this text'})) -class RenderTests(MIUTestCase): - look_for = 'var element = $("#my_id");' - auto_preview_override = True - - def test_widget_render(self): - widget = MarkItUpWidget() - self.assertIn(self.look_for, - widget.render('name', 'value', {'id': 'my_id'})) - - def test_widget_render_with_custom_id(self): - widget = MarkItUpWidget(attrs={'id': 'my_id'}) - self.assertIn(self.look_for, - widget.render('name', 'value')) - - def test_widget_render_preview_parser_path(self): - widget = MarkItUpWidget() - self.assertIn('mySettings["previewParserPath"] = "/markitup/preview/";', - widget.render('name', 'value', {'id': 'my_id'})) - - def test_templatetag_render(self): - template = """{% load markitup_tags %}{% markitup_editor "my_id" %}""" - self.assertIn(self.look_for, - self.render(template)) - - def test_templatetag_render_preview_parser_path(self): - template = """{% load markitup_tags %}{% markitup_editor "my_id" %}""" - self.assertIn('mySettings["previewParserPath"] = "/markitup/preview/";', - self.render(template)) - - def test_per_widget_auto_preview_override(self): - widget = MarkItUpWidget(auto_preview=self.auto_preview_override) - self.assertIn(AutoPreviewSettingTests.look_for, - widget.render('name', 'value', {'id': 'my_id'}), - reverse=not self.auto_preview_override) - - def test_per_ttag_auto_preview_override(self): - if self.auto_preview_override: - arg = "auto_preview" - else: - arg = "no_auto_preview" - template = """{%% load markitup_tags %%}{%% markitup_editor "my_id" "%s" %%}""" % (arg,) - self.assertIn(AutoPreviewSettingTests.look_for, - self.render(template), - reverse=not self.auto_preview_override) - - -class AutoPreviewSettingTests(RenderTests): - look_for = "$('a[title=\"Preview\"]').trigger('mouseup');" - auto_preview_override = False +class RenderTestMixin(object): + look_for = 'OVERRIDE ME' + look_for_auto_preview = 'data-auto-preview="1"' def setUp(self): self._old_auto = settings.MARKITUP_AUTO_PREVIEW - settings.MARKITUP_AUTO_PREVIEW = True def tearDown(self): settings.MARKITUP_AUTO_PREVIEW = self._old_auto + def render_subject(self, auto_preview=None): + raise NotImplemented('OVERRIDE ME') + + def test_render(self): + self.assertIn(self.look_for, self.render_subject()) + + def test_render_preview_parser_path(self): + self.assertIn('data-preview-url="/markitup/preview/"', + self.render_subject()) + + def test_auto_preview_setting(self): + settings.MARKITUP_AUTO_PREVIEW = True + self.assertIn(self.look_for_auto_preview, self.render_subject()) + + def test_auto_preview_override(self): + self.assertIn(self.look_for_auto_preview, + self.render_subject(True)) + + def test_auto_preview_override_setting(self): + settings.MARKITUP_AUTO_PREVIEW = True + self.assertIn(self.look_for_auto_preview, + self.render_subject(False), + reverse=True) + + +class RenderTemplateTagTests(RenderTestMixin, MIUTestCase): + look_for = 'data-element="#my_id"' + + def render_subject(self, auto_preview=None): + if auto_preview is True: + params = '"auto_preview"' + elif auto_preview is False: + params = '"no_auto_preview"' + else: + params = '' + template = ('{% load markitup_tags %}{% markitup_editor "my_id" ' + + params + ' %}') + return self.render(template) + + +class RenderWidgetTests(RenderTestMixin, MIUTestCase): + look_for = 'class="django-markitup-widget"' + + def render_subject(self, auto_preview=None): + widget = MarkItUpWidget(auto_preview=auto_preview) + return widget.render('name', 'value') + class TemplatetagMediaUrlTests(MIUTestCase): maxDiff = None prefix = '/static' + @property + def script_tags(self): + return ( + '\n' + '\n' + '\n' + '' + ) % {'prefix': self.prefix} + def setUp(self): self._reset_storage() @@ -339,9 +352,7 @@ def _get_expected_media(self): out = """ - - -""" % {'prefix': self.prefix} +""" % {'prefix': self.prefix} + self.script_tags return out # JQUERY_URL settings and resulting link @@ -382,12 +393,7 @@ def test_jquery_url(self): else: self.assertHTMLEqual( self._get_js(), - ( - '\n' - '\n' - '' - % {'prefix': self.prefix} - )) + self.script_tags) finally: settings.JQUERY_URL = _old_jquery_url