Created
September 15, 2014 11:43
-
-
Save Spoygg/4e9b6d78b0476d5fde9c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/library/class_upfront_theme.php b/library/class_upfront_theme.php | |
index d3559e0..188d532 100644 | |
--- a/library/class_upfront_theme.php | |
+++ b/library/class_upfront_theme.php | |
@@ -80,19 +80,19 @@ class Upfront_Theme { | |
return $this->regions; | |
} | |
- public function get_default_layout($cascade, $layout_slug = "", $add_global_regions = false) { | |
+ public function get_default_layout($cascade, $layout_slug = "") { | |
$regions = new Upfront_Layout_Maker(); | |
$template_path = $this->find_default_layout($cascade, $layout_slug); | |
$current_theme = Upfront_ChildTheme::get_instance(); | |
- if ($add_global_regions && $current_theme && $current_theme->has_global_region('header')) { | |
+ if ($current_theme && $current_theme->has_global_region('header')) { | |
include(get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'global-regions' . DIRECTORY_SEPARATOR . 'header.php'); | |
} | |
require $template_path; | |
- if ($add_global_regions && $current_theme && $current_theme->has_global_region('footer')) { | |
+ if ($current_theme && $current_theme->has_global_region('footer')) { | |
include(get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'global-regions' . DIRECTORY_SEPARATOR . 'footer.php'); | |
} | |
@@ -320,7 +320,7 @@ class Upfront_Virtual_Region { | |
$breakpoint_data[$breakpoint->get_id()]['col'] = $wrapper_col; | |
} | |
} | |
- | |
+ | |
} | |
if ( $group && $this->modules[$group] ){ | |
$class = $this->get_property('class', $this->modules[$group]['wrappers'][$this->current_group_wrapper]); | |
@@ -507,16 +507,12 @@ class Upfront_Virtual_Region { | |
public function add_group($options){ | |
$properties = array(); | |
- if(isset($options['id']) && !empty($options['id'])) | |
+ if(!isset($options['id'])) | |
$properties['element_id'] = $options['id']; | |
- if(isset($options['breakpoint']) && !empty($options['breakpoint'])) | |
- $properties['breakpoint'] = $options['breakpoint']; | |
if(!isset($options['close_wrapper'])) | |
$options['close_wrapper'] = true; | |
if(!isset($options['new_line'])) | |
$options['new_line'] = false; | |
- if(!isset($options['wrapper_id'])) | |
- $options['wrapper_id'] = false; | |
$pos = array_merge(array( | |
'columns' => 24, | |
'margin_left' => 0, | |
@@ -528,7 +524,7 @@ class Upfront_Virtual_Region { | |
'margin-top' => $pos['margin_top'] | |
); | |
if(!$this->current_wrapper) | |
- $this->start_wrapper($options['wrapper_id'], $options['new_line']); | |
+ $this->start_wrapper(false, $options['new_line']); | |
$this->start_module_group($position, $properties); | |
$group_id = $this->current_group; | |
@@ -648,15 +644,15 @@ class Upfront_Layout_Maker { | |
else | |
$side_regions_after[] = $sidedata; | |
} | |
- usort($side_regions_before, array(Upfront_Theme, '_sort_region')); | |
- usort($side_regions_after, array(Upfront_Theme, '_sort_region')); | |
- | |
+ usort($side_regions_before, array("Upfront_Theme", '_sort_region')); | |
+ usort($side_regions_after, array("Upfront_Theme", '_sort_region')); | |
+ | |
foreach($side_regions_before as $side){ | |
$regions[] = $side; | |
} | |
- | |
+ | |
$regions[] = $region; | |
- | |
+ | |
foreach($side_regions_after as $side){ | |
$regions[] = $side; | |
} | |
@@ -680,8 +676,7 @@ abstract class Upfront_ChildTheme implements IUpfront_Server { | |
$this->version = wp_get_theme()->version; | |
$this->themeSettings = new Upfront_Theme_Settings(get_stylesheet_directory() . DIRECTORY_SEPARATOR . 'settings.php'); | |
self::$instance = $this; | |
- //add_filter('upfront_create_default_layout', array($this, 'load_page_regions'), 10, 3); // Soooo... this no longer works, yay | |
- add_filter('upfront_override_layout_data', array($this, 'load_page_regions'), 10, 2); // This goes in instead of the above ^ | |
+ add_filter('upfront_create_default_layout', array($this, 'load_page_regions'), 10, 3); | |
add_filter('upfront_get_layout_properties', array($this, 'getLayoutProperties')); | |
add_filter('upfront_get_theme_fonts', array($this, 'getThemeFonts'), 10, 2); | |
add_filter('upfront_get_theme_colors', array($this, 'getThemeColors'), 10, 2); | |
@@ -876,7 +871,7 @@ abstract class Upfront_ChildTheme implements IUpfront_Server { | |
public function getResponsiveSettings($settings) { | |
if (empty($settings) === false) return $settings; | |
- $properties = $this->themeSettings->get('responsive_settings'); | |
+ $properties = $this->themeSettings->get('responsive'); | |
if (!empty($properties)) { | |
$properties = json_decode($properties, true); | |
} | |
@@ -999,12 +994,12 @@ abstract class Upfront_ChildTheme implements IUpfront_Server { | |
*/ | |
} | |
- public function load_page_regions($data, $ids/*, $cascade*/){ | |
+ public function load_page_regions($data, $ids, $cascade){ | |
$layoutId = $this->_get_page_default_layout($ids); | |
if($layoutId){ | |
$theme = Upfront_Theme::get_instance(); | |
$ids['theme_defined'] = $layoutId; | |
- $data['regions'] = $theme->get_default_layout($ids, $layoutId); | |
+ $data['regions'] = $theme->get_default_layout($ids); | |
//$data['regions'] = $theme->get_default_layout(array(), $layoutId); | |
} | |
//return apply_filters('upfront_augment_theme_layout', $data); // So, this doesn't work anymore either. Yay. | |
diff --git a/scripts/redactor/redactor.js b/scripts/redactor/redactor.js | |
index f9d9781..76081af 100755 | |
--- a/scripts/redactor/redactor.js | |
+++ b/scripts/redactor/redactor.js | |
@@ -1,15 +1,14 @@ | |
/* | |
- Redactor v9.1.8 | |
- Updated: Nov 20, 2013 | |
+ Redactor v9.2.6 | |
+ Updated: Jul 19, 2014 | |
http://imperavi.com/redactor/ | |
- Copyright (c) 2009-2013, Imperavi LLC. | |
+ Copyright (c) 2009-2014, Imperavi LLC. | |
License: http://imperavi.com/redactor/license/ | |
Usage: $('#content').redactor(); | |
*/ | |
- | |
(function($) | |
{ | |
var uuid = 0; | |
@@ -31,6 +30,9 @@ | |
return this[0] === this[1]; | |
}; | |
+ var reUrlYoutube = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig; | |
+ var reUrlVimeo = /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/; | |
+ | |
// Plugin | |
$.fn.redactor = function(options) | |
{ | |
@@ -71,7 +73,7 @@ | |
} | |
$.Redactor = Redactor; | |
- $.Redactor.VERSION = '9.1.8'; | |
+ $.Redactor.VERSION = '9.2.6'; | |
$.Redactor.opts = { | |
// settings | |
@@ -86,12 +88,15 @@ | |
placeholder: false, | |
+ typewriter: false, | |
wym: false, | |
mobile: true, | |
cleanup: true, | |
tidyHtml: true, | |
pastePlainText: false, | |
removeEmptyTags: true, | |
+ cleanSpaces: true, | |
+ cleanFontTag: true, | |
templateVars: false, | |
xhtml: false, | |
@@ -101,29 +106,43 @@ | |
autoresize: true, | |
minHeight: false, | |
maxHeight: false, | |
- shortcuts: true, | |
+ shortcuts: { | |
+ 'ctrl+m, meta+m': "this.execCommand('removeFormat', false)", | |
+ 'ctrl+b, meta+b': "this.execCommand('bold', false)", | |
+ 'ctrl+i, meta+i': "this.execCommand('italic', false)", | |
+ 'ctrl+h, meta+h': "this.execCommand('superscript', false)", | |
+ 'ctrl+l, meta+l': "this.execCommand('subscript', false)", | |
+ 'ctrl+k, meta+k': "this.linkShow()", | |
+ 'ctrl+shift+7': "this.execCommand('insertorderedlist', false)", | |
+ 'ctrl+shift+8': "this.execCommand('insertunorderedlist', false)" | |
+ }, | |
+ shortcutsAdd: false, | |
autosave: false, // false or url | |
autosaveInterval: 60, // seconds | |
plugins: false, // array | |
- linkAnchor: true, | |
- linkEmail: true, | |
+ //linkAnchor: true, | |
+ //linkEmail: true, | |
linkProtocol: 'http://', | |
linkNofollow: false, | |
linkSize: 50, | |
+ predefinedLinks: false, // json url (ex. /some-url.json ) or false | |
imageFloatMargin: '10px', | |
- imageGetJson: false, // url (ex. /folder/images.json ) or false | |
+ imageGetJson: false, // json url (ex. /some-images.json ) or false | |
+ dragUpload: true, // false | |
+ imageTabLink: true, | |
imageUpload: false, // url | |
imageUploadParam: 'file', // input name | |
+ imageResizable: true, | |
+ | |
fileUpload: false, // url | |
fileUploadParam: 'file', // input name | |
clipboardUpload: true, // or false | |
clipboardUploadUrl: false, // url | |
- dragUpload: true, // false | |
dnbImageTypes: ['image/png', 'image/jpeg', 'image/gif'], // or false | |
@@ -139,7 +158,7 @@ | |
tabFocus: true, | |
air: false, | |
- airButtons: ['formatting', '|', 'bold', 'italic', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent'], | |
+ airButtons: ['formatting', 'bold', 'italic', 'deleted', 'unorderedlist', 'orderedlist', 'outdent', 'indent'], | |
toolbar: true, | |
toolbarFixed: false, | |
@@ -147,15 +166,16 @@ | |
toolbarFixedTopOffset: 0, // pixels | |
toolbarFixedBox: false, | |
toolbarExternal: false, // ID selector | |
+ toolbarOverflow: false, | |
buttonSource: true, | |
- buttonSeparator: '<li class="redactor_separator"></li>', | |
+ buttons: ['html', 'formatting', 'bold', 'italic', 'deleted', 'unorderedlist', 'orderedlist', | |
+ 'outdent', 'indent', 'image', 'video', 'file', 'table', 'link', 'alignment', '|', | |
+ 'horizontalrule'], // 'underline', 'alignleft', 'aligncenter', 'alignright', 'justify' | |
+ buttonsHideOnMobile: [], | |
- buttonsCustom: {}, | |
- buttonsAdd: [], | |
- buttons: ['html', '|', 'formatting', '|', 'bold', 'italic', 'deleted', '|', 'unorderedlist', 'orderedlist', 'outdent', 'indent', '|', 'image', 'video', 'file', 'table', 'link', '|', 'alignment', '|', 'horizontalrule'], // 'underline', 'alignleft', 'aligncenter', 'alignright', 'justify' | |
- | |
- activeButtons: ['deleted', 'italic', 'bold', 'underline', 'unorderedlist', 'orderedlist', 'alignleft', 'aligncenter', 'alignright', 'justify', 'table'], | |
+ activeButtons: ['deleted', 'italic', 'bold', 'underline', 'unorderedlist', 'orderedlist', | |
+ 'alignleft', 'aligncenter', 'alignright', 'justify', 'table'], | |
activeButtonsStates: { | |
b: 'bold', | |
strong: 'bold', | |
@@ -170,7 +190,6 @@ | |
td: 'table', | |
table: 'table' | |
}, | |
- activeButtonsAdd: false, // object, ex.: { tag: 'buttonName' } | |
formattingTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], | |
@@ -206,6 +225,8 @@ | |
blockLevelElements: ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'DD', 'DL', 'DT', 'DIV', 'LI', | |
'BLOCKQUOTE', 'OUTPUT', 'FIGCAPTION', 'PRE', 'ADDRESS', 'SECTION', | |
'HEADER', 'FOOTER', 'ASIDE', 'ARTICLE', 'TD'], | |
+ | |
+ | |
// lang | |
langs: { | |
en: { | |
@@ -255,6 +276,7 @@ | |
none: 'None', | |
left: 'Left', | |
right: 'Right', | |
+ center: 'Center', | |
image_web_link: 'Image Web Link', | |
text: 'Text', | |
mailto: 'Email', | |
@@ -301,7 +323,6 @@ | |
// Initialization | |
init: function(el, options) | |
{ | |
- | |
this.rtePaste = false; | |
this.$element = this.$source = $(el); | |
this.uuid = uuid++; | |
@@ -377,6 +398,12 @@ | |
// load lang | |
this.opts.curLang = this.opts.langs[this.opts.lang]; | |
+ // extend shortcuts | |
+ $.extend(this.opts.shortcuts, this.opts.shortcutsAdd); | |
+ | |
+ // init placeholder | |
+ this.placeholderInit(); | |
+ | |
// Build | |
this.buildStart(); | |
@@ -586,16 +613,6 @@ | |
} | |
} | |
}, | |
- fontcolor: | |
- { | |
- title: lang.fontcolor, | |
- func: 'show' | |
- }, | |
- backcolor: | |
- { | |
- title: lang.backcolor, | |
- func: 'show' | |
- }, | |
alignment: | |
{ | |
title: lang.alignment, | |
@@ -639,7 +656,7 @@ | |
title: lang.align_right, | |
func: 'alignmentRight' | |
}, | |
- justify: | |
+ alignjustify: | |
{ | |
title: lang.align_justify, | |
func: 'alignmentJustify' | |
@@ -694,6 +711,11 @@ | |
$elem.removeClass('redactor_editor').removeClass('redactor_editor_wym').removeAttr('contenteditable').html(html).show(); | |
} | |
+ if (this.opts.toolbarExternal) | |
+ { | |
+ $(this.opts.toolbarExternal).html(''); | |
+ } | |
+ | |
if (this.opts.air) | |
{ | |
$('#redactor_air_' + this.uuid).remove(); | |
@@ -738,26 +760,32 @@ | |
set: function(html, strip, placeholderRemove) | |
{ | |
html = html.toString(); | |
+ html = html.replace(/\$/g, '$'); | |
if (this.opts.fullpage) this.setCodeIframe(html); | |
else this.setEditor(html, strip); | |
if (html == '') placeholderRemove = false; | |
- if (placeholderRemove !== false) this.placeholderRemove(); | |
+ if (placeholderRemove !== false) this.placeholderRemoveFromEditor(); | |
}, | |
setEditor: function(html, strip) | |
{ | |
+ | |
if (strip !== false) | |
{ | |
html = this.cleanSavePreCode(html); | |
+ | |
html = this.cleanStripTags(html); | |
html = this.cleanConvertProtected(html); | |
html = this.cleanConvertInlineTags(html, true); | |
- if (this.opts.linebreaks === false) html = this.cleanConverters(html); | |
+ if (this.opts.linebreaks === false) html = this.cleanConverters(html); | |
else html = html.replace(/<p(.*?)>([\w\W]*?)<\/p>/gi, '$2<br>'); | |
} | |
+ // $ fix | |
+ html = html.replace(/&#36;/g, '$'); | |
+ | |
html = this.cleanEmpty(html); | |
this.$editor.html(html); | |
@@ -765,6 +793,7 @@ | |
// set no editable | |
this.setNonEditable(); | |
this.setSpansVerified(); | |
+ | |
this.sync(); | |
}, | |
setCodeIframe: function(html) | |
@@ -794,6 +823,12 @@ | |
}, | |
setFullpageOnInit: function(html) | |
{ | |
+ this.fullpageDoctype = html.match(/^<\!doctype[^>]*>/i); | |
+ if (this.fullpageDoctype && this.fullpageDoctype.length == 1) | |
+ { | |
+ html = html.replace(/^<\!doctype[^>]*>/i, ''); | |
+ } | |
+ | |
html = this.cleanSavePreCode(html, true); | |
html = this.cleanConverters(html); | |
html = this.cleanEmpty(html); | |
@@ -806,6 +841,14 @@ | |
this.setSpansVerified(); | |
this.sync(); | |
}, | |
+ setFullpageDoctype: function() | |
+ { | |
+ if (this.fullpageDoctype && this.fullpageDoctype.length == 1) | |
+ { | |
+ var source = this.fullpageDoctype[0] + '\n' + this.$source.val(); | |
+ this.$source.val(source); | |
+ } | |
+ }, | |
setSpansVerified: function() | |
{ | |
var spans = this.$editor.find('span'); | |
@@ -837,7 +880,7 @@ | |
}, | |
// SYNC | |
- sync: function() | |
+ sync: function(e) | |
{ | |
var html = ''; | |
@@ -847,9 +890,17 @@ | |
else html = this.$editor.html(); | |
html = this.syncClean(html); | |
- //html = this.cleanRemoveSpaces(html); | |
html = this.cleanRemoveEmptyTags(html); | |
+ // is there a need to synchronize | |
+ var source = this.cleanRemoveSpaces(this.$source.val(), false); | |
+ var editor = this.cleanRemoveSpaces(html, false); | |
+ | |
+ if (source == editor) | |
+ { | |
+ // do not sync | |
+ return false; | |
+ } | |
// fix second level up ul, ol | |
html = html.replace(/<\/li><(ul|ol)>([\w\W]*?)<\/(ul|ol)>/gi, '<$1>$2</$1></li>'); | |
@@ -870,13 +921,34 @@ | |
html = this.callback('syncBefore', false, html); | |
this.$source.val(html); | |
+ this.setFullpageDoctype(); | |
// onchange & after callback | |
this.callback('syncAfter', false, html); | |
if (this.start === false) | |
{ | |
- this.callback('change', false, html); | |
+ | |
+ if (typeof e != 'undefined') | |
+ { | |
+ switch(e.which) | |
+ { | |
+ case 37: // left | |
+ break; | |
+ case 38: // up | |
+ break; | |
+ case 39: // right | |
+ break; | |
+ case 40: // down | |
+ break; | |
+ | |
+ default: this.callback('change', false, html); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ this.callback('change', false, html); | |
+ } | |
} | |
}, | |
@@ -884,6 +956,7 @@ | |
{ | |
if (!this.opts.fullpage) html = this.cleanStripTags(html); | |
+ // trim | |
html = $.trim(html); | |
// removeplaceholder | |
@@ -893,6 +966,12 @@ | |
html = html.replace(/​/gi, ''); | |
html = html.replace(/​/gi, ''); | |
html = html.replace(/<\/a> /gi, '<\/a> '); | |
+ html = html.replace(/\u200B/g, ''); | |
+ | |
+ if (html == '<p></p>' || html == '<p> </p>' || html == '<p> </p>') | |
+ { | |
+ html = ''; | |
+ } | |
// link nofollow | |
if (this.opts.linkNofollow) | |
@@ -912,25 +991,41 @@ | |
html = html.replace(/<br\s?\/?>\n?<\/(P|H[1-6]|LI|ADDRESS|SECTION|HEADER|FOOTER|ASIDE|ARTICLE)>/gi, '</$1>'); | |
// remove image resize | |
- html = html.replace(/<span(.*?)id="redactor-image-box"(.*?)>([\w\W]*?)<img(.*?)><\/span>/i, '$3<img$4>'); | |
- html = html.replace(/<span(.*?)id="redactor-image-resizer"(.*?)>(.*?)<\/span>/i, ''); | |
- html = html.replace(/<span(.*?)id="redactor-image-editter"(.*?)>(.*?)<\/span>/i, ''); | |
+ html = html.replace(/<span(.*?)id="redactor-image-box"(.*?)>([\w\W]*?)<img(.*?)><\/span>/gi, '$3<img$4>'); | |
+ html = html.replace(/<span(.*?)id="redactor-image-resizer"(.*?)>(.*?)<\/span>/gi, ''); | |
+ html = html.replace(/<span(.*?)id="redactor-image-editter"(.*?)>(.*?)<\/span>/gi, ''); | |
+ | |
+ // remove empty lists | |
+ html = html.replace(/<(ul|ol)>\s*\t*\n*<\/(ul|ol)>/gi, ''); | |
// remove font | |
- html = html.replace(/<font(.*?)>([\w\W]*?)<\/font>/gi, '$2'); | |
+ if (this.opts.cleanFontTag) | |
+ { | |
+ html = html.replace(/<font(.*?)>([\w\W]*?)<\/font>/gi, '$2'); | |
+ } | |
// remove spans | |
html = html.replace(/<span(.*?)>([\w\W]*?)<\/span>/gi, '$2'); | |
+ html = html.replace(/<inline>([\w\W]*?)<\/inline>/gi, '$1'); | |
html = html.replace(/<inline>/gi, '<span>'); | |
html = html.replace(/<inline /gi, '<span '); | |
html = html.replace(/<\/inline>/gi, '</span>'); | |
- html = html.replace(/<span(.*?)class="redactor_placeholder"(.*?)>([\w\W]*?)<\/span>/gi, ''); | |
- // fixes | |
- html = html.replace(/&/gi, '&'); | |
- html = html.replace(/™/gi, '™'); | |
- html = html.replace(/©/gi, '©'); | |
+ if (this.opts.removeEmptyTags) | |
+ { | |
+ html = html.replace(/<span>([\w\W]*?)<\/span>/gi, '$1'); | |
+ } | |
+ | |
+ html = html.replace(/<span(.*?)class="redactor_placeholder"(.*?)>([\w\W]*?)<\/span>/gi, ''); | |
+ html = html.replace(/<img(.*?)contenteditable="false"(.*?)>/gi, '<img$1$2>'); | |
+ // special characters | |
+ html = html.replace(/&/gi, '&'); | |
+ html = html.replace(/\u2122/gi, '™'); | |
+ html = html.replace(/\u00a9/gi, '©'); | |
+ html = html.replace(/\u2026/gi, '…'); | |
+ html = html.replace(/\u2014/gi, '—'); | |
+ html = html.replace(/\u2010/gi, '‐'); | |
html = this.cleanReConvertProtected(html); | |
@@ -938,6 +1033,7 @@ | |
}, | |
+ | |
// BUILD | |
buildStart: function() | |
{ | |
@@ -1039,14 +1135,29 @@ | |
// options | |
if (this.opts.tabindex) $source.attr('tabindex', this.opts.tabindex); | |
+ | |
if (this.opts.minHeight) $source.css('min-height', this.opts.minHeight + 'px'); | |
+ // FF fix bug with line-height rendering | |
+ else if (this.browser('mozilla') && this.opts.linebreaks) | |
+ { | |
+ this.$editor.css('min-height', '45px'); | |
+ } | |
+ // FF fix bug with line-height rendering | |
+ if (this.browser('mozilla') && this.opts.linebreaks) | |
+ { | |
+ this.$editor.css('padding-bottom', '10px'); | |
+ } | |
+ | |
+ | |
if (this.opts.maxHeight) | |
{ | |
this.opts.autoresize = false; | |
- $source.css('max-height', this.opts.maxHeight + 'px'); | |
+ this.sourceHeight = this.opts.maxHeight; | |
} | |
if (this.opts.wym) this.$editor.addClass('redactor_editor_wym'); | |
+ if (this.opts.typewriter) this.$editor.addClass('redactor-editor-typewriter'); | |
if (!this.opts.autoresize) $source.css('height', this.sourceHeight); | |
+ | |
}, | |
buildAfter: function() | |
{ | |
@@ -1104,11 +1215,18 @@ | |
{ | |
this.dblEnter = 0; | |
- if (this.opts.dragUpload && this.opts.imageUpload !== false) | |
+ if (this.opts.dragUpload && (this.opts.imageUpload !== false || this.opts.s3 !== false)) | |
{ | |
this.$editor.on('drop.redactor', $.proxy(this.buildEventDrop, this)); | |
} | |
+ this.$editor.on('click.redactor', $.proxy(function() | |
+ { | |
+ this.selectall = false; | |
+ | |
+ }, this)); | |
+ | |
+ this.$editor.on('input.redactor', $.proxy(this.sync, this)); | |
this.$editor.on('paste.redactor', $.proxy(this.buildEventPaste, this)); | |
this.$editor.on('keydown.redactor', $.proxy(this.buildEventKeydown, this)); | |
this.$editor.on('keyup.redactor', $.proxy(this.buildEventKeyup, this)); | |
@@ -1161,18 +1279,18 @@ | |
this.bufferSet(); | |
- var progress = $('<div id="redactor-progress-drag" class="redactor-progress redactor-progress-striped"><div id="redactor-progress-bar" class="redactor-progress-bar" style="width: 100%;"></div></div>'); | |
- $(document.body).append(progress); | |
+ this.showProgressBar(); | |
if (this.opts.s3 === false) | |
{ | |
- this.dragUploadAjax(this.opts.imageUpload, file, true, progress, e, this.opts.imageUploadParam); | |
+ this.dragUploadAjax(this.opts.imageUpload, file, true, e, this.opts.imageUploadParam); | |
} | |
else | |
{ | |
this.s3uploadFile(file); | |
} | |
+ | |
}, | |
buildEventPaste: function(e) | |
{ | |
@@ -1232,6 +1350,7 @@ | |
var event = e.originalEvent || e; | |
this.clipboardFilePaste = false; | |
+ | |
if (typeof(event.clipboardData) === 'undefined') return false; | |
if (event.clipboardData.items) | |
{ | |
@@ -1265,6 +1384,38 @@ | |
this.callback('keydown', e); | |
+ /* | |
+ firefox cmd+left/Cmd+right browser back/forward fix - | |
+ http://joshrhoderick.wordpress.com/2010/05/05/how-firefoxs-command-key-bug-kills-usability-on-the-mac/ | |
+ */ | |
+ if (this.browser('mozilla') && "modify" in window.getSelection()) | |
+ { | |
+ if ((ctrl) && (e.keyCode===37 || e.keyCode===39)) | |
+ { | |
+ var selection = this.getSelection(); | |
+ var lineOrWord = (e.metaKey ? "line" : "word"); | |
+ if (e.keyCode===37) | |
+ { | |
+ selection.modify("extend","left",lineOrWord); | |
+ if (!e.shiftKey) | |
+ { | |
+ selection.collapseToStart(); | |
+ } | |
+ } | |
+ if (e.keyCode===39) | |
+ { | |
+ selection.modify("extend","right",lineOrWord); | |
+ if (!e.shiftKey) | |
+ { | |
+ selection.collapseToEnd(); | |
+ } | |
+ } | |
+ | |
+ e.preventDefault(); | |
+ } | |
+ } | |
+ | |
+ | |
this.imageResizeHide(false); | |
// pre & down | |
@@ -1291,7 +1442,7 @@ | |
} | |
// shortcuts setup | |
- if (ctrl && !e.shiftKey) this.shortcuts(e, key); | |
+ this.shortcuts(e, key); | |
// buffer setup | |
if (ctrl && key === 90 && !e.shiftKey && !e.altKey) // z key | |
@@ -1310,13 +1461,37 @@ | |
return; | |
} | |
+ // space | |
+ if (key == 32) | |
+ { | |
+ this.bufferSet(); | |
+ } | |
+ | |
// select all | |
- if (ctrl && key === 65) this.selectall = true; | |
- else if (key != this.keyCode.LEFT_WIN && !ctrl) this.selectall = false; | |
+ if (ctrl && key === 65) | |
+ { | |
+ this.bufferSet(); | |
+ this.selectall = true; | |
+ } | |
+ else if (key != this.keyCode.LEFT_WIN && !ctrl) | |
+ { | |
+ this.selectall = false; | |
+ } | |
// enter | |
- if (key == this.keyCode.ENTER && !e.shiftKey && !e.ctrlKey && !e.metaKey ) | |
+ if (key == this.keyCode.ENTER && !e.shiftKey && !e.ctrlKey && !e.metaKey) | |
{ | |
+ // remove selected content on enter | |
+ var range = this.getRange(); | |
+ if (range && range.collapsed === false) | |
+ { | |
+ sel = this.getSelection(); | |
+ if (sel.rangeCount) | |
+ { | |
+ range.deleteContents(); | |
+ } | |
+ } | |
+ | |
// In ie, opera in the tables are created paragraphs, fix it. | |
if (this.browser('msie') && (parent.nodeType == 1 && (parent.tagName == 'TD' || parent.tagName == 'TH'))) | |
{ | |
@@ -1368,14 +1543,44 @@ | |
else this.dblEnter++; | |
} | |
- | |
- | |
// pre | |
- if (pre === true) return this.buildEventKeydownPre(e, current); | |
+ if (pre === true) | |
+ { | |
+ return this.buildEventKeydownPre(e, current); | |
+ } | |
else | |
{ | |
if (!this.opts.linebreaks) | |
{ | |
+ // lists exit | |
+ if (block && block.tagName == 'LI') | |
+ { | |
+ var listCurrent = this.getBlock(); | |
+ if (listCurrent !== false || listCurrent.tagName === 'LI') | |
+ { | |
+ var listText = $.trim($(block).text()); | |
+ var listCurrentText = $.trim($(listCurrent).text()); | |
+ if (listText == '' | |
+ && listCurrentText == '' | |
+ && $(listCurrent).next('li').size() == 0 | |
+ && $(listCurrent).parents('li').size() == 0) | |
+ { | |
+ this.bufferSet(); | |
+ | |
+ var $list = $(listCurrent).closest('ol, ul'); | |
+ $(listCurrent).remove(); | |
+ var node = $('<p>' + this.opts.invisibleSpace + '</p>'); | |
+ $list.after(node); | |
+ this.selectionStart(node); | |
+ | |
+ this.sync(); | |
+ this.callback('enter', e); | |
+ return false; | |
+ } | |
+ } | |
+ | |
+ } | |
+ | |
// replace div to p | |
if (block && this.opts.rBlockTest.test(block.tagName)) | |
{ | |
@@ -1398,7 +1603,6 @@ | |
{ | |
// hit enter | |
this.bufferSet(); | |
- | |
var node = $('<p>' + this.opts.invisibleSpace + '</p>'); | |
this.insertNode(node[0]); | |
this.selectionStart(node); | |
@@ -1450,11 +1654,14 @@ | |
this.insertLineBreak(); | |
} | |
- // tab | |
- if (key === this.keyCode.TAB && this.opts.shortcuts) return this.buildEventKeydownTab(e, pre); | |
+ // tab (cmd + [) | |
+ if ((key === this.keyCode.TAB || e.metaKey && key === 219) && this.opts.shortcuts) | |
+ { | |
+ return this.buildEventKeydownTab(e, pre, key); | |
+ } | |
// delete zero-width space before the removing | |
- if (key === this.keyCode.BACKSPACE) this.buildEventKeydownBackspace(current); | |
+ if (key === this.keyCode.BACKSPACE) this.buildEventKeydownBackspace(e, current, parent); | |
}, | |
buildEventKeydownPre: function(e, current) | |
@@ -1472,7 +1679,7 @@ | |
this.callback('enter', e); | |
return false; | |
}, | |
- buildEventKeydownTab: function(e, pre) | |
+ buildEventKeydownTab: function(e, pre, key) | |
{ | |
if (!this.opts.tabFocus) return true; | |
if (this.isEmpty(this.get()) && this.opts.tabSpaces === false) return true; | |
@@ -1502,8 +1709,23 @@ | |
return false; | |
}, | |
- buildEventKeydownBackspace: function(current) | |
+ buildEventKeydownBackspace: function(e, current, parent) | |
{ | |
+ // remove empty list in table | |
+ if (parent && current && parent.parentNode.tagName == 'TD' | |
+ && parent.tagName == 'UL' && current.tagName == 'LI' && $(parent).children('li').size() == 1) | |
+ { | |
+ var text = $(current).text().replace(/[\u200B-\u200D\uFEFF]/g, ''); | |
+ if (text == '') | |
+ { | |
+ var node = parent.parentNode; | |
+ $(parent).remove(); | |
+ this.selectionStart(node); | |
+ this.sync(); | |
+ return false; | |
+ } | |
+ } | |
+ | |
if (typeof current.tagName !== 'undefined' && /^(H[1-6])$/i.test(current.tagName)) | |
{ | |
var node; | |
@@ -1512,14 +1734,15 @@ | |
$(current).replaceWith(node); | |
this.selectionStart(node); | |
+ this.sync(); | |
} | |
if (typeof current.nodeValue !== 'undefined' && current.nodeValue !== null) | |
{ | |
- //var value = $.trim(current.nodeValue.replace(/[^\u0000-\u1C7F]/g, '')); | |
- if (current.remove && current.nodeType === 3 && current.nodeValue.match(/[^/\u200B]/g) == null) | |
+ if (current.remove && current.nodeType === 3 && current.nodeValue.match(/[^\u200B]/g) == null) | |
{ | |
- current.remove(); | |
+ $(current).prev().remove(); | |
+ this.sync(); | |
} | |
} | |
}, | |
@@ -1549,6 +1772,7 @@ | |
{ | |
next.remove(); | |
} | |
+ | |
this.selectionEnd(node); | |
} | |
@@ -1565,7 +1789,7 @@ | |
} | |
this.callback('keyup', e); | |
- this.sync(); | |
+ this.sync(e); | |
}, | |
buildEventKeyupConverters: function() | |
{ | |
@@ -1680,7 +1904,10 @@ | |
// iframe css | |
this.iframeAddCss(); | |
- if (this.opts.fullpage) this.setFullpageOnInit(this.$editor.html()); | |
+ if (this.opts.fullpage) | |
+ { | |
+ this.setFullpageOnInit(this.$source.val()); | |
+ } | |
else this.set(this.content, true, false); | |
this.buildOptions(); | |
@@ -1688,30 +1915,85 @@ | |
}, | |
// PLACEHOLDER | |
+ placeholderInit: function() | |
+ { | |
+ if (this.opts.placeholder !== false) | |
+ { | |
+ this.placeholderText = this.opts.placeholder; | |
+ this.opts.placeholder = true; | |
+ } | |
+ else | |
+ { | |
+ if (typeof this.$element.attr('placeholder') == 'undefined' || this.$element.attr('placeholder') == '') | |
+ { | |
+ this.opts.placeholder = false; | |
+ } | |
+ else | |
+ { | |
+ this.placeholderText = this.$element.attr('placeholder'); | |
+ this.opts.placeholder = true; | |
+ } | |
+ } | |
+ }, | |
placeholderStart: function(html) | |
{ | |
- if (this.isEmpty(html)) | |
+ if (this.opts.placeholder === false) | |
{ | |
- if (this.$element.attr('placeholder')) this.opts.placeholder = this.$element.attr('placeholder'); | |
- if (this.opts.placeholder === '') this.opts.placeholder = false; | |
+ return false; | |
+ } | |
- if (this.opts.placeholder !== false) | |
- { | |
- this.opts.focus = false; | |
- this.$editor.one('focus.redactor_placeholder', $.proxy(this.placeholderFocus, this)); | |
+ if (this.isEmpty(html)) | |
+ { | |
+ this.opts.focus = false; | |
+ this.placeholderOnFocus(); | |
+ this.placeholderOnBlur(); | |
- return $('<span class="redactor_placeholder" data-redactor="verified">').attr('contenteditable', false).text(this.opts.placeholder); | |
- } | |
+ return this.placeholderGet(); | |
+ } | |
+ else | |
+ { | |
+ this.placeholderOnBlur(); | |
} | |
return false; | |
}, | |
+ placeholderOnFocus: function() | |
+ { | |
+ this.$editor.on('focus.redactor_placeholder', $.proxy(this.placeholderFocus, this)); | |
+ }, | |
+ placeholderOnBlur: function() | |
+ { | |
+ this.$editor.on('blur.redactor_placeholder', $.proxy(this.placeholderBlur, this)); | |
+ }, | |
+ placeholderGet: function() | |
+ { | |
+ var ph = $('<span class="redactor_placeholder">').data('redactor', 'verified') | |
+ .attr('contenteditable', false).text(this.placeholderText); | |
+ | |
+ if (this.opts.linebreaks === false) | |
+ { | |
+ return $('<p>').append(ph); | |
+ } | |
+ else return ph; | |
+ }, | |
+ placeholderBlur: function() | |
+ { | |
+ var html = this.get(); | |
+ if (this.isEmpty(html)) | |
+ { | |
+ this.placeholderOnFocus(); | |
+ this.$editor.html(this.placeholderGet()); | |
+ } | |
+ }, | |
placeholderFocus: function() | |
{ | |
this.$editor.find('span.redactor_placeholder').remove(); | |
var html = ''; | |
- if (this.opts.linebreaks === false) html = this.opts.emptyHtml; | |
+ if (this.opts.linebreaks === false) | |
+ { | |
+ html = this.opts.emptyHtml; | |
+ } | |
this.$editor.off('focus.redactor_placeholder'); | |
this.$editor.html(html); | |
@@ -1728,9 +2010,8 @@ | |
this.sync(); | |
}, | |
- placeholderRemove: function() | |
+ placeholderRemoveFromEditor: function() | |
{ | |
- this.opts.placeholder = false; | |
this.$editor.find('span.redactor_placeholder').remove(); | |
this.$editor.off('focus.redactor_placeholder'); | |
}, | |
@@ -1743,109 +2024,221 @@ | |
shortcuts: function(e, key) | |
{ | |
- if (!this.opts.shortcuts) return; | |
- | |
- if (!e.altKey) | |
+ // disable browser's hot keys for bold and italic | |
+ if (!this.opts.shortcuts) | |
{ | |
- if (key === 77) this.shortcutsLoad(e, 'removeFormat'); // Ctrl + m | |
- else if (key === 66) this.shortcutsLoad(e, 'bold'); // Ctrl + b | |
- else if (key === 73) this.shortcutsLoad(e, 'italic'); // Ctrl + i | |
- | |
- else if (key === 74) this.shortcutsLoad(e, 'insertunorderedlist'); // Ctrl + j | |
- else if (key === 75) this.shortcutsLoad(e, 'insertorderedlist'); // Ctrl + k | |
+ if ((e.ctrlKey || e.metaKey) && (key === 66 || key === 73)) | |
+ { | |
+ e.preventDefault(); | |
+ } | |
- else if (key === 72) this.shortcutsLoad(e, 'superscript'); // Ctrl + h | |
- else if (key === 76) this.shortcutsLoad(e, 'subscript'); // Ctrl + l | |
+ return false; | |
} | |
- else | |
+ | |
+ $.each(this.opts.shortcuts, $.proxy(function(str, command) | |
{ | |
- if (key === 48) this.shortcutsLoadFormat(e, 'p'); // ctrl + alt + 0 | |
- else if (key === 49) this.shortcutsLoadFormat(e, 'h1'); // ctrl + alt + 1 | |
- else if (key === 50) this.shortcutsLoadFormat(e, 'h2'); // ctrl + alt + 2 | |
- else if (key === 51) this.shortcutsLoadFormat(e, 'h3'); // ctrl + alt + 3 | |
- else if (key === 52) this.shortcutsLoadFormat(e, 'h4'); // ctrl + alt + 4 | |
- else if (key === 53) this.shortcutsLoadFormat(e, 'h5'); // ctrl + alt + 5 | |
- else if (key === 54) this.shortcutsLoadFormat(e, 'h6'); // ctrl + alt + 6 | |
+ var keys = str.split(','); | |
+ for (var i in keys) | |
+ { | |
+ if (typeof keys[i] === 'string') | |
+ { | |
+ this.shortcutsHandler(e, $.trim(keys[i]), $.proxy(function() | |
+ { | |
+ eval(command); | |
+ }, this)); | |
+ } | |
- } | |
+ } | |
+ | |
+ }, this)); | |
- }, | |
- shortcutsLoad: function(e, cmd) | |
- { | |
- e.preventDefault(); | |
- this.execCommand(cmd, false); | |
- }, | |
- shortcutsLoadFormat: function(e, cmd) | |
- { | |
- e.preventDefault(); | |
- this.formatBlocks(cmd); | |
- }, | |
- // FOCUS | |
- focus: function() | |
- { | |
- if (!this.browser('opera')) this.window.setTimeout($.proxy(this.focusSet, this, true), 1); | |
- else this.$editor.focus(); | |
- }, | |
- focusEnd: function() | |
- { | |
- this.focusSet(); | |
}, | |
- focusSet: function(collapse) | |
+ shortcutsHandler: function(e, keys, origHandler) | |
{ | |
- this.$editor.focus(); | |
+ // based on https://github.com/jeresig/jquery.hotkeys | |
+ var hotkeysSpecialKeys = | |
+ { | |
+ 8: "backspace", 9: "tab", 10: "return", 13: "return", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", | |
+ 20: "capslock", 27: "esc", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 36: "home", | |
+ 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "del", 59: ";", 61: "=", | |
+ 96: "0", 97: "1", 98: "2", 99: "3", 100: "4", 101: "5", 102: "6", 103: "7", | |
+ 104: "8", 105: "9", 106: "*", 107: "+", 109: "-", 110: ".", 111 : "/", | |
+ 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", | |
+ 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scroll", 173: "-", 186: ";", 187: "=", | |
+ 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", 221: "]", 222: "'" | |
+ }; | |
- var range = this.getRange(); | |
- range.selectNodeContents(this.$editor[0]); | |
- // collapse - controls the position of focus: the beginning (true), at the end (false). | |
- range.collapse(collapse || false); | |
+ var hotkeysShiftNums = | |
+ { | |
+ "`": "~", "1": "!", "2": "@", "3": "#", "4": "$", "5": "%", "6": "^", "7": "&", | |
+ "8": "*", "9": "(", "0": ")", "-": "_", "=": "+", ";": ": ", "'": "\"", ",": "<", | |
+ ".": ">", "/": "?", "\\": "|" | |
+ }; | |
- var sel = this.getSelection(); | |
- sel.removeAllRanges(); | |
- sel.addRange(range); | |
- }, | |
+ keys = keys.toLowerCase().split(" "); | |
+ var special = hotkeysSpecialKeys[e.keyCode], | |
+ character = String.fromCharCode( e.which ).toLowerCase(), | |
+ modif = "", possible = {}; | |
- // TOGGLE | |
- toggle: function(direct) | |
- { | |
- if (this.opts.visual) this.toggleCode(direct); | |
- else this.toggleVisual(); | |
- }, | |
- toggleVisual: function() | |
- { | |
- var html = this.$source.hide().val(); | |
+ $.each([ "alt", "ctrl", "meta", "shift"], function(index, specialKey) | |
+ { | |
+ if (e[specialKey + 'Key'] && special !== specialKey) | |
+ { | |
+ modif += specialKey + '+'; | |
+ } | |
+ }); | |
- if (typeof this.modified !== 'undefined') | |
+ | |
+ if (special) | |
{ | |
- this.modified = this.cleanRemoveSpaces(this.modified, false) !== this.cleanRemoveSpaces(html, false); | |
+ possible[modif + special] = true; | |
} | |
- if (this.modified) | |
+ if (character) | |
{ | |
- // don't remove the iframe even if cleared all. | |
- if (this.opts.fullpage && html === '') this.setFullpageOnInit(html); | |
- else | |
+ possible[modif + character] = true; | |
+ possible[modif + hotkeysShiftNums[character]] = true; | |
+ | |
+ // "$" can be triggered as "Shift+4" or "Shift+$" or just "$" | |
+ if (modif === "shift+") | |
{ | |
- this.set(html); | |
- if (this.opts.fullpage) this.buildBindKeyboard(); | |
+ possible[hotkeysShiftNums[character]] = true; | |
} | |
} | |
- if (this.opts.iframe) this.$frame.show(); | |
- else this.$editor.show(); | |
- | |
- if (this.opts.fullpage) this.$editor.attr('contenteditable', true ); | |
- | |
- this.$source.off('keydown.redactor-textarea-indenting'); | |
- | |
- this.$editor.focus(); | |
- this.selectionRestore(); | |
+ for (var i = 0, l = keys.length; i < l; i++) | |
+ { | |
+ if (possible[keys[i]]) | |
+ { | |
+ e.preventDefault(); | |
+ return origHandler.apply(this, arguments); | |
+ } | |
+ } | |
+ }, | |
- this.observeStart(); | |
- this.buttonActiveVisual(); | |
- this.buttonInactive('html'); | |
+ // FOCUS | |
+ focus: function() | |
+ { | |
+ if (!this.browser('opera')) | |
+ { | |
+ this.window.setTimeout($.proxy(this.focusSet, this, true), 1); | |
+ } | |
+ else | |
+ { | |
+ this.$editor.focus(); | |
+ } | |
+ }, | |
+ focusWithSaveScroll: function() | |
+ { | |
+ if (this.browser('msie')) | |
+ { | |
+ var top = this.document.documentElement.scrollTop; | |
+ } | |
+ | |
+ this.$editor.focus(); | |
+ | |
+ if (this.browser('msie')) | |
+ { | |
+ this.document.documentElement.scrollTop = top; | |
+ } | |
+ }, | |
+ focusEnd: function() | |
+ { | |
+ if (!this.browser('mozilla')) | |
+ { | |
+ this.focusSet(); | |
+ } | |
+ else | |
+ { | |
+ if (this.opts.linebreaks === false) | |
+ { | |
+ var last = this.$editor.children().last(); | |
+ | |
+ this.$editor.focus(); | |
+ this.selectionEnd(last); | |
+ } | |
+ else | |
+ { | |
+ this.focusSet(); | |
+ } | |
+ } | |
+ }, | |
+ focusSet: function(collapse, element) | |
+ { | |
+ this.$editor.focus(); | |
+ | |
+ if (typeof element == 'undefined') | |
+ { | |
+ element = this.$editor[0]; | |
+ } | |
+ | |
+ var range = this.getRange(); | |
+ range.selectNodeContents(element); | |
+ | |
+ // collapse - controls the position of focus: the beginning (true), at the end (false). | |
+ range.collapse(collapse || false); | |
+ | |
+ var sel = this.getSelection(); | |
+ sel.removeAllRanges(); | |
+ sel.addRange(range); | |
+ }, | |
+ | |
+ // TOGGLE | |
+ toggle: function(direct) | |
+ { | |
+ if (this.opts.visual) this.toggleCode(direct); | |
+ else this.toggleVisual(); | |
+ }, | |
+ toggleVisual: function() | |
+ { | |
+ var html = this.$source.hide().val(); | |
+ if (typeof this.modified !== 'undefined') | |
+ { | |
+ var modified = this.modified.replace(/\n/g, ''); | |
+ | |
+ var thtml = html.replace(/\n/g, ''); | |
+ thtml = this.cleanRemoveSpaces(thtml, false); | |
+ | |
+ this.modified = this.cleanRemoveSpaces(modified, false) !== thtml; | |
+ } | |
+ | |
+ if (this.modified) | |
+ { | |
+ // don't remove the iframe even if cleared all. | |
+ if (this.opts.fullpage && html === '') | |
+ { | |
+ this.setFullpageOnInit(html); | |
+ } | |
+ else | |
+ { | |
+ this.set(html); | |
+ if (this.opts.fullpage) | |
+ { | |
+ this.buildBindKeyboard(); | |
+ } | |
+ } | |
+ | |
+ this.callback('change', false, html); | |
+ } | |
+ | |
+ if (this.opts.iframe) this.$frame.show(); | |
+ else this.$editor.show(); | |
+ | |
+ if (this.opts.fullpage) this.$editor.attr('contenteditable', true ); | |
+ | |
+ this.$source.off('keydown.redactor-textarea-indenting'); | |
+ | |
+ this.$editor.focus(); | |
+ this.selectionRestore(); | |
+ | |
+ this.observeStart(); | |
+ this.buttonActiveVisual(); | |
+ this.buttonInactive('html'); | |
this.opts.visual = true; | |
+ | |
+ | |
}, | |
toggleCode: function(direct) | |
{ | |
@@ -1904,13 +2297,25 @@ | |
var html = this.get(); | |
if (savedHtml !== html) | |
{ | |
+ var name = this.$source.attr('name'); | |
$.ajax({ | |
url: this.opts.autosave, | |
type: 'post', | |
- data: this.$source.attr('name') + '=' + escape(encodeURIComponent(html)), | |
+ data: 'name=' + name + '&' + name + '=' + escape(encodeURIComponent(html)), | |
success: $.proxy(function(data) | |
{ | |
- this.callback('autosave', false, data); | |
+ var json = $.parseJSON(data); | |
+ if (typeof json.error == 'undefined') | |
+ { | |
+ // success | |
+ this.callback('autosave', false, json); | |
+ } | |
+ else | |
+ { | |
+ // error | |
+ this.callback('autosaveError', false, json); | |
+ } | |
+ | |
savedHtml = html; | |
}, this) | |
@@ -1922,6 +2327,17 @@ | |
// TOOLBAR | |
toolbarBuild: function() | |
{ | |
+ // hide on mobile | |
+ if (this.isMobile() && this.opts.buttonsHideOnMobile.length > 0) | |
+ { | |
+ $.each(this.opts.buttonsHideOnMobile, $.proxy(function(i, s) | |
+ { | |
+ var index = this.opts.buttons.indexOf(s); | |
+ this.opts.buttons.splice(index, 1); | |
+ | |
+ }, this)); | |
+ } | |
+ | |
// extend buttons | |
if (this.opts.air) | |
{ | |
@@ -1931,19 +2347,11 @@ | |
{ | |
if (!this.opts.buttonSource) | |
{ | |
- var index = this.opts.buttons.indexOf('html'), next = this.opts.buttons[index + 1]; | |
+ var index = this.opts.buttons.indexOf('html'); | |
this.opts.buttons.splice(index, 1); | |
- if (next === '|') this.opts.buttons.splice(index, 1); | |
} | |
} | |
- $.extend(this.opts.toolbar, this.opts.buttonsCustom); | |
- $.each(this.opts.buttonsAdd, $.proxy(function(i, s) | |
- { | |
- this.opts.buttons.push(s); | |
- | |
- }, this)); | |
- | |
// formatting tags | |
if (this.opts.toolbar) | |
{ | |
@@ -1963,6 +2371,16 @@ | |
// toolbar build | |
this.$toolbar = $('<ul>').addClass('redactor_toolbar').attr('id', 'redactor_toolbar_' + this.uuid); | |
+ if (this.opts.typewriter) | |
+ { | |
+ this.$toolbar.addClass('redactor-toolbar-typewriter'); | |
+ } | |
+ | |
+ if (this.opts.toolbarOverflow && this.isMobile()) | |
+ { | |
+ this.$toolbar.addClass('redactor-toolbar-overflow'); | |
+ } | |
+ | |
if (this.opts.air) | |
{ | |
// air box | |
@@ -1972,15 +2390,17 @@ | |
} | |
else | |
{ | |
- if (this.opts.toolbarExternal) $(this.opts.toolbarExternal).html(this.$toolbar); | |
+ if (this.opts.toolbarExternal) | |
+ { | |
+ this.$toolbar.addClass('redactor-toolbar-external'); | |
+ $(this.opts.toolbarExternal).html(this.$toolbar); | |
+ } | |
else this.$box.prepend(this.$toolbar); | |
} | |
$.each(this.opts.buttons, $.proxy(function(i, btnName) | |
{ | |
- // separator | |
- if ( btnName === '|' ) this.$toolbar.append($(this.opts.buttonSeparator)); | |
- else if(this.opts.toolbar[btnName]) | |
+ if (this.opts.toolbar[btnName]) | |
{ | |
var btnObject = this.opts.toolbar[btnName]; | |
if (this.opts.fileUpload === false && btnName === 'file') return true; | |
@@ -2001,17 +2421,27 @@ | |
// buttons response | |
if (this.opts.activeButtons) | |
{ | |
- var buttonActiveObserver = $.proxy(this.buttonActiveObserver, this); | |
- this.$editor.on('mouseup.redactor keyup.redactor', buttonActiveObserver); | |
+ this.$editor.on('mouseup.redactor keyup.redactor', $.proxy(this.buttonActiveObserver, this)); | |
} | |
}, | |
toolbarObserveScroll: function() | |
{ | |
var scrollTop = $(this.opts.toolbarFixedTarget).scrollTop(); | |
- var boxTop = this.$box.offset().top; | |
+ | |
+ var boxTop = 0; | |
var left = 0; | |
+ var end = 0; | |
+ | |
+ if (this.opts.toolbarFixedTarget === document) | |
+ { | |
+ boxTop = this.$box.offset().top; | |
+ } | |
+ else | |
+ { | |
+ boxTop = 1; | |
+ } | |
- var end = boxTop + this.$box.height() + 40; | |
+ end = boxTop + this.$box.height() + 40; | |
if (scrollTop > boxTop) | |
{ | |
@@ -2024,13 +2454,27 @@ | |
} | |
this.toolbarFixed = true; | |
- this.$toolbar.css({ | |
- position: 'fixed', | |
- width: width, | |
- zIndex: 1005, | |
- top: this.opts.toolbarFixedTopOffset + 'px', | |
- left: left | |
- }); | |
+ | |
+ if (this.opts.toolbarFixedTarget === document) | |
+ { | |
+ this.$toolbar.css({ | |
+ position: 'fixed', | |
+ width: width, | |
+ zIndex: 10005, | |
+ top: this.opts.toolbarFixedTopOffset + 'px', | |
+ left: left | |
+ }); | |
+ } | |
+ else | |
+ { | |
+ this.$toolbar.css({ | |
+ position: 'absolute', | |
+ width: width, | |
+ zIndex: 10005, | |
+ top: (this.opts.toolbarFixedTopOffset + scrollTop) + 'px', | |
+ left: 0 | |
+ }); | |
+ } | |
if (scrollTop < end) this.$toolbar.css('visibility', 'visible'); | |
else this.$toolbar.css('visibility', 'hidden'); | |
@@ -2072,6 +2516,8 @@ | |
{ | |
if (!this.opts.air) return; | |
+ this.selectionSave(); | |
+ | |
var left, top; | |
$('.redactor_air').hide(); | |
@@ -2177,6 +2623,11 @@ | |
$item = $('<a href="#" class="' + btnObject.className + ' redactor_dropdown_' + btnName + '">' + btnObject.title + '</a>'); | |
$item.on('click', $.proxy(function(e) | |
{ | |
+ if (this.opts.air) | |
+ { | |
+ this.selectionRestore(); | |
+ } | |
+ | |
if (e.preventDefault) e.preventDefault(); | |
if (this.browser('msie')) e.returnValue = false; | |
@@ -2187,6 +2638,7 @@ | |
this.buttonActiveObserver(); | |
if (this.opts.air) this.$air.fadeOut(100); | |
+ | |
}, this)); | |
} | |
@@ -2202,22 +2654,21 @@ | |
return false; | |
} | |
- var $dropdown = this.$toolbar.find('.redactor_dropdown_box_' + key); | |
var $button = this.buttonGet(key); | |
+ // Always re-append it to the end of <body> so it always has the highest sub-z-index. | |
+ var $dropdown = $button.data('dropdown').appendTo(document.body); | |
+ | |
if ($button.hasClass('dropact')) this.dropdownHideAll(); | |
else | |
{ | |
this.dropdownHideAll(); | |
+ this.callback('dropdownShow', { dropdown: $dropdown, key: key, button: $button }); | |
this.buttonActive(key); | |
$button.addClass('dropact'); | |
- var keyPosition = $button.position(); | |
- if (this.toolbarFixed) | |
- { | |
- keyPosition = $button.offset(); | |
- } | |
+ var keyPosition = $button.offset(); | |
// fix right placement | |
var dropdownWidth = $dropdown.width(); | |
@@ -2227,15 +2678,16 @@ | |
} | |
var left = keyPosition.left + 'px'; | |
- var btnHeight = 29; | |
+ var btnHeight = $button.innerHeight(); | |
var position = 'absolute'; | |
- var top = btnHeight + 'px'; | |
+ var top = (btnHeight + this.opts.toolbarFixedTopOffset) + 'px'; | |
if (this.opts.toolbarFixed && this.toolbarFixed) position = 'fixed'; | |
- else if (!this.opts.air) top = keyPosition.top + btnHeight + 'px'; | |
+ else top = keyPosition.top + btnHeight + 'px'; | |
$dropdown.css({ position: position, left: left, top: top }).show(); | |
+ this.callback('dropdownShown', { dropdown: $dropdown, key: key, button: $button }); | |
} | |
@@ -2247,13 +2699,17 @@ | |
$(document).one('click', hdlHideDropDown); | |
this.$editor.one('click', hdlHideDropDown); | |
+ this.$editor.one('touchstart', hdlHideDropDown); | |
+ | |
e.stopPropagation(); | |
+ this.focusWithSaveScroll(); | |
}, | |
dropdownHideAll: function() | |
{ | |
this.$toolbar.find('a.dropact').removeClass('redactor_act').removeClass('dropact'); | |
$('.redactor_dropdown').hide(); | |
+ this.callback('dropdownHide'); | |
}, | |
dropdownHide: function (e, $dropdown) | |
{ | |
@@ -2265,9 +2721,14 @@ | |
}, | |
// BUTTONS | |
- buttonBuild: function(btnName, btnObject) | |
+ buttonBuild: function(btnName, btnObject, buttonImage) | |
{ | |
- var $button = $('<a href="javascript:;" title="' + btnObject.title + '" tabindex="-1" class="redactor_btn redactor_btn_' + btnName + '"></a>'); | |
+ var $button = $('<a href="javascript:;" title="' + btnObject.title + '" tabindex="-1" class="re-icon re-' + btnName + '"></a>'); | |
+ | |
+ if (typeof buttonImage != 'undefined') | |
+ { | |
+ $button.addClass('redactor-btn-image'); | |
+ } | |
$button.on('click', $.proxy(function(e) | |
{ | |
@@ -2278,12 +2739,13 @@ | |
if (this.isFocused() === false && !btnObject.exec) | |
{ | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
} | |
if (btnObject.exec) | |
{ | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
+ | |
this.execCommand(btnObject.exec, btnName); | |
this.airBindMousemoveHide(); | |
@@ -2313,7 +2775,7 @@ | |
if (btnObject.dropdown) | |
{ | |
var $dropdown = $('<div class="redactor_dropdown redactor_dropdown_box_' + btnName + '" style="display: none;">'); | |
- $dropdown.appendTo(this.$toolbar); | |
+ $button.data('dropdown', $dropdown); | |
this.dropdownBuild($dropdown, btnObject.dropdown); | |
} | |
@@ -2322,112 +2784,103 @@ | |
buttonGet: function(key) | |
{ | |
if (!this.opts.toolbar) return false; | |
- return $(this.$toolbar.find('a.redactor_btn_' + key)); | |
+ return $(this.$toolbar.find('a.re-' + key)); | |
+ }, | |
+ buttonTagToActiveState: function(buttonName, tagName) | |
+ { | |
+ this.opts.activeButtons.push(buttonName); | |
+ this.opts.activeButtonsStates[tagName] = buttonName; | |
}, | |
buttonActiveToggle: function(key) | |
{ | |
var btn = this.buttonGet(key); | |
- if (btn.hasClass('redactor_act')) btn.removeClass('redactor_act'); | |
- else btn.addClass('redactor_act'); | |
+ if (btn.hasClass('redactor_act')) | |
+ { | |
+ this.buttonInactive(key); | |
+ } | |
+ else | |
+ { | |
+ this.buttonActive(key); | |
+ } | |
}, | |
buttonActive: function(key) | |
{ | |
- this.buttonGet(key).addClass('redactor_act'); | |
+ var btn = this.buttonGet(key); | |
+ btn.addClass('redactor_act'); | |
}, | |
buttonInactive: function(key) | |
{ | |
- this.buttonGet(key).removeClass('redactor_act'); | |
+ var btn = this.buttonGet(key); | |
+ btn.removeClass('redactor_act'); | |
}, | |
buttonInactiveAll: function(btnName) | |
{ | |
- $.each(this.opts.toolbar, $.proxy(function(k) | |
- { | |
- if (k != btnName) this.buttonInactive(k); | |
- | |
- }, this)); | |
+ this.$toolbar.find('a.re-icon').not('.re-' + btnName).removeClass('redactor_act'); | |
}, | |
buttonActiveVisual: function() | |
{ | |
- this.$toolbar.find('a.redactor_btn').not('a.redactor_btn_html').removeClass('redactor_button_disabled'); | |
+ this.$toolbar.find('a.re-icon').not('a.re-html').removeClass('redactor_button_disabled'); | |
}, | |
buttonInactiveVisual: function() | |
{ | |
- this.$toolbar.find('a.redactor_btn').not('a.redactor_btn_html').addClass('redactor_button_disabled'); | |
+ this.$toolbar.find('a.re-icon').not('a.re-html').addClass('redactor_button_disabled'); | |
}, | |
buttonChangeIcon: function (key, classname) | |
{ | |
- this.buttonGet(key).addClass('redactor_btn_' + classname); | |
+ this.buttonGet(key).addClass('re-' + classname); | |
}, | |
buttonRemoveIcon: function(key, classname) | |
{ | |
- this.buttonGet(key).removeClass('redactor_btn_' + classname); | |
- }, | |
- buttonAddSeparator: function() | |
- { | |
- this.$toolbar.append($(this.opts.buttonSeparator)); | |
+ this.buttonGet(key).removeClass('re-' + classname); | |
}, | |
- buttonAddSeparatorAfter: function(key) | |
+ buttonAwesome: function(key, name) | |
{ | |
- this.buttonGet(key).parent().after($(this.opts.buttonSeparator)); | |
- }, | |
- buttonAddSeparatorBefore: function(key) | |
- { | |
- this.buttonGet(key).parent().before($(this.opts.buttonSeparator)); | |
- }, | |
- buttonRemoveSeparatorAfter: function(key) | |
- { | |
- this.buttonGet(key).parent().next().remove(); | |
- }, | |
- buttonRemoveSeparatorBefore: function(key) | |
- { | |
- this.buttonGet(key).parent().prev().remove(); | |
- }, | |
- buttonSetRight: function(key) | |
- { | |
- if (!this.opts.toolbar) return; | |
- this.buttonGet(key).parent().addClass('redactor_btn_right'); | |
- }, | |
- buttonSetLeft: function(key) | |
- { | |
- if (!this.opts.toolbar) return; | |
- this.buttonGet(key).parent().removeClass('redactor_btn_right'); | |
+ var button = this.buttonGet(key); | |
+ button.removeClass('redactor-btn-image'); | |
+ button.addClass('fa-redactor-btn'); | |
+ button.html('<i class="fa ' + name + '"></i>'); | |
}, | |
buttonAdd: function(key, title, callback, dropdown) | |
{ | |
if (!this.opts.toolbar) return; | |
- var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }); | |
- this.$toolbar.append( $('<li>').append(btn)); | |
+ var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }, true); | |
+ | |
+ this.$toolbar.append($('<li>').append(btn)); | |
+ | |
+ return btn; | |
}, | |
buttonAddFirst: function(key, title, callback, dropdown) | |
{ | |
if (!this.opts.toolbar) return; | |
- var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }); | |
+ var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }, true); | |
this.$toolbar.prepend($('<li>').append(btn)); | |
}, | |
buttonAddAfter: function(afterkey, key, title, callback, dropdown) | |
{ | |
if (!this.opts.toolbar) return; | |
- var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }); | |
+ var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }, true); | |
var $btn = this.buttonGet(afterkey); | |
if ($btn.size() !== 0) $btn.parent().after($('<li>').append(btn)); | |
else this.$toolbar.append($('<li>').append(btn)); | |
+ | |
+ return btn; | |
}, | |
buttonAddBefore: function(beforekey, key, title, callback, dropdown) | |
{ | |
if (!this.opts.toolbar) return; | |
- var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }); | |
+ var btn = this.buttonBuild(key, { title: title, callback: callback, dropdown: dropdown }, true); | |
var $btn = this.buttonGet(beforekey); | |
if ($btn.size() !== 0) $btn.parent().before($('<li>').append(btn)); | |
else this.$toolbar.append($('<li>').append(btn)); | |
+ | |
+ return btn; | |
}, | |
- buttonRemove: function (key, separator) | |
+ buttonRemove: function (key) | |
{ | |
var $btn = this.buttonGet(key); | |
- if (separator) $btn.parent().next().remove(); | |
- $btn.parent().removeClass('redactor_btn_right'); | |
$btn.remove(); | |
}, | |
buttonActiveObserver: function(e, btnName) | |
@@ -2447,17 +2900,6 @@ | |
if (parent && parent.tagName === 'A') this.$toolbar.find('a.redactor_dropdown_link').text(this.opts.curLang.link_edit); | |
else this.$toolbar.find('a.redactor_dropdown_link').text(this.opts.curLang.link_insert); | |
- if (this.opts.activeButtonsAdd) | |
- { | |
- $.each(this.opts.activeButtonsAdd, $.proxy(function(i,s) | |
- { | |
- this.opts.activeButtons.push(s); | |
- | |
- }, this)); | |
- | |
- $.extend(this.opts.activeButtonsStates, this.opts.activeButtonsAdd); | |
- } | |
- | |
$.each(this.opts.activeButtonsStates, $.proxy(function(key, value) | |
{ | |
if ($(parent).closest(key, this.$editor.get()[0]).length != 0) | |
@@ -2471,34 +2913,61 @@ | |
if ($parent.length) | |
{ | |
var align = $parent.css('text-align'); | |
- | |
- switch (align) | |
+ if (align == '') | |
{ | |
- case 'right': | |
- this.buttonActive('alignright'); | |
- break; | |
- case 'center': | |
- this.buttonActive('aligncenter'); | |
- break; | |
- case 'justify': | |
- this.buttonActive('justify'); | |
- break; | |
- default: | |
- this.buttonActive('alignleft'); | |
- break; | |
+ align = 'left'; | |
} | |
+ | |
+ this.buttonActive('align' + align); | |
} | |
}, | |
// EXEC | |
+ execPasteFrag: function(html) | |
+ { | |
+ var sel = this.getSelection(); | |
+ if (sel.getRangeAt && sel.rangeCount) | |
+ { | |
+ var range = this.getRange(); | |
+ range.deleteContents(); | |
+ | |
+ var el = this.document.createElement("div"); | |
+ el.innerHTML = html; | |
+ | |
+ var frag = this.document.createDocumentFragment(), node, lastNode; | |
+ while ((node = el.firstChild)) | |
+ { | |
+ lastNode = frag.appendChild(node); | |
+ } | |
+ | |
+ var firstNode = frag.firstChild; | |
+ range.insertNode(frag); | |
+ | |
+ if (lastNode) | |
+ { | |
+ range = range.cloneRange(); | |
+ range.setStartAfter(lastNode); | |
+ range.collapse(true); | |
+ } | |
+ sel.removeAllRanges(); | |
+ sel.addRange(range); | |
+ } | |
+ }, | |
exec: function(cmd, param, sync) | |
{ | |
- if (cmd === 'formatblock' && this.browser('msie')) param = '<' + param + '>'; | |
+ if (cmd === 'formatblock' && this.browser('msie')) | |
+ { | |
+ param = '<' + param + '>'; | |
+ } | |
if (cmd === 'inserthtml' && this.browser('msie')) | |
{ | |
- this.$editor.focus(); | |
- this.document.selection.createRange().pasteHTML(param); | |
+ if (!this.isIe11()) | |
+ { | |
+ this.focusWithSaveScroll(); | |
+ this.document.selection.createRange().pasteHTML(param); | |
+ } | |
+ else this.execPasteFrag(param); | |
} | |
else | |
{ | |
@@ -2516,6 +2985,24 @@ | |
return false; | |
} | |
+ if ( cmd === 'bold' | |
+ || cmd === 'italic' | |
+ || cmd === 'underline' | |
+ || cmd === 'strikethrough') | |
+ { | |
+ this.bufferSet(); | |
+ } | |
+ | |
+ | |
+ if (cmd === 'superscript' || cmd === 'subscript') | |
+ { | |
+ var parent = this.getParent(); | |
+ if (parent.tagName === 'SUP' || parent.tagName === 'SUB') | |
+ { | |
+ this.inlineRemoveFormatReplace(parent); | |
+ } | |
+ } | |
+ | |
if (cmd === 'inserthtml') | |
{ | |
this.insertHtml(param, sync); | |
@@ -2559,9 +3046,15 @@ | |
var parent = this.getParent(); | |
var $list = $(parent).closest('ol, ul'); | |
+ | |
+ if (!this.isParentRedactor($list) && $list.size() != 0) | |
+ { | |
+ $list = false; | |
+ } | |
+ | |
var remove = false; | |
- if ($list.length) | |
+ if ($list && $list.length) | |
{ | |
remove = true; | |
var listTag = $list[0].tagName; | |
@@ -2577,6 +3070,7 @@ | |
// remove lists | |
if (remove) | |
{ | |
+ | |
var nodes = this.getNodes(); | |
var elems = this.getBlocks(nodes); | |
@@ -2595,8 +3089,15 @@ | |
var cloned = $s.clone(); | |
cloned.find('ul', 'ol').remove(); | |
- if (this.opts.linebreaks === false) data += this.outerHtml($('<p>').append(cloned.contents())); | |
- else data += cloned.html() + '<br>'; | |
+ if (this.opts.linebreaks === false) | |
+ { | |
+ data += this.outerHtml($('<p>').append(cloned.contents())); | |
+ } | |
+ else | |
+ { | |
+ var clonedHtml = cloned.html().replace(/<br\s?\/?>$/i, ''); | |
+ data += clonedHtml + '<br>'; | |
+ } | |
if (i == 0) | |
{ | |
@@ -2608,6 +3109,7 @@ | |
}, this)); | |
+ | |
html = this.$editor.html().replace(replaced, '</' + listTag + '>' + data + '<' + listTag + '>'); | |
this.$editor.html(html); | |
@@ -2618,38 +3120,74 @@ | |
// insert lists | |
else | |
{ | |
- var firstParent = this.getParent(); | |
+ var firstParent = $(this.getParent()).closest('td'); | |
+ | |
+ if (this.browser('msie') && !this.isIe11() && this.opts.linebreaks) | |
+ { | |
+ var wrapper = this.selectionWrap('div'); | |
+ var wrapperHtml = $(wrapper).html(); | |
+ var tmpList = $('<ul>'); | |
+ if (cmd == 'insertorderedlist') | |
+ { | |
+ tmpList = $('<ol>'); | |
+ } | |
+ | |
+ var tmpLi = $('<li>'); | |
- this.document.execCommand(cmd); | |
+ if ($.trim(wrapperHtml) == '') | |
+ { | |
+ tmpLi.append(wrapperHtml + '<span id="selection-marker-1">' + this.opts.invisibleSpace + '</span>'); | |
+ tmpList.append(tmpLi); | |
+ this.$editor.find('#selection-marker-1').replaceWith(tmpList); | |
+ } | |
+ else | |
+ { | |
+ tmpLi.append(wrapperHtml); | |
+ tmpList.append(tmpLi); | |
+ $(wrapper).replaceWith(tmpList); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ this.document.execCommand(cmd); | |
+ } | |
var parent = this.getParent(); | |
var $list = $(parent).closest('ol, ul'); | |
- if (firstParent && firstParent.tagName == 'TD') | |
+ if (this.opts.linebreaks === false) | |
+ { | |
+ var listText = $.trim($list.text()); | |
+ if (listText == '') | |
+ { | |
+ $list.children('li').find('br').remove(); | |
+ $list.children('li').append('<span id="selection-marker-1">' + this.opts.invisibleSpace + '</span>'); | |
+ } | |
+ } | |
+ | |
+ if (firstParent.size() != 0) | |
{ | |
$list.wrapAll('<td>'); | |
} | |
if ($list.length) | |
{ | |
- if ((this.browser('msie') || this.browser('mozilla')) && parent.tagName !== 'LI') | |
- { | |
- $(parent).replaceWith($(parent).html()); | |
- } | |
- | |
+ // remove block-element list wrapper | |
var $listParent = $list.parent(); | |
- if (this.isParentRedactor($listParent) && this.nodeTestBlocks($listParent[0])) | |
+ if (this.isParentRedactor($listParent) && $listParent[0].tagName != 'LI' && this.nodeTestBlocks($listParent[0])) | |
{ | |
$listParent.replaceWith($listParent.contents()); | |
} | |
} | |
- if (this.browser('mozilla')) this.$editor.focus(); | |
- | |
+ if (this.browser('mozilla')) | |
+ { | |
+ this.$editor.focus(); | |
+ } | |
} | |
this.selectionRestore(); | |
- | |
+ this.$editor.find('#selection-marker-1').removeAttr('id'); | |
this.sync(); | |
this.callback('execCommand', cmd, param); | |
return; | |
@@ -2777,7 +3315,7 @@ | |
// linebreaks | |
if (this.opts.linebreaks === true && typeof($el.data('tagblock')) !== 'undefined') | |
{ | |
- $el.replaceWith($el.html()); | |
+ $el.replaceWith($el.html() + '<br>'); | |
} | |
// all block tags | |
else | |
@@ -2860,8 +3398,8 @@ | |
if (!block && this.opts.linebreaks) | |
{ | |
// one element | |
- this.exec('formatBlock', 'blockquote'); | |
- this.selectionRestore(); | |
+ this.exec('formatblock', 'div'); | |
+ | |
var newblock = this.getBlock(); | |
var block = $('<div data-tagblock="">').html($(newblock).html()); | |
$(newblock).replaceWith(block); | |
@@ -2900,7 +3438,6 @@ | |
} | |
this.selectionRestore(); | |
- | |
this.sync(); | |
}, | |
@@ -2921,7 +3458,11 @@ | |
cleanConverters: function(html) | |
{ | |
// convert div to p | |
- if (this.opts.convertDivs) html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '<p$1>$2</p>'); | |
+ if (this.opts.convertDivs && !this.opts.gallery) | |
+ { | |
+ html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '<p$1>$2</p>'); | |
+ } | |
+ | |
if (this.opts.paragraphy) html = this.cleanParagraphy(html); | |
return html; | |
@@ -3011,8 +3552,6 @@ | |
}, | |
cleanRemoveEmptyTags: function(html) | |
{ | |
- html = html.replace(/<span>([\w\W]*?)<\/span>/gi, '$1'); | |
- | |
// remove zero width-space | |
html = html.replace(/[\u200B-\u200D\uFEFF]/g, ''); | |
@@ -3042,6 +3581,10 @@ | |
html = html + "\n"; | |
+ if (this.opts.removeEmptyTags === false) | |
+ { | |
+ return html; | |
+ } | |
var safes = []; | |
var matches = html.match(/<(table|div|pre|object)(.*?)>([\w\W]*?)<\/(table|div|pre|object)>/gi); | |
@@ -3066,6 +3609,7 @@ | |
} | |
html = html.replace(/<br \/>\s*<br \/>/gi, "\n\n"); | |
+ html = html.replace(/<br><br>/gi, "\n\n"); | |
function R(str, mod, r) | |
{ | |
@@ -3089,20 +3633,31 @@ | |
{ | |
if (htmls[i].search('{replace') == -1) | |
{ | |
- html += '<p>' + htmls[i].replace(/^\n+|\n+$/g, "") + "</p>"; | |
+ htmls[i] = htmls[i].replace(/<p>\n\t?<\/p>/gi, ''); | |
+ htmls[i] = htmls[i].replace(/<p><\/p>/gi, ''); | |
+ | |
+ if (htmls[i] != '') | |
+ { | |
+ html += '<p>' + htmls[i].replace(/^\n+|\n+$/g, "") + "</p>"; | |
+ } | |
} | |
else html += htmls[i]; | |
} | |
} | |
- html = R('<p>\s*</p>', 'gi', ''); | |
+ html = R('<p><p>', 'gi', '<p>'); | |
+ html = R('</p></p>', 'gi', '</p>'); | |
+ | |
+ html = R('<p>\s?</p>', 'gi', ''); | |
+ | |
html = R('<p>([^<]+)</(div|address|form)>', 'gi', "<p>$1</p></$2>"); | |
- html = R('<p>\s*(</?' + blocks + '[^>]*>)\s*</p>', 'gi', "$1"); | |
+ | |
+ html = R('<p>(</?' + blocks + '[^>]*>)</p>', 'gi', "$1"); | |
html = R("<p>(<li.+?)</p>", 'gi', "$1"); | |
- html = R('<p>\s*(</?' + blocks + '[^>]*>)', 'gi', "$1"); | |
+ html = R('<p>\s?(</?' + blocks + '[^>]*>)', 'gi', "$1"); | |
- html = R('(</?' + blocks + '[^>]*>)\s*</p>', 'gi', "$1"); | |
- html = R('(</?' + blocks + '[^>]*>)\s*<br />', 'gi', "$1"); | |
+ html = R('(</?' + blocks + '[^>]*>)\s?</p>', 'gi', "$1"); | |
+ html = R('(</?' + blocks + '[^>]*>)\s?<br />', 'gi', "$1"); | |
html = R('<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol)[^>]*>)', 'gi', '$1'); | |
html = R("\n</p>", 'gi', '</p>'); | |
@@ -3110,14 +3665,13 @@ | |
html = R('</p></li>', 'gi', '</li>'); | |
html = R('</li><p>', 'gi', '</li>'); | |
//html = R('</ul><p>(.*?)</li>', 'gi', '</ul></li>'); | |
- /* html = R('</ol><p>', 'gi', '</ol>'); */ | |
+ // html = R('</ol><p>', 'gi', '</ol>'); | |
html = R('<p>\t?\n?<p>', 'gi', '<p>'); | |
html = R('</dt><p>', 'gi', '</dt>'); | |
html = R('</dd><p>', 'gi', '</dd>'); | |
html = R('<br></p></blockquote>', 'gi', '</blockquote>'); | |
html = R('<p>\t*</p>', 'gi', ''); | |
- | |
// restore safes | |
$.each(safes, function(i,s) | |
{ | |
@@ -3144,14 +3698,10 @@ | |
if (this.opts.italicTag === 'em') html = html.replace(/<i>([\w\W]*?)<\/i>/gi, '<em>$1</em>'); | |
else html = html.replace(/<em>([\w\W]*?)<\/em>/gi, '<i>$1</i>'); | |
- if (set !== true) | |
- { | |
- html = html.replace(/<strike>([\w\W]*?)<\/strike>/gi, '<del>$1</del>'); | |
- } | |
- else | |
- { | |
- html = html.replace(/<del>([\w\W]*?)<\/del>/gi, '<strike>$1</strike>'); | |
- } | |
+ html = html.replace(/<span style="text-decoration: underline;">([\w\W]*?)<\/span>/gi, '<u>$1</u>'); | |
+ | |
+ if (set !== true) html = html.replace(/<strike>([\w\W]*?)<\/strike>/gi, '<del>$1</del>'); | |
+ else html = html.replace(/<del>([\w\W]*?)<\/del>/gi, '<strike>$1</strike>'); | |
return html; | |
}, | |
@@ -3189,6 +3739,9 @@ | |
if (encode !== false) arr[3] = this.cleanEncodeEntities(arr[3]); | |
+ // $ fix | |
+ arr[3] = arr[3].replace(/\$/g, '$'); | |
+ | |
html = html.replace(s, '<' + arr[1] + arr[2] + '>' + arr[3] + '</' + arr[1] + '>'); | |
}, this)); | |
@@ -3199,7 +3752,7 @@ | |
cleanEncodeEntities: function(str) | |
{ | |
str = String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); | |
- return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); | |
+ return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); | |
}, | |
cleanUnverified: function() | |
{ | |
@@ -3220,9 +3773,23 @@ | |
this.removeEmptyAttr(s, 'style'); | |
}, this)); | |
+ var $elem2 = this.$editor.find('b, strong, i, em, u, strike, del'); | |
+ $elem2.css('font-size', ''); | |
+ | |
+ $.each($elem2, $.proxy(function(i,s) | |
+ { | |
+ this.removeEmptyAttr(s, 'style'); | |
+ }, this)); | |
+ | |
// When we paste text in Safari is wrapping inserted div (remove it) | |
this.$editor.find('div[style="text-align: -webkit-auto;"]').contents().unwrap(); | |
+ | |
+ // Remove all styles in ul, ol, li | |
+ this.$editor.find('ul, ol, li').removeAttr('style'); | |
}, | |
+ | |
+ | |
+ // TEXTAREA CODE FORMATTING | |
cleanHtml: function(code) | |
{ | |
var i = 0, | |
@@ -3332,7 +3899,7 @@ | |
} | |
} | |
- return this.cleanFinish( out ); | |
+ return this.cleanFinish(out); | |
}, | |
cleanGetTabs: function() | |
{ | |
@@ -3346,10 +3913,10 @@ | |
}, | |
cleanFinish: function(code) | |
{ | |
- code = code.replace( /\n\s*\n/g, '\n' ); | |
- code = code.replace( /^[\s\n]*/, '' ); | |
- code = code.replace( /[\s\n]*$/, '' ); | |
- code = code.replace( /<script(.*?)>\n<\/script>/gi, '<script$1></script>' ); | |
+ code = code.replace(/\n\s*\n/g, '\n'); | |
+ code = code.replace(/^[\s\n]*/, ''); | |
+ code = code.replace(/[\s\n]*$/, ''); | |
+ code = code.replace(/<script(.*?)>\n<\/script>/gi, '<script$1></script>'); | |
this.cleanlevel = 0; | |
@@ -3438,6 +4005,11 @@ | |
}, | |
formatBlocks: function(tag) | |
{ | |
+ if (this.browser('mozilla') && this.isFocused()) | |
+ { | |
+ this.$editor.focus(); | |
+ } | |
+ | |
this.bufferSet(); | |
var nodes = this.getBlocks(); | |
@@ -3460,7 +4032,14 @@ | |
this.formatQuote(); | |
return; | |
} | |
- else if (this.opts.linebreaks) return; | |
+ else if (this.opts.linebreaks) | |
+ { | |
+ if (node && node.tagName.search(/H[1-6]/) == 0) | |
+ { | |
+ $(node).replaceWith(node.innerHTML + '<br>'); | |
+ } | |
+ else return; | |
+ } | |
else | |
{ | |
this.formatBlock(tag, node); | |
@@ -3480,9 +4059,9 @@ | |
formatBlock: function(tag, block) | |
{ | |
if (block === false) block = this.getBlock(); | |
- if (block === false) | |
+ if (block === false && this.opts.linebreaks === true) | |
{ | |
- if (this.opts.linebreaks === true) this.execCommand('formatblock', tag); | |
+ this.execCommand('formatblock', tag); | |
return true; | |
} | |
@@ -3535,6 +4114,11 @@ | |
// QUOTE | |
formatQuote: function() | |
{ | |
+ if (this.browser('mozilla') && this.isFocused()) | |
+ { | |
+ this.$editor.focus(); | |
+ } | |
+ | |
this.bufferSet(); | |
// paragraphy | |
@@ -3695,7 +4279,6 @@ | |
}); | |
var blocksElems = this.opts.blockLevelElements; | |
- blocksElems.push('td'); | |
$.each(blocksElems, function(i,s) | |
{ | |
html = html.replace(new RegExp('<' + s + '(.*?)>', 'gi'), ''); | |
@@ -3775,7 +4358,6 @@ | |
this.selectionRestore(); | |
this.sync(); | |
}, | |
- | |
inlineSetClass: function(className) | |
{ | |
var current = this.getCurrent(); | |
@@ -3834,7 +4416,25 @@ | |
} | |
else | |
{ | |
- this.document.execCommand('fontSize', false, 4 ); | |
+ var cmd, arg = value; | |
+ switch (attr) | |
+ { | |
+ case 'font-size': | |
+ cmd = 'fontSize'; | |
+ arg = 4; | |
+ break; | |
+ case 'font-family': | |
+ cmd = 'fontName'; | |
+ break; | |
+ case 'color': | |
+ cmd = 'foreColor'; | |
+ break; | |
+ case 'background-color': | |
+ cmd = 'backColor'; | |
+ break; | |
+ } | |
+ | |
+ this.document.execCommand(cmd, false, arg); | |
var fonts = this.$editor.find('font'); | |
$.each(fonts, $.proxy(function(i, s) | |
@@ -3842,17 +4442,21 @@ | |
this.inlineSetMethods(type, s, attr, value); | |
}, this)); | |
+ | |
} | |
this.selectionRestore(); | |
- | |
this.sync(); | |
}, | |
inlineSetMethods: function(type, s, attr, value) | |
{ | |
var parent = $(s).parent(), el; | |
- if (parent && parent[0].tagName === 'INLINE' && parent[0].attributes.length != 0) | |
+ var selectionHtml = this.getSelectionText(); | |
+ var parentHtml = $(parent).text(); | |
+ var selected = selectionHtml == parentHtml; | |
+ | |
+ if (selected && parent && parent[0].tagName === 'INLINE' && parent[0].attributes.length != 0) | |
{ | |
el = parent; | |
$(s).replaceWith($(s).html()); | |
@@ -3863,6 +4467,7 @@ | |
$(s).replaceWith(el); | |
} | |
+ | |
$(el)[type](attr, value); | |
return el; | |
@@ -3885,7 +4490,11 @@ | |
{ | |
if (!collapsed && node.tagName !== 'INLINE') | |
{ | |
- if (node.parentNode.tagName === 'INLINE' && !$(node.parentNode).hasClass('redactor_editor')) | |
+ var selectionHtml = this.getSelectionText(); | |
+ var parentHtml = $(node).parent().text(); | |
+ var selected = selectionHtml == parentHtml; | |
+ | |
+ if (selected && node.parentNode.tagName === 'INLINE' && !$(node.parentNode).hasClass('redactor_editor')) | |
{ | |
node = node.parentNode; | |
} | |
@@ -3952,13 +4561,14 @@ | |
$(el).replaceWith($(el).contents()); | |
}, | |
+ | |
// INSERT | |
insertHtml: function (html, sync) | |
{ | |
var current = this.getCurrent(); | |
var parent = current.parentNode; | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
this.bufferSet(); | |
@@ -3969,7 +4579,6 @@ | |
// Update value | |
$html = $('<div>').append($.parseHTML(html)); | |
- | |
var currBlock = this.getBlock(); | |
if ($html.contents().length == 1) | |
@@ -3979,11 +4588,16 @@ | |
// If the inserted and received text tags match | |
if (htmlTagName != 'P' && htmlTagName == currBlock.tagName || htmlTagName == 'PRE') | |
{ | |
- html = $html.text(); | |
+ //html = $html.html(); | |
$html = $('<div>').append(html); | |
} | |
} | |
+ if (this.opts.linebreaks) | |
+ { | |
+ html = html.replace(/<p(.*?)>([\w\W]*?)<\/p>/gi, '$2<br>'); | |
+ } | |
+ | |
// add text in a paragraph | |
if (!this.opts.linebreaks && $html.contents().length == 1 && $html.contents()[0].nodeType == 3 | |
&& (this.getRangeSelectedNodes().length > 2 || (!current || current.tagName == 'BODY' && !parent || parent.tagName == 'HTML'))) | |
@@ -3994,11 +4608,23 @@ | |
html = this.setSpansVerifiedHtml(html); | |
if ($html.contents().length > 1 && currBlock | |
- || $html.contents().is('p, :header, ul, ol, li, div, table, td, blockquote, pre, address, section, header, footer, aside, article')) | |
+ || $html.contents().is('p, :header, ul, ol, li, div, table, td, blockquote, pre, address, section, header, footer, aside, article')) | |
{ | |
- if (this.browser('msie')) this.document.selection.createRange().pasteHTML(html); | |
- else this.document.execCommand('inserthtml', false, html); | |
- //else { this.insertHtmlAdvanced(html, false); this.callback('execCommand', 'inserthtml', html); } | |
+ if (this.browser('msie')) | |
+ { | |
+ if (!this.isIe11()) | |
+ { | |
+ this.document.selection.createRange().pasteHTML(html); | |
+ } | |
+ else | |
+ { | |
+ this.execPasteFrag(html); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ this.document.execCommand('inserthtml', false, html); | |
+ } | |
} | |
else this.insertHtmlAdvanced(html, false); | |
@@ -4030,9 +4656,9 @@ | |
var range = sel.getRangeAt(0); | |
range.deleteContents(); | |
- var el = this.document.createElement('div'); | |
+ var el = document.createElement('div'); | |
el.innerHTML = html; | |
- var frag = this.document.createDocumentFragment(), node, lastNode; | |
+ var frag = document.createDocumentFragment(), node, lastNode; | |
while ((node = el.firstChild)) | |
{ | |
lastNode = frag.appendChild(node); | |
@@ -4082,10 +4708,23 @@ | |
if ($html.length) html = $html.text(); | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
- if (this.browser('msie')) this.document.selection.createRange().pasteHTML(html); | |
- else this.document.execCommand('inserthtml', false, html); | |
+ if (this.browser('msie')) | |
+ { | |
+ if (!this.isIe11()) | |
+ { | |
+ this.document.selection.createRange().pasteHTML(html); | |
+ } | |
+ else | |
+ { | |
+ this.execPasteFrag(html); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ this.document.execCommand('inserthtml', false, html); | |
+ } | |
this.sync(); | |
}, | |
@@ -4121,6 +4760,8 @@ | |
sel.removeAllRanges(); | |
sel.addRange(range); | |
} | |
+ | |
+ return node; | |
}, | |
insertNodeToCaretPositionFromPoint: function(e, node) | |
{ | |
@@ -4159,7 +4800,13 @@ | |
if (this.opts.linebreaks) | |
{ | |
var contents = $('<div>').append($.trim(this.$editor.html())).contents(); | |
- if (this.outerHtml(contents.last()[0]) != this.outerHtml(element)) | |
+ var last = contents.last()[0]; | |
+ if (last.tagName == 'SPAN' && last.innerHTML == '') | |
+ { | |
+ last = contents.prev()[0]; | |
+ } | |
+ | |
+ if (this.outerHtml(last) != this.outerHtml(element)) | |
{ | |
return false; | |
} | |
@@ -4194,21 +4841,60 @@ | |
this.$editor.find('span#selection-marker-1').removeAttr('id'); | |
} | |
}, | |
- insertLineBreak: function() | |
+ insertLineBreak: function(twice) | |
{ | |
this.selectionSave(); | |
- this.$editor.find('#selection-marker-1').before('<br>' + (this.browser('webkit') ? this.opts.invisibleSpace : '')); | |
- this.selectionRestore(); | |
+ | |
+ var br = '<br>'; | |
+ if (twice == true) | |
+ { | |
+ br = '<br><br>'; | |
+ } | |
+ | |
+ if (this.browser('mozilla')) | |
+ { | |
+ var span = $('<span>').html(this.opts.invisibleSpace); | |
+ this.$editor.find('#selection-marker-1').before(br).before(span).before(this.opts.invisibleSpace); | |
+ | |
+ this.setCaretAfter(span[0]); | |
+ span.remove(); | |
+ | |
+ this.selectionRemoveMarkers(); | |
+ } | |
+ else | |
+ { | |
+ var parent = this.getParent(); | |
+ if (parent && parent.tagName === 'A') | |
+ { | |
+ var offset = this.getCaretOffset(parent); | |
+ | |
+ var text = $.trim($(parent).text()).replace(/\n\r\n/g, ''); | |
+ var len = text.length; | |
+ | |
+ if (offset == len) | |
+ { | |
+ this.selectionRemoveMarkers(); | |
+ | |
+ var node = $('<span id="selection-marker-1">' + this.opts.invisibleSpace + '</span>', this.document)[0]; | |
+ $(parent).after(node); | |
+ $(node).before(br + (this.browser('webkit') ? this.opts.invisibleSpace : '')); | |
+ this.selectionRestore(); | |
+ | |
+ return true; | |
+ } | |
+ | |
+ } | |
+ | |
+ this.$editor.find('#selection-marker-1').before(br + (this.browser('webkit') ? this.opts.invisibleSpace : '')); | |
+ this.selectionRestore(); | |
+ } | |
}, | |
insertDoubleLineBreak: function() | |
{ | |
- this.selectionSave(); | |
- this.$editor.find('#selection-marker-1').before('<br><br>' + (this.browser('webkit') ? this.opts.invisibleSpace : '')); | |
- this.selectionRestore(); | |
+ this.insertLineBreak(true); | |
}, | |
replaceLineBreak: function(element) | |
{ | |
- //var node = this.document.createTextNode('\uFEFF'); | |
var node = $('<br>' + this.opts.invisibleSpace); | |
$(element).replaceWith(node); | |
this.selectionStart(node); | |
@@ -4246,6 +4932,21 @@ | |
return false; | |
} | |
+ // clean up table | |
+ var tablePaste = false; | |
+ if (this.currentOrParentIs('TD')) | |
+ { | |
+ tablePaste = true; | |
+ var blocksElems = this.opts.blockLevelElements; | |
+ blocksElems.push('tr'); | |
+ blocksElems.push('table'); | |
+ $.each(blocksElems, function(i,s) | |
+ { | |
+ html = html.replace(new RegExp('<' + s + '(.*?)>', 'gi'), ''); | |
+ html = html.replace(new RegExp('</' + s + '>', 'gi'), '<br>'); | |
+ }); | |
+ } | |
+ | |
// clean up pre | |
if (this.currentOrParentIs('PRE')) | |
{ | |
@@ -4254,6 +4955,8 @@ | |
return true; | |
} | |
+ // ms words shapes | |
+ html = html.replace(/<img(.*?)v:shapes=(.*?)>/gi, ''); | |
// ms word list | |
html = html.replace(/<p(.*?)class="MsoListParagraphCxSpFirst"([\w\W]*?)<\/p>/gi, '<ul><li$2</li>'); | |
@@ -4268,18 +4971,29 @@ | |
html = html.replace(/<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi, ''); | |
// remove nbsp | |
- html = html.replace(/( ){2,}/gi, ' '); | |
- html = html.replace(/ /gi, ' '); | |
+ if (this.opts.cleanSpaces === true) | |
+ { | |
+ html = html.replace(/( ){2,}/gi, ' '); | |
+ html = html.replace(/ /gi, ' '); | |
+ } | |
// remove google docs marker | |
html = html.replace(/<b\sid="internal-source-marker(.*?)">([\w\W]*?)<\/b>/gi, "$2"); | |
html = html.replace(/<b(.*?)id="docs-internal-guid(.*?)">([\w\W]*?)<\/b>/gi, "$3"); | |
+ | |
+ html = html.replace(/<span[^>]*(font-style: italic; font-weight: bold|font-weight: bold; font-style: italic)[^>]*>/gi, '<span style="font-weight: bold;"><span style="font-style: italic;">'); | |
+ html = html.replace(/<span[^>]*font-style: italic[^>]*>/gi, '<span style="font-style: italic;">'); | |
+ html = html.replace(/<span[^>]*font-weight: bold[^>]*>/gi, '<span style="font-weight: bold;">'); | |
+ html = html.replace(/<span[^>]*text-decoration: underline[^>]*>/gi, '<span style="text-decoration: underline;">'); | |
+ | |
// strip tags | |
- html = this.cleanStripTags(html); | |
+ //html = this.cleanStripTags(html); | |
+ | |
+ | |
// prevert | |
- html = html.replace(/<td><\/td>/gi, '[td]'); | |
+ html = html.replace(/<td>\u200b*<\/td>/gi, '[td]'); | |
html = html.replace(/<td> <\/td>/gi, '[td]'); | |
html = html.replace(/<td><br><\/td>/gi, '[td]'); | |
html = html.replace(/<td(.*?)colspan="(.*?)"(.*?)>([\w\W]*?)<\/td>/gi, '[td colspan="$2"]$4[/td]'); | |
@@ -4291,6 +5005,7 @@ | |
html = html.replace(/<embed(.*?)>([\w\W]*?)<\/embed>/gi, '[embed$1]$2[/embed]'); | |
html = html.replace(/<object(.*?)>([\w\W]*?)<\/object>/gi, '[object$1]$2[/object]'); | |
html = html.replace(/<param(.*?)>/gi, '[param$1]'); | |
+ | |
html = html.replace(/<img(.*?)>/gi, '[img$1]'); | |
// remove classes | |
@@ -4300,7 +5015,24 @@ | |
html = html.replace(/<(\w+)([\w\W]*?)>/gi, '<$1>'); | |
// remove empty | |
- html = html.replace(/<[^\/>][^>]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, ''); | |
+ if (this.opts.linebreaks) | |
+ { | |
+ // prevent double linebreaks when an empty line in RTF has bold or underlined formatting associated with it | |
+ html = html.replace(/<strong><\/strong>/gi, ''); | |
+ html = html.replace(/<u><\/u>/gi, ''); | |
+ | |
+ if (this.opts.cleanFontTag) | |
+ { | |
+ html = html.replace(/<font(.*?)>([\w\W]*?)<\/font>/gi, '$2'); | |
+ } | |
+ | |
+ html = html.replace(/<[^\/>][^>]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, '<br>'); | |
+ } | |
+ else | |
+ { | |
+ html = html.replace(/<[^\/>][^>]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, ''); | |
+ } | |
+ | |
html = html.replace(/<div>\s*?\t*?\n*?(<ul>|<ol>|<p>)/gi, '$1'); | |
// revert | |
@@ -4322,24 +5054,31 @@ | |
html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '<p>$2</p>'); | |
html = html.replace(/<\/div><p>/gi, '<p>'); | |
html = html.replace(/<\/p><\/div>/gi, '</p>'); | |
+ html = html.replace(/<p><\/p>/gi, '<br />'); | |
} | |
+ else | |
+ { | |
+ html = html.replace(/<div><\/div>/gi, '<br />'); | |
+ } | |
+ | |
+ // strip tags | |
+ html = this.cleanStripTags(html); | |
if (this.currentOrParentIs('LI')) | |
{ | |
html = html.replace(/<p>([\w\W]*?)<\/p>/gi, '$1<br>'); | |
} | |
- else | |
+ else if (tablePaste === false) | |
{ | |
html = this.cleanParagraphy(html); | |
} | |
- | |
// remove span | |
html = html.replace(/<span(.*?)>([\w\W]*?)<\/span>/gi, '$2'); | |
// remove empty | |
html = html.replace(/<img>/gi, ''); | |
- html = html.replace(/<[^\/>][^>][^img|param|source]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, ''); | |
+ html = html.replace(/<[^\/>][^>][^img|param|source|td][^<]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, ''); | |
html = html.replace(/\n{3,}/gi, '\n'); | |
@@ -4356,7 +5095,7 @@ | |
} | |
// remove empty finally | |
- html = html.replace(/<[^\/>][^>][^img|param|source]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, ''); | |
+ html = html.replace(/<[^\/>][^>][^img|param|source|td][^<]*>(\s*|\t*|\n*| |<br>)<\/[^>]+>/gi, ''); | |
// remove safari local images | |
html = html.replace(/<img src="webkit-fake-url\:\/\/(.*?)"(.*?)>/gi, ''); | |
@@ -4365,8 +5104,11 @@ | |
html = html.replace(/<td(.*?)>(\s*|\t*|\n*)<p>([\w\W]*?)<\/p>(\s*|\t*|\n*)<\/td>/gi, '<td$1>$3</td>'); | |
// remove divs | |
- html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '$2'); | |
- html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '$2'); | |
+ if (this.opts.convertDivs) | |
+ { | |
+ html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '$2'); | |
+ html = html.replace(/<div(.*?)>([\w\W]*?)<\/div>/gi, '$2'); | |
+ } | |
// FF specific | |
this.pasteClipboardMozilla = false; | |
@@ -4397,11 +5139,28 @@ | |
html = html.replace(/<p>•([\w\W]*?)<\/p>/gi, '<li>$1</li>'); | |
// ie inserts a blank font tags when pasting | |
- while (/<font>([\w\W]*?)<\/font>/gi.test(html)) | |
+ if (this.browser('msie')) | |
{ | |
- html = html.replace(/<font>([\w\W]*?)<\/font>/gi, '$1'); | |
+ while (/<font>([\w\W]*?)<\/font>/gi.test(html)) | |
+ { | |
+ html = html.replace(/<font>([\w\W]*?)<\/font>/gi, '$1'); | |
+ } | |
+ } | |
+ | |
+ // remove table paragraphs | |
+ if (tablePaste === false) | |
+ { | |
+ html = html.replace(/<td(.*?)>([\w\W]*?)<p(.*?)>([\w\W]*?)<\/td>/gi, '<td$1>$2$4</td>'); | |
+ html = html.replace(/<td(.*?)>([\w\W]*?)<\/p>([\w\W]*?)<\/td>/gi, '<td$1>$2$3</td>'); | |
+ html = html.replace(/<td(.*?)>([\w\W]*?)<p(.*?)>([\w\W]*?)<\/td>/gi, '<td$1>$2$4</td>'); | |
+ html = html.replace(/<td(.*?)>([\w\W]*?)<\/p>([\w\W]*?)<\/td>/gi, '<td$1>$2$3</td>'); | |
} | |
+ // ms word break lines | |
+ html = html.replace(/\n/g, ' '); | |
+ | |
+ // ms word lists break lines | |
+ html = html.replace(/<p>\n?<li>/gi, '<li>'); | |
this.pasteInsert(html); | |
@@ -4416,19 +5175,22 @@ | |
}, | |
pasteInsert: function(html) | |
{ | |
+ html = this.callback('pasteAfter', false, html); | |
+ | |
if (this.selectall) | |
{ | |
- if (!this.opts.linebreaks) this.$editor.html(this.opts.emptyHtml); | |
- else this.$editor.html(''); | |
- | |
- this.$editor.focus(); | |
+ this.$editor.html(html); | |
+ this.selectionRemove(); | |
+ this.focusEnd(); | |
+ this.sync(); | |
+ } | |
+ else | |
+ { | |
+ this.insertHtml(html); | |
} | |
- | |
- html = this.callback('pasteAfter', false, html); | |
- | |
- this.insertHtml(html); | |
this.selectall = false; | |
+ | |
setTimeout($.proxy(function() | |
{ | |
this.rtePaste = false; | |
@@ -4445,8 +5207,29 @@ | |
}, this), 100); | |
- if (this.opts.autoresize && this.fullscreen !== true) $(this.document.body).scrollTop(this.saveScroll); | |
- else this.$editor.scrollTop(this.saveScroll); | |
+ if (this.opts.autoresize && this.fullscreen !== true) | |
+ { | |
+ $(this.document.body).scrollTop(this.saveScroll); | |
+ } | |
+ else | |
+ { | |
+ this.$editor.scrollTop(this.saveScroll); | |
+ } | |
+ }, | |
+ pasteClipboardAppendFields: function(postData) | |
+ { | |
+ // append hidden fields | |
+ if (this.opts.uploadFields !== false && typeof this.opts.uploadFields === 'object') | |
+ { | |
+ $.each(this.opts.uploadFields, $.proxy(function(k, v) | |
+ { | |
+ if (v != null && v.toString().indexOf('#') === 0) v = $(v).val(); | |
+ postData[k] = v; | |
+ | |
+ }, this)); | |
+ } | |
+ | |
+ return postData; | |
}, | |
pasteClipboardUploadMozilla: function() | |
{ | |
@@ -4455,13 +5238,15 @@ | |
{ | |
var $s = $(s); | |
var arr = s.src.split(","); | |
- var data = arr[1]; // raw base64 | |
- var contentType = arr[0].split(";")[0].split(":")[1]; | |
+ var postData = { | |
+ 'contentType': arr[0].split(";")[0].split(":")[1], | |
+ 'data': arr[1] // raw base64 | |
+ }; | |
- $.post(this.opts.clipboardUploadUrl, { | |
- contentType: contentType, | |
- data: data | |
- }, | |
+ // append hidden fields | |
+ postData = this.pasteClipboardAppendFields(postData); | |
+ | |
+ $.post(this.opts.clipboardUploadUrl, postData, | |
$.proxy(function(data) | |
{ | |
var json = (typeof data === 'string' ? $.parseJSON(data) : data); | |
@@ -4481,15 +5266,18 @@ | |
{ | |
var result = e.target.result; | |
var arr = result.split(","); | |
- var data = arr[1]; // raw base64 | |
- var contentType = arr[0].split(";")[0].split(":")[1]; | |
+ var postData = { | |
+ 'contentType': arr[0].split(";")[0].split(":")[1], | |
+ 'data': arr[1] // raw base64 | |
+ }; | |
+ | |
if (this.opts.clipboardUpload) | |
{ | |
- $.post(this.opts.clipboardUploadUrl, { | |
- contentType: contentType, | |
- data: data | |
- }, | |
+ // append hidden fields | |
+ postData = this.pasteClipboardAppendFields(postData); | |
+ | |
+ $.post(this.opts.clipboardUploadUrl, postData, | |
$.proxy(function(data) | |
{ | |
var json = (typeof data === 'string' ? $.parseJSON(data) : data); | |
@@ -4520,21 +5308,26 @@ | |
}, | |
// BUFFER | |
- bufferSet: function(html) | |
+ bufferSet: function(selectionSave) | |
{ | |
- if (html !== undefined) this.opts.buffer.push(html); | |
- else | |
+ if (selectionSave !== false) | |
{ | |
this.selectionSave(); | |
- this.opts.buffer.push(this.$editor.html()); | |
+ } | |
+ | |
+ this.opts.buffer.push(this.$editor.html()); | |
+ | |
+ if (selectionSave !== false) | |
+ { | |
this.selectionRemoveMarkers('buffer'); | |
} | |
+ | |
}, | |
bufferUndo: function() | |
{ | |
if (this.opts.buffer.length === 0) | |
{ | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
return; | |
} | |
@@ -4552,7 +5345,7 @@ | |
{ | |
if (this.opts.rebuffer.length === 0) | |
{ | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
return false; | |
} | |
@@ -4576,11 +5369,18 @@ | |
observeLinks: function() | |
{ | |
this.$editor.find('a').on('click', $.proxy(this.linkObserver, this)); | |
+ | |
this.$editor.on('click.redactor', $.proxy(function(e) | |
{ | |
this.linkObserverTooltipClose(e); | |
}, this)); | |
+ | |
+ $(document).on('click.redactor', $.proxy(function(e) | |
+ { | |
+ this.linkObserverTooltipClose(e); | |
+ | |
+ }, this)); | |
}, | |
observeImages: function() | |
{ | |
@@ -4589,13 +5389,31 @@ | |
this.$editor.find('img').each($.proxy(function(i, elem) | |
{ | |
if (this.browser('msie')) $(elem).attr('unselectable', 'on'); | |
- this.imageResize(elem); | |
+ | |
+ var parent = $(elem).parent(); | |
+ if (!parent.hasClass('royalSlider') && !parent.hasClass('fotorama')) | |
+ { | |
+ this.imageResize(elem); | |
+ } | |
}, this)); | |
+ | |
+ // royalSlider and fotorama | |
+ this.$editor.find('.fotorama, .royalSlider').on('click', $.proxy(this.editGallery, this)); | |
+ | |
}, | |
linkObserver: function(e) | |
{ | |
var $link = $(e.target); | |
+ | |
+ var parent = $(e.target).parent(); | |
+ if (parent.hasClass('royalSlider') || parent.hasClass('fotorama')) | |
+ { | |
+ return; | |
+ } | |
+ | |
+ if ($link.size() == 0 || $link[0].tagName !== 'A') return; | |
+ | |
var pos = $link.offset(); | |
if (this.opts.iframe) | |
{ | |
@@ -4607,7 +5425,12 @@ | |
var tooltip = $('<span class="redactor-link-tooltip"></span>'); | |
var href = $link.attr('href'); | |
- if (href.length > 24) href = href.substring(0,24) + '...'; | |
+ if (href === undefined) | |
+ { | |
+ href = ''; | |
+ } | |
+ | |
+ if (href.length > 24) href = href.substring(0, 24) + '...'; | |
var aLink = $('<a href="' + $link.attr('href') + '" target="_blank">' + href + '</a>').on('click', $.proxy(function(e) | |
{ | |
@@ -4698,6 +5521,19 @@ | |
var sel = this.getSelection(); | |
if (!sel) return; | |
+ if (orgn.tagName == 'P' && orgn.innerHTML == '') | |
+ { | |
+ orgn.innerHTML = this.opts.invisibleSpace; | |
+ } | |
+ | |
+ if (orgn.tagName == 'BR' && this.opts.linebreaks === false) | |
+ { | |
+ var par = $(this.opts.emptyHtml)[0]; | |
+ $(orgn).replaceWith(par); | |
+ orgn = par; | |
+ focn = orgn; | |
+ } | |
+ | |
var range = this.getRange(); | |
range.setStart(orgn, orgo); | |
range.setEnd(focn, foco ); | |
@@ -4801,6 +5637,33 @@ | |
sel.removeAllRanges(); | |
sel.addRange( range ); | |
}, | |
+ setCaretAfter: function(node) | |
+ { | |
+ this.$editor.focus(); | |
+ | |
+ node = node[0] || node; | |
+ | |
+ var range = this.document.createRange() | |
+ | |
+ var start = 1; | |
+ var end = -1; | |
+ | |
+ range.setStart(node, start) | |
+ range.setEnd(node, end + 2) | |
+ | |
+ | |
+ var selection = this.window.getSelection() | |
+ var cursorRange = this.document.createRange() | |
+ | |
+ var emptyElement = this.document.createTextNode('\u200B') | |
+ $(node).after(emptyElement) | |
+ | |
+ cursorRange.setStartAfter(emptyElement) | |
+ | |
+ selection.removeAllRanges() | |
+ selection.addRange(cursorRange) | |
+ $(emptyElement).remove(); | |
+ }, | |
getTextNodesIn: function (node) | |
{ | |
var textNodes = []; | |
@@ -4824,7 +5687,11 @@ | |
var el = false; | |
var sel = this.getSelection(); | |
- if (sel.rangeCount > 0) el = sel.getRangeAt(0).startContainer; | |
+ if (sel && sel.rangeCount > 0) | |
+ { | |
+ el = sel.getRangeAt(0).startContainer; | |
+ //el = sel.getRangeAt(0).commonAncestorContainer; | |
+ } | |
return this.isParentRedactor(el); | |
}, | |
@@ -4872,6 +5739,12 @@ | |
return newnodes; | |
}, | |
+ isInlineNode: function(node) | |
+ { | |
+ if (node.nodeType != 1) return false; | |
+ | |
+ return !this.rTestBlock.test(node.nodeName); | |
+ }, | |
nodeTestBlocks: function(node) | |
{ | |
return node.nodeType == 1 && this.rTestBlock.test(node.nodeName); | |
@@ -5025,7 +5898,10 @@ | |
// SAVE & RESTORE | |
selectionSave: function() | |
{ | |
- if (!this.isFocused()) this.$editor.focus(); | |
+ if (!this.isFocused()) | |
+ { | |
+ this.focusWithSaveScroll(); | |
+ } | |
if (!this.opts.rangy) | |
{ | |
@@ -5062,10 +5938,19 @@ | |
{ | |
var boundaryRange = range.cloneRange(); | |
- boundaryRange.collapse(type); | |
+ try { | |
+ boundaryRange.collapse(type); | |
+ boundaryRange.insertNode(node); | |
+ boundaryRange.detach(); | |
+ } | |
+ catch (e) | |
+ { | |
+ var html = this.opts.emptyHtml; | |
+ if (this.opts.linebreaks) html = '<br>'; | |
- boundaryRange.insertNode(node); | |
- boundaryRange.detach(); | |
+ this.$editor.prepend(html); | |
+ this.focus(); | |
+ } | |
}, | |
selectionRestore: function(replace, remove) | |
{ | |
@@ -5085,11 +5970,12 @@ | |
} | |
else if (!this.isFocused()) | |
{ | |
- this.$editor.focus(); | |
+ this.focusWithSaveScroll(); | |
} | |
if (node1.length != 0 && node2.length != 0) | |
{ | |
+ | |
this.selectionSet(node1[0], 0, node2[0], 0); | |
} | |
else if (node1.length != 0) | |
@@ -5152,6 +6038,8 @@ | |
}, | |
tableInsert: function() | |
{ | |
+ this.bufferSet(false); | |
+ | |
var rows = $('#redactor_table_rows').val(), | |
columns = $('#redactor_table_columns').val(), | |
$table_box = $('<div></div>'), | |
@@ -5168,7 +6056,10 @@ | |
$column = $('<td>' + this.opts.invisibleSpace + '</td>'); | |
// set the focus to the first td | |
- if (i === 0 && z === 0) $column.append('<span id="selection-marker-1">' + this.opts.invisibleSpace + '</span>'); | |
+ if (i === 0 && z === 0) | |
+ { | |
+ $column.append('<span id="selection-marker-1">' + this.opts.invisibleSpace + '</span>'); | |
+ } | |
$($row).append($column); | |
} | |
@@ -5179,20 +6070,37 @@ | |
$table_box.append($table); | |
var html = $table_box.html(); | |
+ if (this.opts.linebreaks === false && this.browser('mozilla')) | |
+ { | |
+ html += '<p>' + this.opts.invisibleSpace + '</p>'; | |
+ } | |
+ | |
this.modalClose(); | |
this.selectionRestore(); | |
var current = this.getBlock() || this.getCurrent(); | |
- if (current && current.tagName != 'BODY') $(current).after(html) | |
- else this.insertHtmlAdvanced(html, false); | |
+ if (current && current.tagName != 'BODY') | |
+ { | |
+ if (current.tagName == 'LI') | |
+ { | |
+ var current = $(current).closest('ul, ol'); | |
+ } | |
+ | |
+ $(current).after(html) | |
+ } | |
+ else | |
+ { | |
+ | |
+ this.insertHtmlAdvanced(html, false); | |
+ } | |
this.selectionRestore(); | |
var table = this.$editor.find('#table' + tableId); | |
this.buttonActiveObserver(); | |
- table.find('span#selection-marker-1').remove(); | |
+ table.find('span#selection-marker-1, inline#selection-marker-1').remove(); | |
table.removeAttr('id'); | |
this.sync(); | |
@@ -5210,13 +6118,16 @@ | |
}, | |
tableDeleteRow: function() | |
{ | |
- var $table = $(this.getParent()).closest('table'); | |
+ var parent = this.getParent(); | |
+ var $table = $(parent).closest('table'); | |
+ | |
+ | |
if (!this.isParentRedactor($table)) return false; | |
if ($table.size() == 0) return false; | |
this.bufferSet(); | |
- var $current_tr = $(this.getParent()).closest('tr'); | |
+ var $current_tr = $(parent).closest('tr'); | |
var $focus_tr = $current_tr.prev().length ? $current_tr.prev() : $current_tr.next(); | |
if ($focus_tr.length) | |
{ | |
@@ -5229,17 +6140,25 @@ | |
$current_tr.remove(); | |
this.selectionRestore(); | |
+ $table.find('span#selection-marker-1').remove(); | |
this.sync(); | |
}, | |
tableDeleteColumn: function() | |
{ | |
- var $table = $(this.getParent()).closest('table'); | |
+ var parent = this.getParent(); | |
+ var $table = $(parent).closest('table'); | |
+ | |
if (!this.isParentRedactor($table)) return false; | |
if ($table.size() == 0) return false; | |
this.bufferSet(); | |
- var $current_td = $(this.getParent()).closest('td'); | |
+ var $current_td = $(parent).closest('td'); | |
+ if (!($current_td.is('td'))) | |
+ { | |
+ $current_td = $current_td.closest('td'); | |
+ } | |
+ | |
var index = $current_td.get(0).cellIndex; | |
// Set the focus correctly | |
@@ -5256,6 +6175,7 @@ | |
}, this)); | |
this.selectionRestore(); | |
+ $table.find('span#selection-marker-1').remove(); | |
this.sync(); | |
}, | |
tableAddHead: function() | |
@@ -5326,7 +6246,9 @@ | |
}, | |
tableAddColumn: function (type) | |
{ | |
- var $table = $(this.getParent()).closest('table'); | |
+ var parent = this.getParent(); | |
+ var $table = $(parent).closest('table'); | |
+ | |
if (!this.isParentRedactor($table)) return false; | |
if ($table.size() == 0) return false; | |
@@ -5334,8 +6256,9 @@ | |
var index = 0; | |
- var $current_tr = $(this.getParent()).closest('tr'); | |
- var $current_td = $(this.getParent()).closest('td'); | |
+ var current = this.getCurrent(); | |
+ var $current_tr = $(current).closest('tr'); | |
+ var $current_td = $(current).closest('td'); | |
$current_tr.find('td').each($.proxy(function(i, elem) | |
{ | |
@@ -5379,6 +6302,19 @@ | |
var data = $('#redactor_insert_video_area').val(); | |
data = this.cleanStripTags(data); | |
+ // parse if it is link on youtube & vimeo | |
+ var iframeStart = '<iframe width="500" height="281" src="', | |
+ iframeEnd = '" frameborder="0" allowfullscreen></iframe>'; | |
+ | |
+ if (data.match(reUrlYoutube)) | |
+ { | |
+ data = data.replace(reUrlYoutube, iframeStart + '//www.youtube.com/embed/$1' + iframeEnd); | |
+ } | |
+ else if (data.match(reUrlVimeo)) | |
+ { | |
+ data = data.replace(reUrlVimeo, iframeStart + '//player.vimeo.com/video/$2' + iframeEnd); | |
+ } | |
+ | |
this.selectionRestore(); | |
var current = this.getBlock() || this.getCurrent(); | |
@@ -5390,13 +6326,48 @@ | |
this.modalClose(); | |
}, | |
+ | |
// LINK | |
linkShow: function() | |
{ | |
this.selectionSave(); | |
- var callback = $.proxy(function() | |
- { | |
+ var callback = $.proxy(function() | |
+ { | |
+ // Predefined links | |
+ if (this.opts.predefinedLinks !== false) | |
+ { | |
+ this.predefinedLinksStorage = {}; | |
+ var that = this; | |
+ $.getJSON(this.opts.predefinedLinks, function(data) | |
+ { | |
+ var $select = $('#redactor-predefined-links'); | |
+ $select .html(''); | |
+ $.each(data, function(key, val) | |
+ { | |
+ that.predefinedLinksStorage[key] = val; | |
+ $select.append($('<option>').val(key).html(val.name)); | |
+ }); | |
+ | |
+ $select.on('change', function() | |
+ { | |
+ var key = $(this).val(); | |
+ var name = '', url = ''; | |
+ if (key != 0) | |
+ { | |
+ name = that.predefinedLinksStorage[key].name; | |
+ url = that.predefinedLinksStorage[key].url; | |
+ } | |
+ | |
+ $('#redactor_link_url').val(url); | |
+ $('#redactor_link_url_text').val(name); | |
+ | |
+ }); | |
+ | |
+ $select.show(); | |
+ }); | |
+ } | |
+ | |
this.insert_link_node = false; | |
var sel = this.getSelection(); | |
@@ -5419,52 +6390,31 @@ | |
} | |
else text = sel.toString(); | |
- $('.redactor_link_text').val(text); | |
+ $('#redactor_link_url_text').val(text); | |
var thref = self.location.href.replace(/\/$/i, ''); | |
- var turl = url.replace(thref, ''); | |
+ url = url.replace(thref, ''); | |
+ url = url.replace(/^\/#/, '#'); | |
+ url = url.replace('mailto:', ''); | |
// remove host from href | |
if (this.opts.linkProtocol === false) | |
{ | |
var re = new RegExp('^(http|ftp|https)://' + self.location.host, 'i'); | |
- turl = turl.replace(re, ''); | |
+ url = url.replace(re, ''); | |
} | |
- var tabs = $('#redactor_tabs').find('a'); | |
+ // set url | |
+ $('#redactor_link_url').val(url); | |
- if (this.opts.linkEmail === false) tabs.eq(1).remove(); | |
- if (this.opts.linkAnchor === false) tabs.eq(2).remove(); | |
- if (this.opts.linkEmail === false && this.opts.linkAnchor === false) | |
- { | |
- $('#redactor_tabs').remove(); | |
- $('#redactor_link_url').val(turl); | |
- } | |
- else | |
+ if (target === '_blank') | |
{ | |
- if (url.search('mailto:') === 0) | |
- { | |
- this.modalSetTab.call(this, 2); | |
- | |
- $('#redactor_tab_selected').val(2); | |
- $('#redactor_link_mailto').val(url.replace('mailto:', '')); | |
- } | |
- else if (turl.search(/^#/gi) === 0) | |
- { | |
- this.modalSetTab.call(this, 3); | |
- | |
- $('#redactor_tab_selected').val(3); | |
- $('#redactor_link_anchor').val(turl.replace(/^#/gi, '' )); | |
- } | |
- else | |
- { | |
- $('#redactor_link_url').val(turl); | |
- } | |
+ $('#redactor_link_blank').prop('checked', true); | |
} | |
- if (target === '_blank') $('#redactor_link_blank').prop('checked', true); | |
+ this.linkInsertPressed = false; | |
+ $('#redactor_insert_link_btn').on('click', $.proxy(this.linkProcess, this)); | |
- $('#redactor_insert_link_btn').click($.proxy(this.linkProcess, this)); | |
setTimeout(function() | |
{ | |
@@ -5479,15 +6429,25 @@ | |
}, | |
linkProcess: function() | |
{ | |
- var tab_selected = $('#redactor_tab_selected').val(); | |
- var link = '', text = '', target = '', targetBlank = ''; | |
- | |
- // url | |
- if (tab_selected === '1') | |
+ if (this.linkInsertPressed) | |
{ | |
- link = $('#redactor_link_url').val(); | |
- text = $('#redactor_link_url_text').val(); | |
+ return; | |
+ } | |
+ this.linkInsertPressed = true; | |
+ var target = '', targetBlank = ''; | |
+ | |
+ var link = $('#redactor_link_url').val(); | |
+ var text = $('#redactor_link_url_text').val(); | |
+ | |
+ // mailto | |
+ if (link.search('@') != -1 && /(http|ftp|https):\/\//i.test(link) === false) | |
+ { | |
+ link = 'mailto:' + link; | |
+ } | |
+ // url, not anchor | |
+ else if (link.search('#') != 0) | |
+ { | |
if ($('#redactor_link_blank').prop('checked')) | |
{ | |
target = ' target="_blank"'; | |
@@ -5504,21 +6464,15 @@ | |
link = this.opts.linkProtocol + link; | |
} | |
} | |
- // mailto | |
- else if (tab_selected === '2') | |
- { | |
- link = 'mailto:' + $('#redactor_link_mailto').val(); | |
- text = $('#redactor_link_mailto_text').val(); | |
- } | |
- // anchor | |
- else if (tab_selected === '3') | |
+ | |
+ text = text.replace(/<|>/g, ''); | |
+ var extra = ' '; | |
+ if (this.browser('mozilla')) | |
{ | |
- link = '#' + $('#redactor_link_anchor').val(); | |
- text = $('#redactor_link_anchor_text').val(); | |
+ extra = ' '; | |
} | |
- text = text.replace(/<|>/g, ''); | |
- this.linkInsert('<a href="' + link + '"' + target + '>' + text + '</a>', $.trim(text), link, targetBlank); | |
+ this.linkInsert('<a href="' + link + '"' + target + '>' + text + '</a>' + extra, $.trim(text), link, targetBlank); | |
}, | |
linkInsert: function (a, text, link, target) | |
@@ -5533,21 +6487,37 @@ | |
$(this.insert_link_node).text(text).attr('href', link); | |
- if (target !== '') $(this.insert_link_node).attr('target', target); | |
- else $(this.insert_link_node).removeAttr('target'); | |
- | |
- this.sync(); | |
+ if (target !== '') | |
+ { | |
+ $(this.insert_link_node).attr('target', target); | |
+ } | |
+ else | |
+ { | |
+ $(this.insert_link_node).removeAttr('target'); | |
+ } | |
} | |
else | |
{ | |
- this.exec('inserthtml', a); | |
+ var $a = $(a).addClass('redactor-added-link'); | |
+ this.exec('inserthtml', this.outerHtml($a), false); | |
+ | |
+ var link = this.$editor.find('a.redactor-added-link'); | |
+ | |
+ link.removeAttr('style').removeClass('redactor-added-link').each(function() | |
+ { | |
+ if (this.className == '') $(this).removeAttr('class'); | |
+ }); | |
+ | |
} | |
+ | |
+ this.sync(); | |
} | |
// link tooltip | |
setTimeout($.proxy(function() | |
{ | |
if (this.opts.observeLinks) this.observeLinks(); | |
+ | |
}, this), 5); | |
this.modalClose(); | |
@@ -5570,7 +6540,7 @@ | |
$('#redactor_filename').val(text); | |
// dragupload | |
- if (!this.isMobile()) | |
+ if (!this.isMobile() && !this.isIPad()) | |
{ | |
this.draguploadInit('#redactor_file', { | |
url: this.opts.fileUpload, | |
@@ -5645,6 +6615,7 @@ | |
// json | |
if (this.opts.imageGetJson) | |
{ | |
+ | |
$.getJSON(this.opts.imageGetJson, $.proxy(function(data) | |
{ | |
var folders = {}, count = 0; | |
@@ -5706,13 +6677,13 @@ | |
} | |
else | |
{ | |
- $('#redactor_tabs').find('a').eq(1).remove(); | |
+ $('#redactor-tab-control-2').remove(); | |
} | |
if (this.opts.imageUpload || this.opts.s3) | |
{ | |
// dragupload | |
- if (!this.isMobile() && this.opts.s3 === false) | |
+ if (!this.isMobile() && !this.isIPad() && this.opts.s3 === false) | |
{ | |
if ($('#redactor_file' ).length) | |
{ | |
@@ -5761,13 +6732,17 @@ | |
} | |
else | |
{ | |
- var tabs = $('#redactor_tabs').find('a'); | |
- tabs.eq(0).remove(); | |
- tabs.eq(1).addClass('redactor_tabs_act'); | |
+ $('#redactor-tab-control-1').remove(); | |
+ $('#redactor-tab-control-2').addClass('redactor_tabs_act'); | |
$('#redactor_tab2').show(); | |
} | |
} | |
+ if (!this.opts.imageTabLink && (this.opts.imageUpload || this.opts.imageGetJson)) | |
+ { | |
+ $('#redactor-tab-control-3').hide(); | |
+ } | |
+ | |
$('#redactor_upload_btn').click($.proxy(this.imageCallbackLink, this)); | |
if (!this.opts.imageUpload && !this.opts.imageGetJson) | |
@@ -5793,7 +6768,15 @@ | |
{ | |
$('#redactor_file_alt').val($el.attr('alt')); | |
$('#redactor_image_edit_src').attr('href', $el.attr('src')); | |
- $('#redactor_form_image_align').val($el.css('float')); | |
+ | |
+ if ($el.css('display') == 'block' && $el.css('float') == 'none') | |
+ { | |
+ $('#redactor_form_image_align').val('center'); | |
+ } | |
+ else | |
+ { | |
+ $('#redactor_form_image_align').val($el.css('float')); | |
+ } | |
if ($(parent).get(0).tagName === 'A') | |
{ | |
@@ -5824,13 +6807,30 @@ | |
}, | |
imageRemove: function(el) | |
{ | |
+ var parentLink = $(el).parent().parent(); | |
var parent = $(el).parent(); | |
- $(el).remove(); | |
+ var parentEl = false; | |
+ | |
+ if (parentLink.length && parentLink[0].tagName === 'A') | |
+ { | |
+ parentEl = true; | |
+ $(parentLink).remove(); | |
+ } | |
+ else if (parent.length && parent[0].tagName === 'A') | |
+ { | |
+ parentEl = true; | |
+ $(parent).remove(); | |
+ } | |
+ else | |
+ { | |
+ $(el).remove(); | |
+ } | |
if (parent.length && parent[0].tagName === 'P') | |
{ | |
- this.$editor.focus(); | |
- this.selectionStart(parent); | |
+ this.focusWithSaveScroll(); | |
+ | |
+ if (parentEl === false) this.selectionStart(parent); | |
} | |
// delete callback | |
@@ -5841,29 +6841,33 @@ | |
}, | |
imageSave: function(el) | |
{ | |
+ this.imageResizeHide(false); | |
+ | |
var $el = $(el); | |
var parent = $el.parent(); | |
$el.attr('alt', $('#redactor_file_alt').val()); | |
var floating = $('#redactor_form_image_align').val(); | |
+ var margin = ''; | |
if (floating === 'left') | |
{ | |
- this.imageMargin = '0 ' + this.opts.imageFloatMargin + ' ' + this.opts.imageFloatMargin + ' 0'; | |
- $el.css({ 'float': 'left', 'margin': this.imageMargin }); | |
+ margin = '0 ' + this.opts.imageFloatMargin + ' ' + this.opts.imageFloatMargin + ' 0'; | |
+ $el.css({ 'float': 'left', 'margin': margin }); | |
} | |
else if (floating === 'right') | |
{ | |
- this.imageMargin = '0 0 ' + this.opts.imageFloatMargin + ' ' + this.opts.imageFloatMargin + ''; | |
- $el.css({ 'float': 'right', 'margin': this.imageMargin }); | |
+ margin = '0 0 ' + this.opts.imageFloatMargin + ' ' + this.opts.imageFloatMargin + ''; | |
+ $el.css({ 'float': 'right', 'margin': margin }); | |
+ } | |
+ else if (floating === 'center') | |
+ { | |
+ $el.css({ 'float': '', 'display': 'block', 'margin': 'auto' }); | |
} | |
else | |
{ | |
- this.imageMargin = '0px'; | |
- var imageBox = $el.closest('#redactor-image-box'); | |
- if (imageBox.size() != 0) imageBox.css({ 'float': '', 'margin': '' }); | |
- $el.css({ 'float': '', 'margin': '' }); | |
+ $el.css({ 'float': '', 'display': '', 'margin': '' }); | |
} | |
// as link | |
@@ -5928,13 +6932,15 @@ | |
this.$editor.find('#redactor-image-editter, #redactor-image-resizer').remove(); | |
+ imageBox.find('img').css({ | |
+ marginTop: imageBox[0].style.marginTop, | |
+ marginBottom: imageBox[0].style.marginBottom, | |
+ marginLeft: imageBox[0].style.marginLeft, | |
+ marginRight: imageBox[0].style.marginRight | |
+ }); | |
+ | |
+ imageBox.css('margin', ''); | |
- if (this.imageMargin != '0px') | |
- { | |
- imageBox.find('img').css('margin', this.imageMargin); | |
- imageBox.css('margin', ''); | |
- this.imageMargin = '0px'; | |
- } | |
imageBox.find('img').css('opacity', ''); | |
imageBox.replaceWith(function() | |
@@ -5991,63 +6997,66 @@ | |
// resize | |
var isResizing = false; | |
- imageResizer.on('mousedown', function(e) | |
+ if (imageResizer !== false) | |
{ | |
- isResizing = true; | |
- e.preventDefault(); | |
+ imageResizer.on('mousedown', function(e) | |
+ { | |
+ isResizing = true; | |
+ e.preventDefault(); | |
- ratio = $image.width() / $image.height(); | |
+ ratio = $image.width() / $image.height(); | |
- start_x = Math.round(e.pageX - $image.eq(0).offset().left); | |
- start_y = Math.round(e.pageY - $image.eq(0).offset().top); | |
+ start_x = Math.round(e.pageX - $image.eq(0).offset().left); | |
+ start_y = Math.round(e.pageY - $image.eq(0).offset().top); | |
- }); | |
+ }); | |
- $(this.document.body).on('mousemove', $.proxy(function(e) | |
- { | |
- if (isResizing) | |
+ $(this.document.body).on('mousemove', $.proxy(function(e) | |
{ | |
- var mouse_x = Math.round(e.pageX - $image.eq(0).offset().left) - start_x; | |
- var mouse_y = Math.round(e.pageY - $image.eq(0).offset().top) - start_y; | |
- | |
- var div_h = $image.height(); | |
+ if (isResizing) | |
+ { | |
+ var mouse_x = Math.round(e.pageX - $image.eq(0).offset().left) - start_x; | |
+ var mouse_y = Math.round(e.pageY - $image.eq(0).offset().top) - start_y; | |
- var new_h = parseInt(div_h, 10) + mouse_y; | |
- var new_w = Math.round(new_h * ratio); | |
+ var div_h = $image.height(); | |
- if (new_w > min_w) | |
- { | |
- $image.width(new_w); | |
+ var new_h = parseInt(div_h, 10) + mouse_y; | |
+ var new_w = Math.round(new_h * ratio); | |
- if (new_w < 100) | |
- { | |
- this.imageEditter.css({ | |
- marginTop: '-7px', | |
- marginLeft: '-13px', | |
- fontSize: '9px', | |
- padding: '3px 5px' | |
- }); | |
- } | |
- else | |
+ if (new_w > min_w) | |
{ | |
- this.imageEditter.css({ | |
- marginTop: '-11px', | |
- marginLeft: '-18px', | |
- fontSize: '11px', | |
- padding: '7px 10px' | |
- }); | |
+ $image.width(new_w); | |
+ | |
+ if (new_w < 100) | |
+ { | |
+ this.imageEditter.css({ | |
+ marginTop: '-7px', | |
+ marginLeft: '-13px', | |
+ fontSize: '9px', | |
+ padding: '3px 5px' | |
+ }); | |
+ } | |
+ else | |
+ { | |
+ this.imageEditter.css({ | |
+ marginTop: '-11px', | |
+ marginLeft: '-18px', | |
+ fontSize: '11px', | |
+ padding: '7px 10px' | |
+ }); | |
+ } | |
} | |
- } | |
- start_x = Math.round(e.pageX - $image.eq(0).offset().left); | |
- start_y = Math.round(e.pageY - $image.eq(0).offset().top); | |
+ start_x = Math.round(e.pageX - $image.eq(0).offset().left); | |
+ start_y = Math.round(e.pageY - $image.eq(0).offset().top); | |
- this.sync() | |
- } | |
- }, this)).on('mouseup', function() | |
- { | |
- isResizing = false; | |
- }); | |
+ this.sync() | |
+ } | |
+ }, this)).on('mouseup', function() | |
+ { | |
+ isResizing = false; | |
+ }); | |
+ } | |
this.$editor.on('keydown.redactor-image-delete', $.proxy(function(e) | |
@@ -6056,7 +7065,7 @@ | |
if (this.keyCode.BACKSPACE == key || this.keyCode.DELETE == key) | |
{ | |
- this.bufferSet(); | |
+ this.bufferSet(false); | |
this.imageResizeHide(false); | |
this.imageRemove($image); | |
} | |
@@ -6081,12 +7090,21 @@ | |
}); | |
imageBox.attr('contenteditable', false); | |
- this.imageMargin = $image[0].style.margin; | |
- if (this.imageMargin != '0px') | |
+ if ($image[0].style.margin != 'auto') | |
{ | |
- imageBox.css('margin', this.imageMargin); | |
+ imageBox.css({ | |
+ marginTop: $image[0].style.marginTop, | |
+ marginBottom: $image[0].style.marginBottom, | |
+ marginLeft: $image[0].style.marginLeft, | |
+ marginRight: $image[0].style.marginRight | |
+ }); | |
+ | |
$image.css('margin', ''); | |
} | |
+ else | |
+ { | |
+ imageBox.css({ 'display': 'block', 'margin': 'auto' }); | |
+ } | |
$image.css('opacity', .5).after(imageBox); | |
@@ -6094,7 +7112,7 @@ | |
this.imageEditter = $('<span id="redactor-image-editter" data-redactor="verified">' + this.opts.curLang.edit + '</span>'); | |
this.imageEditter.css({ | |
position: 'absolute', | |
- zIndex: 2, | |
+ zIndex: 5, | |
top: '50%', | |
left: '50%', | |
marginTop: '-11px', | |
@@ -6114,25 +7132,34 @@ | |
imageBox.append(this.imageEditter); | |
// resizer | |
- var imageResizer = $('<span id="redactor-image-resizer" data-redactor="verified"></span>'); | |
- imageResizer.css({ | |
- position: 'absolute', | |
- zIndex: 2, | |
- lineHeight: 1, | |
- cursor: 'nw-resize', | |
- bottom: '-4px', | |
- right: '-5px', | |
- border: '1px solid #fff', | |
- backgroundColor: '#000', | |
- width: '8px', | |
- height: '8px' | |
- }); | |
- imageResizer.attr('contenteditable', false); | |
- imageBox.append(imageResizer); | |
+ if (this.opts.imageResizable) | |
+ { | |
+ var imageResizer = $('<span id="redactor-image-resizer" data-redactor="verified"></span>'); | |
+ imageResizer.css({ | |
+ position: 'absolute', | |
+ zIndex: 2, | |
+ lineHeight: 1, | |
+ cursor: 'nw-resize', | |
+ bottom: '-4px', | |
+ right: '-5px', | |
+ border: '1px solid #fff', | |
+ backgroundColor: '#000', | |
+ width: '8px', | |
+ height: '8px' | |
+ }); | |
+ imageResizer.attr('contenteditable', false); | |
+ imageBox.append(imageResizer); | |
- imageBox.append($image); | |
+ imageBox.append($image); | |
+ | |
+ return imageResizer; | |
+ } | |
+ else | |
+ { | |
+ imageBox.append($image); | |
- return imageResizer; | |
+ return false; | |
+ } | |
}, | |
imageThumbClick: function(e) | |
{ | |
@@ -6165,7 +7192,6 @@ | |
{ | |
this.selectionRestore(); | |
- | |
if (json !== false) | |
{ | |
var html = ''; | |
@@ -6201,16 +7227,31 @@ | |
this.observeImages(); | |
}, | |
+ // PROGRESS BAR | |
+ buildProgressBar: function() | |
+ { | |
+ if ($('#redactor-progress').size() != 0) return; | |
+ | |
+ this.$progressBar = $('<div id="redactor-progress"><span></span></div>'); | |
+ $(document.body).append(this.$progressBar); | |
+ }, | |
+ showProgressBar: function() | |
+ { | |
+ this.buildProgressBar(); | |
+ $('#redactor-progress').fadeIn(); | |
+ }, | |
+ hideProgressBar: function() | |
+ { | |
+ $('#redactor-progress').fadeOut(1500); | |
+ }, | |
+ | |
// MODAL | |
modalTemplatesInit: function() | |
{ | |
$.extend( this.opts, | |
{ | |
modal_file: String() | |
- + '<section>' | |
- + '<div id="redactor-progress" class="redactor-progress redactor-progress-striped" style="display: none;">' | |
- + '<div id="redactor-progress-bar" class="redactor-progress-bar" style="width: 100%;"></div>' | |
- + '</div>' | |
+ + '<section id="redactor-modal-file-insert">' | |
+ '<form id="redactorUploadFileForm" method="post" action="" enctype="multipart/form-data">' | |
+ '<label>' + this.opts.curLang.filename + '</label>' | |
+ '<input type="text" id="redactor_filename" class="redactor_input" />' | |
@@ -6221,34 +7262,32 @@ | |
+ '</section>', | |
modal_image_edit: String() | |
- + '<section>' | |
+ + '<section id="redactor-modal-image-edit">' | |
+ '<label>' + this.opts.curLang.title + '</label>' | |
- + '<input id="redactor_file_alt" class="redactor_input" />' | |
+ + '<input type="text" id="redactor_file_alt" class="redactor_input" />' | |
+ '<label>' + this.opts.curLang.link + '</label>' | |
- + '<input id="redactor_file_link" class="redactor_input" />' | |
+ + '<input type="text" id="redactor_file_link" class="redactor_input" />' | |
+ '<label><input type="checkbox" id="redactor_link_blank"> ' + this.opts.curLang.link_new_tab + '</label>' | |
+ '<label>' + this.opts.curLang.image_position + '</label>' | |
+ '<select id="redactor_form_image_align">' | |
+ '<option value="none">' + this.opts.curLang.none + '</option>' | |
+ '<option value="left">' + this.opts.curLang.left + '</option>' | |
+ + '<option value="center">' + this.opts.curLang.center + '</option>' | |
+ '<option value="right">' + this.opts.curLang.right + '</option>' | |
+ '</select>' | |
+ '</section>' | |
+ '<footer>' | |
- + '<button id="redactor_image_delete_btn" class="redactor_modal_btn redactor_modal_delete_btn">' + this.opts.curLang._delete + '</button> ' | |
+ + '<button id="redactor_image_delete_btn" class="redactor_modal_btn redactor_modal_delete_btn">' + this.opts.curLang._delete + '</button>' | |
+ '<button class="redactor_modal_btn redactor_btn_modal_close">' + this.opts.curLang.cancel + '</button>' | |
- + '<input type="button" name="save" class="redactor_modal_btn redactor_modal_action_btn" id="redactorSaveBtn" value="' + this.opts.curLang.save + '" />' | |
+ + '<button id="redactorSaveBtn" class="redactor_modal_btn redactor_modal_action_btn">' + this.opts.curLang.save + '</button>' | |
+ '</footer>', | |
modal_image: String() | |
- + '<section>' | |
+ + '<section id="redactor-modal-image-insert">' | |
+ '<div id="redactor_tabs">' | |
- + '<a href="#" class="redactor_tabs_act">' + this.opts.curLang.upload + '</a>' | |
- + '<a href="#">' + this.opts.curLang.choose + '</a>' | |
- + '<a href="#">' + this.opts.curLang.link + '</a>' | |
- + '</div>' | |
- + '<div id="redactor-progress" class="redactor-progress redactor-progress-striped" style="display: none;">' | |
- + '<div id="redactor-progress-bar" class="redactor-progress-bar" style="width: 100%;"></div>' | |
+ + '<a href="#" id="redactor-tab-control-1" class="redactor_tabs_act">' + this.opts.curLang.upload + '</a>' | |
+ + '<a href="#" id="redactor-tab-control-2">' + this.opts.curLang.choose + '</a>' | |
+ + '<a href="#" id="redactor-tab-control-3">' + this.opts.curLang.link + '</a>' | |
+ '</div>' | |
+ '<form id="redactorInsertImageForm" method="post" action="" enctype="multipart/form-data">' | |
+ '<div id="redactor_tab1" class="redactor_tab">' | |
@@ -6260,51 +7299,30 @@ | |
+ '</form>' | |
+ '<div id="redactor_tab3" class="redactor_tab" style="display: none;">' | |
+ '<label>' + this.opts.curLang.image_web_link + '</label>' | |
- + '<input type="text" name="redactor_file_link" id="redactor_file_link" class="redactor_input" />' | |
+ + '<input type="text" name="redactor_file_link" id="redactor_file_link" class="redactor_input" /><br><br>' | |
+ '</div>' | |
+ '</section>' | |
+ '<footer>' | |
+ '<button class="redactor_modal_btn redactor_btn_modal_close">' + this.opts.curLang.cancel + '</button>' | |
- + '<input type="button" name="upload" class="redactor_modal_btn redactor_modal_action_btn" id="redactor_upload_btn" value="' + this.opts.curLang.insert + '" />' | |
+ + '<button class="redactor_modal_btn redactor_modal_action_btn" id="redactor_upload_btn">' + this.opts.curLang.insert + '</button>' | |
+ '</footer>', | |
modal_link: String() | |
- + '<section>' | |
- + '<form id="redactorInsertLinkForm" method="post" action="">' | |
- + '<div id="redactor_tabs">' | |
- + '<a href="#" class="redactor_tabs_act">URL</a>' | |
- + '<a href="#">Email</a>' | |
- + '<a href="#">' + this.opts.curLang.anchor + '</a>' | |
- + '</div>' | |
- + '<input type="hidden" id="redactor_tab_selected" value="1" />' | |
- + '<div class="redactor_tab" id="redactor_tab1">' | |
- + '<label>URL</label>' | |
- + '<input type="text" id="redactor_link_url" class="redactor_input" />' | |
- + '<label>' + this.opts.curLang.text + '</label>' | |
- + '<input type="text" class="redactor_input redactor_link_text" id="redactor_link_url_text" />' | |
- + '<label><input type="checkbox" id="redactor_link_blank"> ' + this.opts.curLang.link_new_tab + '</label>' | |
- + '</div>' | |
- + '<div class="redactor_tab" id="redactor_tab2" style="display: none;">' | |
- + '<label>Email</label>' | |
- + '<input type="text" id="redactor_link_mailto" class="redactor_input" />' | |
- + '<label>' + this.opts.curLang.text + '</label>' | |
- + '<input type="text" class="redactor_input redactor_link_text" id="redactor_link_mailto_text" />' | |
- + '</div>' | |
- + '<div class="redactor_tab" id="redactor_tab3" style="display: none;">' | |
- + '<label>' + this.opts.curLang.anchor + '</label>' | |
- + '<input type="text" class="redactor_input" id="redactor_link_anchor" />' | |
- + '<label>' + this.opts.curLang.text + '</label>' | |
- + '<input type="text" class="redactor_input redactor_link_text" id="redactor_link_anchor_text" />' | |
- + '</div>' | |
- + '</form>' | |
+ + '<section id="redactor-modal-link-insert">' | |
+ + '<select id="redactor-predefined-links" style="width: 99.5%; display: none;"></select>' | |
+ + '<label>URL</label>' | |
+ + '<input type="text" class="redactor_input" id="redactor_link_url" />' | |
+ + '<label>' + this.opts.curLang.text + '</label>' | |
+ + '<input type="text" class="redactor_input" id="redactor_link_url_text" />' | |
+ + '<label><input type="checkbox" id="redactor_link_blank"> ' + this.opts.curLang.link_new_tab + '</label>' | |
+ '</section>' | |
+ '<footer>' | |
+ '<button class="redactor_modal_btn redactor_btn_modal_close">' + this.opts.curLang.cancel + '</button>' | |
- + '<input type="button" class="redactor_modal_btn redactor_modal_action_btn" id="redactor_insert_link_btn" value="' + this.opts.curLang.insert + '" />' | |
+ + '<button id="redactor_insert_link_btn" class="redactor_modal_btn redactor_modal_action_btn">' + this.opts.curLang.insert + '</button>' | |
+ '</footer>', | |
modal_table: String() | |
- + '<section>' | |
+ + '<section id="redactor-modal-table-insert">' | |
+ '<label>' + this.opts.curLang.rows + '</label>' | |
+ '<input type="text" size="5" value="2" id="redactor_table_rows" />' | |
+ '<label>' + this.opts.curLang.columns + '</label>' | |
@@ -6312,11 +7330,11 @@ | |
+ '</section>' | |
+ '<footer>' | |
+ '<button class="redactor_modal_btn redactor_btn_modal_close">' + this.opts.curLang.cancel + '</button>' | |
- + '<input type="button" name="upload" class="redactor_modal_btn redactor_modal_action_btn" id="redactor_insert_table_btn" value="' + this.opts.curLang.insert + '" />' | |
+ + '<button id="redactor_insert_table_btn" class="redactor_modal_btn redactor_modal_action_btn">' + this.opts.curLang.insert + '</button>' | |
+ '</footer>', | |
modal_video: String() | |
- + '<section>' | |
+ + '<section id="redactor-modal-video-insert">' | |
+ '<form id="redactorInsertVideoForm">' | |
+ '<label>' + this.opts.curLang.video_html_code + '</label>' | |
+ '<textarea id="redactor_insert_video_area" style="width: 99%; height: 160px;"></textarea>' | |
@@ -6324,51 +7342,114 @@ | |
+ '</section>' | |
+ '<footer>' | |
+ '<button class="redactor_modal_btn redactor_btn_modal_close">' + this.opts.curLang.cancel + '</button>' | |
- + '<input type="button" class="redactor_modal_btn redactor_modal_action_btn" id="redactor_insert_video_btn" value="' + this.opts.curLang.insert + '" />' | |
+ + '<button id="redactor_insert_video_btn" class="redactor_modal_btn redactor_modal_action_btn">' + this.opts.curLang.insert + '</button>' | |
+ '</footer>' | |
}); | |
}, | |
modalInit: function(title, content, width, callback) | |
{ | |
- var $redactorModalOverlay = $('#redactor_modal_overlay'); | |
+ this.modalSetOverlay(); | |
- // modal overlay | |
- if (!$redactorModalOverlay.length) | |
+ this.$redactorModalWidth = width; | |
+ this.$redactorModal = $('#redactor_modal'); | |
+ | |
+ if (!this.$redactorModal.length) | |
{ | |
- this.$overlay = $redactorModalOverlay = $('<div id="redactor_modal_overlay" style="display: none;"></div>'); | |
- $('body').prepend(this.$overlay); | |
+ this.$redactorModal = $('<div id="redactor_modal" style="display: none;" />'); | |
+ this.$redactorModal.append($('<div id="redactor_modal_close">×</div>')); | |
+ this.$redactorModal.append($('<header id="redactor_modal_header" />')); | |
+ this.$redactorModal.append($('<div id="redactor_modal_inner" />')); | |
+ this.$redactorModal.appendTo(document.body); | |
} | |
- if (this.opts.modalOverlay) | |
+ $('#redactor_modal_close').on('click', $.proxy(this.modalClose, this)); | |
+ $(document).on('keyup', $.proxy(this.modalCloseHandler, this)); | |
+ this.$editor.on('keyup', $.proxy(this.modalCloseHandler, this)); | |
+ | |
+ this.modalSetContent(content); | |
+ this.modalSetTitle(title); | |
+ this.modalSetDraggable(); | |
+ this.modalLoadTabs(); | |
+ this.modalOnCloseButton(); | |
+ this.modalSetButtonsWidth(); | |
+ | |
+ this.saveModalScroll = this.document.body.scrollTop; | |
+ if (this.opts.autoresize === false) | |
{ | |
- $redactorModalOverlay.show().on('click', $.proxy(this.modalClose, this)); | |
+ this.saveModalScroll = this.$editor.scrollTop(); | |
} | |
- var $redactorModal = $('#redactor_modal'); | |
+ if (this.isMobile() === false) this.modalShowOnDesktop(); | |
+ else this.modalShowOnMobile(); | |
- if (!$redactorModal.length) | |
+ // modal actions callback | |
+ if (typeof callback === 'function') | |
{ | |
- this.$modal = $redactorModal = $('<div id="redactor_modal" style="display: none;"><div id="redactor_modal_close">×</div><header id="redactor_modal_header"></header><div id="redactor_modal_inner"></div></div>'); | |
- $('body').append(this.$modal); | |
+ callback(); | |
} | |
- $('#redactor_modal_close').on('click', $.proxy(this.modalClose, this)); | |
+ // modal shown callback | |
+ setTimeout($.proxy(function() | |
+ { | |
+ this.callback('modalOpened', this.$redactorModal); | |
+ | |
+ }, this), 11); | |
- this.hdlModalClose = $.proxy(function(e) | |
+ // fix bootstrap modal focus | |
+ $(document).off('focusin.modal'); | |
+ | |
+ // enter | |
+ this.$redactorModal.find('input[type=text]').on('keypress', $.proxy(function(e) | |
{ | |
- if (e.keyCode === this.keyCode.ESC) | |
+ if (e.which === 13) | |
{ | |
- this.modalClose(); | |
- return false; | |
+ this.$redactorModal.find('.redactor_modal_action_btn').click(); | |
+ e.preventDefault(); | |
} | |
+ }, this)); | |
- }, this); | |
+ return this.$redactorModal; | |
+ | |
+ }, | |
+ modalShowOnDesktop: function() | |
+ { | |
+ this.$redactorModal.css({ | |
+ position: 'fixed', | |
+ top: '-2000px', | |
+ left: '50%', | |
+ width: this.$redactorModalWidth + 'px', | |
+ marginLeft: '-' + (this.$redactorModalWidth / 2) + 'px' | |
+ }).show(); | |
- $(document).keyup(this.hdlModalClose); | |
- this.$editor.keyup(this.hdlModalClose); | |
+ this.modalSaveBodyOveflow = $(document.body).css('overflow'); | |
+ $(document.body).css('overflow', 'hidden'); | |
- // set content | |
+ setTimeout($.proxy(function() | |
+ { | |
+ var height = this.$redactorModal.outerHeight(); | |
+ this.$redactorModal.css({ | |
+ top: '50%', | |
+ height: 'auto', | |
+ minHeight: 'auto', | |
+ marginTop: '-' + (height + 10) / 2 + 'px' | |
+ }); | |
+ }, this), 15); | |
+ }, | |
+ modalShowOnMobile: function() | |
+ { | |
+ this.$redactorModal.css({ | |
+ position: 'fixed', | |
+ width: '100%', | |
+ height: '100%', | |
+ top: '0', | |
+ left: '0', | |
+ margin: '0', | |
+ minHeight: '300px' | |
+ }).show(); | |
+ }, | |
+ modalSetContent: function(content) | |
+ { | |
this.modalcontent = false; | |
if (content.indexOf('#') == 0) | |
{ | |
@@ -6381,104 +7462,85 @@ | |
{ | |
$('#redactor_modal_inner').empty().append(content); | |
} | |
- | |
- $redactorModal.find('#redactor_modal_header').html(title); | |
- | |
- // draggable | |
- if (typeof $.fn.draggable !== 'undefined') | |
+ }, | |
+ modalSetTitle: function(title) | |
+ { | |
+ this.$redactorModal.find('#redactor_modal_header').html(title); | |
+ }, | |
+ modalSetButtonsWidth: function() | |
+ { | |
+ var buttons = this.$redactorModal.find('footer button').not('.redactor_modal_btn_hidden'); | |
+ var buttonsSize = buttons.size(); | |
+ if (buttonsSize > 0) | |
{ | |
- $redactorModal.draggable({ handle: '#redactor_modal_header' }); | |
- $redactorModal.find('#redactor_modal_header').css('cursor', 'move'); | |
+ $(buttons).css('width', (this.$redactorModalWidth/buttonsSize) + 'px') | |
} | |
- | |
- var $redactor_tabs = $('#redactor_tabs'); | |
- | |
- // tabs | |
- if ($redactor_tabs.length ) | |
+ }, | |
+ modalOnCloseButton: function() | |
+ { | |
+ this.$redactorModal.find('.redactor_btn_modal_close').on('click', $.proxy(this.modalClose, this)); | |
+ }, | |
+ modalSetOverlay: function() | |
+ { | |
+ if (this.opts.modalOverlay) | |
{ | |
- var that = this; | |
- $redactor_tabs.find('a').each(function(i, s) | |
+ this.$redactorModalOverlay = $('#redactor_modal_overlay'); | |
+ if (!this.$redactorModalOverlay.length) | |
{ | |
- i++; | |
- $(s).on('click', function(e) | |
- { | |
- e.preventDefault(); | |
- | |
- $redactor_tabs.find('a').removeClass('redactor_tabs_act'); | |
- $(this).addClass('redactor_tabs_act'); | |
- $('.redactor_tab').hide(); | |
- $('#redactor_tab' + i ).show(); | |
- $('#redactor_tab_selected').val(i); | |
- | |
- if (that.isMobile() === false) | |
- { | |
- var height = $redactorModal.outerHeight(); | |
- $redactorModal.css('margin-top', '-' + (height + 10) / 2 + 'px'); | |
- } | |
- }); | |
- }); | |
- } | |
- | |
- $redactorModal.find('.redactor_btn_modal_close').on('click', $.proxy(this.modalClose, this)); | |
+ this.$redactorModalOverlay = $('<div id="redactor_modal_overlay" style="display: none;"></div>'); | |
+ $('body').prepend(this.$redactorModalOverlay); | |
+ } | |
- // save scroll | |
- if (this.opts.autoresize === true) | |
- { | |
- this.saveModalScroll = this.document.body.scrollTop; | |
+ this.$redactorModalOverlay.show().on('click', $.proxy(this.modalClose, this)); | |
} | |
- else | |
+ }, | |
+ modalSetDraggable: function() | |
+ { | |
+ if (typeof $.fn.draggable !== 'undefined') | |
{ | |
- this.saveModalScroll = this.$editor.scrollTop(); | |
+ this.$redactorModal.draggable({ handle: '#redactor_modal_header' }); | |
+ this.$redactorModal.find('#redactor_modal_header').css('cursor', 'move'); | |
} | |
+ }, | |
+ modalLoadTabs: function() | |
+ { | |
+ var $redactor_tabs = $('#redactor_tabs'); | |
+ if (!$redactor_tabs.length) return false; | |
- if (this.isMobile() === false) | |
+ var that = this; | |
+ $redactor_tabs.find('a').each(function(i, s) | |
{ | |
- $redactorModal.css({ | |
- position: 'fixed', | |
- top: '-2000px', | |
- left: '50%', | |
- width: width + 'px', | |
- marginLeft: '-' + (width + 60) / 2 + 'px' | |
- }).show(); | |
- | |
- this.modalSaveBodyOveflow = $(document.body).css('overflow'); | |
- $(document.body).css('overflow', 'hidden'); | |
+ i++; | |
+ $(s).on('click', function(e) | |
+ { | |
+ e.preventDefault(); | |
- } | |
- else | |
- { | |
- $redactorModal.css({ | |
- position: 'fixed', | |
- width: '100%', | |
- height: '100%', | |
- top: '0', | |
- left: '0', | |
- margin: '0', | |
- minHeight: '300px' | |
- }).show(); | |
- } | |
+ $redactor_tabs.find('a').removeClass('redactor_tabs_act'); | |
+ $(this).addClass('redactor_tabs_act'); | |
+ $('.redactor_tab').hide(); | |
+ $('#redactor_tab' + i ).show(); | |
+ $('#redactor_tab_selected').val(i); | |
- // callback | |
- if (typeof callback === 'function') callback(); | |
+ if (that.isMobile() === false) | |
+ { | |
+ var height = that.$redactorModal.outerHeight(); | |
+ that.$redactorModal.css('margin-top', '-' + (height + 10) / 2 + 'px'); | |
+ } | |
+ }); | |
+ }); | |
- if (this.isMobile() === false) | |
+ }, | |
+ modalCloseHandler: function(e) | |
+ { | |
+ if (e.keyCode === this.keyCode.ESC) | |
{ | |
- setTimeout(function() | |
- { | |
- var height = $redactorModal.outerHeight(); | |
- $redactorModal.css({ | |
- top: '50%', | |
- height: 'auto', | |
- minHeight: 'auto', | |
- marginTop: '-' + (height + 10) / 2 + 'px' | |
- }); | |
- }, 10); | |
+ this.modalClose(); | |
+ return false; | |
} | |
- | |
}, | |
modalClose: function() | |
{ | |
- $('#redactor_modal_close').off('click', this.modalClose ); | |
+ $('#redactor_modal_close').off('click', this.modalClose); | |
$('#redactor_modal').fadeOut('fast', $.proxy(function() | |
{ | |
var redactorModalInner = $('#redactor_modal_inner'); | |
@@ -6496,8 +7558,8 @@ | |
$('#redactor_modal_overlay').hide().off('click', this.modalClose); | |
} | |
- $(document).unbind('keyup', this.hdlModalClose); | |
- this.$editor.unbind('keyup', this.hdlModalClose); | |
+ $(document).off('keyup', this.modalCloseHandler); | |
+ this.$editor.off('keyup', this.modalCloseHandler); | |
this.selectionRestore(); | |
@@ -6511,6 +7573,8 @@ | |
this.$editor.scrollTop(this.saveModalScroll); | |
} | |
+ this.callback('modalClosed'); | |
+ | |
}, this)); | |
@@ -6555,13 +7619,14 @@ | |
xhr.open('GET', this.opts.s3 + mark + 'name=' + file.name + '&type=' + file.type, true); | |
// Hack to pass bytes through unprocessed. | |
- xhr.overrideMimeType('text/plain; charset=x-user-defined'); | |
+ if (xhr.overrideMimeType) xhr.overrideMimeType('text/plain; charset=x-user-defined'); | |
+ var that = this; | |
xhr.onreadystatechange = function(e) | |
{ | |
if (this.readyState == 4 && this.status == 200) | |
{ | |
- $('#redactor-progress').fadeIn(); | |
+ that.showProgressBar(); | |
callback(decodeURIComponent(this.responseText)); | |
} | |
else if(this.readyState == 4 && this.status != 200) | |
@@ -6606,7 +7671,7 @@ | |
{ | |
//setProgress(100, 'Upload completed.'); | |
- $('#redactor-progress, #redactor-progress-drag').hide(); | |
+ this.hideProgressBar(); | |
var s3image = url.split('?'); | |
@@ -6716,7 +7781,7 @@ | |
}, | |
uploadSubmit: function(e) | |
{ | |
- $('#redactor-progress').fadeIn(); | |
+ this.showProgressBar(); | |
this.uploadForm(this.element, this.uploadFrame()); | |
}, | |
uploadFrame: function() | |
@@ -6797,7 +7862,7 @@ | |
// Success | |
if (this.uploadOptions.success) | |
{ | |
- $('#redactor-progress').hide(); | |
+ this.hideProgressBar(); | |
if (typeof d !== 'undefined') | |
{ | |
@@ -6873,15 +7938,13 @@ | |
e.preventDefault(); | |
this.dropareabox.removeClass('hover').addClass('drop'); | |
- | |
- this.dragUploadAjax(this.draguploadOptions.url, e.dataTransfer.files[0], false, false, false, this.draguploadOptions.uploadParam); | |
+ this.showProgressBar(); | |
+ this.dragUploadAjax(this.draguploadOptions.url, e.dataTransfer.files[0], false, e, this.draguploadOptions.uploadParam); | |
}, this ); | |
}, | |
- dragUploadAjax: function(url, file, directupload, progress, e, uploadParam) | |
+ dragUploadAjax: function(url, file, directupload, e, uploadParam) | |
{ | |
- | |
- | |
if (!directupload) | |
{ | |
var xhr = $.ajaxSettings.xhr(); | |
@@ -6895,6 +7958,9 @@ | |
}); | |
} | |
+ // drop callback | |
+ this.callback('drop', e); | |
+ | |
var fd = new FormData(); | |
// append file data | |
@@ -6933,13 +7999,10 @@ | |
var json = (typeof data === 'string' ? $.parseJSON(data) : data); | |
+ this.hideProgressBar(); | |
+ | |
if (directupload) | |
{ | |
- progress.fadeOut('slow', function() | |
- { | |
- $(this).remove(); | |
- }); | |
- | |
var $img = $('<img>'); | |
$img.attr('src', json.filelink).attr('id', 'drag-image-marker'); | |
@@ -6995,6 +8058,10 @@ | |
{ | |
return /(iPhone|iPod|BlackBerry|Android)/.test(navigator.userAgent); | |
}, | |
+ isIPad: function() | |
+ { | |
+ return /iPad/.test(navigator.userAgent); | |
+ }, | |
normalize: function(str) | |
{ | |
if (typeof(str) === 'undefined') return 0; | |
@@ -7004,6 +8071,12 @@ | |
{ | |
return $('<div>').append($(el).eq(0).clone()).html(); | |
}, | |
+ stripHtml: function(html) | |
+ { | |
+ var tmp = document.createElement("DIV"); | |
+ tmp.innerHTML = html; | |
+ return tmp.textContent || tmp.innerText || ""; | |
+ }, | |
isString: function(obj) | |
{ | |
return Object.prototype.toString.call(obj) == '[object String]'; | |
@@ -7014,23 +8087,47 @@ | |
html = html.replace(/\s/g, ''); | |
html = html.replace(/^<p>[^\W\w\D\d]*?<\/p>$/i, ''); | |
- | |
return html == ''; | |
}, | |
+ getInternetExplorerVersion: function() | |
+ { | |
+ var rv = false; | |
+ if (navigator.appName == 'Microsoft Internet Explorer') | |
+ { | |
+ var ua = navigator.userAgent; | |
+ var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})"); | |
+ if (re.exec(ua) != null) | |
+ { | |
+ rv = parseFloat(RegExp.$1); | |
+ } | |
+ } | |
+ | |
+ return rv; | |
+ }, | |
+ isIe11: function() | |
+ { | |
+ return !!navigator.userAgent.match(/Trident\/7\./); | |
+ }, | |
browser: function(browser) | |
{ | |
var ua = navigator.userAgent.toLowerCase(); | |
- var match = /(chrome)[ \/]([\w.]+)/.exec(ua) | |
- || /(webkit)[ \/]([\w.]+)/.exec(ua) | |
- || /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) | |
- || /(msie) ([\w.]+)/.exec(ua) | |
- || ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) | |
- || []; | |
+ var match = /(opr)[\/]([\w.]+)/.exec( ua ) || | |
+ /(chrome)[ \/]([\w.]+)/.exec( ua ) || | |
+ /(webkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec(ua) || | |
+ /(webkit)[ \/]([\w.]+)/.exec( ua ) || | |
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || | |
+ /(msie) ([\w.]+)/.exec( ua ) || | |
+ ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) || | |
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || | |
+ []; | |
if (browser == 'version') return match[2]; | |
if (browser == 'webkit') return (match[1] == 'chrome' || match[1] == 'webkit'); | |
+ if (match[1] == 'rv') return browser == 'msie'; | |
+ if (match[1] == 'opr') return browser == 'webkit'; | |
+ | |
+ return browser == match[1]; | |
- return match[1] == browser; | |
}, | |
oldIE: function() | |
{ | |
@@ -7121,11 +8218,9 @@ | |
// LINKIFY | |
$.Redactor.fn.formatLinkify = function(protocol, convertLinks, convertImageLinks, convertVideoLinks, linkSize) | |
{ | |
- var url1 = /(^|<|\s)(www\..+?\..+?)(\s|>|$)/g, | |
- url2 = /(^|<|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|>|$)/g, | |
- urlImage = /(https?:\/\/.*\.(?:png|jpg|jpeg|gif))/gi, | |
- urlYoutube = /https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com\S*[^\w\-\s])([\w\-]{11})(?=[^\w\-]|$)(?![?=&+%\w.-]*(?:['"][^<>]*>|<\/a>))[?=&+%\w.-]*/ig, | |
- urlVimeo = /https?:\/\/(www\.)?vimeo.com\/(\d+)($|\/)/; | |
+ var url = /(((https?|ftps?):\/\/)|www[.][^\s])(.+?\..+?)([.),]?)(\s|\.\s+|\)|$)/gi, | |
+ rProtocol = /(https?|ftp):\/\//i, | |
+ urlImage = /(https?:\/\/.*\.(?:png|jpg|jpeg|gif))/gi; | |
var childNodes = (this.$editor ? this.$editor.get(0) : this).childNodes, i = childNodes.length; | |
while (i--) | |
@@ -7141,14 +8236,14 @@ | |
var iframeStart = '<iframe width="500" height="281" src="', | |
iframeEnd = '" frameborder="0" allowfullscreen></iframe>'; | |
- if (html.match(urlYoutube)) | |
+ if (html.match(reUrlYoutube)) | |
{ | |
- html = html.replace(urlYoutube, iframeStart + '//www.youtube.com/embed/$1' + iframeEnd); | |
+ html = html.replace(reUrlYoutube, iframeStart + '//www.youtube.com/embed/$1' + iframeEnd); | |
$(n).after(html).remove(); | |
} | |
- else if (html.match(urlVimeo)) | |
+ else if (html.match(reUrlVimeo)) | |
{ | |
- html = html.replace(urlVimeo, iframeStart + '//player.vimeo.com/video/$2' + iframeEnd); | |
+ html = html.replace(reUrlVimeo, iframeStart + '//player.vimeo.com/video/$2' + iframeEnd); | |
$(n).after(html).remove(); | |
} | |
} | |
@@ -7162,18 +8257,33 @@ | |
} | |
// link | |
- if (convertLinks && html && (html.match(url1) || html.match(url2))) | |
+ if (convertLinks && html && html.match(url)) | |
{ | |
- var href = (html.match(url1) || html.match(url2)); | |
- href = href[0]; | |
- if (href.length > linkSize) href = href.substring(0, linkSize) + '...'; | |
+ var matches = html.match(url); | |
+ | |
+ for (var i in matches) | |
+ { | |
+ var href = matches[i]; | |
+ var text = href; | |
+ | |
+ var space = ''; | |
+ if (href.match(/\s$/) !== null) space = ' '; | |
- html = html.replace(/&/g, '&') | |
- .replace(/</g, '<') | |
- .replace(/>/g, '>') | |
- .replace(url1, '$1<a href="' + protocol + '$2">' + $.trim(href) + '</a>$3') | |
- .replace(url2, '$1<a href="$2">' + $.trim(href) + '</a>$5'); | |
+ var addProtocol = protocol; | |
+ if (href.match(rProtocol) !== null) addProtocol = ''; | |
+ if (text.length > linkSize) text = text.substring(0, linkSize) + '...'; | |
+ | |
+ text = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') | |
+ | |
+ /* | |
+ To handle URLs which may have $ characters in them, need to escape $ -> $$ to prevent $1 from getting treated as a backreference. | |
+ See http://gotofritz.net/blog/code-snippets/escaping-in-replace-strings-in-javascript/ | |
+ */ | |
+ var escapedBackReferences = text.replace('$', '$$$'); | |
+ | |
+ html = html.replace(href, '<a href=\"' + addProtocol + $.trim(href) + '\">' + $.trim(escapedBackReferences) + '</a>' + space); | |
+ } | |
$(n).after(html).remove(); | |
} | |
diff --git a/scripts/redactor/ueditor-templates.html b/scripts/redactor/ueditor-templates.html | |
index dcbc2dd..a61be69 100755 | |
--- a/scripts/redactor/ueditor-templates.html | |
+++ b/scripts/redactor/ueditor-templates.html | |
@@ -113,16 +113,16 @@ | |
</div> | |
<ul class="upfront-font-icons-controlls"> | |
<li> | |
- <label for="font-icons-size"> | |
+ <label> | |
Size: | |
</label> | |
- <input id="font-icons-size" class="upfront-field-number" type="number" value="27" step="1" min="16" max="200"> | |
+ <input class="upfront-field-number font-icons-size" type="number" value="27" step="1" min="16" max="200"> | |
</li> | |
<li class="font-icons-top-li"> | |
- <label for="font-icons-top"> | |
+ <label> | |
Top: | |
</label> | |
- <input id="font-icons-top" class="upfront-field-number" type="number" value="0" step="1" min="-35" max="45"> | |
+ <input class="upfront-field-number font-icons-top" type="number" value="0" step="1" min="-35" max="45"> | |
</li> | |
</ul> | |
</script> | |
diff --git a/scripts/redactor/ueditor.js b/scripts/redactor/ueditor.js | |
index 5826efc..3b90141 100755 | |
--- a/scripts/redactor/ueditor.js | |
+++ b/scripts/redactor/ueditor.js | |
@@ -82,6 +82,41 @@ var hackRedactor = function(){ | |
this.set(this.content, false, false); | |
}; | |
+ // Let Ctrl/Cmd+A (yeah...) work normally | |
+ $.Redactor.prototype.airEnable = function () { | |
+ if (!this.opts.air || !this.opts.airButtons) return; | |
+ var _cmd_keys = [224, 17, 91, 93]; // Yay for Mac OS X | |
+ | |
+ this.$editor.on('mouseup.redactor keyup.redactor', this, $.proxy(function(e) { | |
+ var insert = $(e.target).closest('.ueditor-insert'); | |
+ if(insert.length && insert.closest(this.$box).length) | |
+ return; | |
+ | |
+ var text = this.getSelectionText(); | |
+ this.opts.toolbarFixedTopOffset = "50"; | |
+ if (e.type === 'mouseup' && text != '') this.airShow(e); | |
+ if (e.type === 'keyup' && e.shiftKey && text != '') { | |
+ var $focusElem = $(this.getElement(this.getSelection().focusNode)), offset = $focusElem.offset(); | |
+ offset.height = $focusElem.height(); | |
+ this.airShow(offset, true); | |
+ } | |
+ // Additional ctrl/cmd stuffs | |
+ if ('keyup' === e.type && e.ctrlKey && '' != text) this.airShow(e); // Ctrl | |
+ if ('keyup' === e.type && _cmd_keys.indexOf(e.which) > 0 && '' != text) this.airShow(e); // Cmd (?) | |
+ /** | |
+ * If redactor is to high for the user to see it, show it under the selected text | |
+ */ | |
+ if( this.$air.offset().top < 0 ){ | |
+ this.$air.css({ | |
+ top : e.clientY + 14 + this.$box.position().top + "px" | |
+ }); | |
+ this.$air.addClass("under"); | |
+ }else{ | |
+ this.$air.removeClass("under"); | |
+ } | |
+ }, this)); | |
+ }; | |
+ | |
// We already have all the plugins' methods in redactor, just call init | |
$.Redactor.prototype.buildPlugins = function() { | |
var me = this; | |
@@ -94,42 +129,8 @@ var hackRedactor = function(){ | |
}); | |
}; | |
- // Let Ctrl/Cmd+A (yeah...) work normally | |
- $.Redactor.prototype.airEnable = function () { | |
- if (!this.opts.air || !this.opts.airButtons) return; | |
- var _cmd_keys = [224, 17, 91, 93]; // Yay for Mac OS X | |
- | |
- this.$editor.on('mouseup.redactor keyup.redactor', this, $.proxy(function(e) { | |
- var insert = $(e.target).closest('.ueditor-insert'); | |
- if(insert.length && insert.closest(this.$box).length) | |
- return; | |
- | |
- var text = this.getSelectionText(); | |
-// console.log("this", this); | |
- this.opts.toolbarFixedTopOffset = "50"; | |
- if (e.type === 'mouseup' && text != '') this.airShow(e); | |
- if (e.type === 'keyup' && e.shiftKey && text != '') { | |
- var $focusElem = $(this.getElement(this.getSelection().focusNode)), offset = $focusElem.offset(); | |
- offset.height = $focusElem.height(); | |
- this.airShow(offset, true); | |
- } | |
- // Additional ctrl/cmd stuffs | |
- if ('keyup' === e.type && e.ctrlKey && '' != text) this.airShow(e); // Ctrl | |
- if ('keyup' === e.type && _cmd_keys.indexOf(e.which) > 0 && '' != text) this.airShow(e); // Cmd (?) | |
- /** | |
- * If redactor is to high for the user to see it, show it under the selected text | |
- */ | |
- if( this.$air.offset().top < 0 ){ | |
- this.$air.css({ | |
- top : e.clientY + 14 + this.$box.position().top + "px" | |
- }); | |
- this.$air.addClass("under"); | |
- }else{ | |
- this.$air.removeClass("under"); | |
- } | |
- }, this)); | |
- }; | |
+ | |
// Make click consistent | |
$.Redactor.prototype.airBindHide = function () { | |
if (!this.opts.air) return; | |
@@ -140,7 +141,8 @@ var hackRedactor = function(){ | |
if ($(e.target).closest(this.$toolbar).length === 0) { | |
if (!this.getSelectionText()) { | |
this.$air.fadeOut(100); | |
- //this.selectionRemove(); | |
+ $(".redactor_dropdown").hide(); | |
+ this.$toolbar.find(".dropact").removeClass("dropact"); | |
$(doc).off(e); | |
} | |
} | |
@@ -148,10 +150,8 @@ var hackRedactor = function(){ | |
if (e.which === this.keyCode.ESC) { | |
this.getSelection().collapseToStart(); | |
} | |
- | |
this.$air.fadeOut(100); | |
$(doc).off(e); | |
- | |
}, this)); | |
}, this); | |
@@ -197,7 +197,7 @@ var hackRedactor = function(){ | |
$('.redactor_air').hide(); | |
- this.selectionRemoveMarkers(); | |
+ // this.selectionRemoveMarkers(); | |
this.selectionSave(); | |
var width = this.airWidth || this.$air.width(), | |
@@ -246,7 +246,7 @@ var hackRedactor = function(){ | |
this.airBindHide(); | |
this.$air.trigger('show'); | |
- }, | |
+ }; | |
// Add possiblity to disable linebreak (for one line title) | |
$.Redactor.prototype.doInsertLineBreak = $.Redactor.prototype.insertLineBreak; | |
@@ -256,6 +256,7 @@ var hackRedactor = function(){ | |
return this.doInsertLineBreak(); | |
return false; | |
}; | |
+ | |
/* | |
$.Redactor.prototype.getCurrent = function(){ | |
var el = false; | |
@@ -269,6 +270,9 @@ var hackRedactor = function(){ | |
return this.isParentRedactor(el); | |
}; | |
*/ | |
+ | |
+ | |
+ | |
hackedRedactor = true; | |
$.Redactor.prototype.events = UeditorEvents; | |
@@ -303,7 +307,7 @@ var Ueditor = function($el, options) { | |
focus: true, | |
cleanup: false, | |
plugins: plugins, | |
- airButtons: ['upfrontFormatting', 'bold', 'italic', 'blockquote', 'upfrontLink', 'stateLists', 'stateAlign', 'upfrontColor', 'icons'], | |
+ airButtons: ['upfrontFormatting', 'bold', 'italic', 'blockquote', 'upfrontLink', 'stateLists', 'stateAlign', 'upfrontColor', 'upftonIcons'], | |
buttonsCustom: {}, | |
activeButtonsAdd: {}, | |
observeLinks: false, | |
@@ -314,7 +318,8 @@ var Ueditor = function($el, options) { | |
; | |
/* --- Redactor allows for single callbacks - let's dispatch events instead --- */ | |
- | |
+ this.options.dropdownShowCallback = function () { UeditorEvents.trigger("ueditor:dropdownShow", this); }; | |
+ this.options.dropdownHideCallback = function () { UeditorEvents.trigger("ueditor:dropdownHide", this); }; | |
this.options.initCallback = function () { UeditorEvents.trigger("ueditor:init", this); }; | |
this.options.enterCallback = function () { UeditorEvents.trigger("ueditor:enter", this); }; | |
this.options.changeCallback = function () { UeditorEvents.trigger("ueditor:change", this); }; | |
@@ -522,7 +527,7 @@ Ueditor.prototype = { | |
} | |
}, | |
pluginList: function(options){ | |
- var allPlugins = ['stateAlignment', 'stateAlignmentCTA', 'stateLists', 'blockquote', 'stateButtons', 'upfrontLink', 'upfrontLinkCTA', 'upfrontColor', 'panelButtons', /* 'upfrontMedia', 'upfrontImages', */'upfrontFormatting', 'upfrontSink', 'upfrontPlaceholder', 'icons'], | |
+ var allPlugins = ['stateAlignment', 'stateLists', 'blockquote', 'stateButtons', 'upfrontLink', 'upfrontColor', 'panelButtons', /* 'upfrontMedia', 'upfrontImages', */'upfrontFormatting', 'upfrontSink', 'upfrontPlaceholder', 'upftonIcons'], | |
pluginList = [] | |
; | |
$.each(allPlugins, function(i, name){ | |
@@ -573,29 +578,40 @@ Ueditor.prototype = { | |
if (!RedactorPlugins) var RedactorPlugins = {}; | |
+UpfrontRedactorPanels = _.extend(RedactorPlugins, { | |
+ init : function(){ | |
+ console.log(this.buttons); | |
+ } | |
+}); | |
/* | |
STATE BUTTONS PLUGIN | |
*/ | |
RedactorPlugins.stateButtons = { | |
- beforeInit: function(){ | |
+ init: function(){ | |
+ var self = this; | |
this.addStateButtons(); | |
this.startStateObserver(); | |
- }, | |
+ }, | |
addStateButtons: function(){ | |
if(this.stateButtons) | |
return; | |
var me = this; | |
- | |
this.stateButtons = {}; | |
$.each(this.opts.stateButtons, function(id, data){ | |
var button = new me.StateButton(id, data); | |
- me.stateButtons[id] = button; | |
- me.opts.buttonsCustom[id] = button; | |
+ me.buttonAdd(id, data.title, function(){ me.stateCallback( id, button ) }); | |
+ // set state of button | |
+ me.$air.on("show", function(){ | |
+ button.guessState(me); | |
+ }); | |
}); | |
}, | |
- | |
+ stateCallback : function( id, button ){ | |
+ button.guessState( this ); | |
+ button.callback(id, this.buttonGet(id) ,button ); | |
+ }, | |
startStateObserver: function(){ | |
var observer = $.proxy(this.stateObserver, this); | |
this.$element.on('mouseup.redactor keyup.redactor', observer); | |
@@ -640,7 +656,6 @@ RedactorPlugins.stateButtons = { | |
}; | |
me.setState = function(id, el){ | |
this.currentState = id; | |
- | |
el.removeClass(this.iconClasses) | |
.addClass(this.states[this.currentState].iconClass) | |
; | |
@@ -656,15 +671,11 @@ RedactorPlugins.stateButtons = { | |
}); | |
if(!found) | |
found = this.defaultState; | |
- | |
- | |
- this.setState(found, this.getElement(redactor)); | |
+ this.setState(found, redactor.buttonGet(this.id)); | |
}; | |
- | |
me.getElement = function(redactor){ | |
return redactor.$toolbar.find('.redactor_btn_' + this.id); | |
}; | |
- | |
return { | |
id: id, | |
title: data.title, | |
@@ -687,6 +698,7 @@ RedactorPlugins.stateButtons = { | |
--------------------- */ | |
RedactorPlugins.stateAlignment = { | |
beforeInit: function(){ | |
+ var self = this; | |
this.opts.stateButtons.stateAlign = { | |
title: 'Text alignment', | |
defaultState: 'left', | |
@@ -700,7 +712,7 @@ RedactorPlugins.stateAlignment = { | |
return $parent.length && $parent.css('text-align') == 'left'; | |
}, | |
callback: function(name, el , button){ | |
- this.alignmentLeft(); | |
+ self.alignmentLeft(); | |
} | |
}, | |
center: { | |
@@ -712,7 +724,7 @@ RedactorPlugins.stateAlignment = { | |
return $parent.length && $parent.css('text-align') == 'center'; | |
}, | |
callback: function(name, el , button){ | |
- this.alignmentCenter(); | |
+ self.alignmentCenter(); | |
} | |
}, | |
right: { | |
@@ -724,7 +736,7 @@ RedactorPlugins.stateAlignment = { | |
return $parent.length && $parent.css('text-align') == 'right'; | |
}, | |
callback: function(name, el , button){ | |
- this.alignmentRight(); | |
+ self.alignmentRight(); | |
} | |
}, | |
justify: { | |
@@ -736,7 +748,7 @@ RedactorPlugins.stateAlignment = { | |
return $parent.length && $parent.css('text-align') == 'justify'; | |
}, | |
callback: function(name, el , button){ | |
- this.alignmentJustify(); | |
+ self.alignmentJustify(); | |
} | |
} | |
} | |
@@ -744,65 +756,10 @@ RedactorPlugins.stateAlignment = { | |
} | |
} | |
-RedactorPlugins.stateAlignmentCTA = { | |
- beforeInit: function(){ | |
- this.opts.stateButtons.stateAlignCTA = { | |
- title: 'Text alignment', | |
- defaultState: 'left', | |
- states: { | |
- left: { | |
- iconClass: 'ueditor-left', | |
- isActive: function(redactor){ | |
- | |
- return true; | |
- | |
- }, | |
- callback: function(name, el , button){ | |
- this.$element.css('text-align', 'left'); | |
- //this.alignmentLeft(); | |
- } | |
- }, | |
- center: { | |
- iconClass: 'ueditor-center', | |
- isActive: function(redactor){ | |
- | |
- return true; | |
- | |
- }, | |
- callback: function(name, el , button){ | |
- this.$element.css('text-align', 'center'); | |
- //this.alignmentCenter(); | |
- } | |
- }, | |
- right: { | |
- iconClass: 'ueditor-right', | |
- isActive: function(redactor){ | |
- | |
- return true; | |
- | |
- }, | |
- callback: function(name, el , button){ | |
- this.$element.css('text-align', 'right'); | |
- } | |
- }, | |
- justify: { | |
- iconClass: 'ueditor-justify', | |
- isActive: function(redactor){ | |
- | |
- return true; | |
- | |
- }, | |
- callback: function(name, el , button){ | |
- this.$element.css('text-align', 'justify'); | |
- } | |
- } | |
- } | |
- } | |
- } | |
-} | |
RedactorPlugins.stateLists = { | |
beforeInit: function(){ | |
+ var self = this; | |
this.opts.stateButtons.stateLists = { | |
title: 'List style', | |
defaultState: 'none', | |
@@ -814,7 +771,7 @@ RedactorPlugins.stateLists = { | |
return $parent.length && $parent.css('text-align') == 'left'; | |
}, | |
callback: function(name, el , button){ | |
- this.execLists('insertorderedlist', 'orderedlist'); | |
+ self.execLists('insertorderedlist', 'orderedlist'); | |
} | |
}, | |
unordered: { | |
@@ -829,7 +786,7 @@ RedactorPlugins.stateLists = { | |
return false; | |
}, | |
callback: function(name, el , button){ | |
- this.execLists('insertunorderedlist', 'unorderedlist'); | |
+ self.execLists('insertunorderedlist', 'unorderedlist'); | |
} | |
}, | |
ordered: { | |
@@ -844,7 +801,7 @@ RedactorPlugins.stateLists = { | |
return false; | |
}, | |
callback: function(name, el , button){ | |
- this.execLists('insertorderedlist', 'orderedlist'); | |
+ self.execLists('insertorderedlist', 'orderedlist'); | |
} | |
} | |
} | |
@@ -857,13 +814,21 @@ RedactorPlugins.stateLists = { | |
-------------------*/ | |
RedactorPlugins.panelButtons = { | |
+ beforeInit : function(){ | |
+ var self = this; | |
+ // $.each(this.opts.buttonsCustom, function(id, b){ | |
+ // console.log(id, b); | |
+ // self.buttonAdd(id, b.title); | |
+ // }); | |
+ }, | |
init: function(){ | |
var me = this; | |
$.each(this.opts.buttonsCustom, function(id, b){ | |
if(b.panel){ | |
var $panel = $('<div class="redactor_dropdown ueditor_panel redactor_dropdown_box_' + id + '" style="display: none;">'), | |
- $button = me.$toolbar.find('.redactor_btn_' + id) | |
+ $button = me.buttonGet( id ) | |
; | |
+ | |
b.panel = new b.panel({redactor: me, button: $button, panel: $panel}); | |
$panel.html(b.panel.$el); | |
$panel.appendTo(me.$toolbar); | |
@@ -892,6 +857,38 @@ RedactorPlugins.panelButtons = { | |
e.stopPropagation(); | |
}) | |
; | |
+ me.buttonAdd(id, b.title, function(){ | |
+ var $button = me.buttonGet( id ), | |
+ left = $button.position().left; | |
+ | |
+ $(".re-icon").removeClass( "redactor_act dropact" ); | |
+ $button.addClass("redactor_act dropact"); | |
+ $(".redactor_dropdown").not($panel).hide(); | |
+ | |
+ $panel.css("left", left + "px").toggle(); | |
+ | |
+ | |
+ /** | |
+ * Triggers panel open or close events | |
+ */ | |
+ if( $panel.is(":visible") && typeof b.panel.open === "function" ){ | |
+ b.panel.open.apply(b.panel, [jQuery.Event( "open" ), me]); | |
+ }else{ | |
+ if( typeof b.panel.close === "function" ){ | |
+ b.panel.close.apply(jQuery.Event( "close" ), [$.Event, me]); | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * Makes sure the last button's panel is kept under the toolbar | |
+ * @type {[type]} | |
+ */ | |
+ var $last = $(".redactor_dropdown.ueditor_panel").last(), | |
+ lastDropdownLeft = left - $last.innerWidth() + $button.width(); | |
+ $last.css( "left", lastDropdownLeft + "px" ); | |
+ }, false); | |
+ | |
+ | |
} | |
}); | |
} | |
@@ -969,6 +966,13 @@ var UeditorPanel = Backbone.View.extend({ | |
-----------------------*/ | |
RedactorPlugins.upfrontLink = { | |
+ // init : function(){ | |
+ // this.buttonAdd("link", "Link", this.openPanel); | |
+ // }, | |
+ openPanel : function(){ | |
+ var left = this.buttonGet( "link" ).position().left; | |
+ $(".redactor_dropdown_box_upfrontLink").css("left", left + "px").toggle(); | |
+ }, | |
beforeInit: function(){ | |
this.opts.buttonsCustom.upfrontLink = { | |
title: 'Link', | |
@@ -1062,93 +1066,6 @@ RedactorPlugins.upfrontLink = { | |
}) | |
} | |
-RedactorPlugins.upfrontLinkCTA = { | |
- beforeInit: function(){ | |
- this.opts.buttonsCustom.upfrontLinkCTA = { | |
- title: 'Link', | |
- panel: this.panel | |
- }; | |
- }, | |
- panel: UeditorPanel.extend({ | |
- tpl: _.template($(tpl).find('#link-tpl').html()), | |
- events:{ | |
- open: 'open' | |
- }, | |
- initialize: function(){ | |
- this.linkPanel = new Upfront.Views.Editor.LinkPanel({linkTypes: {unlink: true}, button: true}); | |
- this.bindEvents(); | |
- UeditorPanel.prototype.initialize.apply(this, arguments); | |
- }, | |
- render: function(options){ | |
- options = options || {}; | |
- console.log(options); | |
- this.linkPanel.model.set({ | |
- url: options.url, | |
- type: options.link || this.guessLinkType(options.url) | |
- }); | |
- | |
- this.linkPanel.render(); | |
- this.$el.html(this.linkPanel.el); | |
- this.linkPanel.delegateEvents(); | |
- }, | |
- open: function(e, redactor){ | |
- this.redactor = redactor; | |
- | |
- var link = redactor.currentOrParentIs('A'); | |
- | |
- if(link){ | |
- this.render({url: $(link).attr('href'), link: $(link).attr('rel') || 'external'}); | |
- } | |
- else | |
- this.render(); | |
- }, | |
- close: function(e, redactor){ | |
- this.redactor.selectionRemoveMarkers(); | |
- }, | |
- unlink: function(e){ | |
- if(e) | |
- e.preventDefault(); | |
- this.redactor.$element.attr('href', '#'); | |
- | |
- }, | |
- link: function(url, type){ | |
- if(url){ | |
- this.redactor.$element.attr('href', url); | |
- } | |
- }, | |
- | |
- bindEvents: function(){ | |
- this.listenTo(this.linkPanel, 'link:ok', function(data){ | |
- if(data.type == 'unlink') | |
- this.unlink(); | |
- else | |
- this.link(data.url, data.type); | |
- | |
- this.closeToolbar(); | |
- }); | |
- | |
- this.listenTo(this.linkPanel, 'link:postselector', this.disableEditorStop); | |
- | |
- this.listenTo(this.linkPanel, 'link:postselected', function(data){ | |
- this.enableEditorStop(); | |
- this.link(data.url, data.type); | |
- }); | |
- }, | |
- | |
- guessLinkType: function(url){ | |
- if(!$.trim(url)) | |
- return 'unlink'; | |
- if(url.lenght && url[0] == '#') | |
- return 'anchor'; | |
- if(url.substring(0, location.origin.length) == location.origin) | |
- return 'entry'; | |
- | |
- return 'external'; | |
- } | |
- | |
- }) | |
-} | |
- | |
RedactorPlugins.upfrontColor = { | |
beforeInit: function(){ | |
this.opts.buttonsCustom.upfrontColor = { | |
@@ -1162,21 +1079,26 @@ RedactorPlugins.upfrontColor = { | |
events:{ | |
'open': 'open' | |
}, | |
+ close : function(e, redactor){ | |
+ redactor.cleanRemoveEmptyTags(redactor.getCurrent()); | |
+ }, | |
setCurrentColors: function() { | |
- var parent = this.redactor.getParent(); | |
- if(parent || (parent && $(parent).prop('tagName')=='INLINE')) { | |
- var rgb_a = $(parent).css('background-color').split(','); | |
+ var parent = this.redactor.getCurrent(); | |
+ if( (parent && $(parent).prop('tagName')=='INLINE') || $( parent ).hasClass(".upfront_theme_colors")) { | |
+ | |
+ var bg_color = tinycolor($(parent).css('background-color')); | |
this.current_color = $(parent).css('color'); | |
- if(rgb_a.length < 4 || parseFloat(rgb_a[3].replace(')', '')) > 0) | |
+ if(bg_color.getAlpha() > 0) | |
this.current_bg = $(parent).css('background-color'); | |
- | |
} | |
else { | |
this.current_color = this.current_bg = false; | |
} | |
}, | |
open: function(e, redactor){ | |
+ redactor.selectionSave(); | |
+ this.updateIcon(); | |
this.setCurrentColors(); | |
var self = this, | |
foreground_picker = new Upfront.Views.Editor.Field.Color({ | |
@@ -1192,7 +1114,7 @@ RedactorPlugins.upfrontColor = { | |
showInput: true, | |
allowEmpty: true, | |
change: function(color) { | |
- self.updateColors(); | |
+ self.current_color = color; | |
}, | |
move: function(color) { | |
redactor.selectionRestore(true, false); | |
@@ -1214,7 +1136,7 @@ RedactorPlugins.upfrontColor = { | |
showInput: true, | |
allowEmpty: true, | |
change: function(color) { | |
- self.updateColors(); | |
+ self.current_bg = color; | |
}, | |
move: function(color) { | |
redactor.selectionRestore(true, false); | |
@@ -1275,10 +1197,12 @@ RedactorPlugins.upfrontColor = { | |
// this.$('input.foreground').spectrum('resetUI'); | |
// this.$('input.background').spectrum('resetUI'); | |
// | |
-console.log("color picker opened"); | |
+ | |
this.$(".sp-choose").on("click", function(){ | |
+ self.updateColors(); | |
self.closePanel(); | |
self.closeToolbar(); | |
+ self.redactor.dropdownHideAll(); | |
}); | |
}, | |
render: function(){ | |
@@ -1295,9 +1219,7 @@ console.log("color picker opened"); | |
redac.bufferAirBindHide = this.redactor.airBindHide; | |
redac.airBindHide = function() { | |
- | |
self.updateIcon(); | |
- | |
redac.bufferAirBindHide(); | |
}; | |
@@ -1320,142 +1242,150 @@ console.log("color picker opened"); | |
updateIcon : function () { | |
var self = this; | |
self.setCurrentColors(); | |
- | |
if(self.current_bg){ | |
var color = tinycolor( self.current_bg ); | |
if( color.getAlpha() === 0 ){ | |
- this.redactor.$toolbar.find('.redactor_btn.redactor_btn_upfrontColor').css('border-color', color.toRgbString()); | |
+ this.redactor.$toolbar.find('.re-icon.re-upfrontColor').addClass('transparent').css('border-color', ""); | |
}else{ | |
- this.redactor.$toolbar.find('.redactor_btn.redactor_btn_upfrontColor').removeClass('transparent').css('border-color', color.toRgbString()); | |
+ this.redactor.$toolbar.find('.re-icon.re-upfrontColor').removeClass('transparent').css('border-color', color.toRgbString()); | |
} | |
} | |
else{ | |
- this.redactor.$toolbar.find('.redactor_btn.redactor_btn_upfrontColor').addClass('transparent').css('border-color', ''); | |
+ this.redactor.$toolbar.find('.re-icon.re-upfrontColor').addClass('transparent').css('border-color', ''); | |
} | |
if(self.current_color) | |
- this.redactor.$toolbar.find('.redactor_btn.redactor_btn_upfrontColor').css('color', self.current_color ); | |
+ this.redactor.$toolbar.find('.re-icon.re-upfrontColor').css('color', self.current_color ); | |
else | |
- this.redactor.$toolbar.find('.redactor_btn.redactor_btn_upfrontColor').css('color', ''); | |
+ this.redactor.$toolbar.find('.re-icon.re-upfrontColor').css('color', ''); | |
}, | |
updateColors : function() { | |
- var self = this; | |
+ | |
+ var self = this, | |
+ parent = this.redactor.getParent(), | |
+ bg = ""; | |
+ bg_class = "", | |
+ html = ""; | |
+ | |
+ /** | |
+ * Set background color | |
+ */ | |
+ if(self.current_bg && typeof(self.current_bg) == 'object') { | |
+ this.redactor.inlineRemoveStyle("background-color"); | |
+ bg = 'background-color:' + self.current_bg.toRgbString(); | |
+ bg_class = Upfront.Views.Theme_Colors.colors.get_css_class( self.current_bg.toHexString(), true ); | |
+ | |
+ if( bg_class ){ | |
+ bg = ""; | |
+ bg_class += " upfront_theme_colors"; | |
+ }else{ | |
+ bg_class = "inline_color"; | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * Set font color | |
+ */ | |
if(self.current_color && typeof(self.current_color) == 'object') { | |
var theme_color_classname = Upfront.Views.Theme_Colors.colors.get_css_class( self.current_color.toHexString() ); | |
if( theme_color_classname ){ | |
var current = this.redactor.getCurrent(); | |
if( !$(current).hasClass(theme_color_classname) ){ | |
- // remove inline color if any | |
- // this.redactor.inlineRemoveStyle("color"); | |
- | |
- // this.redactor.inlineRemoveStyle('color'); | |
- // this.redactor.inlineRemoveClass("inline_color"); | |
- var html = this.redactor.getSelectionHtml(); | |
- $(html).removeClass("inline_color upfront_theme_colors"); | |
- $(html).css("color", ""); | |
- $(html).children().removeClass("inline_color upfront_theme_colors"); | |
- $(html).children().css("color", ""); | |
- | |
- html = "<span class='upfront_theme_colors " + theme_color_classname + "'>" + html + "</span>"; | |
- if( $(this.redactor.getCurrent()).hasClass("upfront_theme_colors") ){ | |
- $(this.redactor.getCurrent()).replaceWith( html ); | |
- }else{ | |
- this.redactor.execCommand("inserthtml", html, true); | |
- } | |
+ | |
+ this.redactor.selectionRestore(true, true); | |
+ this.redactor.bufferSet(); | |
+ this.redactor.$editor.focus(); | |
+ this.redactor.inlineRemoveStyle("color"); | |
+ this.redactor.inlineRemoveClass( "upfront_theme_colors" ); | |
+ this.redactor.inlineRemoveClass( "inline_color" ); | |
+ html = this.redactor.cleanHtml(this.redactor.cleanRemoveEmptyTags(this.redactor.getSelectionHtml())); | |
+ | |
+ html = "<span class='upfront_theme_colors " + theme_color_classname + " " + bg_class + "' style='" + bg + "'>" + html + "</span>"; | |
+ //this.redactor.execCommand("inserthtml", html, true); | |
} | |
}else{ | |
- this.redactor.selectionRestore(true, false); | |
- // make sure it doesn't have any theme color classes | |
+ // Making sure it doesn't have any theme color classes | |
_.each(Upfront.Views.Theme_Colors.colors.get_all_classes(), function( cls ){ | |
self.redactor.inlineRemoveClass( cls ); | |
}); | |
- this.redactor.inlineRemoveClass( "upfront_theme_colors" ); | |
- this.redactor.inlineRemoveClass( "inline_color" ); | |
- var html = this.redactor.cleanHtml(this.redactor.cleanRemoveEmptyTags(this.redactor.getSelectionHtml())); | |
- | |
- $(html).removeClass("upfront_theme_colors"); | |
- $(html).removeClass("inline_color"); | |
- $(html).css("color", ""); | |
- $(html).children().removeClass("inline_color"); | |
- $(html).children().removeClass("upfront_theme_colors"); | |
- $(html).children().css("color", ""); | |
- // $(this.redactor.getCurrent()).removeClass("inline_color"); | |
- html = "<span class='inline_color' style='color: " + self.current_color.toRgbString() + "'>" + html + "</span>"; | |
- if( $(this.redactor.getCurrent()).hasClass("inline_color") ){ | |
- $(this.redactor.getCurrent()).replaceWith( html ); | |
- }else{ | |
- this.redactor.execCommand("inserthtml", html, true); | |
- // $(this.redactor.getCurrent()).replaceWith( html ); | |
- } | |
- | |
- // this.redactor.inlineSetStyle('color', self.current_color.toRgbString()); | |
- } | |
+ this.redactor.selectionRestore(true, true); | |
+ this.redactor.bufferSet(); | |
+ this.redactor.$editor.focus(); | |
+ this.redactor.inlineRemoveStyle("color"); | |
+ this.redactor.inlineRemoveClass( "upfront_theme_colors" ); | |
+ this.redactor.inlineRemoveClass( "inline_color" ); | |
+ html = this.redactor.cleanHtml(this.redactor.cleanRemoveEmptyTags(this.redactor.getSelectionHtml())); | |
+ html = "<inline class='inline_color' style='color: " + self.current_color.toRgbString() + ";" + bg +"'>" + html + "</inline>"; | |
+ | |
+ } | |
} | |
- if(self.current_bg && typeof(self.current_bg) == 'object') { | |
- this.redactor.selectionRestore(true, false); | |
- this.redactor.inlineRemoveStyle('background-color'); | |
- // if(self.current_bg.toRgbString().toLowerCase() != 'rgba(0, 0, 0, 0)') | |
- this.redactor.inlineSetStyle('background-color', self.current_bg.toRgbString()); | |
+ | |
+ if( html === "" ){ | |
+ html = this.redactor.cleanHtml(this.redactor.cleanRemoveEmptyTags(this.redactor.getSelectionHtml())); | |
+ html = "<inline class='" + bg_class + "' style='" + bg +"'>" + html + "</inline>"; | |
} | |
+ | |
+ this.redactor.execCommand("inserthtml", html, true); | |
+ | |
+ // Doing more cleanup | |
+ if( $.trim( $(parent).text() ).localeCompare( $.trim( $(html).text() ) ) === 0 && ( $(parent).hasClass("inline_color") || $(parent).hasClass("upfront_theme_colors") ) ){ | |
+ // $(parent).replaceWith( html ); | |
+ } | |
self.updateIcon(); | |
- self.redactor.selectionRemove(); | |
- self.redactor.sync(); | |
- | |
+ self.redactor.selectionRemoveMarkers(); | |
+ self.redactor.syncClean(); | |
} | |
- | |
}) | |
}; | |
RedactorPlugins.upfrontFormatting = { | |
- beforeInit: function(){ | |
- this.opts.buttonsCustom.upfrontFormatting = { | |
- title: 'Formatting', | |
- panel: this.panel | |
- }; | |
+ init: function(){ | |
+ var self = this, | |
+ buttons = {}, | |
+ tags = { | |
+ p: 'P', | |
+ h1: 'H1', | |
+ h2: 'H2', | |
+ h3: 'H3', | |
+ h4: 'H4', | |
+ h5: 'H5', | |
+ pre: '</>', | |
+ blockquote: '"' | |
+ }; | |
+ $.each( tags, function( id, tag ){ | |
+ buttons[id] = { title: tag, callback: self.applyTag }; | |
+ } ); | |
+ this.buttonAddFirst('upfrontFormatting', 'Formatting', false, buttons); | |
+ | |
+ UeditorEvents.on("ueditor:dropdownShow", function(){ | |
+ var tag = $(self.getElement()).length ? $(self.getElement())[0].tagName : false; | |
+ if( tag ){ | |
+ tag = tag.toLowerCase(); | |
+ $(".redactor_dropdown_box_upfrontFormatting a").removeClass("active"); | |
+ $(".redactor_dropdown_" + tag).addClass("active"); | |
+ } | |
+ }); | |
}, | |
- panel: UeditorPanel.extend({ | |
- tags: { | |
- p: 'P', | |
- h1: 'H1', | |
- h2: 'H2', | |
- h3: 'H3', | |
- h4: 'H4', | |
- h5: 'H5', | |
- pre: '</>', | |
- blockquote: '"' | |
- }, | |
- events: { | |
- 'click .ueditor-format-option': 'applyTag', | |
- 'open': 'selectionSave' | |
- }, | |
- render: function(){ | |
- var me = this, | |
- out = '' | |
- ; | |
- _.each(this.redactor.opts.formattingTags, function(tag){ | |
- out += '<a class="ueditor-format-option ueditor-format-' + tag + '" data-value="' + tag + '">' + me.tags[tag] + '</a>'; | |
- }); | |
+ applyTag: function(tag){ | |
+ this.selectionRestore(true, true); | |
+ this.bufferSet(); | |
+ this.$editor.focus(); | |
+ var text_align = $( this.getCurrent() ).css("text-align"); | |
- this.button.html('¶'); | |
- this.$el.html(out); | |
- }, | |
- applyTag: function(e){ | |
- var tag = $(e.target).data('value'); | |
- this.redactor.selectionRestore(); | |
- this.redactor.formatBlocks(tag); | |
- this.closePanel(); | |
- }, | |
- selectionSave: function(e){ | |
- this.redactor.selectionSave(); | |
- } | |
- }) | |
+ this.formatBlocks(tag); | |
+ | |
+ if( typeof text_align !== "undefined" ) | |
+ this.blockSetStyle( "text-align", text_align ); | |
+ | |
+ this.dropdownHideAll(); | |
+ } | |
}; | |
RedactorPlugins.blockquote = { | |
@@ -2298,7 +2228,7 @@ RedactorPlugins.upfrontPlaceholder = { | |
if (placeholder === '') placeholder = false; | |
if (placeholder !== false) | |
{ | |
- this.placeholderRemove(); | |
+ this.placeholderRemoveFromEditor(); | |
this.$placeholder = this.$editor.clone(false); | |
this.$placeholder.attr('contenteditable', false).removeClass('ueditable redactor_editor').addClass('ueditor-placeholder').html( this.opts.linebreaks ? placeholder : this.cleanParagraphy(placeholder) ); | |
this.$editor.after(this.$placeholder); | |
@@ -2332,13 +2262,13 @@ RedactorPlugins.upfrontPlaceholder = { | |
/*-------------------- | |
Font icons button | |
-----------------------*/ | |
-RedactorPlugins.icons = { | |
+RedactorPlugins.upftonIcons = { | |
+ $sel : false, | |
beforeInit: function(){ | |
- this.opts.buttonsCustom.icons = { | |
+ this.opts.buttonsCustom.upftonIcons = { | |
title: 'Icons', | |
panel: this.panel | |
}; | |
- | |
}, | |
init : function(){ | |
UeditorEvents.on("ueditor:key:down", function(redactor, e){ | |
@@ -2352,7 +2282,8 @@ RedactorPlugins.icons = { | |
panel: UeditorPanel.extend(_.extend({}, Upfront.Views.Mixins.Upfront_Scroll_Mixin, { | |
tpl: _.template($(tpl).find('#font-icons').html()), | |
events:{ | |
- 'click .ueditor-font-icon': 'select_icon', | |
+ 'click .ueditor-font-icon': 'insert_icon', | |
+ // "change input.font-icons-top" : 'update_offset', | |
'open': 'open', | |
'closed': 'close' | |
}, | |
@@ -2364,30 +2295,42 @@ RedactorPlugins.icons = { | |
this.redactor = redactor; | |
this.redactor.selectionRestore(); | |
this.redactor.selectionSave(); | |
- this.select_current_icon(); | |
+ this.set_current_icon(); | |
+ | |
this.$el.parent().css({ | |
left : 193 | |
}); | |
}, | |
close : function(){ | |
- this.redactor.selectionRemoveMarkers(); | |
+ if( this.redactor ){ | |
+ this.redactor.selectionRemoveMarkers(); | |
+ } | |
}, | |
- select_icon : function(e){ | |
- this.redactor.selectionRestore(true, false); | |
+ // update_offset : function( e ){ | |
+ // console.log(this.$sel); | |
+ // if( this.$sel && this.$sel.hasClass( "uf_font_icon" ) ){ | |
+ // window.$sel = this.$sel; | |
+ // this.$sel.css("top", parseFloat( $(e.target).val() ) + "px" ); | |
+ // this.redactor.selectionRestore(); | |
+ // this.redactor.sync(); | |
+ // } | |
+ // }, | |
+ insert_icon : function(e){ | |
+ this.redactor.selectionRestore(true, false); | |
var $icon = $( $(e.target).hasClass("ueditor-font-icon") ? $(e.target).html() : $(e.target).closest(".ueditor-font-icon").html() ), | |
- fontSize = this.$("#font-icons-size").val(), | |
- top = this.$("#font-icons-top").val(); | |
+ fontSize = this.$(".font-icons-size").val(), | |
+ top = this.$(".font-icons-top").val(); | |
$icon.css({ | |
"font-size" : fontSize + "px", | |
"top" : top + "px" | |
}); | |
this.redactor.execCommand("inserthtml", $icon[0].outerHTML , true); | |
- // $(this.redactor.getCurrent()).replaceWith( $icon ); | |
this.redactor.sync(); | |
this.closePanel(); | |
}, | |
- select_current_icon : function(){ | |
+ set_current_icon : function(){ | |
this.redactor.selectionRestore(true, false); | |
+ window.re = this.redactor; | |
var $sel = $(this.redactor.getParent()).eq(0), | |
self = this; | |
@@ -2395,25 +2338,26 @@ RedactorPlugins.icons = { | |
if( $sel.parent().hasClass("uf_font_icon") ) {$sel = $sel.parent()}; | |
} | |
if( $sel.hasClass("uf_font_icon") ){ | |
- this.$("#font-icons-size").val( parseFloat( $sel.css("font-size") ) ); | |
- this.$("#font-icons-top").val( parseFloat( $sel.css("top") ) ); | |
+ this.$(".font-icons-size").val( parseFloat( $sel.css("font-size") ) ); | |
+ this.$(".font-icons-top").val( parseFloat( $sel.css("top") ) ); | |
this.$(".upfront-font-icons-controlls input").on("change", function(e){ | |
e.stopPropagation(); | |
e.preventDefault(); | |
+ self.redactor.selectionSave(); | |
+ self.redactor.bufferSet(); | |
var val = $(this).val() + "px"; | |
- | |
- if( this.id === "font-icons-size" ){ | |
+ | |
+ if( $(this).hasClass("font-icons-size") ){ | |
$sel.css("font-size", val); | |
} | |
- if( this.id === "font-icons-top" ){ | |
+ if( $(this).hasClass( "font-icons-top" ) ){ | |
$sel.css("top", val); | |
} | |
self.redactor.sync(); | |
self.redactor.selectionRestore(); | |
- // self.redactor.execCommand("inserthtml", $sel[0].outerHTML , true); | |
}); | |
diff --git a/scripts/upfront/upfront-views-editor.js b/scripts/upfront/upfront-views-editor.js | |
index 99398eb..ffbd804 100644 | |
--- a/scripts/upfront/upfront-views-editor.js | |
+++ b/scripts/upfront/upfront-views-editor.js | |
@@ -1763,28 +1763,30 @@ define([ | |
color = this.color_to_hex( color ); | |
return _.indexOf(this.get_colors(), color) !== -1 | |
}, | |
- get_css_class : function(color){ | |
+ get_css_class : function(color, bg){ | |
color = this.color_to_hex( color ); | |
+ var prefix = _.isUndefined( bg ) || bg === false ? "upfront_theme_color_" : "upfront_theme_bg_color_"; | |
if( this.is_theme_color(color) ){ | |
var model = this.findWhere({ | |
color : color | |
}); | |
if( model ){ | |
var index = this.indexOf( model ); | |
- return "upfront_theme_color_" + index; | |
+ return prefix + index; | |
} | |
} | |
return false | |
}, | |
- get_all_classes : function(){ | |
+ get_all_classes : function( bg ){ | |
+ var prefix = _.isUndefined( bg ) || bg === false ? "upfront_theme_color_" : "upfront_theme_bg_color_"; | |
var classes = []; | |
_.each( this.get_colors(), function(item, index){ | |
- classes.push("upfront_theme_color_" + index); | |
+ classes.push(prefix + index); | |
}); | |
return classes; | |
}, | |
- remove_theme_color_classes : function( $el ){ | |
- _.each(this.get_all_classes(), function(cls){ | |
+ remove_theme_color_classes : function( $el, bg ){ | |
+ _.each(this.get_all_classes( bg ), function(cls){ | |
$el.removeClass(cls); | |
}); | |
}, | |
@@ -1855,6 +1857,9 @@ define([ | |
self.styles += " .upfront_theme_color_" + index +"{ color: " + item.get("color") + ";}"; | |
self.styles += " a .upfront_theme_color_" + index +":hover{ color: " + item.get_hover_color() + ";}"; | |
self.styles += " button .upfront_theme_color_" + index +":hover{ color: " + item.get_hover_color() + ";}"; | |
+ self.styles += " .upfront_theme_bg_color_" + index +"{ background-color: " + item.get("color") + ";}"; | |
+ self.styles += " a .upfront_theme_bg_color_" + index +":hover{ background-color: " + item.get_hover_color() + ";}"; | |
+ self.styles += " button .upfront_theme_bg_color_" + index +":hover{ background-color: " + item.get_hover_color() + ";}"; | |
}); | |
$("#upfront_theme_colors_dom_styles").remove(); | |
$("<style id='upfront_theme_colors_dom_styles' type='text/css'>" + this.styles + "</style>").appendTo("body"); | |
@@ -3731,7 +3736,7 @@ define([ | |
blank_alpha : 1 | |
}, | |
spectrumDefaults: { | |
- clickoutFiresChange: true, | |
+ clickoutFiresChange: false, | |
chooseText: 'OK', | |
showSelectionPalette: true, | |
showAlpha: true, | |
diff --git a/styles/editor-interface.css b/styles/editor-interface.css | |
index 4f11f20..ac0f070 100644 | |
--- a/styles/editor-interface.css | |
+++ b/styles/editor-interface.css | |
@@ -1067,7 +1067,7 @@ span.draggable-post-element.element-dragging | |
#upfront-general-csseditor .ace_scrollbar::-webkit-scrollbar, | |
.upfront_code-editor-complex-wrapper .ace_scrollbar-inner::-webkit-scrollbar, | |
.upfront_code-editor-complex-wrapper .ace_scrollbar::-webkit-scrollbar, | |
-.redactor_dropdown_box_icons div.icons::-webkit-scrollbar | |
+.redactor_dropdown_box_upftonIcons div.icons::-webkit-scrollbar | |
{ | |
background: none; | |
width: 5px; | |
@@ -1112,7 +1112,7 @@ span.draggable-post-element.element-dragging | |
#upfront-general-csseditor .ace_scrollbar::-webkit-scrollbar-thumb, | |
.upfront_code-editor-complex-wrapper .ace_scrollbar-inner::-webkit-scrollbar-thumb, | |
.upfront_code-editor-complex-wrapper .ace_scrollbar::-webkit-scrollbar-thumb, | |
-.redactor_dropdown_box_icons div.icons::-webkit-scrollbar-thumb | |
+.redactor_dropdown_box_upftonIcons div.icons::-webkit-scrollbar-thumb | |
{ | |
border-right: 5px solid #1fcd8f; | |
} | |
@@ -9312,10 +9312,10 @@ only screen and ( min-resolution: 2dppx) { | |
*/ | |
body .redactor_toolbar li a.redactor_btn_html { background-position: 0px; } | |
body .redactor_toolbar li a.redactor_btn_formatting { background-position: -25px; } | |
-body .redactor_toolbar li a.redactor_btn_bold { background-position: -510px -41px; } | |
-body .redactor_toolbar li a.redactor_btn_bold.redactor_act { background-position: -552px -41px; } | |
-body .redactor_toolbar li a.redactor_btn_italic { background-position: -594px -42px; } | |
-body .redactor_toolbar li a.redactor_btn_italic.redactor_act { background-position: -636px -42px } | |
+body .redactor_toolbar li a.re-bold { background-position: -510px -41px; } | |
+body .redactor_toolbar li a.re-bold.redactor_act { background-position: -552px -41px; } | |
+body .redactor_toolbar li a.re-italic { background-position: -594px -42px; } | |
+body .redactor_toolbar li a.re-italic.redactor_act { background-position: -636px -42px } | |
body .redactor_toolbar li a.redactor_btn_deleted { background-position: -500px; } | |
body .redactor_toolbar li a.redactor_btn_unorderedlist { background-position: -100px; } | |
body .redactor_toolbar li a.redactor_btn_orderedlist { background-position: -125px; } | |
@@ -9361,8 +9361,8 @@ body .redactor_toolbar li a.redactor_btn_quote.redactor_act { background-positio | |
body .redactor_toolbar li a.ueditor-quote-alternative { background-position: -594px -208px; } | |
body .redactor_toolbar li a.redactor_btn_pre { background-position: -875px; } | |
-body .redactor_toolbar li a.redactor_btn_icons { background-position: -593px -252px; } | |
-body .redactor_toolbar li a.redactor_btn_icons:hover { background-position: -635px -252px; } | |
+body .redactor_toolbar li a.re-upftonIcons { background-position: -593px -252px; } | |
+body .redactor_toolbar li a.re-upftonIcons:hover { background-position: -635px -252px; } | |
ul.redactor_toolbar li a.ueditor-justify { | |
@@ -9381,7 +9381,7 @@ ul.redactor_toolbar li a.ueditor-right { | |
background-position: -594px -82px; | |
} | |
-ul.redactor_toolbar li a.ueditor-nolist { | |
+ul.redactor_toolbar li a.re-stateLists{ | |
background-position: -510px -124px; | |
} | |
@@ -9393,7 +9393,7 @@ ul.redactor_toolbar li a.ueditor-unorderedlist { | |
background-position: -552px -124px; | |
} | |
-ul.redactor_toolbar li a.redactor_btn_upfrontLink, ul.redactor_toolbar li a.redactor_btn_upfrontLinkCTA{ | |
+ul.redactor_toolbar li a.re-upfrontLink{ | |
background-position: -510px -167px; | |
} | |
@@ -9404,7 +9404,7 @@ ul.redactor_toolbar.ueditor-sink-open li a.redactor_btn_upfrontSink{ | |
background-position: -636px -167px; | |
} | |
-body .redactor_toolbar li a.redactor_btn_upfrontLink.redactor_act { background-position: -552px -167px; } | |
+body .redactor_toolbar li a.re-upfrontLink.redactor_act { background-position: -552px -167px; } | |
/* | |
Toolbar classes | |
@@ -9511,20 +9511,24 @@ body .redactor_toolbar li a.redactor_btn_upfrontLink.redactor_act { background-p | |
padding: 0; | |
} | |
*/ | |
-a.ueditor-format-option { | |
+.redactor_dropdown_box_upfrontFormatting a { | |
color: #97b8da !important; | |
width: 38px; | |
line-height: 30px; | |
padding: 2px 0; | |
display: block; | |
+ z-index: 99999; | |
+ margin-top: 0; | |
+} | |
+.redactor_dropdown_box_upfrontFormatting a.active{ | |
+ color: #40a6ff !important; | |
} | |
- | |
a.ueditor-format-pre{ | |
font-size: 15px; | |
font-weight: bold; | |
} | |
-.redactor_toolbar li a.redactor_btn_upfrontFormatting { | |
+.redactor_toolbar li a.re-upfrontFormatting { | |
text-indent: 0; | |
font-family: Georgia, serif; | |
color: #97b8da; | |
@@ -9532,7 +9536,9 @@ a.ueditor-format-pre{ | |
line-height: 36px; | |
text-align: center; | |
} | |
- | |
+.redactor_toolbar li a.re-upfrontFormatting:after{ | |
+ content : "¶"; | |
+} | |
/* MODAL */ | |
/* 300 lines deleted here, not using modals */ | |
@@ -9749,8 +9755,8 @@ li#tabbackground-content .sp-palette-row-selection span.sp-thumb-el:last-child > | |
width:auto; | |
background-color: transparent; | |
box-shadow: none; | |
- top: -164px !important; | |
- left: -30px !important; | |
+ /*top: -164px !important;*/ | |
+ /*left: -30px !important;*/ | |
font-family: Verdana, sans-serif!important; | |
} | |
.redactor_air.under .redactor_dropdown_box_upfrontColor{ | |
@@ -10021,7 +10027,7 @@ border:none; | |
} | |
div.sp-val:active .sp-dragger:after { display:block;} | |
-.redactor_btn.redactor_btn_upfrontColor { | |
+.re-icon.re-upfrontColor { | |
text-indent: 0; | |
position:relative; | |
border-radius: 3px; | |
@@ -10033,7 +10039,7 @@ div.sp-val:active .sp-dragger:after { display:block;} | |
/*box-shadow: 0 3px 0 rgba(0,0,0,0.1);*/ | |
} | |
-.redactor_btn.redactor_btn_upfrontColor:after { | |
+.re-icon.re-upfrontColor:after { | |
content: 'T'; | |
color: inherit; | |
display: block; | |
@@ -10052,7 +10058,7 @@ div.sp-val:active .sp-dragger:after { display:block;} | |
} | |
-.redactor_btn.redactor_btn_upfrontColor.transparent:after { | |
+.re-icon.re-upfrontColor.transparent:after { | |
border: none; | |
height: 24px; | |
width: 24px; | |
@@ -11038,7 +11044,7 @@ li#new-custom-breakpoint { | |
margin: 10px 0 10px 15px; | |
} | |
/*------------ Font Icons --------------*/ | |
-.redactor_dropdown_box_icons div.icons{ | |
+.redactor_dropdown_box_upftonIcons div.icons{ | |
font-size: 24px; | |
height: 140px; | |
overflow-x: hidden; | |
@@ -11046,22 +11052,22 @@ li#new-custom-breakpoint { | |
padding: 7px; | |
margin-right: 1px; | |
} | |
-.redactor_dropdown.redactor_dropdown_box_icons{ | |
+.redactor_dropdown.redactor_dropdown_box_upftonIcons{ | |
min-width: 153px; | |
width: 153px; | |
line-height: 38px; | |
padding: 0; | |
opacity: 0.9; | |
} | |
-.redactor_dropdown.redactor_dropdown_box_icons a, | |
-.redactor_dropdown.redactor_dropdown_box_icons a:link{ | |
+.redactor_dropdown.redactor_dropdown_box_upftonIcons a, | |
+.redactor_dropdown.redactor_dropdown_box_upftonIcons a:link{ | |
color: #97b8da !important; | |
text-decoration: none; | |
display: inline-block; | |
width: 28px; | |
text-align: center; | |
} | |
-.redactor_dropdown.redactor_dropdown_box_icons a:hover{ | |
+.redactor_dropdown.redactor_dropdown_box_upftonIcons a:hover{ | |
color: rgb(64, 166, 255) !important; | |
} | |
.upfront-font-icons-controlls{ | |
@@ -12372,3 +12378,4 @@ div.upfront-region.empty_in_theme_mode:not(.upfront-region-floating):not(.upfron | |
.upfront-region-bg-setting-add-global-region { | |
margin-bottom: 20px; | |
} | |
+>>>>>>> eea43a57793d2b674014aac2b20fc534316c3fc9 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment