diff --git a/www/pad/comment.js b/www/pad/comment.js index 1a059a50e..b5598137b 100644 --- a/www/pad/comment.js +++ b/www/pad/comment.js @@ -44,8 +44,8 @@ path = path || editor.elementPath(); sel = sel || editor.getSelection(); var applicable = removeStyle.checkApplicable(path, editor); - var el = editor.getSelectedHtml().$; - var hasComments = el && el.querySelectorAll('comment').length; + var el = editor.getSelectedHtml(); + var hasComments = el && el.$ && el.$.querySelectorAll('comment').length; var isComment = removeStyle.checkActive(path, editor); var empty = !sel.getSelectedText(); return applicable && !empty && !hasComments && !isComment; diff --git a/www/pad/csp.js b/www/pad/csp.js new file mode 100644 index 000000000..5d6072348 --- /dev/null +++ b/www/pad/csp.js @@ -0,0 +1,301 @@ +define(['jquery'], function ($) { + var CKEDITOR = window.CKEDITOR; + + + // Buttons + var $a = $('.cke_toolbox_main').find('.cke_button, .cke_combo_button'); + $a.each(function (i, el) { + var attr = $(el).attr('onclick'); + var reg = /CKEDITOR.tools.callFunction\(([0-9]+),this\);return false;/; + var f = attr.match(reg)[1]; + $(el).click(function () { + CKEDITOR.tools.callFunction(Number(f), el); + }); + }); + + + // Dropdown menus + + var frameTpl = CKEDITOR.getTemplate('panel-frame'); + var panelTpl = CKEDITOR.getTemplate('panel'); + var frameDocTpl = CKEDITOR.addTemplate( 'panel-frame-inner-csp', '' + + '' + + '
{css}' + + '' + + '<\/html>' ); + CKEDITOR.ui.panel.prototype.render = function( editor, output ) { + var data = { + editorId: editor.id, + id: this.id, + langCode: editor.langCode, + dir: editor.lang.dir, + cls: this.className, + frame: '', + env: CKEDITOR.env.cssClass, + 'z-index': editor.config.baseFloatZIndex + 1 + }; + + this.getHolderElement = function() { + var holder = this._.holder; + + if ( !holder ) { + if ( this.isFramed ) { + var iframe = this.document.getById( this.id + '_frame' ), + parentDiv = iframe.getParent(), + doc = iframe.getFrameDocument(); + + // Make it scrollable on iOS. (https://dev.ckeditor.com/ticket/8308) + if (CKEDITOR.env.iOS) { + parentDiv.setStyles( { + 'overflow': 'scroll', + '-webkit-overflow-scrolling': 'touch' + } ); + } + + var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function() { + this.isLoaded = true; + if ( this.onLoad ) { + this.onLoad(); + } + }, this ) ); + + doc.write( frameDocTpl.output( CKEDITOR.tools.extend( { + css: CKEDITOR.tools.buildStyleHtml( this.css ) + }, data ) ) ); + + var that = this; + $(iframe.$).on('load', function () { + that.isLoaded = true; + if (that.onLoad) { + that.onLoad(); + } + }).contents().find('body').on('click', '.cke_button, a.cke_colormore, a.cke_colorbox, .cke_colorauto, .cke_combo_button, .cke_panel_listItem a', function (e) { + var attr = $(e.currentTarget).attr('onclick'); + var reg = /CKEDITOR.tools.callFunction\(([0-9]+),'([A-Za-z0-9 ]+)'(,'([A-Za-z0-9 ]+)')?\);/; + var match = attr.match(reg); + var f = match[1]; + var el = match[2]; + CKEDITOR.tools.callFunction(Number(f), el, match[4]); + }); + + // Register the CKEDITOR global. + var win = doc.getWindow(); + win.$.CKEDITOR = CKEDITOR; + + // Arrow keys for scrolling is only preventable with 'keypress' event in Opera (https://dev.ckeditor.com/ticket/4534). + doc.on( 'keydown', function( evt ) { + var keystroke = evt.data.getKeystroke(), + dir = this.document.getById( this.id ).getAttribute( 'dir' ); + + // Arrow left and right should use native behaviour inside input element + if ( evt.data.getTarget().getName() === 'input' && ( keystroke === 37 || keystroke === 39 ) ) { + return; + } + // Delegate key processing to block. + if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false ) { + if ( !( evt.data.getTarget().getName() === 'input' && keystroke === 32 ) ) { + // Don't prevent space when is pressed on a input filed. + evt.data.preventDefault(); + } + return; + } + + // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl) + if ( keystroke === 27 || keystroke === ( dir === 'rtl' ? 39 : 37 ) ) { + if ( this.onEscape && this.onEscape( keystroke ) === false ) { + evt.data.preventDefault(); + } + } + }, this ); + + holder = doc.getBody(); + holder.unselectable(); + if (CKEDITOR.env.air) { CKEDITOR.tools.callFunction( onLoad ); } + } else { + holder = this.document.getById( this.id ); + } + + this._.holder = holder; + } + + return holder; + }; + + if ( this.isFramed ) { + // With IE, the custom domain has to be taken care at first, + // for other browers, the 'src' attribute should be left empty to + // trigger iframe's 'load' event. + var src = + CKEDITOR.env.air ? 'javascript:void(0)' : // jshint ignore:line + ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? 'javascript:void(function(){' + encodeURIComponent( // jshint ignore:line + 'document.open();' + + // In IE, the document domain must be set any time we call document.open(). + '(' + CKEDITOR.tools.fixDomain + ')();' + + 'document.close();' + ) + '}())' : + ''; + + data.frame = frameTpl.output( { + id: this.id + '_frame', + src: src + } ); + } + + var html = panelTpl.output( data ); + + if ( output ) { output.push( html ); } + + return html; + }; + + + + + + + // Mathjax + + if ( !( CKEDITOR.env.ie && CKEDITOR.env.version === 8 ) ) { + CKEDITOR.plugins.mathjax.frameWrapper = function( iFrame, editor ) { + + var update = function () {}; // Placeholder + var buffer, preview, value, newValue, + doc = iFrame.getFrameDocument(), + + // Is MathJax loaded and ready to work. + isInit = false, + + // Is MathJax parsing Tex. + isRunning = false, + + // Function called when MathJax is loaded. + loadedHandler = CKEDITOR.tools.addFunction( function() { + preview = doc.getById( 'preview' ); + buffer = doc.getById( 'buffer' ); + isInit = true; + + if ( newValue ) { update(); } + + // Private! For test usage only. + CKEDITOR.fire( 'mathJaxLoaded', iFrame ); + } ), + + // Function called when MathJax finish his job. + updateDoneHandler = CKEDITOR.tools.addFunction( function() { + CKEDITOR.plugins.mathjax.copyStyles( iFrame, preview ); + + preview.setHtml( buffer.getHtml() ); + + editor.fire( 'lockSnapshot' ); + + iFrame.setStyles( { + height: 0, + width: 0 + } ); + + // Set iFrame dimensions. + var height = Math.max( doc.$.body.offsetHeight, doc.$.documentElement.offsetHeight ), + width = Math.max( preview.$.offsetWidth, doc.$.body.scrollWidth ); + + iFrame.setStyles( { + height: height + 'px', + width: width + 'px' + } ); + + editor.fire( 'unlockSnapshot' ); + + // Private! For test usage only. + CKEDITOR.fire( 'mathJaxUpdateDone', iFrame ); + + // If value changed in the meantime update it again. + if ( value !== newValue ) { + update(); + } else { + isRunning = false; + } + } ); + + // Run MathJax parsing Tex. + update = function () { + isRunning = true; + + value = newValue; + + editor.fire( 'lockSnapshot' ); + + buffer.setHtml( value ); + + // Set loading indicator. + preview.setHtml( '