Anonymous avatar Anonymous committed 9e9afbc

Started integration of jQuery plugin for CodeMirror initialization.

Comments (0)

Files changed (8)

docs/installation.rst

    ``head_offset=0, html_type='xhtml', auto_link=False, encoding=None,
    output=None``.
 
-   Defaults to: ``{'encoding': 'utf-8', 'output': 'utf-8'}``
+   Defaults to::
 
-.. py:data:: MARKUPMIRROR_FEINCMS_INIT_TEMPLATE
+    MARKUPMIRROR_TEXTILE_SETTINGS = {
+        'encoding': 'utf-8',
+        'output': 'utf-8'
+    }
 
-   Defines the template used by FeinCMS to initialize Pages with
-   ``MarkupMirrorContent`` blocks.
+.. py:data:: MARKUPMIRROR_CODEMIRROR_SETTINGS
 
-   .. deprecated:: 0.1a2
-      This will soon be obsolete due to a generic jQuery plugin to initialize
-      the CodeMirror editor anywhere.
+   Basic settings passed to all CodeMirror editor instances for initialization.
+   Check the `CodeMirror documentation on configuration settings`_ for details.
 
-.. py:data:: MARKUPMIRROR_FEINCMS_INIT_CONTEXT
+   Defaults to::
 
-   Context passed to the ``MARKUPMIRROR_FEINCMS_INIT_TEMPLATE``.
-
-   .. deprecated:: 0.1a2
-      This will soon be obsolete due to a generic jQuery plugin to initialize
-      the CodeMirror editor anywhere.
+    MARKUPMIRROR_CODEMIRROR_SETTINGS = {
+        'width': '50%',
+        'height': '300px',
+        'indentUnit': 4,
+        'lineNumbers': True,
+        'lineWrapping': True,
+        'path': settings.STATIC_URL + 'markupmirror/',
+    }
 
 
 .. _Markdown: http://daringfireball.net/projects/markdown/
 .. _Markdown's package documentation: http://packages.python.org/Markdown/
 .. _a list of available extensions:
     http://packages.python.org/Markdown/extensions/
+.. _CodeMirror documentation on configuration settings:
+    http://codemirror.net/doc/manual.html#config

markupmirror/feincms/models.py

     # TODO: find a way to include a button like richtext content
     # __name__ = 'richtextcontent'
 
-    feincms_item_editor_context_processors = (
-        lambda x: settings.MARKUPMIRROR_FEINCMS_INIT_CONTEXT,
-    )
-    feincms_item_editor_includes = {
-        'head': [settings.MARKUPMIRROR_FEINCMS_INIT_TEMPLATE],
-    }
-
     content = MarkupMirrorField(
         verbose_name=_(u"Markup content"),
         markup_type=settings.MARKUPMIRROR_DEFAULT_MARKUP_TYPE,

markupmirror/fields.py

 from django.core.exceptions import ImproperlyConfigured
 from django.db import models
+from django.utils import simplejson as json
 from django.utils.html import escape
 from django.utils.safestring import mark_safe
 
         }
         if (self.default_markup_type and
             self.default_markup_type in markup_pool):
-            widget_attrs['data-mode'] = markup_pool[
-                self.default_markup_type].codemirror_mode
-            widget_attrs['data-markuptype'] = self.default_markup_type
+            # prepare default settings for CodeMirror and preview in case
+            # the widget has no value yet.
+            mm_settings = {
+                'mode': markup_pool[self.default_markup_type].codemirror_mode,
+                'markup_type': self.default_markup_type,
+            }
+            widget_attrs['data-mm-settings'] = json.dumps(mm_settings)
 
         defaults = {
             'widget': widgets.MarkupMirrorTextarea(attrs=widget_attrs),

markupmirror/settings.py

     {'encoding': 'utf-8', 'output': 'utf-8'})
 
 
-# Settings for MarkupMirrorContent for FeinCMS
+# CodeMirror settings
 
