File:  [LON-CAPA] / loncom / html / adm / ckeditor / plugins / chem / plugin.js
Revision 1.1: download - view: text, annotated - select for diffs
Wed Apr 1 16:14:33 2015 UTC (9 years, 5 months ago) by damieng
Branches: MAIN
CVS tags: version_2_12_X, version_2_11_X, version_2_11_5_msu, version_2_11_5, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, HEAD
update for ckeditor, with a new plugin for <chem>

/**
 * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or http://ckeditor.com/license
 */

/**
 * @fileOverview [Chemistry] LON-CAPA ckeditor plugin for the <chem> element.
 */

'use strict';

CKEDITOR.plugins.add( 'chem', {
    lang: 'de,en,es,fr,ja,pt,pt-br,ru,zh,zh-cn',
    requires: 'widget',
    icons: 'chem',
    hidpi: true,

    init: function( editor ) {
        editor.widgets.add( 'chem', {

            dialog: 'chem',
            
            button: editor.lang.chem.button,

            template:
                '<span class="chem"></span>',

            data: function() {
                var span = this.element;
                if (this.data.reaction)
                    CKEDITOR.plugins.chem.add_html(this.data.reaction, span);
                else
                    span.setHtml('?');
            },

            upcast: function( el, data ) {
                if ( !( el.name == 'chem' ) )
                    return;

                if ( el.children.length > 1 || el.children[ 0 ].type != CKEDITOR.NODE_TEXT )
                    return;

                data.reaction = CKEDITOR.tools.htmlDecode( el.children[ 0 ].value );
                
                var span = new CKEDITOR.htmlParser.element('span');
                span.addClass('chem');
                
                CKEDITOR.plugins.chem.add_html(data.reaction, span);
                
                // Add attribute to prevent deleting empty span in data processing.
                var attrs = span.attributes;
                attrs[ 'data-cke-survive' ] = 1;
                if (el.attributes.eval)
                    attrs['data-eval'] = el.attributes.eval;
                el.replaceWith(span);
                return span;
            },

            downcast: function( el ) {
                var chem = new CKEDITOR.htmlParser.element('chem');
                if (el.attributes['data-eval'])
                    chem.attributes.eval = el.attributes['data-eval'];
                chem.add(new CKEDITOR.htmlParser.text(CKEDITOR.tools.htmlEncode(this.data.reaction)));
                return chem;
            }
            
        } );
        // Add dialog.
        CKEDITOR.dialog.add( 'chem', this.path + 'dialogs/chem.js' );
    }
} );


/**
 * @private
 * @singleton
 * @class CKEDITOR.plugins.chem
 */
CKEDITOR.plugins.chem = {};

/**
 * Adds HTML to the span for the given reaction, using UNICODE characters for arrows.
 *
 * @private
 * @param {string} reaction
 * @param {CKEDITOR.dom.element} span - element the HTML will be constructed inside
 */
CKEDITOR.plugins.chem.add_html = function( reaction, span ) {
    // this is doing the same thing as chemparse, except it uses UNICODE characters instead of LaTeX
    var tokens = reaction.split(/(\s\+|\->|<=>|<\-|\.)/);
    var formula = '';
    for (var i=0; i<tokens.length; i++) {
        var token = tokens[i];
        if (token == '->' ) {
            formula += '&#8594; ';
            continue;
        }
        if (token == '<-' ) {
            formula += '&#8592; ';
            continue;
        }  
        if (token == '<=>') {
            formula += '&#8652; ';
            continue;
        }
        if (token == '.') {
          formula = formula.replace(/&nbsp;| /, '');
          formula += '&middot;';
          continue;
        }
        var found = token.match(/^\s*([\d|\/]*(?:&frac\d\d)?)(.*)/);
        if (found != null && found.length > 1 && found[1] != '1')
            formula += found[1]; // stoichiometric coefficient
        
        var molecule;
        if (found != null && found.length > 2)
            molecule = found[2];
        else
            molecule = '';
        // subscripts
        // $molecule =~ s|(?<=[a-zA-Z\)\]\s])(\d+)|<sub>$1</sub>|g;
        // Javascript does not support look-behind like Perl
        molecule = molecule.replace(/([a-zA-Z\)\]\s])(\d+)/g, '$1<sub>$2</sub>');
        // superscripts
        molecule = molecule.replace(/\^(\d*[+\-]*)/g, '<sup>$1</sup>');
        // strip whitespace
        molecule = molecule.replace(/\s*/g, '');
        // forced space
        molecule = molecule.replace(/_/g, ' ');
        molecule = molecule.replace(/-/g, '&minus;');
        formula += molecule + '&nbsp;';
    }
    // get rid of trailing space
    formula = formula.replace(/(&nbsp;| )$/, '');
    // we need to add CSS here, because ckeditor changes CSS for sup and sub, and ckeditor css for plugins is not used inside dialogs
    // (whether we define it with CKEDITOR.editor.addContentsCss or CKEDITOR.addCss)
    formula = formula.replace(/<sub>/g,'<sub style="vertical-align:sub; font-size:smaller">');
    formula = formula.replace(/<sup>/g,'<sup style="vertical-align:super; font-size:smaller">');
    span.setHtml(formula);
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>