diff options
Diffstat (limited to 'js/components/htmleditor.js')
| -rwxr-xr-x | js/components/htmleditor.js | 679 |
1 files changed, 0 insertions, 679 deletions
diff --git a/js/components/htmleditor.js b/js/components/htmleditor.js deleted file mode 100755 index 68b5b52..0000000 --- a/js/components/htmleditor.js +++ /dev/null | |||
| @@ -1,679 +0,0 @@ | |||
| 1 | /*! UIkit 2.26.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */ | ||
| 2 | (function(addon) { | ||
| 3 | |||
| 4 | var component; | ||
| 5 | |||
| 6 | if (window.UIkit) { | ||
| 7 | component = addon(UIkit); | ||
| 8 | } | ||
| 9 | |||
| 10 | if (typeof define == "function" && define.amd) { | ||
| 11 | define("uikit-htmleditor", ["uikit"], function(){ | ||
| 12 | return component || addon(UIkit); | ||
| 13 | }); | ||
| 14 | } | ||
| 15 | |||
| 16 | })(function(UI) { | ||
| 17 | |||
| 18 | "use strict"; | ||
| 19 | |||
| 20 | var editors = []; | ||
| 21 | |||
| 22 | UI.component('htmleditor', { | ||
| 23 | |||
| 24 | defaults: { | ||
| 25 | iframe : false, | ||
| 26 | mode : 'split', | ||
| 27 | markdown : false, | ||
| 28 | autocomplete : true, | ||
| 29 | enablescripts: false, | ||
| 30 | height : 500, | ||
| 31 | maxsplitsize : 1000, | ||
| 32 | codemirror : { mode: 'htmlmixed', lineWrapping: true, dragDrop: false, autoCloseTags: true, matchTags: true, autoCloseBrackets: true, matchBrackets: true, indentUnit: 4, indentWithTabs: false, tabSize: 4, hintOptions: {completionSingle:false} }, | ||
| 33 | toolbar : [ 'bold', 'italic', 'strike', 'link', 'image', 'blockquote', 'listUl', 'listOl' ], | ||
| 34 | lblPreview : 'Preview', | ||
| 35 | lblCodeview : 'HTML', | ||
| 36 | lblMarkedview: 'Markdown' | ||
| 37 | }, | ||
| 38 | |||
| 39 | boot: function() { | ||
| 40 | |||
| 41 | // init code | ||
| 42 | UI.ready(function(context) { | ||
| 43 | |||
| 44 | UI.$('textarea[data-uk-htmleditor]', context).each(function() { | ||
| 45 | |||
| 46 | var editor = UI.$(this); | ||
| 47 | |||
| 48 | if (!editor.data('htmleditor')) { | ||
| 49 | UI.htmleditor(editor, UI.Utils.options(editor.attr('data-uk-htmleditor'))); | ||
| 50 | } | ||
| 51 | }); | ||
| 52 | }); | ||
| 53 | }, | ||
| 54 | |||
| 55 | init: function() { | ||
| 56 | |||
| 57 | var $this = this, tpl = UI.components.htmleditor.template; | ||
| 58 | |||
| 59 | this.CodeMirror = this.options.CodeMirror || CodeMirror; | ||
| 60 | this.buttons = {}; | ||
| 61 | |||
| 62 | tpl = tpl.replace(/\{:lblPreview}/g, this.options.lblPreview); | ||
| 63 | tpl = tpl.replace(/\{:lblCodeview}/g, this.options.lblCodeview); | ||
| 64 | |||
| 65 | this.htmleditor = UI.$(tpl); | ||
| 66 | this.content = this.htmleditor.find('.uk-htmleditor-content'); | ||
| 67 | this.toolbar = this.htmleditor.find('.uk-htmleditor-toolbar'); | ||
| 68 | this.preview = this.htmleditor.find('.uk-htmleditor-preview').children().eq(0); | ||
| 69 | this.code = this.htmleditor.find('.uk-htmleditor-code'); | ||
| 70 | |||
| 71 | this.element.before(this.htmleditor).appendTo(this.code); | ||
| 72 | this.editor = this.CodeMirror.fromTextArea(this.element[0], this.options.codemirror); | ||
| 73 | this.editor.htmleditor = this; | ||
| 74 | this.editor.on('change', UI.Utils.debounce(function() { $this.render(); }, 150)); | ||
| 75 | this.editor.on('change', function() { | ||
| 76 | $this.editor.save(); | ||
| 77 | $this.element.trigger('input'); | ||
| 78 | }); | ||
| 79 | this.code.find('.CodeMirror').css('height', this.options.height); | ||
| 80 | |||
| 81 | // iframe mode? | ||
| 82 | if (this.options.iframe) { | ||
| 83 | |||
| 84 | this.iframe = UI.$('<iframe class="uk-htmleditor-iframe" frameborder="0" scrolling="auto" height="100" width="100%"></iframe>'); | ||
| 85 | this.preview.append(this.iframe); | ||
| 86 | |||
| 87 | // must open and close document object to start using it! | ||
| 88 | this.iframe[0].contentWindow.document.open(); | ||
| 89 | this.iframe[0].contentWindow.document.close(); | ||
| 90 | |||
| 91 | this.preview.container = UI.$(this.iframe[0].contentWindow.document).find('body'); | ||
| 92 | |||
| 93 | // append custom stylesheet | ||
| 94 | if (typeof(this.options.iframe) === 'string') { | ||
| 95 | this.preview.container.parent().append('<link rel="stylesheet" href="'+this.options.iframe+'">'); | ||
| 96 | } | ||
| 97 | |||
| 98 | } else { | ||
| 99 | this.preview.container = this.preview; | ||
| 100 | } | ||
| 101 | |||
| 102 | UI.$win.on('resize load', UI.Utils.debounce(function() { $this.fit(); }, 200)); | ||
| 103 | |||
| 104 | var previewContainer = this.iframe ? this.preview.container:$this.preview.parent(), | ||
| 105 | codeContent = this.code.find('.CodeMirror-sizer'), | ||
| 106 | codeScroll = this.code.find('.CodeMirror-scroll').on('scroll', UI.Utils.debounce(function() { | ||
| 107 | |||
| 108 | if ($this.htmleditor.attr('data-mode') == 'tab') return; | ||
| 109 | |||
| 110 | // calc position | ||
| 111 | var codeHeight = codeContent.height() - codeScroll.height(), | ||
| 112 | previewHeight = previewContainer[0].scrollHeight - ($this.iframe ? $this.iframe.height() : previewContainer.height()), | ||
| 113 | ratio = previewHeight / codeHeight, | ||
| 114 | previewPosition = codeScroll.scrollTop() * ratio; | ||
| 115 | |||
| 116 | // apply new scroll | ||
| 117 | previewContainer.scrollTop(previewPosition); | ||
| 118 | |||
| 119 | }, 10)); | ||
| 120 | |||
| 121 | this.htmleditor.on('click', '.uk-htmleditor-button-code, .uk-htmleditor-button-preview', function(e) { | ||
| 122 | |||
| 123 | e.preventDefault(); | ||
| 124 | |||
| 125 | if ($this.htmleditor.attr('data-mode') == 'tab') { | ||
| 126 | |||
| 127 | $this.htmleditor.find('.uk-htmleditor-button-code, .uk-htmleditor-button-preview').removeClass('uk-active').filter(this).addClass('uk-active'); | ||
| 128 | |||
| 129 | $this.activetab = UI.$(this).hasClass('uk-htmleditor-button-code') ? 'code' : 'preview'; | ||
| 130 | $this.htmleditor.attr('data-active-tab', $this.activetab); | ||
| 131 | $this.editor.refresh(); | ||
| 132 | } | ||
| 133 | }); | ||
| 134 | |||
| 135 | // toolbar actions | ||
| 136 | this.htmleditor.on('click', 'a[data-htmleditor-button]', function() { | ||
| 137 | |||
| 138 | if (!$this.code.is(':visible')) return; | ||
| 139 | |||
| 140 | $this.trigger('action.' + UI.$(this).data('htmleditor-button'), [$this.editor]); | ||
| 141 | }); | ||
| 142 | |||
| 143 | this.preview.parent().css('height', this.code.height()); | ||
| 144 | |||
| 145 | // autocomplete | ||
| 146 | if (this.options.autocomplete && this.CodeMirror.showHint && this.CodeMirror.hint && this.CodeMirror.hint.html) { | ||
| 147 | |||
| 148 | this.editor.on('inputRead', UI.Utils.debounce(function() { | ||
| 149 | var doc = $this.editor.getDoc(), POS = doc.getCursor(), mode = $this.CodeMirror.innerMode($this.editor.getMode(), $this.editor.getTokenAt(POS).state).mode.name; | ||
| 150 | |||
| 151 | if (mode == 'xml') { //html depends on xml | ||
| 152 | |||
| 153 | var cur = $this.editor.getCursor(), token = $this.editor.getTokenAt(cur); | ||
| 154 | |||
| 155 | if (token.string.charAt(0) == '<' || token.type == 'attribute') { | ||
| 156 | $this.CodeMirror.showHint($this.editor, $this.CodeMirror.hint.html, { completeSingle: false }); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | }, 100)); | ||
| 160 | } | ||
| 161 | |||
| 162 | this.debouncedRedraw = UI.Utils.debounce(function () { $this.redraw(); }, 5); | ||
| 163 | |||
| 164 | this.on('init.uk.component', function() { | ||
| 165 | $this.debouncedRedraw(); | ||
| 166 | }); | ||
| 167 | |||
| 168 | this.element.attr('data-uk-check-display', 1).on('display.uk.check', function(e) { | ||
| 169 | if (this.htmleditor.is(":visible")) this.fit(); | ||
| 170 | }.bind(this)); | ||
| 171 | |||
| 172 | editors.push(this); | ||
| 173 | }, | ||
| 174 | |||
| 175 | addButton: function(name, button) { | ||
| 176 | this.buttons[name] = button; | ||
| 177 | }, | ||
| 178 | |||
| 179 | addButtons: function(buttons) { | ||
| 180 | UI.$.extend(this.buttons, buttons); | ||
| 181 | }, | ||
| 182 | |||
| 183 | replaceInPreview: function(regexp, callback) { | ||
| 184 | |||
| 185 | var editor = this.editor, results = [], value = editor.getValue(), offset = -1, index = 0; | ||
| 186 | |||
| 187 | this.currentvalue = this.currentvalue.replace(regexp, function() { | ||
| 188 | |||
| 189 | offset = value.indexOf(arguments[0], ++offset); | ||
| 190 | |||
| 191 | var match = { | ||
| 192 | matches: arguments, | ||
| 193 | from : translateOffset(offset), | ||
| 194 | to : translateOffset(offset + arguments[0].length), | ||
| 195 | replace: function(value) { | ||
| 196 | editor.replaceRange(value, match.from, match.to); | ||
| 197 | }, | ||
| 198 | inRange: function(cursor) { | ||
| 199 | |||
| 200 | if (cursor.line === match.from.line && cursor.line === match.to.line) { | ||
| 201 | return cursor.ch >= match.from.ch && cursor.ch < match.to.ch; | ||
| 202 | } | ||
| 203 | |||
| 204 | return (cursor.line === match.from.line && cursor.ch >= match.from.ch) || | ||
| 205 | (cursor.line > match.from.line && cursor.line < match.to.line) || | ||
| 206 | (cursor.line === match.to.line && cursor.ch < match.to.ch); | ||
| 207 | } | ||
| 208 | }; | ||
| 209 | |||
| 210 | var result = typeof(callback) === 'string' ? callback : callback(match, index); | ||
| 211 | |||
| 212 | if (!result && result !== '') { | ||
| 213 | return arguments[0]; | ||
| 214 | } | ||
| 215 | |||
| 216 | index++; | ||
| 217 | |||
| 218 | results.push(match); | ||
| 219 | return result; | ||
| 220 | }); | ||
| 221 | |||
| 222 | function translateOffset(offset) { | ||
| 223 | var result = editor.getValue().substring(0, offset).split('\n'); | ||
| 224 | return { line: result.length - 1, ch: result[result.length - 1].length } | ||
| 225 | } | ||
| 226 | |||
| 227 | return results; | ||
| 228 | }, | ||
| 229 | |||
| 230 | _buildtoolbar: function() { | ||
| 231 | |||
| 232 | if (!(this.options.toolbar && this.options.toolbar.length)) return; | ||
| 233 | |||
| 234 | var $this = this, bar = []; | ||
| 235 | |||
| 236 | this.toolbar.empty(); | ||
| 237 | |||
| 238 | this.options.toolbar.forEach(function(button) { | ||
| 239 | if (!$this.buttons[button]) return; | ||
| 240 | |||
| 241 | var title = $this.buttons[button].title ? $this.buttons[button].title : button; | ||
| 242 | |||
| 243 | bar.push('<li><a data-htmleditor-button="'+button+'" title="'+title+'" data-uk-tooltip>'+$this.buttons[button].label+'</a></li>'); | ||
| 244 | }); | ||
| 245 | |||
| 246 | this.toolbar.html(bar.join('\n')); | ||
| 247 | }, | ||
| 248 | |||
| 249 | fit: function() { | ||
| 250 | |||
| 251 | var mode = this.options.mode; | ||
| 252 | |||
| 253 | if (mode == 'split' && this.htmleditor.width() < this.options.maxsplitsize) { | ||
| 254 | mode = 'tab'; | ||
| 255 | } | ||
| 256 | |||
| 257 | if (mode == 'tab') { | ||
| 258 | if (!this.activetab) { | ||
| 259 | this.activetab = 'code'; | ||
| 260 | this.htmleditor.attr('data-active-tab', this.activetab); | ||
| 261 | } | ||
| 262 | |||
| 263 | this.htmleditor.find('.uk-htmleditor-button-code, .uk-htmleditor-button-preview').removeClass('uk-active') | ||
| 264 | .filter(this.activetab == 'code' ? '.uk-htmleditor-button-code' : '.uk-htmleditor-button-preview') | ||
| 265 | .addClass('uk-active'); | ||
| 266 | } | ||
| 267 | |||
| 268 | this.editor.refresh(); | ||
| 269 | this.preview.parent().css('height', this.code.height()); | ||
| 270 | |||
| 271 | this.htmleditor.attr('data-mode', mode); | ||
| 272 | }, | ||
| 273 | |||
| 274 | redraw: function() { | ||
| 275 | this._buildtoolbar(); | ||
| 276 | this.render(); | ||
| 277 | this.fit(); | ||
| 278 | }, | ||
| 279 | |||
| 280 | getMode: function() { | ||
| 281 | return this.editor.getOption('mode'); | ||
| 282 | }, | ||
| 283 | |||
| 284 | getCursorMode: function() { | ||
| 285 | var param = { mode: 'html'}; | ||
| 286 | this.trigger('cursorMode', [param]); | ||
| 287 | return param.mode; | ||
| 288 | }, | ||
| 289 | |||
| 290 | render: function() { | ||
| 291 | |||
| 292 | this.currentvalue = this.editor.getValue(); | ||
| 293 | |||
| 294 | if (!this.options.enablescripts) { | ||
| 295 | this.currentvalue = this.currentvalue.replace(/<(script|style)\b[^<]*(?:(?!<\/(script|style)>)<[^<]*)*<\/(script|style)>/img, ''); | ||
| 296 | } | ||
| 297 | |||
| 298 | // empty code | ||
| 299 | if (!this.currentvalue) { | ||
| 300 | |||
| 301 | this.element.val(''); | ||
| 302 | this.preview.container.html(''); | ||
| 303 | |||
| 304 | return; | ||
| 305 | } | ||
| 306 | |||
| 307 | this.trigger('render', [this]); | ||
| 308 | this.trigger('renderLate', [this]); | ||
| 309 | |||
| 310 | this.preview.container.html(this.currentvalue); | ||
| 311 | }, | ||
| 312 | |||
| 313 | addShortcut: function(name, callback) { | ||
| 314 | var map = {}; | ||
| 315 | if (!UI.$.isArray(name)) { | ||
| 316 | name = [name]; | ||
| 317 | } | ||
| 318 | |||
| 319 | name.forEach(function(key) { | ||
| 320 | map[key] = callback; | ||
| 321 | }); | ||
| 322 | |||
| 323 | this.editor.addKeyMap(map); | ||
| 324 | |||
| 325 | return map; | ||
| 326 | }, | ||
| 327 | |||
| 328 | addShortcutAction: function(action, shortcuts) { | ||
| 329 | var editor = this; | ||
| 330 | this.addShortcut(shortcuts, function() { | ||
| 331 | editor.element.trigger('action.' + action, [editor.editor]); | ||
| 332 | }); | ||
| 333 | }, | ||
| 334 | |||
| 335 | replaceSelection: function(replace) { | ||
| 336 | |||
| 337 | var text = this.editor.getSelection(); | ||
| 338 | |||
| 339 | if (!text.length) { | ||
| 340 | |||
| 341 | var cur = this.editor.getCursor(), | ||
| 342 | curLine = this.editor.getLine(cur.line), | ||
| 343 | start = cur.ch, | ||
| 344 | end = start; | ||
| 345 | |||
| 346 | while (end < curLine.length && /[\w$]+/.test(curLine.charAt(end))) ++end; | ||
| 347 | while (start && /[\w$]+/.test(curLine.charAt(start - 1))) --start; | ||
| 348 | |||
| 349 | var curWord = start != end && curLine.slice(start, end); | ||
| 350 | |||
| 351 | if (curWord) { | ||
| 352 | this.editor.setSelection({ line: cur.line, ch: start}, { line: cur.line, ch: end }); | ||
| 353 | text = curWord; | ||
| 354 | } | ||
| 355 | } | ||
| 356 | |||
| 357 | var html = replace.replace('$1', text); | ||
| 358 | |||
| 359 | this.editor.replaceSelection(html, 'end'); | ||
| 360 | this.editor.focus(); | ||
| 361 | }, | ||
| 362 | |||
| 363 | replaceLine: function(replace) { | ||
| 364 | var pos = this.editor.getDoc().getCursor(), | ||
| 365 | text = this.editor.getLine(pos.line), | ||
| 366 | html = replace.replace('$1', text); | ||
| 367 | |||
| 368 | this.editor.replaceRange(html , { line: pos.line, ch: 0 }, { line: pos.line, ch: text.length }); | ||
| 369 | this.editor.setCursor({ line: pos.line, ch: html.length }); | ||
| 370 | this.editor.focus(); | ||
| 371 | }, | ||
| 372 | |||
| 373 | save: function() { | ||
| 374 | this.editor.save(); | ||
| 375 | } | ||
| 376 | }); | ||
| 377 | |||
| 378 | |||
| 379 | UI.components.htmleditor.template = [ | ||
| 380 | '<div class="uk-htmleditor uk-clearfix" data-mode="split">', | ||
| 381 | '<div class="uk-htmleditor-navbar">', | ||
| 382 | '<ul class="uk-htmleditor-navbar-nav uk-htmleditor-toolbar"></ul>', | ||
| 383 | '<div class="uk-htmleditor-navbar-flip">', | ||
| 384 | '<ul class="uk-htmleditor-navbar-nav">', | ||
| 385 | '<li class="uk-htmleditor-button-code"><a>{:lblCodeview}</a></li>', | ||
| 386 | '<li class="uk-htmleditor-button-preview"><a>{:lblPreview}</a></li>', | ||
| 387 | '<li><a data-htmleditor-button="fullscreen"><i class="uk-icon-expand"></i></a></li>', | ||
| 388 | '</ul>', | ||
| 389 | '</div>', | ||
| 390 | '</div>', | ||
| 391 | '<div class="uk-htmleditor-content">', | ||
| 392 | '<div class="uk-htmleditor-code"></div>', | ||
| 393 | '<div class="uk-htmleditor-preview"><div></div></div>', | ||
| 394 | '</div>', | ||
| 395 | '</div>' | ||
| 396 | ].join(''); | ||
| 397 | |||
| 398 | |||
| 399 | UI.plugin('htmleditor', 'base', { | ||
| 400 | |||
| 401 | init: function(editor) { | ||
| 402 | |||
| 403 | editor.addButtons({ | ||
| 404 | |||
| 405 | fullscreen: { | ||
| 406 | title : 'Fullscreen', | ||
| 407 | label : '<i class="uk-icon-expand"></i>' | ||
| 408 | }, | ||
| 409 | bold : { | ||
| 410 | title : 'Bold', | ||
| 411 | label : '<i class="uk-icon-bold"></i>' | ||
| 412 | }, | ||
| 413 | italic : { | ||
| 414 | title : 'Italic', | ||
| 415 | label : '<i class="uk-icon-italic"></i>' | ||
| 416 | }, | ||
| 417 | strike : { | ||
| 418 | title : 'Strikethrough', | ||
| 419 | label : '<i class="uk-icon-strikethrough"></i>' | ||
| 420 | }, | ||
| 421 | blockquote : { | ||
| 422 | title : 'Blockquote', | ||
| 423 | label : '<i class="uk-icon-quote-right"></i>' | ||
| 424 | }, | ||
| 425 | link : { | ||
| 426 | title : 'Link', | ||
| 427 | label : '<i class="uk-icon-link"></i>' | ||
| 428 | }, | ||
| 429 | image : { | ||
| 430 | title : 'Image', | ||
| 431 | label : '<i class="uk-icon-picture-o"></i>' | ||
| 432 | }, | ||
| 433 | listUl : { | ||
| 434 | title : 'Unordered List', | ||
| 435 | label : '<i class="uk-icon-list-ul"></i>' | ||
| 436 | }, | ||
| 437 | listOl : { | ||
| 438 | title : 'Ordered List', | ||
| 439 | label : '<i class="uk-icon-list-ol"></i>' | ||
| 440 | } | ||
| 441 | |||
| 442 | }); | ||
| 443 | |||
| 444 | addAction('bold', '<strong>$1</strong>'); | ||
| 445 | addAction('italic', '<em>$1</em>'); | ||
| 446 | addAction('strike', '<del>$1</del>'); | ||
| 447 | addAction('blockquote', '<blockquote><p>$1</p></blockquote>', 'replaceLine'); | ||
| 448 | addAction('link', '<a href="http://">$1</a>'); | ||
| 449 | addAction('image', '<img src="http://" alt="$1">'); | ||
| 450 | |||
| 451 | var listfn = function(tag) { | ||
| 452 | if (editor.getCursorMode() == 'html') { | ||
| 453 | |||
| 454 | tag = tag || 'ul'; | ||
| 455 | |||
| 456 | var cm = editor.editor, | ||
| 457 | doc = cm.getDoc(), | ||
| 458 | pos = doc.getCursor(true), | ||
| 459 | posend = doc.getCursor(false), | ||
| 460 | im = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(cm.getCursor()).state), | ||
| 461 | inList = im && im.state && im.state.context && ['ul','ol'].indexOf(im.state.context.tagName) != -1; | ||
| 462 | |||
| 463 | for (var i=pos.line; i<(posend.line+1);i++) { | ||
| 464 | cm.replaceRange('<li>'+cm.getLine(i)+'</li>', { line: i, ch: 0 }, { line: i, ch: cm.getLine(i).length }); | ||
| 465 | } | ||
| 466 | |||
| 467 | if (!inList) { | ||
| 468 | cm.replaceRange('<'+tag+'>'+"\n"+cm.getLine(pos.line), { line: pos.line, ch: 0 }, { line: pos.line, ch: cm.getLine(pos.line).length }); | ||
| 469 | cm.replaceRange(cm.getLine((posend.line+1))+"\n"+'</'+tag+'>', { line: (posend.line+1), ch: 0 }, { line: (posend.line+1), ch: cm.getLine((posend.line+1)).length }); | ||
| 470 | cm.setCursor({ line: posend.line+1, ch: cm.getLine(posend.line+1).length }); | ||
| 471 | } else { | ||
| 472 | cm.setCursor({ line: posend.line, ch: cm.getLine(posend.line).length }); | ||
| 473 | } | ||
| 474 | |||
| 475 | cm.focus(); | ||
| 476 | } | ||
| 477 | }; | ||
| 478 | |||
| 479 | editor.on('action.listUl', function() { | ||
| 480 | listfn('ul'); | ||
| 481 | }); | ||
| 482 | |||
| 483 | editor.on('action.listOl', function() { | ||
| 484 | listfn('ol'); | ||
| 485 | }); | ||
| 486 | |||
| 487 | editor.htmleditor.on('click', 'a[data-htmleditor-button="fullscreen"]', function() { | ||
| 488 | |||
| 489 | editor.htmleditor.toggleClass('uk-htmleditor-fullscreen'); | ||
| 490 | |||
| 491 | var wrap = editor.editor.getWrapperElement(); | ||
| 492 | |||
| 493 | if (editor.htmleditor.hasClass('uk-htmleditor-fullscreen')) { | ||
| 494 | |||
| 495 | var fixedParent = false, parents = editor.htmleditor.parents().each(function(){ | ||
| 496 | if (UI.$(this).css('position')=='fixed' && !UI.$(this).is('html')) { | ||
| 497 | fixedParent = UI.$(this); | ||
| 498 | } | ||
| 499 | }); | ||
| 500 | |||
| 501 | editor.htmleditor.data('fixedParents', false); | ||
| 502 | |||
| 503 | if (fixedParent) { | ||
| 504 | |||
| 505 | var transformed = []; | ||
| 506 | |||
| 507 | fixedParent = fixedParent.parent().find(parents).each(function(){ | ||
| 508 | |||
| 509 | if (UI.$(this).css('transform') != 'none') { | ||
| 510 | transformed.push(UI.$(this).data('transform-reset', { | ||
| 511 | 'transform': this.style.transform, | ||
| 512 | '-webkit-transform': this.style.webkitTransform, | ||
| 513 | '-webkit-transition':this.style.webkitTransition, | ||
| 514 | 'transition':this.style.transition | ||
| 515 | }).css({ | ||
| 516 | 'transform': 'none', | ||
| 517 | '-webkit-transform': 'none', | ||
| 518 | '-webkit-transition':'none', | ||
| 519 | 'transition':'none' | ||
| 520 | })); | ||
| 521 | } | ||
| 522 | }); | ||
| 523 | |||
| 524 | editor.htmleditor.data('fixedParents', transformed); | ||
| 525 | } | ||
| 526 | |||
| 527 | editor.editor.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset, width: wrap.style.width, height: wrap.style.height}; | ||
| 528 | wrap.style.width = ''; | ||
| 529 | wrap.style.height = editor.content.height()+'px'; | ||
| 530 | document.documentElement.style.overflow = 'hidden'; | ||
| 531 | |||
| 532 | } else { | ||
| 533 | |||
| 534 | document.documentElement.style.overflow = ''; | ||
| 535 | var info = editor.editor.state.fullScreenRestore; | ||
| 536 | wrap.style.width = info.width; wrap.style.height = info.height; | ||
| 537 | window.scrollTo(info.scrollLeft, info.scrollTop); | ||
| 538 | |||
| 539 | if (editor.htmleditor.data('fixedParents')) { | ||
| 540 | editor.htmleditor.data('fixedParents').forEach(function(parent){ | ||
| 541 | parent.css(parent.data('transform-reset')); | ||
| 542 | }); | ||
| 543 | } | ||
| 544 | } | ||
| 545 | |||
| 546 | setTimeout(function() { | ||
| 547 | editor.fit(); | ||
| 548 | UI.$win.trigger('resize'); | ||
| 549 | }, 50); | ||
| 550 | }); | ||
| 551 | |||
| 552 | editor.addShortcut(['Ctrl-S', 'Cmd-S'], function() { editor.element.trigger('htmleditor-save', [editor]); }); | ||
| 553 | editor.addShortcutAction('bold', ['Ctrl-B', 'Cmd-B']); | ||
| 554 | |||
| 555 | function addAction(name, replace, mode) { | ||
| 556 | editor.on('action.'+name, function() { | ||
| 557 | if (editor.getCursorMode() == 'html') { | ||
| 558 | editor[mode == 'replaceLine' ? 'replaceLine' : 'replaceSelection'](replace); | ||
| 559 | } | ||
| 560 | }); | ||
| 561 | } | ||
| 562 | } | ||
| 563 | }); | ||
| 564 | |||
| 565 | UI.plugin('htmleditor', 'markdown', { | ||
| 566 | |||
| 567 | init: function(editor) { | ||
| 568 | |||
| 569 | var parser = editor.options.mdparser || window.marked || null; | ||
| 570 | |||
| 571 | if (!parser) return; | ||
| 572 | |||
| 573 | if (editor.options.markdown) { | ||
| 574 | enableMarkdown(); | ||
| 575 | } | ||
| 576 | |||
| 577 | addAction('bold', '**$1**'); | ||
| 578 | addAction('italic', '*$1*'); | ||
| 579 | addAction('strike', '~~$1~~'); | ||
| 580 | addAction('blockquote', '> $1', 'replaceLine'); | ||
| 581 | addAction('link', '[$1](http://)'); | ||
| 582 | addAction('image', ''); | ||
| 583 | |||
| 584 | editor.on('action.listUl', function() { | ||
| 585 | |||
| 586 | if (editor.getCursorMode() == 'markdown') { | ||
| 587 | |||
| 588 | var cm = editor.editor, | ||
| 589 | pos = cm.getDoc().getCursor(true), | ||
| 590 | posend = cm.getDoc().getCursor(false); | ||
| 591 | |||
| 592 | for (var i=pos.line; i<(posend.line+1);i++) { | ||
| 593 | cm.replaceRange('* '+cm.getLine(i), { line: i, ch: 0 }, { line: i, ch: cm.getLine(i).length }); | ||
| 594 | } | ||
| 595 | |||
| 596 | cm.setCursor({ line: posend.line, ch: cm.getLine(posend.line).length }); | ||
| 597 | cm.focus(); | ||
| 598 | } | ||
| 599 | }); | ||
| 600 | |||
| 601 | editor.on('action.listOl', function() { | ||
| 602 | |||
| 603 | if (editor.getCursorMode() == 'markdown') { | ||
| 604 | |||
| 605 | var cm = editor.editor, | ||
| 606 | pos = cm.getDoc().getCursor(true), | ||
| 607 | posend = cm.getDoc().getCursor(false), | ||
| 608 | prefix = 1; | ||
| 609 | |||
| 610 | if (pos.line > 0) { | ||
| 611 | var prevline = cm.getLine(pos.line-1), matches; | ||
| 612 | |||
| 613 | if(matches = prevline.match(/^(\d+)\./)) { | ||
| 614 | prefix = Number(matches[1])+1; | ||
| 615 | } | ||
| 616 | } | ||
| 617 | |||
| 618 | for (var i=pos.line; i<(posend.line+1);i++) { | ||
| 619 | cm.replaceRange(prefix+'. '+cm.getLine(i), { line: i, ch: 0 }, { line: i, ch: cm.getLine(i).length }); | ||
| 620 | prefix++; | ||
| 621 | } | ||
| 622 | |||
| 623 | cm.setCursor({ line: posend.line, ch: cm.getLine(posend.line).length }); | ||
| 624 | cm.focus(); | ||
| 625 | } | ||
| 626 | }); | ||
| 627 | |||
| 628 | editor.on('renderLate', function() { | ||
| 629 | if (editor.editor.options.mode == 'gfm') { | ||
| 630 | editor.currentvalue = parser(editor.currentvalue); | ||
| 631 | } | ||
| 632 | }); | ||
| 633 | |||
| 634 | editor.on('cursorMode', function(e, param) { | ||
| 635 | if (editor.editor.options.mode == 'gfm') { | ||
| 636 | var pos = editor.editor.getDoc().getCursor(); | ||
| 637 | if (!editor.editor.getTokenAt(pos).state.base.htmlState) { | ||
| 638 | param.mode = 'markdown'; | ||
| 639 | } | ||
| 640 | } | ||
| 641 | }); | ||
| 642 | |||
| 643 | UI.$.extend(editor, { | ||
| 644 | |||
| 645 | enableMarkdown: function() { | ||
| 646 | enableMarkdown(); | ||
| 647 | this.render(); | ||
| 648 | }, | ||
| 649 | disableMarkdown: function() { | ||
| 650 | this.editor.setOption('mode', 'htmlmixed'); | ||
| 651 | this.htmleditor.find('.uk-htmleditor-button-code a').html(this.options.lblCodeview); | ||
| 652 | this.render(); | ||
| 653 | } | ||
| 654 | |||
| 655 | }); | ||
| 656 | |||
| 657 | // switch markdown mode on event | ||
| 658 | editor.on({ | ||
| 659 | enableMarkdown : function() { editor.enableMarkdown(); }, | ||
| 660 | disableMarkdown : function() { editor.disableMarkdown(); } | ||
| 661 | }); | ||
| 662 | |||
| 663 | function enableMarkdown() { | ||
| 664 | editor.editor.setOption('mode', 'gfm'); | ||
| 665 | editor.htmleditor.find('.uk-htmleditor-button-code a').html(editor.options.lblMarkedview); | ||
| 666 | } | ||
| 667 | |||
| 668 | function addAction(name, replace, mode) { | ||
| 669 | editor.on('action.'+name, function() { | ||
| 670 | if (editor.getCursorMode() == 'markdown') { | ||
| 671 | editor[mode == 'replaceLine' ? 'replaceLine' : 'replaceSelection'](replace); | ||
| 672 | } | ||
| 673 | }); | ||
| 674 | } | ||
| 675 | } | ||
| 676 | }); | ||
| 677 | |||
| 678 | return UI.htmleditor; | ||
| 679 | }); | ||