-# Init template for CodeMirror in FeinCMS
-MARKUPMIRROR_FEINCMS_INIT_TEMPLATE = getattr(settings,
-    'MARKUPMIRROR_FEINCMS_INIT_TEMPLATE',
-    'admin/markupmirror/feincms/init_codemirror.html')
-
-# Context for init template
-MARKUPMIRROR_FEINCMS_INIT_CONTEXT = getattr(settings,
-    'MARKUPMIRROR_FEINCMS_INIT_CONTEXT', {
-    #     'CODEMIRROR_JS': CODEMIRROR_JS,
-    #     'CODEMIRROR_CSS': CODEMIRROR_CSS,
-        'CODEMIRROR_PATH': settings.STATIC_URL + 'markupmirror/',
-        'CODEMIRROR_WIDTH': '50%',
-        'CODEMIRROR_HEIGHT': '300px',
+MARKUPMIRROR_CODEMIRROR_SETTINGS = getattr(settings,
+    'MARKUPMIRROR_CODEMIRROR_SETTINGS', {
+        'width': '50%',
+        'height': '300px',
+        'indentUnit': 4,
+        'lineNumbers': True,
+        'lineWrapping': True,
+        'path': settings.STATIC_URL + 'markupmirror/',
     })

markupmirror/static/markupmirror/markupmirror.js

 (function($) {
     $(function() {
 
-        console.log("jQuery 1.7.2 registered as markupmirror.jQuery.");
+        var MarkupMirrorEditor = function( element, options ) {
+                    var _this = this,
+                        _public = {
+
+                            /* to configure the wrapper */
+                            configure: function( obj ) {
+                                for( key in obj ) {
+                                    _private.options[ key ] = obj[ key ];
+                                }
+
+                                return _this;
+                            },
+
+                            get: function( key ) {
+                                return _private.options[ key ] || undefined;
+                            },
+
+                            /* add the Codemirror to a new element */
+                            add: function( el, options ) {
+                                    if( !el || el.length === 0 ) {
+                                        return _this;
+                                    }
+
+                                    var editor;
+
+                                     $.each( el,
+                                            function() {
+                                                if( this.nodeName.toLowerCase() === 'textarea' ) {
+                                                    if( options === undefined ) {
+                                                        if( _private.getOption( '_init' ) === true && _private.getOption( 'inherit' ) === true ) {
+                                                            editor = CodeMirror.fromTextArea( this, _private.getOption( 'initOptions' ) );
+                                                            _public.configure( { 'editor': editor } );
+                                                        } else {
+                                                            editor = CodeMirror.fromTextArea( this );
+                                                            _public.configure( { 'editor': editor } );
+                                                        }
+                                                    } else {
+
+                                                        /* so we are able to overwrite just a few of the options */
+                                                        if(  _private.getOption( '_init' ) === true && _private.getOption( 'extend' ) ) {
+                                                            options = $.extend( _private.getOption( 'initOptions' ), options );
+                                                        }
+
+                                                        editor = CodeMirror.fromTextArea( this, options );
+                                                        _public.configure( { 'editor': editor } );
+                                                    }
+
+                                                    if( typeof( _private.getOption( 'onInit' ) ) === 'function' ) {
+                                                         _private.getOption( 'onInit' )( this );
+                                                    }
+                                                }
+                                            });
+
+                                    return _this;
+                                 }
+                        },
+
+                        /* this will not be exposed to the public */
+                        _private = {
+                            getOption: function( index ) {
+                                return _private.options[ index ] || undefined;
+                            },
+
+                            /* store configuration options here */
+                            options: {
+                                /* initial options passed in */
+                                initOptions: undefined,
+
+                                /* new added elements inherit from the inital options */
+                                inherit: true,
+
+                                /* extends the original options object by passing a new element in */
+                                extend: true,
+
+                                /* initial init was done */
+                                _init: false,
+
+                                /* callback */
+                                onInit: undefined,
+
+                                /* the original codemirror editor object */
+                                editor: undefined
+                            }
+                        };
+
+                    /* initialise the plugin here */
+                    _public.configure( { _init: true,
+                                         initOptions: options } );
+
+                    /* add init element */
+                    _public.add( element, options );
+
+                    return _this = _public;
+                };
+
+
+        var $textarea = $('.item-markupmirror'),
+            CM = new MarkupMirrorEditor( undefined, $textarea.data('mmSettings') )
+                        .configure({'onInit': createIframe})
+                        .configure({'onChange': updateIframe})
+                        .add( $textarea );
+
+                /* when init a textarea with codemirror we also create an iframe */
+                function createIframe( el ) {
+                    var $el = $(el),
+                        $iframe = $('<iframe />').attr('src', $el.data('mmSettings')['base_url']);
+
+                    $el.on('change', updateIframe);
+
+                    $iframe
+                    .insertAfter( $el );
+                }
+
+                /* when changing the textarea we replace the iframe content with the new coming from the server */
+                function updateIframe( e ) {
+                    console.log('update');
+                }
+
+            console.log( CM.get('editor') );
 
     });
 })(markupmirror.jQuery);

markupmirror/urls.py

 
 
 urlpatterns = patterns('',
-    url(r'^preview/(?P<markup_type>[\w-]+)/$',
-        MarkupPreview.as_view(),
-        name='preview'),
+    url(r'^preview/$', MarkupPreview.as_view(), name='preview'),
     url(r'^base/$',
         TemplateView.as_view(
             template_name='markupmirror/preview.html'),

markupmirror/views.py

 
     http_method_names = ['post']
 
-    def post(self, request, markup_type, *args, **kwargs):
+    def post(self, request, *args, **kwargs):
+        markup_type = self.request.POST.get('markup_type')
+        if not markup_type:
+            return HttpResponse(u"", content_type='text/html')
         markup = markup_pool.get_markup(markup_type)
         text = self.request.POST.get('text', u"")
         return HttpResponse(markup(text), content_type='text/html')

markupmirror/widgets.py

 from django import forms
 from django.contrib.admin.widgets import AdminTextareaWidget
+from django.core.urlresolvers import reverse
+from django.utils import simplejson as json
 
 from markupmirror import settings
 from markupmirror.markup.base import markup_pool
 
     def render(self, name, value, attrs=None):
         default_attrs = {}
+
+        # start with CodeMirror base settings
+        mm_settings = settings.MARKUPMIRROR_CODEMIRROR_SETTINGS.copy()
+        markup_type = settings.MARKUPMIRROR_DEFAULT_MARKUP_TYPE
+
+        # if value is filled, use the markup type defined with the content
         if value is not None and not isinstance(value, unicode):
             # get markup converter by type.
             # ``value`` is ``markupmirror.fields.Markup``.
             markup_type = value.markup_type
-            markup = markup_pool.get_markup(markup_type)
-
-            default_attrs = {
-                'data-mode': markup.codemirror_mode,
-                'data-markuptype': markup_type,
-            }
-
             # get real value
             value = value.raw
-        else:
-            default = settings.MARKUPMIRROR_DEFAULT_MARKUP_TYPE
-            default_attrs = {
-                'data-mode': markup_pool[default].codemirror_mode,
-                'data-markuptype': default,
-            }
 
+        # mode for CodeMirror and preview and base URLs plus markup_type
+        # parameter for loading markup previews
+        mm_settings.update({
+            'mode': markup_pool[markup_type].codemirror_mode,
+            'markup_type': markup_type,
+            'preview_url': reverse('markupmirror:preview'),
+            'base_url': reverse('markupmirror:base'),
+        })
+
+        # provide mm_settings as data attribute in widget
+        default_attrs = {
+            'data-mm-settings': json.dumps(mm_settings),
+        }
         if attrs:
             default_attrs.update(attrs)
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.