Вход Регистрация
Файл: tyde/www/web/js/components/htmleditor.js
Строк: 654
<?php
/*! UIkit 2.24.3 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
(function(addon) {

    var 
component;

    if (
window.UIkit) {
        
component addon(UIkit);
    }

    if (
typeof define == "function" && define.amd) {
        
define("uikit-htmleditor", ["uikit"], function(){
            return 
component || addon(UIkit);
        });
    }

})(function(
UI) {

    
"use strict";

    var 
editors = [];

    
UI.component('htmleditor', {

        
defaults: {
            
iframe       false,
            
mode         'split',
            
markdown     false,
            
autocomplete true,
            
height       500,
            
maxsplitsize 1000,
            
codemirror   : { mode'htmlmixed'lineWrappingtruedragDropfalseautoCloseTagstruematchTagstrueautoCloseBracketstruematchBracketstrueindentUnit4indentWithTabsfalsetabSize4hintOptions: {completionSingle:false} },
            
toolbar      : [ 'bold''italic''strike''link''image''blockquote''listUl''listOl' ],
            
lblPreview   'Preview',
            
lblCodeview  'HTML',
            
lblMarkedview'Markdown'
        
},

        
boot: function() {

            
// init code
            
UI.ready(function(context) {

                
UI.$('textarea[data-uk-htmleditor]'context).each(function() {

                    var 
editor UI.$(this);

                    if (!
editor.data('htmleditor')) {
                        
UI.htmleditor(editorUI.Utils.options(editor.attr('data-uk-htmleditor')));
                    }
                });
            });
        },

        
init: function() {

            var 
$this thistpl UI.components.htmleditor.template;

            
this.CodeMirror this.options.CodeMirror || CodeMirror;
            
this.buttons    = {};

            
tpl tpl.replace(/{:lblPreview}/gthis.options.lblPreview);
            
tpl tpl.replace(/{:lblCodeview}/gthis.options.lblCodeview);

            
this.htmleditor UI.$(tpl);
            
this.content    this.htmleditor.find('.uk-htmleditor-content');
            
this.toolbar    this.htmleditor.find('.uk-htmleditor-toolbar');
            
this.preview    this.htmleditor.find('.uk-htmleditor-preview').children().eq(0);
            
this.code       this.htmleditor.find('.uk-htmleditor-code');

            
this.element.before(this.htmleditor).appendTo(this.code);
            
this.editor this.CodeMirror.fromTextArea(this.element[0], this.options.codemirror);
            
this.editor.htmleditor this;
            
this.editor.on('change'UI.Utils.debounce(function() { $this.render(); }, 150));
            
this.editor.on('change', function() {
                
$this.editor.save();
                
$this.element.trigger('input');
            });
            
this.code.find('.CodeMirror').css('height'this.options.height);

            
// iframe mode?
            
if (this.options.iframe) {

                
this.iframe UI.$('<iframe class="uk-htmleditor-iframe" frameborder="0" scrolling="auto" height="100" width="100%"></iframe>');
                
this.preview.append(this.iframe);

                
// must open and close document object to start using it!
                
this.iframe[0].contentWindow.document.open();
                
this.iframe[0].contentWindow.document.close();

                
this.preview.container UI.$(this.iframe[0].contentWindow.document).find('body');

                
// append custom stylesheet
                
if (typeof(this.options.iframe) === 'string') {
                    
this.preview.container.parent().append('<link rel="stylesheet" href="'+this.options.iframe+'">');
                }

            } else {
                
this.preview.container this.preview;
            }

            
UI.$win.on('resize load'UI.Utils.debounce(function() { $this.fit(); }, 200));

            var 
previewContainer this.iframe this.preview.container:$this.preview.parent(),
                
codeContent      this.code.find('.CodeMirror-sizer'),
                
codeScroll       this.code.find('.CodeMirror-scroll').on('scroll'UI.Utils.debounce(function() {

                    if (
$this.htmleditor.attr('data-mode') == 'tab') return;

                    
// calc position
                    
var codeHeight      codeContent.height() - codeScroll.height(),
                        
previewHeight   previewContainer[0].scrollHeight - ($this.iframe $this.iframe.height() : previewContainer.height()),
                        
ratio           previewHeight codeHeight,
                        
previewPosition codeScroll.scrollTop() * ratio;

                    
// apply new scroll
                    
previewContainer.scrollTop(previewPosition);

                }, 
10));

            
this.htmleditor.on('click''.uk-htmleditor-button-code, .uk-htmleditor-button-preview', function(e) {

                
e.preventDefault();

                if (
$this.htmleditor.attr('data-mode') == 'tab') {

                    
$this.htmleditor.find('.uk-htmleditor-button-code, .uk-htmleditor-button-preview').removeClass('uk-active').filter(this).addClass('uk-active');

                    
$this.activetab UI.$(this).hasClass('uk-htmleditor-button-code') ? 'code' 'preview';
                    
$this.htmleditor.attr('data-active-tab'$this.activetab);
                    
$this.editor.refresh();
                }
            });

            
// toolbar actions
            
this.htmleditor.on('click''a[data-htmleditor-button]', function() {

                if (!
$this.code.is(':visible')) return;

                
$this.trigger('action.' UI.$(this).data('htmleditor-button'), [$this.editor]);
            });

            
this.preview.parent().css('height'this.code.height());

            
// autocomplete
            
if (this.options.autocomplete && this.CodeMirror.showHint && this.CodeMirror.hint && this.CodeMirror.hint.html) {

                
this.editor.on('inputRead'UI.Utils.debounce(function() {
                    var 
doc $this.editor.getDoc(), POS doc.getCursor(), mode $this.CodeMirror.innerMode($this.editor.getMode(), $this.editor.getTokenAt(POS).state).mode.name;

                    if (
mode == 'xml') { //html depends on xml

                        
var cur $this.editor.getCursor(), token $this.editor.getTokenAt(cur);

                        if (
token.string.charAt(0) == '<' || token.type == 'attribute') {
                            
$this.CodeMirror.showHint($this.editor$this.CodeMirror.hint.html, { completeSinglefalse });
                        }
                    }
                }, 
100));
            }

            
this.debouncedRedraw UI.Utils.debounce(function () { $this.redraw(); }, 5);

            
this.on('init.uk.component', function() {
                
$this.debouncedRedraw();
            });

            
this.element.attr('data-uk-check-display'1).on('display.uk.check', function(e) {
                if (
this.htmleditor.is(":visible")) this.fit();
            }.
bind(this));

            
editors.push(this);
        },

        
addButton: function(namebutton) {
            
this.buttons[name] = button;
        },

        
addButtons: function(buttons) {
            
UI.$.extend(this.buttonsbuttons);
        },

        
replaceInPreview: function(regexpcallback) {

            var 
editor this.editorresults = [], value editor.getValue(), offset = -1index 0;

            
this.currentvalue this.currentvalue.replace(regexp, function() {

                
offset value.indexOf(arguments[0], ++offset);

                var 
match  = {
                    
matchesarguments,
                    
from   translateOffset(offset),
                    
to     translateOffset(offset arguments[0].length),
                    
replace: function(value) {
                        
editor.replaceRange(valuematch.frommatch.to);
                    },
                    
inRange: function(cursor) {

                        if (
cursor.line === match.from.line && cursor.line === match.to.line) {
                            return 
cursor.ch >= match.from.ch && cursor.ch match.to.ch;
                        }

                        return  (
cursor.line === match.from.line && cursor.ch   >= match.from.ch) ||
                                (
cursor.line >   match.from.line && cursor.line <  match.to.line) ||
                                (
cursor.line === match.to.line   && cursor.ch   <  match.to.ch);
                    }
                };

                var 
result callback(matchindex);

                if (!
result) {
                    return 
arguments[0];
                }

                
index++;

                
results.push(match);
                return 
result;
            });

            function 
translateOffset(offset) {
                var 
result editor.getValue().substring(0offset).split('n');
                return { 
lineresult.length 1chresult[result.length 1].length }
            }

            return 
results;
        },

        
_buildtoolbar: function() {

            if (!(
this.options.toolbar && this.options.toolbar.length)) return;

            var 
$this thisbar = [];

            
this.toolbar.empty();

            
this.options.toolbar.forEach(function(button) {
                if (!
$this.buttons[button]) return;

                var 
title $this.buttons[button].title $this.buttons[button].title button;

                
bar.push('<li><a data-htmleditor-button="'+button+'" title="'+title+'" data-uk-tooltip>'+$this.buttons[button].label+'</a></li>');
            });

            
this.toolbar.html(bar.join('n'));
        },

        
fit: function() {

            var 
mode this.options.mode;

            if (
mode == 'split' && this.htmleditor.width() < this.options.maxsplitsize) {
                
mode 'tab';
            }

            if (
mode == 'tab') {
                if (!
this.activetab) {
                    
this.activetab 'code';
                    
this.htmleditor.attr('data-active-tab'this.activetab);
                }

                
this.htmleditor.find('.uk-htmleditor-button-code, .uk-htmleditor-button-preview').removeClass('uk-active')
                    .
filter(this.activetab == 'code' '.uk-htmleditor-button-code' '.uk-htmleditor-button-preview')
                    .
addClass('uk-active');
            }

            
this.editor.refresh();
            
this.preview.parent().css('height'this.code.height());

            
this.htmleditor.attr('data-mode'mode);
        },

        
redraw: function() {
            
this._buildtoolbar();
            
this.render();
            
this.fit();
        },

        
getMode: function() {
            return 
this.editor.getOption('mode');
        },

        
getCursorMode: function() {
            var 
param = { mode'html'};
            
this.trigger('cursorMode', [param]);
            return 
param.mode;
        },

        
render: function() {

            
this.currentvalue this.editor.getValue();

            
// empty code
            
if (!this.currentvalue) {

                
this.element.val('');
                
this.preview.container.html('');

                return;
            }

            
this.trigger('render', [this]);
            
this.trigger('renderLate', [this]);

            
this.preview.container.html(this.currentvalue);
        },

        
addShortcut: function(namecallback) {
            var 
map = {};
            if (!
UI.$.isArray(name)) {
                
name = [name];
            }

            
name.forEach(function(key) {
                
map[key] = callback;
            });

            
this.editor.addKeyMap(map);

            return 
map;
        },

        
addShortcutAction: function(actionshortcuts) {
            var 
editor this;
            
this.addShortcut(shortcuts, function() {
                
editor.element.trigger('action.' action, [editor.editor]);
            });
        },

        
replaceSelection: function(replace) {

            var 
text this.editor.getSelection();

            if (!
text.length) {

                var 
cur     this.editor.getCursor(),
                    
curLine this.editor.getLine(cur.line),
                    
start   cur.ch,
                    
end     start;

                while (
end curLine.length && /[w$]+/.test(curLine.charAt(end))) ++end;
                while (
start && /[w$]+/.test(curLine.charAt(start 1))) --start;

                var 
curWord start != end && curLine.slice(startend);

                if (
curWord) {
                    
this.editor.setSelection({ linecur.linechstart}, { linecur.linechend });
                    
text curWord;
                }
            }

            var 
html replace.replace('$1'text);

            
this.editor.replaceSelection(html'end');
            
this.editor.focus();
        },

        
replaceLine: function(replace) {
            var 
pos  this.editor.getDoc().getCursor(),
                
text this.editor.getLine(pos.line),
                
html replace.replace('$1'text);

            
this.editor.replaceRange(html , { linepos.linech}, { linepos.linechtext.length });
            
this.editor.setCursor({ linepos.linechhtml.length });
            
this.editor.focus();
        },

        
save: function() {
            
this.editor.save();
        }
    });


    
UI.components.htmleditor.template = [
        
'<div class="uk-htmleditor uk-clearfix" data-mode="split">',
            
'<div class="uk-htmleditor-navbar">',
                
'<ul class="uk-htmleditor-navbar-nav uk-htmleditor-toolbar"></ul>',
                
'<div class="uk-htmleditor-navbar-flip">',
                    
'<ul class="uk-htmleditor-navbar-nav">',
                        
'<li class="uk-htmleditor-button-code"><a>{:lblCodeview}</a></li>',
                        
'<li class="uk-htmleditor-button-preview"><a>{:lblPreview}</a></li>',
                        
'<li><a data-htmleditor-button="fullscreen"><i class="uk-icon-expand"></i></a></li>',
                    
'</ul>',
                
'</div>',
            
'</div>',
            
'<div class="uk-htmleditor-content">',
                
'<div class="uk-htmleditor-code"></div>',
                
'<div class="uk-htmleditor-preview"><div></div></div>',
            
'</div>',
        
'</div>'
    
].join('');


    
UI.plugin('htmleditor''base', {

        
init: function(editor) {

            
editor.addButtons({

                
fullscreen: {
                    
title  'Fullscreen',
                    
label  '<i class="uk-icon-expand"></i>'
                
},
                
bold : {
                    
title  'Bold',
                    
label  '<i class="uk-icon-bold"></i>'
                
},
                
italic : {
                    
title  'Italic',
                    
label  '<i class="uk-icon-italic"></i>'
                
},
                
strike : {
                    
title  'Strikethrough',
                    
label  '<i class="uk-icon-strikethrough"></i>'
                
},
                
blockquote : {
                    
title  'Blockquote',
                    
label  '<i class="uk-icon-quote-right"></i>'
                
},
                
link : {
                    
title  'Link',
                    
label  '<i class="uk-icon-link"></i>'
                
},
                
image : {
                    
title  'Image',
                    
label  '<i class="uk-icon-picture-o"></i>'
                
},
                
listUl : {
                    
title  'Unordered List',
                    
label  '<i class="uk-icon-list-ul"></i>'
                
},
                
listOl : {
                    
title  'Ordered List',
                    
label  '<i class="uk-icon-list-ol"></i>'
                
}

            });

            
addAction('bold''<strong>$1</strong>');
            
addAction('italic''<em>$1</em>');
            
addAction('strike''<del>$1</del>');
            
addAction('blockquote''<blockquote><p>$1</p></blockquote>''replaceLine');
            
addAction('link''<a href="http://">$1</a>');
            
addAction('image''<img src="http://" alt="$1">');

            var 
listfn = function() {
                if (
editor.getCursorMode() == 'html') {

                    var 
cm      editor.editor,
                        
pos     cm.getDoc().getCursor(true),
                        
posend  cm.getDoc().getCursor(false);

                    for (var 
i=pos.linei<(posend.line+1);i++) {
                        
cm.replaceRange('<li>'+cm.getLine(i)+'</li>', { lineich}, { lineichcm.getLine(i).length });
                    }

                    
cm.setCursor({ lineposend.linechcm.getLine(posend.line).length });
                    
cm.focus();
                }
            };

            
editor.on('action.listUl', function() {
                
listfn();
            });

            
editor.on('action.listOl', function() {
                
listfn();
            });

            
editor.htmleditor.on('click''a[data-htmleditor-button="fullscreen"]', function() {
                
editor.htmleditor.toggleClass('uk-htmleditor-fullscreen');

                var 
wrap editor.editor.getWrapperElement();

                if (
editor.htmleditor.hasClass('uk-htmleditor-fullscreen')) {

                    
editor.editor.state.fullScreenRestore = {scrollTopwindow.pageYOffsetscrollLeftwindow.pageXOffsetwidthwrap.style.widthheightwrap.style.height};
                    
wrap.style.width  '';
                    
wrap.style.height editor.content.height()+'px';
                    
document.documentElement.style.overflow 'hidden';

                } else {

                    
document.documentElement.style.overflow '';
                    var 
info editor.editor.state.fullScreenRestore;
                    
wrap.style.width info.widthwrap.style.height info.height;
                    
window.scrollTo(info.scrollLeftinfo.scrollTop);
                }

                
setTimeout(function() {
                    
editor.fit();
                    
UI.$win.trigger('resize');
                }, 
50);
            });

            
editor.addShortcut(['Ctrl-S''Cmd-S'], function() { editor.element.trigger('htmleditor-save', [editor]); });
            
editor.addShortcutAction('bold', ['Ctrl-B''Cmd-B']);

            function 
addAction(namereplacemode) {
                
editor.on('action.'+name, function() {
                    if (
editor.getCursorMode() == 'html') {
                        
editor[mode == 'replaceLine' 'replaceLine' 'replaceSelection'](replace);
                    }
                });
            }
        }
    });

    
UI.plugin('htmleditor''markdown', {

        
init: function(editor) {

            var 
parser editor.options.mdparser || marked || null;

            if (!
parser) return;

            if (
editor.options.markdown) {
                
enableMarkdown();
            }

            
addAction('bold''**$1**');
            
addAction('italic''*$1*');
            
addAction('strike''~~$1~~');
            
addAction('blockquote''> $1''replaceLine');
            
addAction('link''[$1](http://)');
            
addAction('image''![$1](http://)');

            
editor.on('action.listUl', function() {

                if (
editor.getCursorMode() == 'markdown') {

                    var 
cm      editor.editor,
                        
pos     cm.getDoc().getCursor(true),
                        
posend  cm.getDoc().getCursor(false);

                    for (var 
i=pos.linei<(posend.line+1);i++) {
                        
cm.replaceRange('* '+cm.getLine(i), { lineich}, { lineichcm.getLine(i).length });
                    }

                    
cm.setCursor({ lineposend.linechcm.getLine(posend.line).length });
                    
cm.focus();
                }
            });

            
editor.on('action.listOl', function() {

                if (
editor.getCursorMode() == 'markdown') {

                    var 
cm      editor.editor,
                        
pos     cm.getDoc().getCursor(true),
                        
posend  cm.getDoc().getCursor(false),
                        
prefix  1;

                    if (
pos.line 0) {
                        var 
prevline cm.getLine(pos.line-1), matches;

                        if(
matches prevline.match(/^(d+)./)) {
                            
prefix Number(matches[1])+1;
                        }
                    }

                    for (var 
i=pos.linei<(posend.line+1);i++) {
                        
cm.replaceRange(prefix+'. '+cm.getLine(i), { lineich}, { lineichcm.getLine(i).length });
                        
prefix++;
                    }

                    
cm.setCursor({ lineposend.linechcm.getLine(posend.line).length });
                    
cm.focus();
                }
            });

            
editor.on('renderLate', function() {
                if (
editor.editor.options.mode == 'gfm') {
                    
editor.currentvalue parser(editor.currentvalue);
                }
            });

            
editor.on('cursorMode', function(eparam) {
                if (
editor.editor.options.mode == 'gfm') {
                    var 
pos editor.editor.getDoc().getCursor();
                    if (!
editor.editor.getTokenAt(pos).state.base.htmlState) {
                        
param.mode 'markdown';
                    }
                }
            });

            
UI.$.extend(editor, {

                
enableMarkdown: function() {
                    
enableMarkdown();
                    
this.render();
                },
                
disableMarkdown: function() {
                    
this.editor.setOption('mode''htmlmixed');
                    
this.htmleditor.find('.uk-htmleditor-button-code a').html(this.options.lblCodeview);
                    
this.render();
                }

            });

            
// switch markdown mode on event
            
editor.on({
                
enableMarkdown  : function() { editor.enableMarkdown(); },
                
disableMarkdown : function() { editor.disableMarkdown(); }
            });

            function 
enableMarkdown() {
                
editor.editor.setOption('mode''gfm');
                
editor.htmleditor.find('.uk-htmleditor-button-code a').html(editor.options.lblMarkedview);
            }

            function 
addAction(namereplacemode) {
                
editor.on('action.'+name, function() {
                    if (
editor.getCursorMode() == 'markdown') {
                        
editor[mode == 'replaceLine' 'replaceLine' 'replaceSelection'](replace);
                    }
                });
            }
        }
    });

    return 
UI.htmleditor;
});
?>
Онлайн: 2
Реклама