/** * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/license */ /** * @fileOverview [Mathematical Formulas] LON-CAPA ckeditor plugin for the m element, derived from ckeditor mathjax plugin. */ 'use strict'; ( function() { var cdn = 'http:\/\/cdn.mathjax.org\/mathjax\/2.2-latest\/MathJax.js?config=TeX-AMS_HTML'; CKEDITOR.plugins.add( 'lcm', { lang: 'af,ar,ca,cs,cy,da,de,el,en,en-gb,eo,es,fa,fi,fr,gl,he,hr,hu,it,ja,km,ku,lt,nb,nl,no,pl,pt,pt-br,ro,ru,sk,sl,sq,sv,tr,tt,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE% requires: 'widget,dialog', icons: 'lcm', hidpi: true, // %REMOVE_LINE_CORE% init: function( editor ) { var cls = editor.config.mathJaxClass || 'math-tex'; editor.widgets.add( 'lcm', { inline: true, dialog: 'lcm', button: editor.lang.lcm.button, mask: true, allowedContent: 'span(!' + cls + ')', // Allow style classes only on spans having lcm class. styleToAllowedContentRules: function( style ) { var classes = style.getClassesArray(); if ( !classes ) return null; classes.push( '!' + cls ); return 'span(' + classes.join( ',' ) + ')'; }, pathName: editor.lang.lcm.pathName, template: '', parts: { span: 'span' }, defaults: { math: '$ x $' // the default helps to show the $...$ syntax }, init: function() { var iframe = this.parts.span.getChild( 0 ); // Check if span contains iframe and create it otherwise. if ( !iframe || iframe.type != CKEDITOR.NODE_ELEMENT || !iframe.is( 'iframe' ) ) { iframe = new CKEDITOR.dom.element( 'iframe' ); iframe.setAttributes( { style: 'border:0;width:0;height:0', scrolling: 'no', frameborder: 0, allowTransparency: true, src: CKEDITOR.plugins.lcm.fixSrc } ); this.parts.span.append( iframe ); } // Wait for ready because on some browsers iFrame will not // have document element until it is put into document. // This is a problem when you crate widget using dialog. this.once( 'ready', function() { // Src attribute must be recreated to fix custom domain error after undo // (see iFrame.removeAttribute( 'src' ) in frameWrapper.load). if ( CKEDITOR.env.ie ) iframe.setAttribute( 'src', CKEDITOR.plugins.lcm.fixSrc ); this.frameWrapper = new CKEDITOR.plugins.lcm.frameWrapper( iframe, editor ); this.frameWrapper.setValue( this.data.math ); } ); }, data: function() { if ( this.frameWrapper ) this.frameWrapper.setValue( this.data.math ); }, upcast: function( el, data ) { if ( !( el.name == 'm' ) ) return; if ( el.children.length > 1 || el.children[ 0 ].type != CKEDITOR.NODE_TEXT ) return; data.math = CKEDITOR.tools.htmlDecode( el.children[ 0 ].value ); // NOTE: we do not preserve the display attribute, because only MathJax is used for preview var span = new CKEDITOR.htmlParser.element('span'); span.addClass(cls); // Add style display:inline-block to have proper height of widget wrapper and mask. var attrs = span.attributes; if ( attrs.style ) attrs.style += ';display:inline-block'; else attrs.style = 'display:inline-block'; // Add attribute to prevent deleting empty span in data processing. attrs[ 'data-cke-survive' ] = 1; if (el.attributes.eval) attrs['data-eval'] = el.attributes.eval; // NOTE: the display attribute is not preserved el.replaceWith(span); return span; }, downcast: function( el ) { var m = new CKEDITOR.htmlParser.element('m'); if (el.attributes['data-eval']) m.attributes.eval = el.attributes['data-eval']; m.add(new CKEDITOR.htmlParser.text(CKEDITOR.tools.htmlEncode(this.data.math))); return m; } } ); // Add dialog. CKEDITOR.dialog.add( 'lcm', this.path + 'dialogs/lcm.js' ); // Add MathJax script to page preview. editor.on( 'contentPreview', function( evt ) { evt.data.dataValue = evt.data.dataValue.replace( /<\/head>/, '' + // Load MathJax lib. '' + '' + '
' + '' + // Render everything here and after that copy it to the preview. '' + '' + '