tinymce-rails 4.6.5 → 4.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +2057 -1442
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/autolink/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/autosave/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/lists/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/searchreplace/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/table/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/wordcount/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/skins/lightgray/content.inline.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/lightgray/content.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/skins/lightgray/skin.min.css +1 -1
- data/vendor/assets/javascripts/tinymce/tinymce.js +15 -15
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49d5f0a86536177dcfbc5465afb56ddb6df157c8
|
4
|
+
data.tar.gz: 9b797b95e097bff16ee21253aed00aa09cfccae5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d618cda5d83110cd3c856a62e7de9a9267905a07a2ea6c9c774b9d1b637962efa28b1bf3b4db15e01a8e3bde6f6fdd695f2c4fc6db85c9a528125301ff59f509
|
7
|
+
data.tar.gz: 65d5aee2bf6f78780111c48b468085ea8104253d9deca61cdd83a38a1cd60fcec60fb7f6b6227187b589286642b52780d5b0ac66f84bde5cefb7953802d87d90
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// 4.6.
|
1
|
+
// 4.6.6 (2017-08-30)
|
2
2
|
(function () {
|
3
3
|
|
4
4
|
var defs = {}; // id -> {dependencies, definition, instance (possibly undefined)}
|
@@ -82,7 +82,7 @@ var defineGlobal = function (id, ref) {
|
|
82
82
|
define(id, [], function () { return ref; });
|
83
83
|
};
|
84
84
|
/*jsc
|
85
|
-
["tinymce.core.api.Main","ephox.katamari.api.Fun","tinymce.core.api.Tinymce","global!Array","global!Error","tinymce.core.api.Formatter","tinymce.core.geom.Rect","tinymce.core.util.Promise","tinymce.core.util.Delay","tinymce.core.Env","tinymce.core.dom.EventUtils","tinymce.core.dom.Sizzle","tinymce.core.util.Tools","tinymce.core.dom.DomQuery","tinymce.core.html.Styles","tinymce.core.dom.TreeWalker","tinymce.core.html.Entities","tinymce.core.dom.DOMUtils","tinymce.core.dom.ScriptLoader","tinymce.core.AddOnManager","tinymce.core.dom.RangeUtils","tinymce.core.html.Node","tinymce.core.html.Schema","tinymce.core.html.SaxParser","tinymce.core.html.DomParser","tinymce.core.html.Writer","tinymce.core.html.Serializer","tinymce.core.dom.Serializer","tinymce.core.util.VK","tinymce.core.dom.ControlSelection","tinymce.core.dom.BookmarkManager","tinymce.core.dom.Selection","tinymce.core.UndoManager","tinymce.core.EditorCommands","tinymce.core.util.URI","tinymce.core.util.Class","tinymce.core.util.EventDispatcher","tinymce.core.util.Observable","tinymce.core.WindowManager","tinymce.core.NotificationManager","tinymce.core.EditorObservable","tinymce.core.Shortcuts","tinymce.core.Editor","tinymce.core.util.I18n","tinymce.core.FocusManager","tinymce.core.EditorManager","tinymce.core.util.XHR","tinymce.core.util.JSON","tinymce.core.util.JSONRequest","tinymce.core.util.JSONP","tinymce.core.util.LocalStorage","tinymce.core.util.Color","tinymce.core.ui.Api","ephox.katamari.api.Cell","tinymce.core.fmt.ApplyFormat","tinymce.core.fmt.FormatChanged","tinymce.core.fmt.FormatRegistry","tinymce.core.fmt.MatchFormat","tinymce.core.fmt.Preview","tinymce.core.fmt.RemoveFormat","tinymce.core.fmt.ToggleFormat","tinymce.core.keyboard.FormatShortcuts","tinymce.core.util.Arr","tinymce.core.dom.Range","tinymce.core.dom.StyleSheetLoader","tinymce.core.dom.NodeType","tinymce.core.caret.CaretContainer","tinymce.core.text.Zwsp","ephox.sugar.api.node.Element","ephox.sugar.api.search.Selectors","tinymce.core.dom.RangePoint","tinymce.core.caret.CaretBookmark","tinymce.core.caret.CaretPosition","ephox.sugar.api.dom.Compare","tinymce.core.dom.ScrollIntoView","tinymce.core.dom.TridentSelection","tinymce.core.selection.FragmentReader","tinymce.core.undo.Levels","tinymce.core.delete.DeleteCommands","tinymce.core.InsertContent","global!document","tinymce.core.ui.Window","tinymce.core.ui.MessageBox","tinymce.core.ui.Notification","tinymce.core.EditorSettings","tinymce.core.init.Render","tinymce.core.Mode","tinymce.core.ui.Sidebar","tinymce.core.util.Uuid","tinymce.core.ErrorReporter","tinymce.core.LegacyInput","tinymce.core.ui.Selector","tinymce.core.ui.Collection","tinymce.core.ui.ReflowQueue","tinymce.core.ui.Control","tinymce.core.ui.Factory","tinymce.core.ui.KeyboardNavigation","tinymce.core.ui.Container","tinymce.core.ui.DragHelper","tinymce.core.ui.Scrollable","tinymce.core.ui.Panel","tinymce.core.ui.Movable","tinymce.core.ui.Resizable","tinymce.core.ui.FloatPanel","tinymce.core.ui.Tooltip","tinymce.core.ui.Widget","tinymce.core.ui.Progress","tinymce.core.ui.Layout","tinymce.core.ui.AbsoluteLayout","tinymce.core.ui.Button","tinymce.core.ui.ButtonGroup","tinymce.core.ui.Checkbox","tinymce.core.ui.ComboBox","tinymce.core.ui.ColorBox","tinymce.core.ui.PanelButton","tinymce.core.ui.ColorButton","tinymce.core.ui.ColorPicker","tinymce.core.ui.Path","tinymce.core.ui.ElementPath","tinymce.core.ui.FormItem","tinymce.core.ui.Form","tinymce.core.ui.FieldSet","tinymce.core.ui.FilePicker","tinymce.core.ui.FitLayout","tinymce.core.ui.FlexLayout","tinymce.core.ui.FlowLayout","tinymce.core.ui.FormatControls","tinymce.core.ui.GridLayout","tinymce.core.ui.Iframe","tinymce.core.ui.InfoBox","tinymce.core.ui.Label","tinymce.core.ui.Toolbar","tinymce.core.ui.MenuBar","tinymce.core.ui.MenuButton","tinymce.core.ui.MenuItem","tinymce.core.ui.Throbber","tinymce.core.ui.Menu","tinymce.core.ui.ListBox","tinymce.core.ui.Radio","tinymce.core.ui.ResizeHandle","tinymce.core.ui.SelectBox","tinymce.core.ui.Slider","tinymce.core.ui.Spacer","tinymce.core.ui.SplitButton","tinymce.core.ui.StackLayout","tinymce.core.ui.TabPanel","tinymce.core.ui.TextBox","tinymce.core.ui.DropZone","tinymce.core.ui.BrowseButton","ephox.katamari.api.
|
85
|
+
["tinymce.core.api.Main","ephox.katamari.api.Fun","tinymce.core.api.Tinymce","global!Array","global!Error","tinymce.core.api.Formatter","tinymce.core.geom.Rect","tinymce.core.util.Promise","tinymce.core.util.Delay","tinymce.core.Env","tinymce.core.dom.EventUtils","tinymce.core.dom.Sizzle","tinymce.core.util.Tools","tinymce.core.dom.DomQuery","tinymce.core.html.Styles","tinymce.core.dom.TreeWalker","tinymce.core.html.Entities","tinymce.core.dom.DOMUtils","tinymce.core.dom.ScriptLoader","tinymce.core.AddOnManager","tinymce.core.dom.RangeUtils","tinymce.core.html.Node","tinymce.core.html.Schema","tinymce.core.html.SaxParser","tinymce.core.html.DomParser","tinymce.core.html.Writer","tinymce.core.html.Serializer","tinymce.core.dom.Serializer","tinymce.core.util.VK","tinymce.core.dom.ControlSelection","tinymce.core.dom.BookmarkManager","tinymce.core.dom.Selection","tinymce.core.UndoManager","tinymce.core.EditorCommands","tinymce.core.util.URI","tinymce.core.util.Class","tinymce.core.util.EventDispatcher","tinymce.core.util.Observable","tinymce.core.WindowManager","tinymce.core.NotificationManager","tinymce.core.EditorObservable","tinymce.core.Shortcuts","tinymce.core.Editor","tinymce.core.util.I18n","tinymce.core.FocusManager","tinymce.core.EditorManager","tinymce.core.util.XHR","tinymce.core.util.JSON","tinymce.core.util.JSONRequest","tinymce.core.util.JSONP","tinymce.core.util.LocalStorage","tinymce.core.util.Color","tinymce.core.ui.Api","ephox.katamari.api.Cell","tinymce.core.fmt.ApplyFormat","tinymce.core.fmt.FormatChanged","tinymce.core.fmt.FormatRegistry","tinymce.core.fmt.MatchFormat","tinymce.core.fmt.Preview","tinymce.core.fmt.RemoveFormat","tinymce.core.fmt.ToggleFormat","tinymce.core.keyboard.FormatShortcuts","tinymce.core.util.Arr","tinymce.core.dom.Range","tinymce.core.dom.StyleSheetLoader","tinymce.core.dom.NodeType","tinymce.core.caret.CaretContainer","tinymce.core.text.Zwsp","ephox.sugar.api.node.Element","ephox.sugar.api.search.Selectors","tinymce.core.dom.RangePoint","tinymce.core.caret.CaretBookmark","tinymce.core.caret.CaretPosition","ephox.sugar.api.dom.Compare","tinymce.core.dom.ScrollIntoView","tinymce.core.dom.TridentSelection","tinymce.core.selection.FragmentReader","tinymce.core.undo.Levels","tinymce.core.delete.DeleteCommands","tinymce.core.InsertContent","global!document","tinymce.core.ui.Window","tinymce.core.ui.MessageBox","tinymce.core.EditorView","tinymce.core.ui.DomUtils","tinymce.core.ui.Notification","tinymce.core.EditorSettings","tinymce.core.init.Render","tinymce.core.Mode","tinymce.core.ui.Sidebar","tinymce.core.util.Uuid","ephox.katamari.api.Arr","ephox.katamari.api.Type","tinymce.core.ErrorReporter","tinymce.core.LegacyInput","tinymce.core.ui.Selector","tinymce.core.ui.Collection","tinymce.core.ui.ReflowQueue","tinymce.core.ui.Control","tinymce.core.ui.Factory","tinymce.core.ui.KeyboardNavigation","tinymce.core.ui.Container","tinymce.core.ui.DragHelper","tinymce.core.ui.Scrollable","tinymce.core.ui.Panel","tinymce.core.ui.Movable","tinymce.core.ui.Resizable","tinymce.core.ui.FloatPanel","tinymce.core.ui.Tooltip","tinymce.core.ui.Widget","tinymce.core.ui.Progress","tinymce.core.ui.Layout","tinymce.core.ui.AbsoluteLayout","tinymce.core.ui.Button","tinymce.core.ui.ButtonGroup","tinymce.core.ui.Checkbox","tinymce.core.ui.ComboBox","tinymce.core.ui.ColorBox","tinymce.core.ui.PanelButton","tinymce.core.ui.ColorButton","tinymce.core.ui.ColorPicker","tinymce.core.ui.Path","tinymce.core.ui.ElementPath","tinymce.core.ui.FormItem","tinymce.core.ui.Form","tinymce.core.ui.FieldSet","tinymce.core.ui.FilePicker","tinymce.core.ui.FitLayout","tinymce.core.ui.FlexLayout","tinymce.core.ui.FlowLayout","tinymce.core.ui.FormatControls","tinymce.core.ui.GridLayout","tinymce.core.ui.Iframe","tinymce.core.ui.InfoBox","tinymce.core.ui.Label","tinymce.core.ui.Toolbar","tinymce.core.ui.MenuBar","tinymce.core.ui.MenuButton","tinymce.core.ui.MenuItem","tinymce.core.ui.Throbber","tinymce.core.ui.Menu","tinymce.core.ui.ListBox","tinymce.core.ui.Radio","tinymce.core.ui.ResizeHandle","tinymce.core.ui.SelectBox","tinymce.core.ui.Slider","tinymce.core.ui.Spacer","tinymce.core.ui.SplitButton","tinymce.core.ui.StackLayout","tinymce.core.ui.TabPanel","tinymce.core.ui.TextBox","tinymce.core.ui.DropZone","tinymce.core.ui.BrowseButton","ephox.katamari.api.Option","global!String","ephox.katamari.api.Future","ephox.katamari.api.Futures","ephox.katamari.api.Result","tinymce.core.util.Fun","tinymce.core.caret.CaretCandidate","tinymce.core.geom.ClientRect","tinymce.core.text.ExtendingChar","tinymce.core.dom.RangeNormalizer","tinymce.core.fmt.CaretFormat","tinymce.core.fmt.ExpandRange","tinymce.core.fmt.FormatUtils","tinymce.core.fmt.Hooks","tinymce.core.fmt.MergeFormats","tinymce.core.fmt.DefaultFormats","global!console","ephox.sugar.api.node.NodeTypes","ephox.sand.api.Node","ephox.sand.api.PlatformDetection","ephox.sugar.api.dom.Insert","ephox.sugar.api.dom.Replication","ephox.sugar.api.node.Fragment","ephox.sugar.api.node.Node","ephox.sugar.api.search.SelectorFilter","ephox.sugar.api.search.SelectorFind","tinymce.core.dom.ElementType","tinymce.core.dom.Parents","tinymce.core.selection.SelectionUtils","tinymce.core.selection.SimpleTableModel","tinymce.core.undo.Fragments","tinymce.core.delete.BlockBoundaryDelete","tinymce.core.delete.BlockRangeDelete","tinymce.core.delete.CefDelete","tinymce.core.delete.DeleteUtils","tinymce.core.delete.InlineBoundaryDelete","tinymce.core.delete.TableDelete","tinymce.core.caret.CaretWalker","tinymce.core.dom.ElementUtils","tinymce.core.InsertList","tinymce.core.data.ObservableObject","tinymce.core.ui.BoxUtils","tinymce.core.ui.ClassList","ephox.sugar.api.properties.Css","ephox.sugar.api.search.Traverse","ephox.katamari.api.Obj","ephox.katamari.api.Strings","ephox.katamari.api.Struct","global!window","tinymce.core.init.Init","tinymce.core.PluginManager","tinymce.core.ThemeManager","tinymce.core.content.LinkTargets","tinymce.core.fmt.FontInfo","global!RegExp","global!Object","ephox.katamari.api.LazyValue","ephox.katamari.async.Bounce","ephox.katamari.async.AsyncValues","tinymce.core.caret.CaretFinder","tinymce.core.caret.CaretUtils","tinymce.core.dom.PaddingBr","ephox.sand.util.Global","ephox.katamari.api.Thunk","ephox.sand.core.PlatformDetection","global!navigator","ephox.katamari.data.Immutable","ephox.katamari.data.MixedBag","ephox.sugar.alien.Recurse","ephox.sugar.api.properties.Attr","ephox.sugar.api.dom.InsertAll","ephox.sugar.api.dom.Remove","ephox.sugar.api.search.PredicateFilter","ephox.sugar.api.search.PredicateFind","ephox.sugar.impl.ClosestOrAncestor","ephox.katamari.api.Options","tinymce.core.undo.Diff","tinymce.core.delete.BlockBoundary","tinymce.core.delete.MergeBlocks","tinymce.core.delete.CefDeleteAction","tinymce.core.delete.DeleteElement","tinymce.core.keyboard.BoundaryCaret","tinymce.core.keyboard.BoundaryLocation","tinymce.core.keyboard.BoundarySelection","tinymce.core.keyboard.InlineUtils","ephox.katamari.api.Adt","tinymce.core.delete.TableDeleteAction","tinymce.core.data.Binding","ephox.sugar.api.node.Body","ephox.sugar.impl.Style","ephox.katamari.str.StrAppend","ephox.katamari.str.StringParts","tinymce.core.init.InitContentBody","global!setTimeout","ephox.katamari.util.BagUtils","ephox.katamari.api.Resolve","ephox.sand.core.Browser","ephox.sand.core.OperatingSystem","ephox.sand.detect.DeviceType","ephox.sand.detect.UaString","ephox.sand.info.PlatformInfo","tinymce.core.dom.Empty","tinymce.core.caret.CaretContainerInline","tinymce.core.caret.CaretContainerRemove","tinymce.core.text.Bidi","tinymce.core.util.LazyEvaluator","tinymce.core.caret.CaretContainerInput","tinymce.core.EditorUpload","tinymce.core.ForceBlocks","tinymce.core.keyboard.KeyboardOverrides","tinymce.core.NodeChange","tinymce.core.SelectionOverrides","tinymce.core.util.Quirks","ephox.katamari.api.Global","ephox.sand.detect.Version","ephox.sugar.api.search.SelectorExists","tinymce.core.file.Uploader","tinymce.core.file.ImageScanner","tinymce.core.file.BlobCache","tinymce.core.file.UploadStatus","tinymce.core.keyboard.ArrowKeys","tinymce.core.keyboard.DeleteBackspaceKeys","tinymce.core.keyboard.EnterKey","tinymce.core.keyboard.SpaceKey","tinymce.core.caret.FakeCaret","tinymce.core.caret.LineUtils","tinymce.core.DragDropOverrides","tinymce.core.keyboard.CefUtils","tinymce.core.dom.NodePath","global!Number","tinymce.core.file.Conversions","ephox.sand.api.URL","tinymce.core.keyboard.CefNavigation","tinymce.core.keyboard.MatchKeys","tinymce.core.keyboard.InsertNewLine","tinymce.core.keyboard.InsertSpace","tinymce.core.dom.Dimensions","tinymce.core.dom.MousePosition","ephox.sand.api.Window","tinymce.core.caret.LineWalker","ephox.katamari.api.Merger"]
|
86
86
|
jsc*/
|
87
87
|
defineGlobal("global!Array", Array);
|
88
88
|
defineGlobal("global!Error", Error);
|
@@ -13866,129 +13866,6 @@ define(
|
|
13866
13866
|
return BookmarkManager;
|
13867
13867
|
}
|
13868
13868
|
);
|
13869
|
-
/**
|
13870
|
-
* ElementUtils.js
|
13871
|
-
*
|
13872
|
-
* Released under LGPL License.
|
13873
|
-
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
13874
|
-
*
|
13875
|
-
* License: http://www.tinymce.com/license
|
13876
|
-
* Contributing: http://www.tinymce.com/contributing
|
13877
|
-
*/
|
13878
|
-
|
13879
|
-
/**
|
13880
|
-
* Utility class for various element specific functions.
|
13881
|
-
*
|
13882
|
-
* @private
|
13883
|
-
* @class tinymce.dom.ElementUtils
|
13884
|
-
*/
|
13885
|
-
define(
|
13886
|
-
'tinymce.core.dom.ElementUtils',
|
13887
|
-
[
|
13888
|
-
"tinymce.core.dom.BookmarkManager",
|
13889
|
-
"tinymce.core.util.Tools"
|
13890
|
-
],
|
13891
|
-
function (BookmarkManager, Tools) {
|
13892
|
-
var each = Tools.each;
|
13893
|
-
|
13894
|
-
function ElementUtils(dom) {
|
13895
|
-
/**
|
13896
|
-
* Compares two nodes and checks if it's attributes and styles matches.
|
13897
|
-
* This doesn't compare classes as items since their order is significant.
|
13898
|
-
*
|
13899
|
-
* @method compare
|
13900
|
-
* @param {Node} node1 First node to compare with.
|
13901
|
-
* @param {Node} node2 Second node to compare with.
|
13902
|
-
* @return {boolean} True/false if the nodes are the same or not.
|
13903
|
-
*/
|
13904
|
-
this.compare = function (node1, node2) {
|
13905
|
-
// Not the same name
|
13906
|
-
if (node1.nodeName != node2.nodeName) {
|
13907
|
-
return false;
|
13908
|
-
}
|
13909
|
-
|
13910
|
-
/**
|
13911
|
-
* Returns all the nodes attributes excluding internal ones, styles and classes.
|
13912
|
-
*
|
13913
|
-
* @private
|
13914
|
-
* @param {Node} node Node to get attributes from.
|
13915
|
-
* @return {Object} Name/value object with attributes and attribute values.
|
13916
|
-
*/
|
13917
|
-
function getAttribs(node) {
|
13918
|
-
var attribs = {};
|
13919
|
-
|
13920
|
-
each(dom.getAttribs(node), function (attr) {
|
13921
|
-
var name = attr.nodeName.toLowerCase();
|
13922
|
-
|
13923
|
-
// Don't compare internal attributes or style
|
13924
|
-
if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {
|
13925
|
-
attribs[name] = dom.getAttrib(node, name);
|
13926
|
-
}
|
13927
|
-
});
|
13928
|
-
|
13929
|
-
return attribs;
|
13930
|
-
}
|
13931
|
-
|
13932
|
-
/**
|
13933
|
-
* Compares two objects checks if it's key + value exists in the other one.
|
13934
|
-
*
|
13935
|
-
* @private
|
13936
|
-
* @param {Object} obj1 First object to compare.
|
13937
|
-
* @param {Object} obj2 Second object to compare.
|
13938
|
-
* @return {boolean} True/false if the objects matches or not.
|
13939
|
-
*/
|
13940
|
-
function compareObjects(obj1, obj2) {
|
13941
|
-
var value, name;
|
13942
|
-
|
13943
|
-
for (name in obj1) {
|
13944
|
-
// Obj1 has item obj2 doesn't have
|
13945
|
-
if (obj1.hasOwnProperty(name)) {
|
13946
|
-
value = obj2[name];
|
13947
|
-
|
13948
|
-
// Obj2 doesn't have obj1 item
|
13949
|
-
if (typeof value == "undefined") {
|
13950
|
-
return false;
|
13951
|
-
}
|
13952
|
-
|
13953
|
-
// Obj2 item has a different value
|
13954
|
-
if (obj1[name] != value) {
|
13955
|
-
return false;
|
13956
|
-
}
|
13957
|
-
|
13958
|
-
// Delete similar value
|
13959
|
-
delete obj2[name];
|
13960
|
-
}
|
13961
|
-
}
|
13962
|
-
|
13963
|
-
// Check if obj 2 has something obj 1 doesn't have
|
13964
|
-
for (name in obj2) {
|
13965
|
-
// Obj2 has item obj1 doesn't have
|
13966
|
-
if (obj2.hasOwnProperty(name)) {
|
13967
|
-
return false;
|
13968
|
-
}
|
13969
|
-
}
|
13970
|
-
|
13971
|
-
return true;
|
13972
|
-
}
|
13973
|
-
|
13974
|
-
// Attribs are not the same
|
13975
|
-
if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
|
13976
|
-
return false;
|
13977
|
-
}
|
13978
|
-
|
13979
|
-
// Styles are not the same
|
13980
|
-
if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
|
13981
|
-
return false;
|
13982
|
-
}
|
13983
|
-
|
13984
|
-
return !BookmarkManager.isBookmarkNode(node1) && !BookmarkManager.isBookmarkNode(node2);
|
13985
|
-
};
|
13986
|
-
}
|
13987
|
-
|
13988
|
-
return ElementUtils;
|
13989
|
-
}
|
13990
|
-
);
|
13991
|
-
|
13992
13869
|
/**
|
13993
13870
|
* CaretUtils.js
|
13994
13871
|
*
|
@@ -14683,18 +14560,9 @@ define(
|
|
14683
14560
|
[
|
14684
14561
|
'tinymce.core.caret.CaretFinder',
|
14685
14562
|
'tinymce.core.caret.CaretPosition',
|
14686
|
-
'tinymce.core.caret.CaretUtils'
|
14687
|
-
'tinymce.core.dom.NodeType'
|
14563
|
+
'tinymce.core.caret.CaretUtils'
|
14688
14564
|
],
|
14689
|
-
function (CaretFinder, CaretPosition, CaretUtils
|
14690
|
-
var isTextBlockLike = function (elm) {
|
14691
|
-
return NodeType.isElement(elm) && /^(P|H[1-6]|DIV|LI|DT|DD)$/.test(elm.nodeName);
|
14692
|
-
};
|
14693
|
-
|
14694
|
-
var matchEndContainer = function (rng, predicate) {
|
14695
|
-
return predicate(rng.endContainer);
|
14696
|
-
};
|
14697
|
-
|
14565
|
+
function (CaretFinder, CaretPosition, CaretUtils) {
|
14698
14566
|
var createRange = function (sc, so, ec, eo) {
|
14699
14567
|
var rng = document.createRange();
|
14700
14568
|
rng.setStart(sc, so);
|
@@ -14724,12 +14592,8 @@ define(
|
|
14724
14592
|
}).getOr(rng);
|
14725
14593
|
};
|
14726
14594
|
|
14727
|
-
var isEndAtStartOfTextLikeBlock = function (rng) {
|
14728
|
-
return matchEndContainer(rng, isTextBlockLike) && rng.endOffset === 0;
|
14729
|
-
};
|
14730
|
-
|
14731
14595
|
var normalizeBlockSelection = function (rng) {
|
14732
|
-
return rng.collapsed
|
14596
|
+
return rng.collapsed ? rng : normalizeBlockSelectionRange(rng);
|
14733
14597
|
};
|
14734
14598
|
|
14735
14599
|
var normalize = function (rng) {
|
@@ -16599,6 +16463,7 @@ define(
|
|
16599
16463
|
];
|
16600
16464
|
|
16601
16465
|
var headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
16466
|
+
var listItems = ['li', 'dd', 'dt'];
|
16602
16467
|
|
16603
16468
|
var lazyLookup = function (items) {
|
16604
16469
|
var lookup;
|
@@ -16625,6 +16490,7 @@ define(
|
|
16625
16490
|
isInline: isInline,
|
16626
16491
|
isHeading: isHeading,
|
16627
16492
|
isTextBlock: lazyLookup(textBlocks),
|
16493
|
+
isListItem: lazyLookup(listItems),
|
16628
16494
|
isVoid: lazyLookup(voids),
|
16629
16495
|
isTableCell: lazyLookup(tableCells),
|
16630
16496
|
isBr: isBr
|
@@ -17931,6 +17797,129 @@ define(
|
|
17931
17797
|
}
|
17932
17798
|
);
|
17933
17799
|
|
17800
|
+
/**
|
17801
|
+
* ElementUtils.js
|
17802
|
+
*
|
17803
|
+
* Released under LGPL License.
|
17804
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
17805
|
+
*
|
17806
|
+
* License: http://www.tinymce.com/license
|
17807
|
+
* Contributing: http://www.tinymce.com/contributing
|
17808
|
+
*/
|
17809
|
+
|
17810
|
+
/**
|
17811
|
+
* Utility class for various element specific functions.
|
17812
|
+
*
|
17813
|
+
* @private
|
17814
|
+
* @class tinymce.dom.ElementUtils
|
17815
|
+
*/
|
17816
|
+
define(
|
17817
|
+
'tinymce.core.dom.ElementUtils',
|
17818
|
+
[
|
17819
|
+
"tinymce.core.dom.BookmarkManager",
|
17820
|
+
"tinymce.core.util.Tools"
|
17821
|
+
],
|
17822
|
+
function (BookmarkManager, Tools) {
|
17823
|
+
var each = Tools.each;
|
17824
|
+
|
17825
|
+
function ElementUtils(dom) {
|
17826
|
+
/**
|
17827
|
+
* Compares two nodes and checks if it's attributes and styles matches.
|
17828
|
+
* This doesn't compare classes as items since their order is significant.
|
17829
|
+
*
|
17830
|
+
* @method compare
|
17831
|
+
* @param {Node} node1 First node to compare with.
|
17832
|
+
* @param {Node} node2 Second node to compare with.
|
17833
|
+
* @return {boolean} True/false if the nodes are the same or not.
|
17834
|
+
*/
|
17835
|
+
this.compare = function (node1, node2) {
|
17836
|
+
// Not the same name
|
17837
|
+
if (node1.nodeName != node2.nodeName) {
|
17838
|
+
return false;
|
17839
|
+
}
|
17840
|
+
|
17841
|
+
/**
|
17842
|
+
* Returns all the nodes attributes excluding internal ones, styles and classes.
|
17843
|
+
*
|
17844
|
+
* @private
|
17845
|
+
* @param {Node} node Node to get attributes from.
|
17846
|
+
* @return {Object} Name/value object with attributes and attribute values.
|
17847
|
+
*/
|
17848
|
+
function getAttribs(node) {
|
17849
|
+
var attribs = {};
|
17850
|
+
|
17851
|
+
each(dom.getAttribs(node), function (attr) {
|
17852
|
+
var name = attr.nodeName.toLowerCase();
|
17853
|
+
|
17854
|
+
// Don't compare internal attributes or style
|
17855
|
+
if (name.indexOf('_') !== 0 && name !== 'style' && name.indexOf('data-') !== 0) {
|
17856
|
+
attribs[name] = dom.getAttrib(node, name);
|
17857
|
+
}
|
17858
|
+
});
|
17859
|
+
|
17860
|
+
return attribs;
|
17861
|
+
}
|
17862
|
+
|
17863
|
+
/**
|
17864
|
+
* Compares two objects checks if it's key + value exists in the other one.
|
17865
|
+
*
|
17866
|
+
* @private
|
17867
|
+
* @param {Object} obj1 First object to compare.
|
17868
|
+
* @param {Object} obj2 Second object to compare.
|
17869
|
+
* @return {boolean} True/false if the objects matches or not.
|
17870
|
+
*/
|
17871
|
+
function compareObjects(obj1, obj2) {
|
17872
|
+
var value, name;
|
17873
|
+
|
17874
|
+
for (name in obj1) {
|
17875
|
+
// Obj1 has item obj2 doesn't have
|
17876
|
+
if (obj1.hasOwnProperty(name)) {
|
17877
|
+
value = obj2[name];
|
17878
|
+
|
17879
|
+
// Obj2 doesn't have obj1 item
|
17880
|
+
if (typeof value == "undefined") {
|
17881
|
+
return false;
|
17882
|
+
}
|
17883
|
+
|
17884
|
+
// Obj2 item has a different value
|
17885
|
+
if (obj1[name] != value) {
|
17886
|
+
return false;
|
17887
|
+
}
|
17888
|
+
|
17889
|
+
// Delete similar value
|
17890
|
+
delete obj2[name];
|
17891
|
+
}
|
17892
|
+
}
|
17893
|
+
|
17894
|
+
// Check if obj 2 has something obj 1 doesn't have
|
17895
|
+
for (name in obj2) {
|
17896
|
+
// Obj2 has item obj1 doesn't have
|
17897
|
+
if (obj2.hasOwnProperty(name)) {
|
17898
|
+
return false;
|
17899
|
+
}
|
17900
|
+
}
|
17901
|
+
|
17902
|
+
return true;
|
17903
|
+
}
|
17904
|
+
|
17905
|
+
// Attribs are not the same
|
17906
|
+
if (!compareObjects(getAttribs(node1), getAttribs(node2))) {
|
17907
|
+
return false;
|
17908
|
+
}
|
17909
|
+
|
17910
|
+
// Styles are not the same
|
17911
|
+
if (!compareObjects(dom.parseStyle(dom.getAttrib(node1, 'style')), dom.parseStyle(dom.getAttrib(node2, 'style')))) {
|
17912
|
+
return false;
|
17913
|
+
}
|
17914
|
+
|
17915
|
+
return !BookmarkManager.isBookmarkNode(node1) && !BookmarkManager.isBookmarkNode(node2);
|
17916
|
+
};
|
17917
|
+
}
|
17918
|
+
|
17919
|
+
return ElementUtils;
|
17920
|
+
}
|
17921
|
+
);
|
17922
|
+
|
17934
17923
|
/**
|
17935
17924
|
* RemoveFormat.js
|
17936
17925
|
*
|
@@ -18479,7 +18468,7 @@ define(
|
|
18479
18468
|
}
|
18480
18469
|
);
|
18481
18470
|
/**
|
18482
|
-
*
|
18471
|
+
* MergeFormats.js
|
18483
18472
|
*
|
18484
18473
|
* Released under LGPL License.
|
18485
18474
|
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
@@ -18489,83 +18478,25 @@ define(
|
|
18489
18478
|
*/
|
18490
18479
|
|
18491
18480
|
define(
|
18492
|
-
'tinymce.core.fmt.
|
18481
|
+
'tinymce.core.fmt.MergeFormats',
|
18493
18482
|
[
|
18483
|
+
'ephox.katamari.api.Fun',
|
18494
18484
|
'tinymce.core.dom.BookmarkManager',
|
18495
18485
|
'tinymce.core.dom.ElementUtils',
|
18496
18486
|
'tinymce.core.dom.NodeType',
|
18497
|
-
'tinymce.core.dom.RangeNormalizer',
|
18498
|
-
'tinymce.core.dom.RangeUtils',
|
18499
|
-
'tinymce.core.dom.TreeWalker',
|
18500
18487
|
'tinymce.core.fmt.CaretFormat',
|
18501
|
-
'tinymce.core.fmt.ExpandRange',
|
18502
18488
|
'tinymce.core.fmt.FormatUtils',
|
18503
|
-
'tinymce.core.fmt.Hooks',
|
18504
18489
|
'tinymce.core.fmt.MatchFormat',
|
18505
18490
|
'tinymce.core.fmt.RemoveFormat',
|
18506
|
-
'tinymce.core.util.Fun',
|
18507
18491
|
'tinymce.core.util.Tools'
|
18508
18492
|
],
|
18509
|
-
function (
|
18510
|
-
BookmarkManager, ElementUtils, NodeType, RangeNormalizer, RangeUtils, TreeWalker, CaretFormat, ExpandRange, FormatUtils, Hooks, MatchFormat, RemoveFormat,
|
18511
|
-
Fun, Tools
|
18512
|
-
) {
|
18493
|
+
function (Fun, BookmarkManager, ElementUtils, NodeType, CaretFormat, FormatUtils, MatchFormat, RemoveFormat, Tools) {
|
18513
18494
|
var each = Tools.each;
|
18514
18495
|
|
18515
18496
|
var isElementNode = function (node) {
|
18516
18497
|
return node && node.nodeType === 1 && !BookmarkManager.isBookmarkNode(node) && !CaretFormat.isCaretNode(node) && !NodeType.isBogus(node);
|
18517
18498
|
};
|
18518
18499
|
|
18519
|
-
var processChildElements = function (node, filter, process) {
|
18520
|
-
each(node.childNodes, function (node) {
|
18521
|
-
if (isElementNode(node)) {
|
18522
|
-
if (filter(node)) {
|
18523
|
-
process(node);
|
18524
|
-
}
|
18525
|
-
if (node.hasChildNodes()) {
|
18526
|
-
processChildElements(node, filter, process);
|
18527
|
-
}
|
18528
|
-
}
|
18529
|
-
});
|
18530
|
-
};
|
18531
|
-
|
18532
|
-
var clearChildStyles = function (dom, format, node) {
|
18533
|
-
if (format.clear_child_styles) {
|
18534
|
-
var selector = format.links ? '*:not(a)' : '*';
|
18535
|
-
each(dom.select(selector, node), function (node) {
|
18536
|
-
if (isElementNode(node)) {
|
18537
|
-
each(format.styles, function (value, name) {
|
18538
|
-
dom.setStyle(node, name, '');
|
18539
|
-
});
|
18540
|
-
}
|
18541
|
-
});
|
18542
|
-
}
|
18543
|
-
};
|
18544
|
-
|
18545
|
-
var processUnderlineAndColor = function (dom, node) {
|
18546
|
-
var textDecoration;
|
18547
|
-
if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) {
|
18548
|
-
textDecoration = FormatUtils.getTextDecoration(dom, node.parentNode);
|
18549
|
-
if (dom.getStyle(node, 'color') && textDecoration) {
|
18550
|
-
dom.setStyle(node, 'text-decoration', textDecoration);
|
18551
|
-
} else if (dom.getStyle(node, 'text-decoration') === textDecoration) {
|
18552
|
-
dom.setStyle(node, 'text-decoration', null);
|
18553
|
-
}
|
18554
|
-
}
|
18555
|
-
};
|
18556
|
-
|
18557
|
-
var hasStyle = function (dom, name) {
|
18558
|
-
return Fun.curry(function (name, node) {
|
18559
|
-
return !!(node && FormatUtils.getStyle(dom, node, name));
|
18560
|
-
}, name);
|
18561
|
-
};
|
18562
|
-
|
18563
|
-
var applyStyle = function (dom, name, value) {
|
18564
|
-
return Fun.curry(function (name, value, node) {
|
18565
|
-
dom.setStyle(node, name, value);
|
18566
|
-
}, name, value);
|
18567
|
-
};
|
18568
|
-
|
18569
18500
|
var findElementSibling = function (node, siblingName) {
|
18570
18501
|
var sibling;
|
18571
18502
|
|
@@ -18582,15 +18513,7 @@ define(
|
|
18582
18513
|
return node;
|
18583
18514
|
};
|
18584
18515
|
|
18585
|
-
|
18586
|
-
* Merges the next/previous sibling element if they match.
|
18587
|
-
*
|
18588
|
-
* @private
|
18589
|
-
* @param {Node} prev Previous node to compare/merge.
|
18590
|
-
* @param {Node} next Next node to compare/merge.
|
18591
|
-
* @return {Node} Next node if we didn't merge and prev node if we did.
|
18592
|
-
*/
|
18593
|
-
var mergeSiblings = function (dom, prev, next) {
|
18516
|
+
var mergeSiblingsNodes = function (dom, prev, next) {
|
18594
18517
|
var sibling, tmpSibling, elementUtils = new ElementUtils(dom);
|
18595
18518
|
|
18596
18519
|
// Check if next/prev exists and that they are elements
|
@@ -18610,7 +18533,7 @@ define(
|
|
18610
18533
|
|
18611
18534
|
dom.remove(next);
|
18612
18535
|
|
18613
|
-
each(Tools.grep(next.childNodes), function (node) {
|
18536
|
+
Tools.each(Tools.grep(next.childNodes), function (node) {
|
18614
18537
|
prev.appendChild(node);
|
18615
18538
|
});
|
18616
18539
|
|
@@ -18621,36 +18544,196 @@ define(
|
|
18621
18544
|
return next;
|
18622
18545
|
};
|
18623
18546
|
|
18624
|
-
var
|
18625
|
-
|
18547
|
+
var processChildElements = function (node, filter, process) {
|
18548
|
+
each(node.childNodes, function (node) {
|
18549
|
+
if (isElementNode(node)) {
|
18550
|
+
if (filter(node)) {
|
18551
|
+
process(node);
|
18552
|
+
}
|
18553
|
+
if (node.hasChildNodes()) {
|
18554
|
+
processChildElements(node, filter, process);
|
18555
|
+
}
|
18556
|
+
}
|
18557
|
+
});
|
18558
|
+
};
|
18626
18559
|
|
18627
|
-
|
18628
|
-
|
18629
|
-
|
18560
|
+
var hasStyle = function (dom, name) {
|
18561
|
+
return Fun.curry(function (name, node) {
|
18562
|
+
return !!(node && FormatUtils.getStyle(dom, node, name));
|
18563
|
+
}, name);
|
18564
|
+
};
|
18565
|
+
|
18566
|
+
var applyStyle = function (dom, name, value) {
|
18567
|
+
return Fun.curry(function (name, value, node) {
|
18568
|
+
dom.setStyle(node, name, value);
|
18569
|
+
|
18570
|
+
if (node.getAttribute('style') === '') {
|
18571
|
+
node.removeAttribute('style');
|
18630
18572
|
}
|
18631
18573
|
|
18632
|
-
|
18633
|
-
|
18574
|
+
unwrapEmptySpan(dom, node);
|
18575
|
+
}, name, value);
|
18576
|
+
};
|
18577
|
+
|
18578
|
+
var unwrapEmptySpan = function (dom, node) {
|
18579
|
+
if (node.nodeName === 'SPAN' && dom.getAttribs(node).length === 0) {
|
18580
|
+
dom.remove(node, true);
|
18581
|
+
}
|
18582
|
+
};
|
18583
|
+
|
18584
|
+
var processUnderlineAndColor = function (dom, node) {
|
18585
|
+
var textDecoration;
|
18586
|
+
if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) {
|
18587
|
+
textDecoration = FormatUtils.getTextDecoration(dom, node.parentNode);
|
18588
|
+
if (dom.getStyle(node, 'color') && textDecoration) {
|
18589
|
+
dom.setStyle(node, 'text-decoration', textDecoration);
|
18590
|
+
} else if (dom.getStyle(node, 'text-decoration') === textDecoration) {
|
18591
|
+
dom.setStyle(node, 'text-decoration', null);
|
18634
18592
|
}
|
18635
18593
|
}
|
18636
18594
|
};
|
18637
18595
|
|
18638
|
-
|
18639
|
-
|
18640
|
-
|
18641
|
-
|
18642
|
-
|
18643
|
-
|
18644
|
-
|
18596
|
+
var mergeUnderlineAndColor = function (dom, format, vars, node) {
|
18597
|
+
// Colored nodes should be underlined so that the color of the underline matches the text color.
|
18598
|
+
if (format.styles.color || format.styles.textDecoration) {
|
18599
|
+
Tools.walk(node, Fun.curry(processUnderlineAndColor, dom), 'childNodes');
|
18600
|
+
processUnderlineAndColor(dom, node);
|
18601
|
+
}
|
18602
|
+
};
|
18603
|
+
|
18604
|
+
var mergeBackgroundColorAndFontSize = function (dom, format, vars, node) {
|
18605
|
+
// nodes with font-size should have their own background color as well to fit the line-height (see TINY-882)
|
18606
|
+
if (format.styles && format.styles.backgroundColor) {
|
18607
|
+
processChildElements(node,
|
18608
|
+
hasStyle(dom, 'fontSize'),
|
18609
|
+
applyStyle(dom, 'backgroundColor', FormatUtils.replaceVars(format.styles.backgroundColor, vars))
|
18610
|
+
);
|
18611
|
+
}
|
18612
|
+
};
|
18645
18613
|
|
18646
|
-
|
18647
|
-
|
18648
|
-
|
18614
|
+
var mergeSubSup = function (dom, format, vars, node) {
|
18615
|
+
// Remove font size on all chilren of a sub/sup and remove the inverse element
|
18616
|
+
if (format.inline === 'sub' || format.inline === 'sup') {
|
18617
|
+
processChildElements(node,
|
18618
|
+
hasStyle(dom, 'fontSize'),
|
18619
|
+
applyStyle(dom, 'fontSize', '')
|
18620
|
+
);
|
18649
18621
|
|
18650
|
-
|
18622
|
+
dom.remove(dom.select(format.inline === 'sup' ? 'sub' : 'sup', node), true);
|
18651
18623
|
}
|
18624
|
+
};
|
18652
18625
|
|
18653
|
-
|
18626
|
+
var mergeSiblings = function (dom, format, vars, node) {
|
18627
|
+
// Merge next and previous siblings if they are similar <b>text</b><b>text</b> becomes <b>texttext</b>
|
18628
|
+
if (node && format.merge_siblings !== false) {
|
18629
|
+
node = mergeSiblingsNodes(dom, FormatUtils.getNonWhiteSpaceSibling(node), node);
|
18630
|
+
node = mergeSiblingsNodes(dom, node, FormatUtils.getNonWhiteSpaceSibling(node, true));
|
18631
|
+
}
|
18632
|
+
};
|
18633
|
+
|
18634
|
+
var clearChildStyles = function (dom, format, node) {
|
18635
|
+
if (format.clear_child_styles) {
|
18636
|
+
var selector = format.links ? '*:not(a)' : '*';
|
18637
|
+
each(dom.select(selector, node), function (node) {
|
18638
|
+
if (isElementNode(node)) {
|
18639
|
+
each(format.styles, function (value, name) {
|
18640
|
+
dom.setStyle(node, name, '');
|
18641
|
+
});
|
18642
|
+
}
|
18643
|
+
});
|
18644
|
+
}
|
18645
|
+
};
|
18646
|
+
|
18647
|
+
var mergeWithChildren = function (editor, formatList, vars, node) {
|
18648
|
+
// Remove/merge children
|
18649
|
+
each(formatList, function (format) {
|
18650
|
+
// Merge all children of similar type will move styles from child to parent
|
18651
|
+
// this: <span style="color:red"><b><span style="color:red; font-size:10px">text</span></b></span>
|
18652
|
+
// will become: <span style="color:red"><b><span style="font-size:10px">text</span></b></span>
|
18653
|
+
each(editor.dom.select(format.inline, node), function (child) {
|
18654
|
+
if (!isElementNode(child)) {
|
18655
|
+
return;
|
18656
|
+
}
|
18657
|
+
|
18658
|
+
RemoveFormat.removeFormat(editor, format, vars, child, format.exact ? child : null);
|
18659
|
+
});
|
18660
|
+
|
18661
|
+
clearChildStyles(editor.dom, format, node);
|
18662
|
+
});
|
18663
|
+
};
|
18664
|
+
|
18665
|
+
var mergeWithParents = function (editor, format, name, vars, node) {
|
18666
|
+
// Remove format if direct parent already has the same format
|
18667
|
+
if (MatchFormat.matchNode(editor, node.parentNode, name, vars)) {
|
18668
|
+
if (RemoveFormat.removeFormat(editor, format, vars, node)) {
|
18669
|
+
return;
|
18670
|
+
}
|
18671
|
+
}
|
18672
|
+
|
18673
|
+
// Remove format if any ancestor already has the same format
|
18674
|
+
if (format.merge_with_parents) {
|
18675
|
+
editor.dom.getParent(node.parentNode, function (parent) {
|
18676
|
+
if (MatchFormat.matchNode(editor, parent, name, vars)) {
|
18677
|
+
RemoveFormat.removeFormat(editor, format, vars, node);
|
18678
|
+
return true;
|
18679
|
+
}
|
18680
|
+
});
|
18681
|
+
}
|
18682
|
+
};
|
18683
|
+
|
18684
|
+
return {
|
18685
|
+
mergeWithChildren: mergeWithChildren,
|
18686
|
+
mergeUnderlineAndColor: mergeUnderlineAndColor,
|
18687
|
+
mergeBackgroundColorAndFontSize: mergeBackgroundColorAndFontSize,
|
18688
|
+
mergeSubSup: mergeSubSup,
|
18689
|
+
mergeSiblings: mergeSiblings,
|
18690
|
+
mergeWithParents: mergeWithParents
|
18691
|
+
};
|
18692
|
+
}
|
18693
|
+
);
|
18694
|
+
/**
|
18695
|
+
* ApplyFormat.js
|
18696
|
+
*
|
18697
|
+
* Released under LGPL License.
|
18698
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
18699
|
+
*
|
18700
|
+
* License: http://www.tinymce.com/license
|
18701
|
+
* Contributing: http://www.tinymce.com/contributing
|
18702
|
+
*/
|
18703
|
+
|
18704
|
+
define(
|
18705
|
+
'tinymce.core.fmt.ApplyFormat',
|
18706
|
+
[
|
18707
|
+
'tinymce.core.dom.BookmarkManager',
|
18708
|
+
'tinymce.core.dom.NodeType',
|
18709
|
+
'tinymce.core.dom.RangeNormalizer',
|
18710
|
+
'tinymce.core.dom.RangeUtils',
|
18711
|
+
'tinymce.core.fmt.CaretFormat',
|
18712
|
+
'tinymce.core.fmt.ExpandRange',
|
18713
|
+
'tinymce.core.fmt.FormatUtils',
|
18714
|
+
'tinymce.core.fmt.Hooks',
|
18715
|
+
'tinymce.core.fmt.MatchFormat',
|
18716
|
+
'tinymce.core.fmt.MergeFormats',
|
18717
|
+
'tinymce.core.util.Tools'
|
18718
|
+
],
|
18719
|
+
function (BookmarkManager, NodeType, RangeNormalizer, RangeUtils, CaretFormat, ExpandRange, FormatUtils, Hooks, MatchFormat, MergeFormats, Tools) {
|
18720
|
+
var each = Tools.each;
|
18721
|
+
|
18722
|
+
var isElementNode = function (node) {
|
18723
|
+
return node && node.nodeType === 1 && !BookmarkManager.isBookmarkNode(node) && !CaretFormat.isCaretNode(node) && !NodeType.isBogus(node);
|
18724
|
+
};
|
18725
|
+
|
18726
|
+
var processChildElements = function (node, filter, process) {
|
18727
|
+
each(node.childNodes, function (node) {
|
18728
|
+
if (isElementNode(node)) {
|
18729
|
+
if (filter(node)) {
|
18730
|
+
process(node);
|
18731
|
+
}
|
18732
|
+
if (node.hasChildNodes()) {
|
18733
|
+
processChildElements(node, filter, process);
|
18734
|
+
}
|
18735
|
+
}
|
18736
|
+
});
|
18654
18737
|
};
|
18655
18738
|
|
18656
18739
|
var applyFormat = function (ed, name, vars, node) {
|
@@ -18863,23 +18946,6 @@ define(
|
|
18863
18946
|
return child;
|
18864
18947
|
};
|
18865
18948
|
|
18866
|
-
var matchNestedWrapper = function (node, filter) {
|
18867
|
-
do {
|
18868
|
-
if (getChildCount(node) !== 1) {
|
18869
|
-
break;
|
18870
|
-
}
|
18871
|
-
|
18872
|
-
node = getChildElementNode(node);
|
18873
|
-
if (!node) {
|
18874
|
-
break;
|
18875
|
-
} else if (filter(node)) {
|
18876
|
-
return node;
|
18877
|
-
}
|
18878
|
-
} while (node);
|
18879
|
-
|
18880
|
-
return null;
|
18881
|
-
};
|
18882
|
-
|
18883
18949
|
var mergeStyles = function (node) {
|
18884
18950
|
var child, clone;
|
18885
18951
|
|
@@ -18913,55 +18979,11 @@ define(
|
|
18913
18979
|
node = mergeStyles(node);
|
18914
18980
|
}
|
18915
18981
|
|
18916
|
-
|
18917
|
-
|
18918
|
-
|
18919
|
-
|
18920
|
-
|
18921
|
-
each(dom.select(format.inline, node), function (child) {
|
18922
|
-
if (!isElementNode(child)) {
|
18923
|
-
return;
|
18924
|
-
}
|
18925
|
-
|
18926
|
-
RemoveFormat.removeFormat(ed, format, vars, child, format.exact ? child : null);
|
18927
|
-
});
|
18928
|
-
|
18929
|
-
clearChildStyles(dom, format, node);
|
18930
|
-
});
|
18931
|
-
|
18932
|
-
// Remove format if direct parent already has the same format
|
18933
|
-
if (MatchFormat.matchNode(ed, node.parentNode, name, vars)) {
|
18934
|
-
if (RemoveFormat.removeFormat(ed, format, vars, node)) {
|
18935
|
-
node = 0;
|
18936
|
-
}
|
18937
|
-
}
|
18938
|
-
|
18939
|
-
// Remove format if any ancestor already has the same format
|
18940
|
-
if (format.merge_with_parents) {
|
18941
|
-
dom.getParent(node.parentNode, function (parent) {
|
18942
|
-
if (MatchFormat.matchNode(ed, parent, name, vars)) {
|
18943
|
-
if (RemoveFormat.removeFormat(ed, format, vars, node)) {
|
18944
|
-
node = 0;
|
18945
|
-
}
|
18946
|
-
return true;
|
18947
|
-
}
|
18948
|
-
});
|
18949
|
-
}
|
18950
|
-
|
18951
|
-
// fontSize defines the line height for the whole branch of nested style wrappers,
|
18952
|
-
// therefore it should be set on the outermost wrapper
|
18953
|
-
if (node && !dom.isBlock(node) && !FormatUtils.getStyle(dom, node, 'fontSize')) {
|
18954
|
-
var styleNode = matchNestedWrapper(node, hasStyle(dom, 'fontSize'));
|
18955
|
-
if (styleNode) {
|
18956
|
-
applyFormat(ed, 'fontsize', { value: FormatUtils.getStyle(dom, styleNode, 'fontSize') }, node);
|
18957
|
-
}
|
18958
|
-
}
|
18959
|
-
|
18960
|
-
// Merge next and previous siblings if they are similar <b>text</b><b>text</b> becomes <b>texttext</b>
|
18961
|
-
if (node && format.merge_siblings !== false) {
|
18962
|
-
node = mergeSiblings(dom, FormatUtils.getNonWhiteSpaceSibling(node), node);
|
18963
|
-
node = mergeSiblings(dom, node, FormatUtils.getNonWhiteSpaceSibling(node, true));
|
18964
|
-
}
|
18982
|
+
MergeFormats.mergeWithChildren(ed, formatList, vars, node);
|
18983
|
+
MergeFormats.mergeWithParents(ed, format, name, vars, node);
|
18984
|
+
MergeFormats.mergeBackgroundColorAndFontSize(dom, format, vars, node);
|
18985
|
+
MergeFormats.mergeSubSup(dom, format, vars, node);
|
18986
|
+
MergeFormats.mergeSiblings(dom, format, vars, node);
|
18965
18987
|
}
|
18966
18988
|
});
|
18967
18989
|
};
|
@@ -19003,24 +19025,12 @@ define(
|
|
19003
19025
|
}
|
19004
19026
|
|
19005
19027
|
// Apply formatting to selection
|
19006
|
-
ed.selection.setRng(
|
19028
|
+
ed.selection.setRng(RangeNormalizer.normalize(ed.selection.getRng()));
|
19007
19029
|
bookmark = selection.getBookmark();
|
19008
19030
|
applyRngStyle(dom, ExpandRange.expandRng(ed, selection.getRng(true), formatList), bookmark);
|
19009
19031
|
|
19010
19032
|
if (format.styles) {
|
19011
|
-
|
19012
|
-
if (format.styles.color || format.styles.textDecoration) {
|
19013
|
-
Tools.walk(curSelNode, Fun.curry(processUnderlineAndColor, dom), 'childNodes');
|
19014
|
-
processUnderlineAndColor(dom, curSelNode);
|
19015
|
-
}
|
19016
|
-
|
19017
|
-
// nodes with font-size should have their own background color as well to fit the line-height (see TINY-882)
|
19018
|
-
if (format.styles.backgroundColor) {
|
19019
|
-
processChildElements(curSelNode,
|
19020
|
-
hasStyle(dom, 'fontSize'),
|
19021
|
-
applyStyle(dom, 'backgroundColor', FormatUtils.replaceVars(format.styles.backgroundColor, vars))
|
19022
|
-
);
|
19023
|
-
}
|
19033
|
+
MergeFormats.mergeUnderlineAndColor(dom, format, vars, curSelNode);
|
19024
19034
|
}
|
19025
19035
|
|
19026
19036
|
selection.moveToBookmark(bookmark);
|
@@ -19185,7 +19195,14 @@ define(
|
|
19185
19195
|
preview: false,
|
19186
19196
|
defaultBlock: 'div'
|
19187
19197
|
},
|
19188
|
-
{
|
19198
|
+
{
|
19199
|
+
selector: 'img,table',
|
19200
|
+
collapsed: false,
|
19201
|
+
styles: {
|
19202
|
+
'float': 'left'
|
19203
|
+
},
|
19204
|
+
preview: 'font-family font-size'
|
19205
|
+
}
|
19189
19206
|
],
|
19190
19207
|
|
19191
19208
|
aligncenter: [
|
@@ -19195,7 +19212,7 @@ define(
|
|
19195
19212
|
textAlign: 'center'
|
19196
19213
|
},
|
19197
19214
|
inherit: false,
|
19198
|
-
preview:
|
19215
|
+
preview: 'font-family font-size',
|
19199
19216
|
defaultBlock: 'div'
|
19200
19217
|
},
|
19201
19218
|
{
|
@@ -25126,6 +25143,161 @@ define(
|
|
25126
25143
|
}
|
25127
25144
|
);
|
25128
25145
|
|
25146
|
+
define(
|
25147
|
+
'ephox.sugar.impl.ClosestOrAncestor',
|
25148
|
+
|
25149
|
+
[
|
25150
|
+
'ephox.katamari.api.Type',
|
25151
|
+
'ephox.katamari.api.Option'
|
25152
|
+
],
|
25153
|
+
|
25154
|
+
function (Type, Option) {
|
25155
|
+
return function (is, ancestor, scope, a, isRoot) {
|
25156
|
+
return is(scope, a) ?
|
25157
|
+
Option.some(scope) :
|
25158
|
+
Type.isFunction(isRoot) && isRoot(scope) ?
|
25159
|
+
Option.none() :
|
25160
|
+
ancestor(scope, a, isRoot);
|
25161
|
+
};
|
25162
|
+
}
|
25163
|
+
);
|
25164
|
+
define(
|
25165
|
+
'ephox.sugar.api.search.PredicateFind',
|
25166
|
+
|
25167
|
+
[
|
25168
|
+
'ephox.katamari.api.Type',
|
25169
|
+
'ephox.katamari.api.Arr',
|
25170
|
+
'ephox.katamari.api.Fun',
|
25171
|
+
'ephox.katamari.api.Option',
|
25172
|
+
'ephox.sugar.api.node.Body',
|
25173
|
+
'ephox.sugar.api.dom.Compare',
|
25174
|
+
'ephox.sugar.api.node.Element',
|
25175
|
+
'ephox.sugar.impl.ClosestOrAncestor'
|
25176
|
+
],
|
25177
|
+
|
25178
|
+
function (Type, Arr, Fun, Option, Body, Compare, Element, ClosestOrAncestor) {
|
25179
|
+
var first = function (predicate) {
|
25180
|
+
return descendant(Body.body(), predicate);
|
25181
|
+
};
|
25182
|
+
|
25183
|
+
var ancestor = function (scope, predicate, isRoot) {
|
25184
|
+
var element = scope.dom();
|
25185
|
+
var stop = Type.isFunction(isRoot) ? isRoot : Fun.constant(false);
|
25186
|
+
|
25187
|
+
while (element.parentNode) {
|
25188
|
+
element = element.parentNode;
|
25189
|
+
var el = Element.fromDom(element);
|
25190
|
+
|
25191
|
+
if (predicate(el)) return Option.some(el);
|
25192
|
+
else if (stop(el)) break;
|
25193
|
+
}
|
25194
|
+
return Option.none();
|
25195
|
+
};
|
25196
|
+
|
25197
|
+
var closest = function (scope, predicate, isRoot) {
|
25198
|
+
// This is required to avoid ClosestOrAncestor passing the predicate to itself
|
25199
|
+
var is = function (scope) {
|
25200
|
+
return predicate(scope);
|
25201
|
+
};
|
25202
|
+
return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
|
25203
|
+
};
|
25204
|
+
|
25205
|
+
var sibling = function (scope, predicate) {
|
25206
|
+
var element = scope.dom();
|
25207
|
+
if (!element.parentNode) return Option.none();
|
25208
|
+
|
25209
|
+
return child(Element.fromDom(element.parentNode), function (x) {
|
25210
|
+
return !Compare.eq(scope, x) && predicate(x);
|
25211
|
+
});
|
25212
|
+
};
|
25213
|
+
|
25214
|
+
var child = function (scope, predicate) {
|
25215
|
+
var result = Arr.find(scope.dom().childNodes,
|
25216
|
+
Fun.compose(predicate, Element.fromDom));
|
25217
|
+
return result.map(Element.fromDom);
|
25218
|
+
};
|
25219
|
+
|
25220
|
+
var descendant = function (scope, predicate) {
|
25221
|
+
var descend = function (element) {
|
25222
|
+
for (var i = 0; i < element.childNodes.length; i++) {
|
25223
|
+
if (predicate(Element.fromDom(element.childNodes[i])))
|
25224
|
+
return Option.some(Element.fromDom(element.childNodes[i]));
|
25225
|
+
|
25226
|
+
var res = descend(element.childNodes[i]);
|
25227
|
+
if (res.isSome())
|
25228
|
+
return res;
|
25229
|
+
}
|
25230
|
+
|
25231
|
+
return Option.none();
|
25232
|
+
};
|
25233
|
+
|
25234
|
+
return descend(scope.dom());
|
25235
|
+
};
|
25236
|
+
|
25237
|
+
return {
|
25238
|
+
first: first,
|
25239
|
+
ancestor: ancestor,
|
25240
|
+
closest: closest,
|
25241
|
+
sibling: sibling,
|
25242
|
+
child: child,
|
25243
|
+
descendant: descendant
|
25244
|
+
};
|
25245
|
+
}
|
25246
|
+
);
|
25247
|
+
|
25248
|
+
define(
|
25249
|
+
'ephox.sugar.api.search.SelectorFind',
|
25250
|
+
|
25251
|
+
[
|
25252
|
+
'ephox.sugar.api.search.PredicateFind',
|
25253
|
+
'ephox.sugar.api.search.Selectors',
|
25254
|
+
'ephox.sugar.impl.ClosestOrAncestor'
|
25255
|
+
],
|
25256
|
+
|
25257
|
+
function (PredicateFind, Selectors, ClosestOrAncestor) {
|
25258
|
+
// TODO: An internal SelectorFilter module that doesn't Element.fromDom() everything
|
25259
|
+
|
25260
|
+
var first = function (selector) {
|
25261
|
+
return Selectors.one(selector);
|
25262
|
+
};
|
25263
|
+
|
25264
|
+
var ancestor = function (scope, selector, isRoot) {
|
25265
|
+
return PredicateFind.ancestor(scope, function (e) {
|
25266
|
+
return Selectors.is(e, selector);
|
25267
|
+
}, isRoot);
|
25268
|
+
};
|
25269
|
+
|
25270
|
+
var sibling = function (scope, selector) {
|
25271
|
+
return PredicateFind.sibling(scope, function (e) {
|
25272
|
+
return Selectors.is(e, selector);
|
25273
|
+
});
|
25274
|
+
};
|
25275
|
+
|
25276
|
+
var child = function (scope, selector) {
|
25277
|
+
return PredicateFind.child(scope, function (e) {
|
25278
|
+
return Selectors.is(e, selector);
|
25279
|
+
});
|
25280
|
+
};
|
25281
|
+
|
25282
|
+
var descendant = function (scope, selector) {
|
25283
|
+
return Selectors.one(selector, scope);
|
25284
|
+
};
|
25285
|
+
|
25286
|
+
var closest = function (scope, selector, isRoot) {
|
25287
|
+
return ClosestOrAncestor(Selectors.is, ancestor, scope, selector, isRoot);
|
25288
|
+
};
|
25289
|
+
|
25290
|
+
return {
|
25291
|
+
first: first,
|
25292
|
+
ancestor: ancestor,
|
25293
|
+
sibling: sibling,
|
25294
|
+
child: child,
|
25295
|
+
descendant: descendant,
|
25296
|
+
closest: closest
|
25297
|
+
};
|
25298
|
+
}
|
25299
|
+
);
|
25300
|
+
|
25129
25301
|
/**
|
25130
25302
|
* Parents.js
|
25131
25303
|
*
|
@@ -25310,6 +25482,172 @@ define(
|
|
25310
25482
|
}
|
25311
25483
|
);
|
25312
25484
|
|
25485
|
+
/**
|
25486
|
+
* SimpleTableModel.js
|
25487
|
+
*
|
25488
|
+
* Released under LGPL License.
|
25489
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
25490
|
+
*
|
25491
|
+
* License: http://www.tinymce.com/license
|
25492
|
+
* Contributing: http://www.tinymce.com/contributing
|
25493
|
+
*/
|
25494
|
+
|
25495
|
+
define(
|
25496
|
+
'tinymce.core.selection.SimpleTableModel',
|
25497
|
+
[
|
25498
|
+
'ephox.katamari.api.Arr',
|
25499
|
+
'ephox.katamari.api.Option',
|
25500
|
+
'ephox.katamari.api.Struct',
|
25501
|
+
'ephox.sugar.api.dom.Compare',
|
25502
|
+
'ephox.sugar.api.dom.Insert',
|
25503
|
+
'ephox.sugar.api.dom.InsertAll',
|
25504
|
+
'ephox.sugar.api.dom.Replication',
|
25505
|
+
'ephox.sugar.api.node.Element',
|
25506
|
+
'ephox.sugar.api.properties.Attr',
|
25507
|
+
'ephox.sugar.api.search.SelectorFilter'
|
25508
|
+
],
|
25509
|
+
function (Arr, Option, Struct, Compare, Insert, InsertAll, Replication, Element, Attr, SelectorFilter) {
|
25510
|
+
var tableModel = Struct.immutable('element', 'width', 'rows');
|
25511
|
+
var tableRow = Struct.immutable('element', 'cells');
|
25512
|
+
var cellPosition = Struct.immutable('x', 'y');
|
25513
|
+
|
25514
|
+
var getSpan = function (td, key) {
|
25515
|
+
var value = parseInt(Attr.get(td, key), 10);
|
25516
|
+
return isNaN(value) ? 1 : value;
|
25517
|
+
};
|
25518
|
+
|
25519
|
+
var fillout = function (table, x, y, tr, td) {
|
25520
|
+
var rowspan = getSpan(td, 'rowspan');
|
25521
|
+
var colspan = getSpan(td, 'colspan');
|
25522
|
+
var rows = table.rows();
|
25523
|
+
|
25524
|
+
for (var y2 = y; y2 < y + rowspan; y2++) {
|
25525
|
+
if (!rows[y2]) {
|
25526
|
+
rows[y2] = tableRow(Replication.deep(tr), []);
|
25527
|
+
}
|
25528
|
+
|
25529
|
+
for (var x2 = x; x2 < x + colspan; x2++) {
|
25530
|
+
var cells = rows[y2].cells();
|
25531
|
+
|
25532
|
+
// not filler td:s are purposely not cloned so that we can
|
25533
|
+
// find cells in the model by element object references
|
25534
|
+
cells[x2] = y2 == y && x2 == x ? td : Replication.shallow(td);
|
25535
|
+
}
|
25536
|
+
}
|
25537
|
+
};
|
25538
|
+
|
25539
|
+
var cellExists = function (table, x, y) {
|
25540
|
+
var rows = table.rows();
|
25541
|
+
var cells = rows[y] ? rows[y].cells() : [];
|
25542
|
+
return !!cells[x];
|
25543
|
+
};
|
25544
|
+
|
25545
|
+
var skipCellsX = function (table, x, y) {
|
25546
|
+
while (cellExists(table, x, y)) {
|
25547
|
+
x++;
|
25548
|
+
}
|
25549
|
+
|
25550
|
+
return x;
|
25551
|
+
};
|
25552
|
+
|
25553
|
+
var getWidth = function (rows) {
|
25554
|
+
return Arr.foldl(rows, function (acc, row) {
|
25555
|
+
return row.cells().length > acc ? row.cells().length : acc;
|
25556
|
+
}, 0);
|
25557
|
+
};
|
25558
|
+
|
25559
|
+
var findElementPos = function (table, element) {
|
25560
|
+
var rows = table.rows();
|
25561
|
+
for (var y = 0; y < rows.length; y++) {
|
25562
|
+
var cells = rows[y].cells();
|
25563
|
+
for (var x = 0; x < cells.length; x++) {
|
25564
|
+
if (Compare.eq(cells[x], element)) {
|
25565
|
+
return Option.some(cellPosition(x, y));
|
25566
|
+
}
|
25567
|
+
}
|
25568
|
+
}
|
25569
|
+
|
25570
|
+
return Option.none();
|
25571
|
+
};
|
25572
|
+
|
25573
|
+
var extractRows = function (table, sx, sy, ex, ey) {
|
25574
|
+
var newRows = [];
|
25575
|
+
var rows = table.rows();
|
25576
|
+
|
25577
|
+
for (var y = sy; y <= ey; y++) {
|
25578
|
+
var cells = rows[y].cells();
|
25579
|
+
var slice = sx < ex ? cells.slice(sx, ex + 1) : cells.slice(ex, sx + 1);
|
25580
|
+
newRows.push(tableRow(rows[y].element(), slice));
|
25581
|
+
}
|
25582
|
+
|
25583
|
+
return newRows;
|
25584
|
+
};
|
25585
|
+
|
25586
|
+
var subTable = function (table, startPos, endPos) {
|
25587
|
+
var sx = startPos.x(), sy = startPos.y();
|
25588
|
+
var ex = endPos.x(), ey = endPos.y();
|
25589
|
+
var newRows = sy < ey ? extractRows(table, sx, sy, ex, ey) : extractRows(table, sx, ey, ex, sy);
|
25590
|
+
|
25591
|
+
return tableModel(table.element(), getWidth(newRows), newRows);
|
25592
|
+
};
|
25593
|
+
|
25594
|
+
var createDomTable = function (table, rows) {
|
25595
|
+
var tableElement = Replication.shallow(table.element());
|
25596
|
+
var tableBody = Element.fromTag('tbody');
|
25597
|
+
|
25598
|
+
InsertAll.append(tableBody, rows);
|
25599
|
+
Insert.append(tableElement, tableBody);
|
25600
|
+
|
25601
|
+
return tableElement;
|
25602
|
+
};
|
25603
|
+
|
25604
|
+
var modelRowsToDomRows = function (table) {
|
25605
|
+
return Arr.map(table.rows(), function (row) {
|
25606
|
+
var cells = Arr.map(row.cells(), function (cell) {
|
25607
|
+
var td = Replication.deep(cell);
|
25608
|
+
Attr.remove(td, 'colspan');
|
25609
|
+
Attr.remove(td, 'rowspan');
|
25610
|
+
return td;
|
25611
|
+
});
|
25612
|
+
|
25613
|
+
var tr = Replication.shallow(row.element());
|
25614
|
+
InsertAll.append(tr, cells);
|
25615
|
+
return tr;
|
25616
|
+
});
|
25617
|
+
};
|
25618
|
+
|
25619
|
+
var fromDom = function (tableElm) {
|
25620
|
+
var table = tableModel(Replication.shallow(tableElm), 0, []);
|
25621
|
+
|
25622
|
+
Arr.each(SelectorFilter.descendants(tableElm, 'tr'), function (tr, y) {
|
25623
|
+
Arr.each(SelectorFilter.descendants(tr, 'td,th'), function (td, x) {
|
25624
|
+
fillout(table, skipCellsX(table, x, y), y, tr, td);
|
25625
|
+
});
|
25626
|
+
});
|
25627
|
+
|
25628
|
+
return tableModel(table.element(), getWidth(table.rows()), table.rows());
|
25629
|
+
};
|
25630
|
+
|
25631
|
+
var toDom = function (table) {
|
25632
|
+
return createDomTable(table, modelRowsToDomRows(table));
|
25633
|
+
};
|
25634
|
+
|
25635
|
+
var subsection = function (table, startElement, endElement) {
|
25636
|
+
return findElementPos(table, startElement).bind(function (startPos) {
|
25637
|
+
return findElementPos(table, endElement).map(function (endPos) {
|
25638
|
+
return subTable(table, startPos, endPos);
|
25639
|
+
});
|
25640
|
+
});
|
25641
|
+
};
|
25642
|
+
|
25643
|
+
return {
|
25644
|
+
fromDom: fromDom,
|
25645
|
+
toDom: toDom,
|
25646
|
+
subsection: subsection
|
25647
|
+
};
|
25648
|
+
}
|
25649
|
+
);
|
25650
|
+
|
25313
25651
|
/**
|
25314
25652
|
* FragmentReader.js
|
25315
25653
|
*
|
@@ -25325,16 +25663,20 @@ define(
|
|
25325
25663
|
[
|
25326
25664
|
'ephox.katamari.api.Arr',
|
25327
25665
|
'ephox.katamari.api.Fun',
|
25666
|
+
'ephox.sugar.api.dom.Compare',
|
25328
25667
|
'ephox.sugar.api.dom.Insert',
|
25329
25668
|
'ephox.sugar.api.dom.Replication',
|
25330
25669
|
'ephox.sugar.api.node.Element',
|
25331
25670
|
'ephox.sugar.api.node.Fragment',
|
25332
25671
|
'ephox.sugar.api.node.Node',
|
25672
|
+
'ephox.sugar.api.search.SelectorFilter',
|
25673
|
+
'ephox.sugar.api.search.SelectorFind',
|
25333
25674
|
'tinymce.core.dom.ElementType',
|
25334
25675
|
'tinymce.core.dom.Parents',
|
25335
|
-
'tinymce.core.selection.SelectionUtils'
|
25676
|
+
'tinymce.core.selection.SelectionUtils',
|
25677
|
+
'tinymce.core.selection.SimpleTableModel'
|
25336
25678
|
],
|
25337
|
-
function (Arr, Fun, Insert, Replication, Element, Fragment, Node, ElementType, Parents, SelectionUtils) {
|
25679
|
+
function (Arr, Fun, Compare, Insert, Replication, Element, Fragment, Node, SelectorFilter, SelectorFind, ElementType, Parents, SelectionUtils, SimpleTableModel) {
|
25338
25680
|
var findParentListContainer = function (parents) {
|
25339
25681
|
return Arr.find(parents, function (elm) {
|
25340
25682
|
return Node.name(elm) === 'ul' || Node.name(elm) === 'ol';
|
@@ -25366,7 +25708,7 @@ define(
|
|
25366
25708
|
};
|
25367
25709
|
|
25368
25710
|
var getWrapElements = function (rootNode, rng) {
|
25369
|
-
var parents = Parents.parentsAndSelf(Element.fromDom(rng.commonAncestorContainer),
|
25711
|
+
var parents = Parents.parentsAndSelf(Element.fromDom(rng.commonAncestorContainer), rootNode);
|
25370
25712
|
var wrapElements = Arr.filter(parents, function (elm) {
|
25371
25713
|
return ElementType.isInline(elm) || ElementType.isHeading(elm);
|
25372
25714
|
});
|
@@ -25374,12 +25716,41 @@ define(
|
|
25374
25716
|
return Arr.map(wrapElements.concat(fullWrappers), Replication.shallow);
|
25375
25717
|
};
|
25376
25718
|
|
25719
|
+
var emptyFragment = function () {
|
25720
|
+
return Fragment.fromElements([]);
|
25721
|
+
};
|
25722
|
+
|
25377
25723
|
var getFragmentFromRange = function (rootNode, rng) {
|
25378
25724
|
return wrap(Element.fromDom(rng.cloneContents()), getWrapElements(rootNode, rng));
|
25379
25725
|
};
|
25380
25726
|
|
25727
|
+
var getTableCellSelection = function (rootNode) {
|
25728
|
+
return SelectorFilter.descendants(rootNode, 'td[data-mce-selected],th[data-mce-selected]');
|
25729
|
+
};
|
25730
|
+
|
25731
|
+
var getParentTable = function (rootElm, cell) {
|
25732
|
+
return SelectorFind.ancestor(cell, 'table', Fun.curry(Compare.eq, rootElm));
|
25733
|
+
};
|
25734
|
+
|
25735
|
+
var getTableFragment = function (rootNode, selectedTableCells) {
|
25736
|
+
return getParentTable(rootNode, selectedTableCells[0]).bind(function (tableElm) {
|
25737
|
+
var firstCell = selectedTableCells[0];
|
25738
|
+
var lastCell = selectedTableCells[selectedTableCells.length - 1];
|
25739
|
+
var fullTableModel = SimpleTableModel.fromDom(tableElm);
|
25740
|
+
|
25741
|
+
return SimpleTableModel.subsection(fullTableModel, firstCell, lastCell).map(function (sectionedTableModel) {
|
25742
|
+
return Fragment.fromElements([SimpleTableModel.toDom(sectionedTableModel)]);
|
25743
|
+
});
|
25744
|
+
}).getOrThunk(emptyFragment);
|
25745
|
+
};
|
25746
|
+
|
25747
|
+
var getSelectionFragment = function (rootNode, rng) {
|
25748
|
+
return rng.collapsed ? emptyFragment() : getFragmentFromRange(rootNode, rng);
|
25749
|
+
};
|
25750
|
+
|
25381
25751
|
var read = function (rootNode, rng) {
|
25382
|
-
|
25752
|
+
var selectedTableCells = getTableCellSelection(rootNode, rng);
|
25753
|
+
return selectedTableCells.length > 0 ? getTableFragment(rootNode, selectedTableCells) : getSelectionFragment(rootNode, rng);
|
25383
25754
|
};
|
25384
25755
|
|
25385
25756
|
return {
|
@@ -25524,7 +25895,7 @@ define(
|
|
25524
25895
|
}
|
25525
25896
|
|
25526
25897
|
if (rng.cloneContents) {
|
25527
|
-
fragment = args.contextual ? FragmentReader.read(self.editor.getBody(), rng).dom() : rng.cloneContents();
|
25898
|
+
fragment = args.contextual ? FragmentReader.read(Element.fromDom(self.editor.getBody()), rng).dom() : rng.cloneContents();
|
25528
25899
|
if (fragment) {
|
25529
25900
|
tmpElm.appendChild(fragment);
|
25530
25901
|
}
|
@@ -27146,108 +27517,6 @@ define(
|
|
27146
27517
|
}
|
27147
27518
|
);
|
27148
27519
|
|
27149
|
-
define(
|
27150
|
-
'ephox.sugar.impl.ClosestOrAncestor',
|
27151
|
-
|
27152
|
-
[
|
27153
|
-
'ephox.katamari.api.Type',
|
27154
|
-
'ephox.katamari.api.Option'
|
27155
|
-
],
|
27156
|
-
|
27157
|
-
function (Type, Option) {
|
27158
|
-
return function (is, ancestor, scope, a, isRoot) {
|
27159
|
-
return is(scope, a) ?
|
27160
|
-
Option.some(scope) :
|
27161
|
-
Type.isFunction(isRoot) && isRoot(scope) ?
|
27162
|
-
Option.none() :
|
27163
|
-
ancestor(scope, a, isRoot);
|
27164
|
-
};
|
27165
|
-
}
|
27166
|
-
);
|
27167
|
-
define(
|
27168
|
-
'ephox.sugar.api.search.PredicateFind',
|
27169
|
-
|
27170
|
-
[
|
27171
|
-
'ephox.katamari.api.Type',
|
27172
|
-
'ephox.katamari.api.Arr',
|
27173
|
-
'ephox.katamari.api.Fun',
|
27174
|
-
'ephox.katamari.api.Option',
|
27175
|
-
'ephox.sugar.api.node.Body',
|
27176
|
-
'ephox.sugar.api.dom.Compare',
|
27177
|
-
'ephox.sugar.api.node.Element',
|
27178
|
-
'ephox.sugar.impl.ClosestOrAncestor'
|
27179
|
-
],
|
27180
|
-
|
27181
|
-
function (Type, Arr, Fun, Option, Body, Compare, Element, ClosestOrAncestor) {
|
27182
|
-
var first = function (predicate) {
|
27183
|
-
return descendant(Body.body(), predicate);
|
27184
|
-
};
|
27185
|
-
|
27186
|
-
var ancestor = function (scope, predicate, isRoot) {
|
27187
|
-
var element = scope.dom();
|
27188
|
-
var stop = Type.isFunction(isRoot) ? isRoot : Fun.constant(false);
|
27189
|
-
|
27190
|
-
while (element.parentNode) {
|
27191
|
-
element = element.parentNode;
|
27192
|
-
var el = Element.fromDom(element);
|
27193
|
-
|
27194
|
-
if (predicate(el)) return Option.some(el);
|
27195
|
-
else if (stop(el)) break;
|
27196
|
-
}
|
27197
|
-
return Option.none();
|
27198
|
-
};
|
27199
|
-
|
27200
|
-
var closest = function (scope, predicate, isRoot) {
|
27201
|
-
// This is required to avoid ClosestOrAncestor passing the predicate to itself
|
27202
|
-
var is = function (scope) {
|
27203
|
-
return predicate(scope);
|
27204
|
-
};
|
27205
|
-
return ClosestOrAncestor(is, ancestor, scope, predicate, isRoot);
|
27206
|
-
};
|
27207
|
-
|
27208
|
-
var sibling = function (scope, predicate) {
|
27209
|
-
var element = scope.dom();
|
27210
|
-
if (!element.parentNode) return Option.none();
|
27211
|
-
|
27212
|
-
return child(Element.fromDom(element.parentNode), function (x) {
|
27213
|
-
return !Compare.eq(scope, x) && predicate(x);
|
27214
|
-
});
|
27215
|
-
};
|
27216
|
-
|
27217
|
-
var child = function (scope, predicate) {
|
27218
|
-
var result = Arr.find(scope.dom().childNodes,
|
27219
|
-
Fun.compose(predicate, Element.fromDom));
|
27220
|
-
return result.map(Element.fromDom);
|
27221
|
-
};
|
27222
|
-
|
27223
|
-
var descendant = function (scope, predicate) {
|
27224
|
-
var descend = function (element) {
|
27225
|
-
for (var i = 0; i < element.childNodes.length; i++) {
|
27226
|
-
if (predicate(Element.fromDom(element.childNodes[i])))
|
27227
|
-
return Option.some(Element.fromDom(element.childNodes[i]));
|
27228
|
-
|
27229
|
-
var res = descend(element.childNodes[i]);
|
27230
|
-
if (res.isSome())
|
27231
|
-
return res;
|
27232
|
-
}
|
27233
|
-
|
27234
|
-
return Option.none();
|
27235
|
-
};
|
27236
|
-
|
27237
|
-
return descend(scope.dom());
|
27238
|
-
};
|
27239
|
-
|
27240
|
-
return {
|
27241
|
-
first: first,
|
27242
|
-
ancestor: ancestor,
|
27243
|
-
closest: closest,
|
27244
|
-
sibling: sibling,
|
27245
|
-
child: child,
|
27246
|
-
descendant: descendant
|
27247
|
-
};
|
27248
|
-
}
|
27249
|
-
);
|
27250
|
-
|
27251
27520
|
/**
|
27252
27521
|
* DeleteUtils.js
|
27253
27522
|
*
|
@@ -27261,38 +27530,23 @@ define(
|
|
27261
27530
|
define(
|
27262
27531
|
'tinymce.core.delete.DeleteUtils',
|
27263
27532
|
[
|
27264
|
-
'ephox.katamari.api.Arr',
|
27265
27533
|
'ephox.katamari.api.Option',
|
27266
27534
|
'ephox.sugar.api.dom.Compare',
|
27267
27535
|
'ephox.sugar.api.node.Element',
|
27268
|
-
'ephox.sugar.api.
|
27269
|
-
'
|
27536
|
+
'ephox.sugar.api.search.PredicateFind',
|
27537
|
+
'tinymce.core.dom.ElementType'
|
27270
27538
|
],
|
27271
|
-
function (
|
27272
|
-
var toLookup = function (names) {
|
27273
|
-
var lookup = Arr.foldl(names, function (acc, name) {
|
27274
|
-
acc[name] = true;
|
27275
|
-
return acc;
|
27276
|
-
}, { });
|
27277
|
-
|
27278
|
-
return function (elm) {
|
27279
|
-
return lookup[Node.name(elm)] === true;
|
27280
|
-
};
|
27281
|
-
};
|
27282
|
-
|
27283
|
-
var isTextBlock = toLookup([
|
27284
|
-
'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'div', 'address', 'pre', 'form', 'blockquote', 'center',
|
27285
|
-
'dir', 'fieldset', 'header', 'footer', 'article', 'section', 'hgroup', 'aside', 'nav', 'figure'
|
27286
|
-
]);
|
27287
|
-
|
27539
|
+
function (Option, Compare, Element, PredicateFind, ElementType) {
|
27288
27540
|
var isBeforeRoot = function (rootNode) {
|
27289
27541
|
return function (elm) {
|
27290
27542
|
return Compare.eq(rootNode, Element.fromDom(elm.dom().parentNode));
|
27291
27543
|
};
|
27292
27544
|
};
|
27293
27545
|
|
27294
|
-
var
|
27295
|
-
return Compare.contains(rootNode, elm) ? PredicateFind.closest(elm,
|
27546
|
+
var getParentBlock = function (rootNode, elm) {
|
27547
|
+
return Compare.contains(rootNode, elm) ? PredicateFind.closest(elm, function (element) {
|
27548
|
+
return ElementType.isTextBlock(element) || ElementType.isListItem(element);
|
27549
|
+
}, isBeforeRoot(rootNode)) : Option.none();
|
27296
27550
|
};
|
27297
27551
|
|
27298
27552
|
var placeCaretInEmptyBody = function (editor) {
|
@@ -27309,65 +27563,12 @@ define(
|
|
27309
27563
|
};
|
27310
27564
|
|
27311
27565
|
return {
|
27312
|
-
|
27566
|
+
getParentBlock: getParentBlock,
|
27313
27567
|
paddEmptyBody: paddEmptyBody
|
27314
27568
|
};
|
27315
27569
|
}
|
27316
27570
|
);
|
27317
27571
|
|
27318
|
-
define(
|
27319
|
-
'ephox.sugar.api.search.SelectorFind',
|
27320
|
-
|
27321
|
-
[
|
27322
|
-
'ephox.sugar.api.search.PredicateFind',
|
27323
|
-
'ephox.sugar.api.search.Selectors',
|
27324
|
-
'ephox.sugar.impl.ClosestOrAncestor'
|
27325
|
-
],
|
27326
|
-
|
27327
|
-
function (PredicateFind, Selectors, ClosestOrAncestor) {
|
27328
|
-
// TODO: An internal SelectorFilter module that doesn't Element.fromDom() everything
|
27329
|
-
|
27330
|
-
var first = function (selector) {
|
27331
|
-
return Selectors.one(selector);
|
27332
|
-
};
|
27333
|
-
|
27334
|
-
var ancestor = function (scope, selector, isRoot) {
|
27335
|
-
return PredicateFind.ancestor(scope, function (e) {
|
27336
|
-
return Selectors.is(e, selector);
|
27337
|
-
}, isRoot);
|
27338
|
-
};
|
27339
|
-
|
27340
|
-
var sibling = function (scope, selector) {
|
27341
|
-
return PredicateFind.sibling(scope, function (e) {
|
27342
|
-
return Selectors.is(e, selector);
|
27343
|
-
});
|
27344
|
-
};
|
27345
|
-
|
27346
|
-
var child = function (scope, selector) {
|
27347
|
-
return PredicateFind.child(scope, function (e) {
|
27348
|
-
return Selectors.is(e, selector);
|
27349
|
-
});
|
27350
|
-
};
|
27351
|
-
|
27352
|
-
var descendant = function (scope, selector) {
|
27353
|
-
return Selectors.one(selector, scope);
|
27354
|
-
};
|
27355
|
-
|
27356
|
-
var closest = function (scope, selector, isRoot) {
|
27357
|
-
return ClosestOrAncestor(Selectors.is, ancestor, scope, selector, isRoot);
|
27358
|
-
};
|
27359
|
-
|
27360
|
-
return {
|
27361
|
-
first: first,
|
27362
|
-
ancestor: ancestor,
|
27363
|
-
sibling: sibling,
|
27364
|
-
child: child,
|
27365
|
-
descendant: descendant,
|
27366
|
-
closest: closest
|
27367
|
-
};
|
27368
|
-
}
|
27369
|
-
);
|
27370
|
-
|
27371
27572
|
define(
|
27372
27573
|
'ephox.sugar.api.search.SelectorExists',
|
27373
27574
|
|
@@ -27541,7 +27742,7 @@ define(
|
|
27541
27742
|
var getBlockPosition = function (rootNode, pos) {
|
27542
27743
|
var rootElm = Element.fromDom(rootNode);
|
27543
27744
|
var containerElm = Element.fromDom(pos.container());
|
27544
|
-
return DeleteUtils.
|
27745
|
+
return DeleteUtils.getParentBlock(rootElm, containerElm).map(function (block) {
|
27545
27746
|
return BlockPosition(block, pos);
|
27546
27747
|
});
|
27547
27748
|
};
|
@@ -27618,59 +27819,114 @@ define(
|
|
27618
27819
|
[
|
27619
27820
|
'ephox.katamari.api.Arr',
|
27620
27821
|
'ephox.katamari.api.Option',
|
27822
|
+
'ephox.sugar.api.dom.Compare',
|
27621
27823
|
'ephox.sugar.api.dom.Insert',
|
27622
27824
|
'ephox.sugar.api.dom.Remove',
|
27623
27825
|
'ephox.sugar.api.node.Element',
|
27624
27826
|
'ephox.sugar.api.search.Traverse',
|
27625
27827
|
'tinymce.core.caret.CaretFinder',
|
27626
27828
|
'tinymce.core.caret.CaretPosition',
|
27829
|
+
'tinymce.core.dom.ElementType',
|
27627
27830
|
'tinymce.core.dom.Empty',
|
27628
|
-
'tinymce.core.dom.NodeType'
|
27831
|
+
'tinymce.core.dom.NodeType',
|
27832
|
+
'tinymce.core.dom.Parents'
|
27629
27833
|
],
|
27630
|
-
function (Arr, Option, Insert, Remove, Element, Traverse, CaretFinder, CaretPosition, Empty, NodeType) {
|
27631
|
-
var
|
27632
|
-
var children = Traverse.children(
|
27633
|
-
|
27634
|
-
|
27635
|
-
|
27636
|
-
|
27637
|
-
|
27834
|
+
function (Arr, Option, Compare, Insert, Remove, Element, Traverse, CaretFinder, CaretPosition, ElementType, Empty, NodeType, Parents) {
|
27835
|
+
var getChildrenUntilBlockBoundary = function (block) {
|
27836
|
+
var children = Traverse.children(block);
|
27837
|
+
return Arr.findIndex(children, ElementType.isBlock).fold(
|
27838
|
+
function () {
|
27839
|
+
return children;
|
27840
|
+
},
|
27841
|
+
function (index) {
|
27842
|
+
return children.slice(0, index);
|
27843
|
+
}
|
27844
|
+
);
|
27845
|
+
};
|
27638
27846
|
|
27639
|
-
|
27640
|
-
|
27641
|
-
Insert.append(toBlock, node);
|
27642
|
-
});
|
27643
|
-
}
|
27847
|
+
var extractChildren = function (block) {
|
27848
|
+
var children = getChildrenUntilBlockBoundary(block);
|
27644
27849
|
|
27645
|
-
|
27646
|
-
Remove.remove(
|
27647
|
-
}
|
27850
|
+
Arr.each(children, function (node) {
|
27851
|
+
Remove.remove(node);
|
27852
|
+
});
|
27648
27853
|
|
27649
|
-
return children
|
27854
|
+
return children;
|
27650
27855
|
};
|
27651
27856
|
|
27652
|
-
var
|
27653
|
-
|
27654
|
-
|
27655
|
-
|
27656
|
-
|
27657
|
-
} else {
|
27658
|
-
return CaretFinder.positionIn(false, block1.dom()).bind(function (toPosition) {
|
27659
|
-
return mergeBlocksAndReposition(forward, block2, block1, toPosition);
|
27660
|
-
});
|
27857
|
+
var trimBr = function (first, block) {
|
27858
|
+
CaretFinder.positionIn(first, block.dom()).each(function (position) {
|
27859
|
+
var node = position.getNode();
|
27860
|
+
if (NodeType.isBr(node)) {
|
27861
|
+
Remove.remove(Element.fromDom(node));
|
27661
27862
|
}
|
27863
|
+
});
|
27864
|
+
};
|
27865
|
+
|
27866
|
+
var removeEmptyRoot = function (rootNode, block) {
|
27867
|
+
var parents = Parents.parentsAndSelf(block, rootNode);
|
27868
|
+
return Arr.find(parents.reverse(), Empty.isEmpty).each(Remove.remove);
|
27869
|
+
};
|
27870
|
+
|
27871
|
+
var findParentInsertPoint = function (toBlock, block) {
|
27872
|
+
var parents = Traverse.parents(block, function (elm) {
|
27873
|
+
return Compare.eq(elm, toBlock);
|
27874
|
+
});
|
27875
|
+
|
27876
|
+
return Option.from(parents[parents.length - 2]);
|
27877
|
+
};
|
27878
|
+
|
27879
|
+
var getInsertionPoint = function (fromBlock, toBlock) {
|
27880
|
+
if (Compare.contains(toBlock, fromBlock)) {
|
27881
|
+
return Traverse.parent(fromBlock).bind(function (parent) {
|
27882
|
+
return Compare.eq(parent, toBlock) ? Option.some(fromBlock) : findParentInsertPoint(toBlock, fromBlock);
|
27883
|
+
});
|
27662
27884
|
} else {
|
27663
|
-
|
27664
|
-
Remove.remove(block2);
|
27665
|
-
return CaretFinder.positionIn(true, block1.dom());
|
27666
|
-
} else {
|
27667
|
-
return CaretFinder.positionIn(false, block2.dom()).bind(function (toPosition) {
|
27668
|
-
return mergeBlocksAndReposition(forward, block1, block2, toPosition);
|
27669
|
-
});
|
27670
|
-
}
|
27885
|
+
return Option.none();
|
27671
27886
|
}
|
27672
27887
|
};
|
27673
27888
|
|
27889
|
+
var mergeBlockInto = function (rootNode, fromBlock, toBlock) {
|
27890
|
+
if (Empty.isEmpty(toBlock)) {
|
27891
|
+
Remove.remove(toBlock);
|
27892
|
+
return CaretFinder.firstPositionIn(fromBlock.dom());
|
27893
|
+
} else {
|
27894
|
+
trimBr(true, fromBlock);
|
27895
|
+
trimBr(false, toBlock);
|
27896
|
+
|
27897
|
+
var children = extractChildren(fromBlock);
|
27898
|
+
|
27899
|
+
return getInsertionPoint(fromBlock, toBlock).fold(
|
27900
|
+
function () {
|
27901
|
+
removeEmptyRoot(rootNode, fromBlock);
|
27902
|
+
|
27903
|
+
var position = CaretFinder.lastPositionIn(toBlock.dom());
|
27904
|
+
|
27905
|
+
Arr.each(children, function (node) {
|
27906
|
+
Insert.append(toBlock, node);
|
27907
|
+
});
|
27908
|
+
|
27909
|
+
return position;
|
27910
|
+
},
|
27911
|
+
function (target) {
|
27912
|
+
var position = CaretFinder.prevPosition(toBlock.dom(), CaretPosition.before(target.dom()));
|
27913
|
+
|
27914
|
+
Arr.each(children, function (node) {
|
27915
|
+
Insert.before(target, node);
|
27916
|
+
});
|
27917
|
+
|
27918
|
+
removeEmptyRoot(rootNode, fromBlock);
|
27919
|
+
|
27920
|
+
return position;
|
27921
|
+
}
|
27922
|
+
);
|
27923
|
+
}
|
27924
|
+
};
|
27925
|
+
|
27926
|
+
var mergeBlocks = function (rootNode, forward, block1, block2) {
|
27927
|
+
return forward ? mergeBlockInto(rootNode, block2, block1) : mergeBlockInto(rootNode, block1, block2);
|
27928
|
+
};
|
27929
|
+
|
27674
27930
|
return {
|
27675
27931
|
mergeBlocks: mergeBlocks
|
27676
27932
|
};
|
@@ -27690,15 +27946,16 @@ define(
|
|
27690
27946
|
define(
|
27691
27947
|
'tinymce.core.delete.BlockBoundaryDelete',
|
27692
27948
|
[
|
27949
|
+
'ephox.sugar.api.node.Element',
|
27693
27950
|
'tinymce.core.delete.BlockBoundary',
|
27694
27951
|
'tinymce.core.delete.MergeBlocks'
|
27695
27952
|
],
|
27696
|
-
function (BlockBoundary, MergeBlocks) {
|
27953
|
+
function (Element, BlockBoundary, MergeBlocks) {
|
27697
27954
|
var backspaceDelete = function (editor, forward) {
|
27698
|
-
var position;
|
27955
|
+
var position, rootNode = Element.fromDom(editor.getBody());
|
27699
27956
|
|
27700
|
-
position = BlockBoundary.read(
|
27701
|
-
return MergeBlocks.mergeBlocks(forward, blockBoundary.from().block(), blockBoundary.to().block());
|
27957
|
+
position = BlockBoundary.read(rootNode.dom(), forward, editor.selection.getRng()).bind(function (blockBoundary) {
|
27958
|
+
return MergeBlocks.mergeBlocks(rootNode, forward, blockBoundary.from().block(), blockBoundary.to().block());
|
27702
27959
|
});
|
27703
27960
|
|
27704
27961
|
position.each(function (pos) {
|
@@ -27740,13 +27997,13 @@ define(
|
|
27740
27997
|
var rng = selection.getRng();
|
27741
27998
|
|
27742
27999
|
return Options.liftN([
|
27743
|
-
DeleteUtils.
|
27744
|
-
DeleteUtils.
|
28000
|
+
DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.startContainer)),
|
28001
|
+
DeleteUtils.getParentBlock(rootNode, Element.fromDom(rng.endContainer))
|
27745
28002
|
], function (block1, block2) {
|
27746
28003
|
if (Compare.eq(block1, block2) === false) {
|
27747
28004
|
rng.deleteContents();
|
27748
28005
|
|
27749
|
-
MergeBlocks.mergeBlocks(true, block1, block2).each(function (pos) {
|
28006
|
+
MergeBlocks.mergeBlocks(rootNode, true, block1, block2).each(function (pos) {
|
27750
28007
|
selection.setRng(pos.toRange());
|
27751
28008
|
});
|
27752
28009
|
|
@@ -27939,7 +28196,7 @@ define(
|
|
27939
28196
|
|
27940
28197
|
var deleteEmptyBlockOrMoveToCef = function (rootNode, forward, from, to) {
|
27941
28198
|
var toCefElm = to.getNode(forward === false);
|
27942
|
-
return DeleteUtils.
|
28199
|
+
return DeleteUtils.getParentBlock(Element.fromDom(rootNode), Element.fromDom(from.getNode())).map(function (blockElm) {
|
27943
28200
|
return Empty.isEmpty(blockElm) ? DeleteAction.remove(blockElm.dom()) : DeleteAction.moveToElement(toCefElm);
|
27944
28201
|
}).orThunk(function () {
|
27945
28202
|
return Option.some(DeleteAction.moveToElement(toCefElm));
|
@@ -28206,15 +28463,12 @@ define(
|
|
28206
28463
|
'ephox.sugar.api.node.Element',
|
28207
28464
|
'ephox.sugar.api.search.SelectorFilter',
|
28208
28465
|
'tinymce.core.caret.CaretPosition',
|
28209
|
-
'tinymce.core.caret.CaretUtils',
|
28210
|
-
'tinymce.core.delete.BlockBoundary',
|
28211
28466
|
'tinymce.core.delete.CefDeleteAction',
|
28212
28467
|
'tinymce.core.delete.DeleteElement',
|
28213
28468
|
'tinymce.core.delete.DeleteUtils',
|
28214
|
-
'tinymce.core.delete.MergeBlocks',
|
28215
28469
|
'tinymce.core.dom.NodeType'
|
28216
28470
|
],
|
28217
|
-
function (Arr, Remove, Element, SelectorFilter, CaretPosition,
|
28471
|
+
function (Arr, Remove, Element, SelectorFilter, CaretPosition, CefDeleteAction, DeleteElement, DeleteUtils, NodeType) {
|
28218
28472
|
var deleteElement = function (editor, forward) {
|
28219
28473
|
return function (element) {
|
28220
28474
|
DeleteElement.deleteElement(editor, forward, Element.fromDom(element));
|
@@ -28522,73 +28776,133 @@ define(
|
|
28522
28776
|
define(
|
28523
28777
|
'tinymce.core.EditorSettings',
|
28524
28778
|
[
|
28779
|
+
'ephox.katamari.api.Arr',
|
28525
28780
|
'ephox.katamari.api.Fun',
|
28781
|
+
'ephox.katamari.api.Obj',
|
28526
28782
|
'ephox.katamari.api.Option',
|
28783
|
+
'ephox.katamari.api.Strings',
|
28784
|
+
'ephox.katamari.api.Struct',
|
28527
28785
|
'ephox.katamari.api.Type',
|
28786
|
+
'ephox.sand.api.PlatformDetection',
|
28528
28787
|
'tinymce.core.util.Tools'
|
28529
28788
|
],
|
28530
|
-
function (Fun, Option, Type, Tools) {
|
28531
|
-
var
|
28532
|
-
|
28789
|
+
function (Arr, Fun, Obj, Option, Strings, Struct, Type, PlatformDetection, Tools) {
|
28790
|
+
var sectionResult = Struct.immutable('sections', 'settings');
|
28791
|
+
var detection = PlatformDetection.detect();
|
28792
|
+
var isTouch = detection.deviceType.isTouch();
|
28793
|
+
var mobilePlugins = [ 'lists', 'autolink', 'autosave' ];
|
28794
|
+
|
28795
|
+
var normalizePlugins = function (plugins) {
|
28796
|
+
return Type.isArray(plugins) ? plugins.join(' ') : plugins;
|
28797
|
+
};
|
28798
|
+
|
28799
|
+
var filterMobilePlugins = function (plugins) {
|
28800
|
+
var trimmedPlugins = Arr.map(normalizePlugins(plugins).split(' '), Strings.trim);
|
28801
|
+
return Arr.filter(trimmedPlugins, Fun.curry(Arr.contains, mobilePlugins)).join(' ');
|
28802
|
+
};
|
28803
|
+
|
28804
|
+
var extractSections = function (keys, settings) {
|
28805
|
+
var result = Obj.bifilter(settings, function (value, key) {
|
28806
|
+
return Arr.contains(keys, key);
|
28807
|
+
});
|
28808
|
+
|
28809
|
+
return sectionResult(result.t, result.f);
|
28810
|
+
};
|
28811
|
+
|
28812
|
+
var getSection = function (sectionResult, name) {
|
28813
|
+
var sections = sectionResult.sections();
|
28814
|
+
return sections.hasOwnProperty(name) ? sections[name] : { };
|
28815
|
+
};
|
28816
|
+
|
28817
|
+
var hasSection = function (sectionResult, name) {
|
28818
|
+
return sectionResult.sections().hasOwnProperty(name);
|
28819
|
+
};
|
28820
|
+
|
28821
|
+
var getDefaultSettings = function (id, documentBaseUrl, editor) {
|
28822
|
+
return {
|
28823
|
+
id: id,
|
28824
|
+
theme: 'modern',
|
28825
|
+
delta_width: 0,
|
28826
|
+
delta_height: 0,
|
28827
|
+
popup_css: '',
|
28828
|
+
plugins: '',
|
28829
|
+
document_base_url: documentBaseUrl,
|
28830
|
+
add_form_submit_trigger: true,
|
28831
|
+
submit_patch: true,
|
28832
|
+
add_unload_trigger: true,
|
28833
|
+
convert_urls: true,
|
28834
|
+
relative_urls: true,
|
28835
|
+
remove_script_host: true,
|
28836
|
+
object_resizing: true,
|
28837
|
+
doctype: '<!DOCTYPE html>',
|
28838
|
+
visual: true,
|
28839
|
+
font_size_style_values: 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
28840
|
+
|
28841
|
+
// See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
|
28842
|
+
font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
|
28843
|
+
forced_root_block: 'p',
|
28844
|
+
hidden_input: true,
|
28845
|
+
padd_empty_editor: true,
|
28846
|
+
render_ui: true,
|
28847
|
+
indentation: '30px',
|
28848
|
+
inline_styles: true,
|
28849
|
+
convert_fonts_to_spans: true,
|
28850
|
+
indent: 'simple',
|
28851
|
+
indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' +
|
28852
|
+
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
28853
|
+
indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' +
|
28854
|
+
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
28855
|
+
entity_encoding: 'named',
|
28856
|
+
url_converter: editor.convertURL,
|
28857
|
+
url_converter_scope: editor,
|
28858
|
+
ie7_compat: true
|
28859
|
+
};
|
28860
|
+
};
|
28861
|
+
|
28862
|
+
var getExternalPlugins = function (overrideSettings, settings) {
|
28863
|
+
var userDefinedExternalPlugins = settings.external_plugins ? settings.external_plugins : { };
|
28864
|
+
|
28865
|
+
if (overrideSettings && overrideSettings.external_plugins) {
|
28866
|
+
return Tools.extend({}, overrideSettings.external_plugins, userDefinedExternalPlugins);
|
28867
|
+
} else {
|
28868
|
+
return userDefinedExternalPlugins;
|
28869
|
+
}
|
28870
|
+
};
|
28871
|
+
|
28872
|
+
var combineSettings = function (defaultSettings, defaultOverrideSettings, settings) {
|
28873
|
+
var sectionResult = extractSections(['mobile'], settings);
|
28874
|
+
var plugins = sectionResult.settings().plugins;
|
28875
|
+
|
28876
|
+
var extendedSettings = Tools.extend(
|
28533
28877
|
// Default settings
|
28534
|
-
|
28535
|
-
id: id,
|
28536
|
-
theme: 'modern',
|
28537
|
-
delta_width: 0,
|
28538
|
-
delta_height: 0,
|
28539
|
-
popup_css: '',
|
28540
|
-
plugins: '',
|
28541
|
-
document_base_url: documentBaseUrl,
|
28542
|
-
add_form_submit_trigger: true,
|
28543
|
-
submit_patch: true,
|
28544
|
-
add_unload_trigger: true,
|
28545
|
-
convert_urls: true,
|
28546
|
-
relative_urls: true,
|
28547
|
-
remove_script_host: true,
|
28548
|
-
object_resizing: true,
|
28549
|
-
doctype: '<!DOCTYPE html>',
|
28550
|
-
visual: true,
|
28551
|
-
font_size_style_values: 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
28552
|
-
|
28553
|
-
// See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
|
28554
|
-
font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
|
28555
|
-
forced_root_block: 'p',
|
28556
|
-
hidden_input: true,
|
28557
|
-
padd_empty_editor: true,
|
28558
|
-
render_ui: true,
|
28559
|
-
indentation: '30px',
|
28560
|
-
inline_styles: true,
|
28561
|
-
convert_fonts_to_spans: true,
|
28562
|
-
indent: 'simple',
|
28563
|
-
indent_before: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' +
|
28564
|
-
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
28565
|
-
indent_after: 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,th,ul,ol,li,dl,dt,dd,area,table,thead,' +
|
28566
|
-
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
28567
|
-
entity_encoding: 'named',
|
28568
|
-
url_converter: editor.convertURL,
|
28569
|
-
url_converter_scope: editor,
|
28570
|
-
ie7_compat: true
|
28571
|
-
},
|
28878
|
+
defaultSettings,
|
28572
28879
|
|
28573
28880
|
// tinymce.overrideDefaults settings
|
28574
28881
|
defaultOverrideSettings,
|
28575
28882
|
|
28576
28883
|
// User settings
|
28577
|
-
settings,
|
28884
|
+
sectionResult.settings(),
|
28885
|
+
|
28886
|
+
// Sections
|
28887
|
+
isTouch ? getSection(sectionResult, 'mobile') : { },
|
28578
28888
|
|
28579
28889
|
// Forced settings
|
28580
28890
|
{
|
28581
28891
|
validate: true,
|
28582
|
-
content_editable: settings.inline
|
28583
|
-
|
28892
|
+
content_editable: sectionResult.settings().inline,
|
28893
|
+
external_plugins: getExternalPlugins(defaultOverrideSettings, sectionResult.settings())
|
28894
|
+
},
|
28895
|
+
|
28896
|
+
// TODO: Remove this once we fix each plugin with a mobile version
|
28897
|
+
isTouch && plugins && hasSection(sectionResult, 'mobile') ? { plugins: filterMobilePlugins(plugins) } : { }
|
28584
28898
|
);
|
28585
28899
|
|
28586
|
-
|
28587
|
-
|
28588
|
-
settings.external_plugins = Tools.extend({}, defaultOverrideSettings.external_plugins, settings.external_plugins);
|
28589
|
-
}
|
28900
|
+
return extendedSettings;
|
28901
|
+
};
|
28590
28902
|
|
28591
|
-
|
28903
|
+
var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {
|
28904
|
+
var defaultSettings = getDefaultSettings(id, documentBaseUrl, editor);
|
28905
|
+
return combineSettings(defaultSettings, defaultOverrideSettings, settings);
|
28592
28906
|
};
|
28593
28907
|
|
28594
28908
|
var get = function (editor, name) {
|
@@ -28602,7 +28916,10 @@ define(
|
|
28602
28916
|
return {
|
28603
28917
|
getEditorSettings: getEditorSettings,
|
28604
28918
|
get: get,
|
28605
|
-
getString: Fun.curry(getFiltered, Type.isString)
|
28919
|
+
getString: Fun.curry(getFiltered, Type.isString),
|
28920
|
+
|
28921
|
+
// TODO: Remove this once we have proper mobile plugins
|
28922
|
+
filterMobilePlugins: filterMobilePlugins
|
28606
28923
|
};
|
28607
28924
|
}
|
28608
28925
|
);
|
@@ -29341,6 +29658,184 @@ define(
|
|
29341
29658
|
};
|
29342
29659
|
}
|
29343
29660
|
);
|
29661
|
+
define(
|
29662
|
+
'tinymce.core.delete.TableDeleteAction',
|
29663
|
+
|
29664
|
+
[
|
29665
|
+
'ephox.katamari.api.Adt',
|
29666
|
+
'ephox.katamari.api.Arr',
|
29667
|
+
'ephox.katamari.api.Fun',
|
29668
|
+
'ephox.katamari.api.Option',
|
29669
|
+
'ephox.katamari.api.Options',
|
29670
|
+
'ephox.katamari.api.Struct',
|
29671
|
+
'ephox.sugar.api.dom.Compare',
|
29672
|
+
'ephox.sugar.api.node.Element',
|
29673
|
+
'ephox.sugar.api.search.SelectorFilter',
|
29674
|
+
'ephox.sugar.api.search.SelectorFind'
|
29675
|
+
],
|
29676
|
+
|
29677
|
+
function (Adt, Arr, Fun, Option, Options, Struct, Compare, Element, SelectorFilter, SelectorFind) {
|
29678
|
+
var tableCellRng = Struct.immutable('start', 'end');
|
29679
|
+
var tableSelection = Struct.immutable('rng', 'table', 'cells');
|
29680
|
+
var deleteAction = Adt.generate([
|
29681
|
+
{ removeTable: [ 'element' ] },
|
29682
|
+
{ emptyCells: [ 'cells' ] }
|
29683
|
+
]);
|
29684
|
+
|
29685
|
+
var getClosestCell = function (container, isRoot) {
|
29686
|
+
return SelectorFind.closest(Element.fromDom(container), 'td,th', isRoot);
|
29687
|
+
};
|
29688
|
+
|
29689
|
+
var getClosestTable = function (cell, isRoot) {
|
29690
|
+
return SelectorFind.ancestor(cell, 'table', isRoot);
|
29691
|
+
};
|
29692
|
+
|
29693
|
+
var isExpandedCellRng = function (cellRng) {
|
29694
|
+
return Compare.eq(cellRng.start(), cellRng.end()) === false;
|
29695
|
+
};
|
29696
|
+
|
29697
|
+
var getTableFromCellRng = function (cellRng, isRoot) {
|
29698
|
+
return getClosestTable(cellRng.start(), isRoot)
|
29699
|
+
.bind(function (startParentTable) {
|
29700
|
+
return getClosestTable(cellRng.end(), isRoot)
|
29701
|
+
.bind(function (endParentTable) {
|
29702
|
+
return Compare.eq(startParentTable, endParentTable) ? Option.some(startParentTable) : Option.none();
|
29703
|
+
});
|
29704
|
+
});
|
29705
|
+
};
|
29706
|
+
|
29707
|
+
var getCellRng = function (rng, isRoot) {
|
29708
|
+
return Options.liftN([ // get start and end cell
|
29709
|
+
getClosestCell(rng.startContainer, isRoot),
|
29710
|
+
getClosestCell(rng.endContainer, isRoot)
|
29711
|
+
], tableCellRng)
|
29712
|
+
.filter(isExpandedCellRng);
|
29713
|
+
};
|
29714
|
+
|
29715
|
+
var getTableSelectionFromCellRng = function (cellRng, isRoot) {
|
29716
|
+
return getTableFromCellRng(cellRng, isRoot)
|
29717
|
+
.bind(function (table) {
|
29718
|
+
var cells = SelectorFilter.descendants(table, 'td,th');
|
29719
|
+
|
29720
|
+
return tableSelection(cellRng, table, cells);
|
29721
|
+
});
|
29722
|
+
};
|
29723
|
+
|
29724
|
+
var getTableSelectionFromRng = function (rootNode, rng) {
|
29725
|
+
var isRoot = Fun.curry(Compare.eq, rootNode);
|
29726
|
+
|
29727
|
+
return getCellRng(rng, isRoot)
|
29728
|
+
.map(function (cellRng) {
|
29729
|
+
return getTableSelectionFromCellRng(cellRng, isRoot);
|
29730
|
+
});
|
29731
|
+
};
|
29732
|
+
|
29733
|
+
var getCellIndex = function (cellArray, cell) {
|
29734
|
+
return Arr.findIndex(cellArray, function (x) {
|
29735
|
+
return Compare.eq(x, cell);
|
29736
|
+
});
|
29737
|
+
};
|
29738
|
+
|
29739
|
+
var getSelectedCells = function (tableSelection) {
|
29740
|
+
return Options.liftN([
|
29741
|
+
getCellIndex(tableSelection.cells(), tableSelection.rng().start()),
|
29742
|
+
getCellIndex(tableSelection.cells(), tableSelection.rng().end())
|
29743
|
+
], function (startIndex, endIndex) {
|
29744
|
+
return tableSelection.cells().slice(startIndex, endIndex + 1);
|
29745
|
+
});
|
29746
|
+
};
|
29747
|
+
|
29748
|
+
var getAction = function (tableSelection) {
|
29749
|
+
return getSelectedCells(tableSelection)
|
29750
|
+
.bind(function (selected) {
|
29751
|
+
var cells = tableSelection.cells();
|
29752
|
+
|
29753
|
+
return selected.length === cells.length ? deleteAction.removeTable(tableSelection.table()) : deleteAction.emptyCells(selected);
|
29754
|
+
});
|
29755
|
+
};
|
29756
|
+
|
29757
|
+
var getActionFromCells = function (cells) {
|
29758
|
+
return deleteAction.emptyCells(cells);
|
29759
|
+
};
|
29760
|
+
|
29761
|
+
var getActionFromRange = function (rootNode, rng) {
|
29762
|
+
return getTableSelectionFromRng(rootNode, rng)
|
29763
|
+
.map(getAction);
|
29764
|
+
};
|
29765
|
+
|
29766
|
+
return {
|
29767
|
+
getActionFromRange: getActionFromRange,
|
29768
|
+
getActionFromCells: getActionFromCells
|
29769
|
+
};
|
29770
|
+
}
|
29771
|
+
);
|
29772
|
+
|
29773
|
+
/**
|
29774
|
+
* TableDelete.js
|
29775
|
+
*
|
29776
|
+
* Released under LGPL License.
|
29777
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
29778
|
+
*
|
29779
|
+
* License: http://www.tinymce.com/license
|
29780
|
+
* Contributing: http://www.tinymce.com/contributing
|
29781
|
+
*/
|
29782
|
+
|
29783
|
+
define(
|
29784
|
+
'tinymce.core.delete.TableDelete',
|
29785
|
+
|
29786
|
+
[
|
29787
|
+
'ephox.katamari.api.Adt',
|
29788
|
+
'ephox.katamari.api.Arr',
|
29789
|
+
'ephox.katamari.api.Fun',
|
29790
|
+
'ephox.sugar.api.node.Element',
|
29791
|
+
'ephox.sugar.api.search.SelectorFilter',
|
29792
|
+
'tinymce.core.delete.DeleteElement',
|
29793
|
+
'tinymce.core.delete.TableDeleteAction',
|
29794
|
+
'tinymce.core.dom.PaddingBr'
|
29795
|
+
],
|
29796
|
+
|
29797
|
+
function (Adt, Arr, Fun, Element, SelectorFilter, DeleteElement, TableDeleteAction, PaddingBr) {
|
29798
|
+
var emptyCells = function (editor, cells) {
|
29799
|
+
Arr.each(cells, PaddingBr.fillWithPaddingBr);
|
29800
|
+
editor.selection.setCursorLocation(cells[0].dom(), 0);
|
29801
|
+
|
29802
|
+
return true;
|
29803
|
+
};
|
29804
|
+
|
29805
|
+
var deleteTableElement = function (editor, table) {
|
29806
|
+
DeleteElement.deleteElement(editor, false, table);
|
29807
|
+
|
29808
|
+
return true;
|
29809
|
+
};
|
29810
|
+
|
29811
|
+
var handleCellRange = function (editor, rootNode, rng) {
|
29812
|
+
return TableDeleteAction.getActionFromRange(rootNode, rng)
|
29813
|
+
.map(function (action) {
|
29814
|
+
return action.fold(
|
29815
|
+
Fun.curry(deleteTableElement, editor),
|
29816
|
+
Fun.curry(emptyCells, editor)
|
29817
|
+
);
|
29818
|
+
}).getOr(false);
|
29819
|
+
};
|
29820
|
+
|
29821
|
+
var deleteRange = function (editor) {
|
29822
|
+
var rootNode = Element.fromDom(editor.getBody());
|
29823
|
+
var rng = editor.selection.getRng();
|
29824
|
+
var selectedCells = SelectorFilter.descendants(rootNode, 'td[data-mce-selected],th[data-mce-selected]');
|
29825
|
+
|
29826
|
+
return selectedCells.length !== 0 ? emptyCells(editor, selectedCells) : handleCellRange(editor, rootNode, rng);
|
29827
|
+
};
|
29828
|
+
|
29829
|
+
var backspaceDelete = function (editor) {
|
29830
|
+
return editor.selection.isCollapsed() ? false : deleteRange(editor);
|
29831
|
+
};
|
29832
|
+
|
29833
|
+
return {
|
29834
|
+
backspaceDelete: backspaceDelete
|
29835
|
+
};
|
29836
|
+
}
|
29837
|
+
);
|
29838
|
+
|
29344
29839
|
/**
|
29345
29840
|
* Commands.js
|
29346
29841
|
*
|
@@ -29358,9 +29853,10 @@ define(
|
|
29358
29853
|
'tinymce.core.delete.BlockRangeDelete',
|
29359
29854
|
'tinymce.core.delete.CefDelete',
|
29360
29855
|
'tinymce.core.delete.DeleteUtils',
|
29361
|
-
'tinymce.core.delete.InlineBoundaryDelete'
|
29856
|
+
'tinymce.core.delete.InlineBoundaryDelete',
|
29857
|
+
'tinymce.core.delete.TableDelete'
|
29362
29858
|
],
|
29363
|
-
function (BlockBoundaryDelete, BlockRangeDelete, CefDelete, DeleteUtils, BoundaryDelete) {
|
29859
|
+
function (BlockBoundaryDelete, BlockRangeDelete, CefDelete, DeleteUtils, BoundaryDelete, TableDelete) {
|
29364
29860
|
var nativeCommand = function (editor, command) {
|
29365
29861
|
editor.getDoc().execCommand(command, false, null);
|
29366
29862
|
};
|
@@ -29372,6 +29868,8 @@ define(
|
|
29372
29868
|
return;
|
29373
29869
|
} else if (BlockBoundaryDelete.backspaceDelete(editor, false)) {
|
29374
29870
|
return;
|
29871
|
+
} else if (TableDelete.backspaceDelete(editor)) {
|
29872
|
+
return;
|
29375
29873
|
} else if (BlockRangeDelete.backspaceDelete(editor, false)) {
|
29376
29874
|
return;
|
29377
29875
|
} else {
|
@@ -29387,6 +29885,8 @@ define(
|
|
29387
29885
|
return;
|
29388
29886
|
} else if (BlockBoundaryDelete.backspaceDelete(editor, true)) {
|
29389
29887
|
return;
|
29888
|
+
} else if (TableDelete.backspaceDelete(editor)) {
|
29889
|
+
return;
|
29390
29890
|
} else if (BlockRangeDelete.backspaceDelete(editor, true)) {
|
29391
29891
|
return;
|
29392
29892
|
} else {
|
@@ -37723,6 +38223,296 @@ define(
|
|
37723
38223
|
}
|
37724
38224
|
);
|
37725
38225
|
|
38226
|
+
define(
|
38227
|
+
'ephox.sugar.impl.Style',
|
38228
|
+
|
38229
|
+
[
|
38230
|
+
|
38231
|
+
],
|
38232
|
+
|
38233
|
+
function () {
|
38234
|
+
// some elements, such as mathml, don't have style attributes
|
38235
|
+
var isSupported = function (dom) {
|
38236
|
+
return dom.style !== undefined;
|
38237
|
+
};
|
38238
|
+
|
38239
|
+
return {
|
38240
|
+
isSupported: isSupported
|
38241
|
+
};
|
38242
|
+
}
|
38243
|
+
);
|
38244
|
+
defineGlobal("global!window", window);
|
38245
|
+
define(
|
38246
|
+
'ephox.sugar.api.properties.Css',
|
38247
|
+
|
38248
|
+
[
|
38249
|
+
'ephox.katamari.api.Type',
|
38250
|
+
'ephox.katamari.api.Arr',
|
38251
|
+
'ephox.katamari.api.Obj',
|
38252
|
+
'ephox.katamari.api.Option',
|
38253
|
+
'ephox.sugar.api.properties.Attr',
|
38254
|
+
'ephox.sugar.api.node.Body',
|
38255
|
+
'ephox.sugar.api.node.Element',
|
38256
|
+
'ephox.sugar.api.node.Node',
|
38257
|
+
'ephox.sugar.impl.Style',
|
38258
|
+
'ephox.katamari.api.Strings',
|
38259
|
+
'global!Error',
|
38260
|
+
'global!console',
|
38261
|
+
'global!window'
|
38262
|
+
],
|
38263
|
+
|
38264
|
+
function (Type, Arr, Obj, Option, Attr, Body, Element, Node, Style, Strings, Error, console, window) {
|
38265
|
+
var internalSet = function (dom, property, value) {
|
38266
|
+
// This is going to hurt. Apologies.
|
38267
|
+
// JQuery coerces numbers to pixels for certain property names, and other times lets numbers through.
|
38268
|
+
// we're going to be explicit; strings only.
|
38269
|
+
if (!Type.isString(value)) {
|
38270
|
+
console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
|
38271
|
+
throw new Error('CSS value must be a string: ' + value);
|
38272
|
+
}
|
38273
|
+
|
38274
|
+
// removed: support for dom().style[property] where prop is camel case instead of normal property name
|
38275
|
+
if (Style.isSupported(dom)) dom.style.setProperty(property, value);
|
38276
|
+
};
|
38277
|
+
|
38278
|
+
var internalRemove = function (dom, property) {
|
38279
|
+
/*
|
38280
|
+
* IE9 and above - MDN doesn't have details, but here's a couple of random internet claims
|
38281
|
+
*
|
38282
|
+
* http://help.dottoro.com/ljopsjck.php
|
38283
|
+
* http://stackoverflow.com/a/7901886/7546
|
38284
|
+
*/
|
38285
|
+
if (Style.isSupported(dom)) dom.style.removeProperty(property);
|
38286
|
+
};
|
38287
|
+
|
38288
|
+
var set = function (element, property, value) {
|
38289
|
+
var dom = element.dom();
|
38290
|
+
internalSet(dom, property, value);
|
38291
|
+
};
|
38292
|
+
|
38293
|
+
var setAll = function (element, css) {
|
38294
|
+
var dom = element.dom();
|
38295
|
+
|
38296
|
+
Obj.each(css, function (v, k) {
|
38297
|
+
internalSet(dom, k, v);
|
38298
|
+
});
|
38299
|
+
};
|
38300
|
+
|
38301
|
+
var setOptions = function(element, css) {
|
38302
|
+
var dom = element.dom();
|
38303
|
+
|
38304
|
+
Obj.each(css, function (v, k) {
|
38305
|
+
v.fold(function () {
|
38306
|
+
internalRemove(dom, k);
|
38307
|
+
}, function (value) {
|
38308
|
+
internalSet(dom, k, value);
|
38309
|
+
});
|
38310
|
+
});
|
38311
|
+
};
|
38312
|
+
|
38313
|
+
/*
|
38314
|
+
* NOTE: For certain properties, this returns the "used value" which is subtly different to the "computed value" (despite calling getComputedStyle).
|
38315
|
+
* Blame CSS 2.0.
|
38316
|
+
*
|
38317
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
|
38318
|
+
*/
|
38319
|
+
var get = function (element, property) {
|
38320
|
+
var dom = element.dom();
|
38321
|
+
/*
|
38322
|
+
* IE9 and above per
|
38323
|
+
* https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle
|
38324
|
+
*
|
38325
|
+
* Not in numerosity, because it doesn't memoize and looking this up dynamically in performance critical code would be horrendous.
|
38326
|
+
*
|
38327
|
+
* JQuery has some magic here for IE popups, but we don't really need that.
|
38328
|
+
* It also uses element.ownerDocument.defaultView to handle iframes but that hasn't been required since FF 3.6.
|
38329
|
+
*/
|
38330
|
+
var styles = window.getComputedStyle(dom);
|
38331
|
+
var r = styles.getPropertyValue(property);
|
38332
|
+
|
38333
|
+
// jquery-ism: If r is an empty string, check that the element is not in a document. If it isn't, return the raw value.
|
38334
|
+
// Turns out we do this a lot.
|
38335
|
+
var v = (r === '' && !Body.inBody(element)) ? getUnsafeProperty(dom, property) : r;
|
38336
|
+
|
38337
|
+
// undefined is the more appropriate value for JS. JQuery coerces to an empty string, but screw that!
|
38338
|
+
return v === null ? undefined : v;
|
38339
|
+
};
|
38340
|
+
|
38341
|
+
var getUnsafeProperty = function (dom, property) {
|
38342
|
+
// removed: support for dom().style[property] where prop is camel case instead of normal property name
|
38343
|
+
// empty string is what the browsers (IE11 and Chrome) return when the propertyValue doesn't exists.
|
38344
|
+
return Style.isSupported(dom) ? dom.style.getPropertyValue(property) : '';
|
38345
|
+
};
|
38346
|
+
|
38347
|
+
/*
|
38348
|
+
* Gets the raw value from the style attribute. Useful for retrieving "used values" from the DOM:
|
38349
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
|
38350
|
+
*
|
38351
|
+
* Returns NONE if the property isn't set, or the value is an empty string.
|
38352
|
+
*/
|
38353
|
+
var getRaw = function (element, property) {
|
38354
|
+
var dom = element.dom();
|
38355
|
+
var raw = getUnsafeProperty(dom, property);
|
38356
|
+
|
38357
|
+
return Option.from(raw).filter(function (r) { return r.length > 0; });
|
38358
|
+
};
|
38359
|
+
|
38360
|
+
var isValidValue = function (tag, property, value) {
|
38361
|
+
var element = Element.fromTag(tag);
|
38362
|
+
set(element, property, value);
|
38363
|
+
var style = getRaw(element, property);
|
38364
|
+
return style.isSome();
|
38365
|
+
};
|
38366
|
+
|
38367
|
+
var remove = function (element, property) {
|
38368
|
+
var dom = element.dom();
|
38369
|
+
|
38370
|
+
internalRemove(dom, property);
|
38371
|
+
|
38372
|
+
if (Attr.has(element, 'style') && Strings.trim(Attr.get(element, 'style')) === '') {
|
38373
|
+
// No more styles left, remove the style attribute as well
|
38374
|
+
Attr.remove(element, 'style');
|
38375
|
+
}
|
38376
|
+
};
|
38377
|
+
|
38378
|
+
var preserve = function (element, f) {
|
38379
|
+
var oldStyles = Attr.get(element, 'style');
|
38380
|
+
var result = f(element);
|
38381
|
+
var restore = oldStyles === undefined ? Attr.remove : Attr.set;
|
38382
|
+
restore(element, 'style', oldStyles);
|
38383
|
+
return result;
|
38384
|
+
};
|
38385
|
+
|
38386
|
+
var copy = function (source, target) {
|
38387
|
+
var sourceDom = source.dom();
|
38388
|
+
var targetDom = target.dom();
|
38389
|
+
if (Style.isSupported(sourceDom) && Style.isSupported(targetDom)) {
|
38390
|
+
targetDom.style.cssText = sourceDom.style.cssText;
|
38391
|
+
}
|
38392
|
+
};
|
38393
|
+
|
38394
|
+
var reflow = function (e) {
|
38395
|
+
/* NOTE:
|
38396
|
+
* do not rely on this return value.
|
38397
|
+
* It's here so the closure compiler doesn't optimise the property access away.
|
38398
|
+
*/
|
38399
|
+
return e.dom().offsetWidth;
|
38400
|
+
};
|
38401
|
+
|
38402
|
+
var transferOne = function (source, destination, style) {
|
38403
|
+
getRaw(source, style).each(function (value) {
|
38404
|
+
// NOTE: We don't want to clobber any existing inline styles.
|
38405
|
+
if (getRaw(destination, style).isNone()) set(destination, style, value);
|
38406
|
+
});
|
38407
|
+
};
|
38408
|
+
|
38409
|
+
var transfer = function (source, destination, styles) {
|
38410
|
+
if (!Node.isElement(source) || !Node.isElement(destination)) return;
|
38411
|
+
Arr.each(styles, function (style) {
|
38412
|
+
transferOne(source, destination, style);
|
38413
|
+
});
|
38414
|
+
};
|
38415
|
+
|
38416
|
+
return {
|
38417
|
+
copy: copy,
|
38418
|
+
set: set,
|
38419
|
+
preserve: preserve,
|
38420
|
+
setAll: setAll,
|
38421
|
+
setOptions: setOptions,
|
38422
|
+
remove: remove,
|
38423
|
+
get: get,
|
38424
|
+
getRaw: getRaw,
|
38425
|
+
isValidValue: isValidValue,
|
38426
|
+
reflow: reflow,
|
38427
|
+
transfer: transfer
|
38428
|
+
};
|
38429
|
+
}
|
38430
|
+
);
|
38431
|
+
|
38432
|
+
/**
|
38433
|
+
* EditorView.js
|
38434
|
+
*
|
38435
|
+
* Released under LGPL License.
|
38436
|
+
* Copyright (c) 1999-2016 Ephox Corp. All rights reserved
|
38437
|
+
*
|
38438
|
+
* License: http://www.tinymce.com/license
|
38439
|
+
* Contributing: http://www.tinymce.com/contributing
|
38440
|
+
*/
|
38441
|
+
|
38442
|
+
define(
|
38443
|
+
'tinymce.core.EditorView',
|
38444
|
+
[
|
38445
|
+
'ephox.katamari.api.Fun',
|
38446
|
+
'ephox.katamari.api.Option',
|
38447
|
+
'ephox.sugar.api.dom.Compare',
|
38448
|
+
'ephox.sugar.api.node.Element',
|
38449
|
+
'ephox.sugar.api.properties.Css',
|
38450
|
+
'ephox.sugar.api.search.Traverse'
|
38451
|
+
],
|
38452
|
+
function (Fun, Option, Compare, Element, Css, Traverse) {
|
38453
|
+
var getProp = function (propName, elm) {
|
38454
|
+
var rawElm = elm.dom();
|
38455
|
+
return rawElm[propName];
|
38456
|
+
};
|
38457
|
+
|
38458
|
+
var getComputedSizeProp = function (propName, elm) {
|
38459
|
+
return parseInt(Css.get(elm, propName), 10);
|
38460
|
+
};
|
38461
|
+
|
38462
|
+
var getClientWidth = Fun.curry(getProp, 'clientWidth');
|
38463
|
+
var getClientHeight = Fun.curry(getProp, 'clientHeight');
|
38464
|
+
var getMarginTop = Fun.curry(getComputedSizeProp, 'margin-top');
|
38465
|
+
var getMarginLeft = Fun.curry(getComputedSizeProp, 'margin-left');
|
38466
|
+
|
38467
|
+
var getBoundingClientRect = function (elm) {
|
38468
|
+
return elm.dom().getBoundingClientRect();
|
38469
|
+
};
|
38470
|
+
|
38471
|
+
var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
|
38472
|
+
var clientWidth = getClientWidth(bodyElm);
|
38473
|
+
var clientHeight = getClientHeight(bodyElm);
|
38474
|
+
|
38475
|
+
return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
|
38476
|
+
};
|
38477
|
+
|
38478
|
+
var transpose = function (inline, elm, clientX, clientY) {
|
38479
|
+
var clientRect = getBoundingClientRect(elm);
|
38480
|
+
var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;
|
38481
|
+
var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;
|
38482
|
+
var x = clientX - deltaX;
|
38483
|
+
var y = clientY - deltaY;
|
38484
|
+
|
38485
|
+
return { x: x, y: y };
|
38486
|
+
};
|
38487
|
+
|
38488
|
+
// Checks if the specified coordinate is within the visual content area excluding the scrollbars
|
38489
|
+
var isXYInContentArea = function (editor, clientX, clientY) {
|
38490
|
+
var bodyElm = Element.fromDom(editor.getBody());
|
38491
|
+
var targetElm = editor.inline ? bodyElm : Traverse.documentElement(bodyElm);
|
38492
|
+
var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
|
38493
|
+
|
38494
|
+
return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
|
38495
|
+
};
|
38496
|
+
|
38497
|
+
var fromDomSafe = function (node) {
|
38498
|
+
return Option.from(node).map(Element.fromDom);
|
38499
|
+
};
|
38500
|
+
|
38501
|
+
var isEditorAttachedToDom = function (editor) {
|
38502
|
+
var rawContainer = editor.inline ? editor.getBody() : editor.getContentAreaContainer();
|
38503
|
+
|
38504
|
+
return fromDomSafe(rawContainer).map(function (container) {
|
38505
|
+
return Compare.contains(Traverse.owner(container), container);
|
38506
|
+
}).getOr(false);
|
38507
|
+
};
|
38508
|
+
|
38509
|
+
return {
|
38510
|
+
isXYInContentArea: isXYInContentArea,
|
38511
|
+
isEditorAttachedToDom: isEditorAttachedToDom
|
38512
|
+
};
|
38513
|
+
}
|
38514
|
+
);
|
38515
|
+
|
37726
38516
|
/**
|
37727
38517
|
* Tooltip.js
|
37728
38518
|
*
|
@@ -38084,6 +38874,8 @@ define(
|
|
38084
38874
|
|
38085
38875
|
self._super(settings);
|
38086
38876
|
|
38877
|
+
self.maxWidth = settings.maxWidth;
|
38878
|
+
|
38087
38879
|
if (settings.text) {
|
38088
38880
|
self.text(settings.text);
|
38089
38881
|
}
|
@@ -38131,9 +38923,7 @@ define(
|
|
38131
38923
|
icon = '<i class="' + prefix + 'ico' + ' ' + prefix + 'i-' + self.icon + '"></i>';
|
38132
38924
|
}
|
38133
38925
|
|
38134
|
-
|
38135
|
-
notificationStyle = ' style="background-color: ' + self.color + '"';
|
38136
|
-
}
|
38926
|
+
notificationStyle = ' style="max-width: ' + self.maxWidth + 'px;' + (self.color ? 'background-color: ' + self.color + ';"' : '"');
|
38137
38927
|
|
38138
38928
|
if (self.closeButton) {
|
38139
38929
|
closeButton = '<button type="button" class="' + prefix + 'close" aria-hidden="true">\u00d7</button>';
|
@@ -38237,20 +39027,31 @@ define(
|
|
38237
39027
|
define(
|
38238
39028
|
'tinymce.core.NotificationManager',
|
38239
39029
|
[
|
38240
|
-
|
38241
|
-
|
38242
|
-
|
39030
|
+
'tinymce.core.EditorView',
|
39031
|
+
'tinymce.core.ui.DomUtils',
|
39032
|
+
'tinymce.core.ui.Notification',
|
39033
|
+
'tinymce.core.util.Delay',
|
39034
|
+
'tinymce.core.util.Tools'
|
38243
39035
|
],
|
38244
|
-
function (Notification, Delay, Tools) {
|
39036
|
+
function (EditorView, DomUtils, Notification, Delay, Tools) {
|
38245
39037
|
return function (editor) {
|
38246
39038
|
var self = this, notifications = [];
|
38247
39039
|
|
39040
|
+
var getContainerWidth = function () {
|
39041
|
+
var container = editor.inline ? editor.getElement() : editor.getContentAreaContainer();
|
39042
|
+
return DomUtils.getSize(container).width;
|
39043
|
+
};
|
39044
|
+
|
38248
39045
|
function getLastNotification() {
|
38249
39046
|
if (notifications.length) {
|
38250
39047
|
return notifications[notifications.length - 1];
|
38251
39048
|
}
|
38252
39049
|
}
|
38253
39050
|
|
39051
|
+
function getEditorContainer(editor) {
|
39052
|
+
return editor.inline ? editor.getElement() : editor.getContentAreaContainer();
|
39053
|
+
}
|
39054
|
+
|
38254
39055
|
self.notifications = notifications;
|
38255
39056
|
|
38256
39057
|
function resizeWindowEvent() {
|
@@ -38271,7 +39072,7 @@ define(
|
|
38271
39072
|
function positionNotifications() {
|
38272
39073
|
if (notifications.length > 0) {
|
38273
39074
|
var firstItem = notifications.slice(0, 1)[0];
|
38274
|
-
var container =
|
39075
|
+
var container = getEditorContainer(editor);
|
38275
39076
|
firstItem.moveRel(container, 'tc-tc');
|
38276
39077
|
if (notifications.length > 1) {
|
38277
39078
|
for (var i = 1; i < notifications.length; i++) {
|
@@ -38300,7 +39101,7 @@ define(
|
|
38300
39101
|
*/
|
38301
39102
|
self.open = function (args) {
|
38302
39103
|
// Never open notification if editor has been removed.
|
38303
|
-
if (editor.removed) {
|
39104
|
+
if (editor.removed || !EditorView.isEditorAttachedToDom(editor)) {
|
38304
39105
|
return;
|
38305
39106
|
}
|
38306
39107
|
|
@@ -38311,6 +39112,9 @@ define(
|
|
38311
39112
|
var duplicate = findDuplicateMessage(notifications, args);
|
38312
39113
|
|
38313
39114
|
if (duplicate === null) {
|
39115
|
+
|
39116
|
+
args = Tools.extend(args, { maxWidth: getContainerWidth() });
|
39117
|
+
|
38314
39118
|
notif = new Notification(args);
|
38315
39119
|
notifications.push(notif);
|
38316
39120
|
|
@@ -38536,7 +39340,7 @@ define(
|
|
38536
39340
|
}
|
38537
39341
|
|
38538
39342
|
delegate = function (e) {
|
38539
|
-
var target = e.target, editors = editor.editorManager.
|
39343
|
+
var target = e.target, editors = editor.editorManager.get(), i = editors.length;
|
38540
39344
|
|
38541
39345
|
while (i--) {
|
38542
39346
|
var body = editors[i].getBody();
|
@@ -38861,7 +39665,6 @@ define(
|
|
38861
39665
|
}
|
38862
39666
|
);
|
38863
39667
|
|
38864
|
-
defineGlobal("global!window", window);
|
38865
39668
|
/**
|
38866
39669
|
* ErrorReporter.js
|
38867
39670
|
*
|
@@ -38881,7 +39684,7 @@ defineGlobal("global!window", window);
|
|
38881
39684
|
define(
|
38882
39685
|
'tinymce.core.ErrorReporter',
|
38883
39686
|
[
|
38884
|
-
|
39687
|
+
'tinymce.core.AddOnManager'
|
38885
39688
|
],
|
38886
39689
|
function (AddOnManager) {
|
38887
39690
|
var PluginManager = AddOnManager.PluginManager;
|
@@ -38929,10 +39732,6 @@ define(
|
|
38929
39732
|
displayError(editor, pluginUrlToMessage(editor, url));
|
38930
39733
|
};
|
38931
39734
|
|
38932
|
-
var contentCssError = function (editor, urls) {
|
38933
|
-
displayError(editor, 'Failed to load content css: ' + urls[0]);
|
38934
|
-
};
|
38935
|
-
|
38936
39735
|
var initError = function (message) {
|
38937
39736
|
var console = window.console;
|
38938
39737
|
if (console && !window.test) { // Skip test env
|
@@ -38948,7 +39747,6 @@ define(
|
|
38948
39747
|
pluginLoadError: pluginLoadError,
|
38949
39748
|
uploadError: uploadError,
|
38950
39749
|
displayError: displayError,
|
38951
|
-
contentCssError: contentCssError,
|
38952
39750
|
initError: initError
|
38953
39751
|
};
|
38954
39752
|
}
|
@@ -39229,6 +40027,45 @@ define(
|
|
39229
40027
|
};
|
39230
40028
|
}
|
39231
40029
|
);
|
40030
|
+
define(
|
40031
|
+
'ephox.sand.api.Window',
|
40032
|
+
|
40033
|
+
[
|
40034
|
+
'ephox.sand.util.Global'
|
40035
|
+
],
|
40036
|
+
|
40037
|
+
function (Global) {
|
40038
|
+
/******************************************************************************************
|
40039
|
+
* BIG BIG WARNING: Don't put anything other than top-level window functions in here.
|
40040
|
+
*
|
40041
|
+
* Objects that are technically available as window.X should be in their own module X (e.g. Blob, FileReader, URL).
|
40042
|
+
******************************************************************************************
|
40043
|
+
*/
|
40044
|
+
|
40045
|
+
/*
|
40046
|
+
* IE10 and above per
|
40047
|
+
* https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame
|
40048
|
+
*/
|
40049
|
+
var requestAnimationFrame = function (callback) {
|
40050
|
+
var f = Global.getOrDie('requestAnimationFrame');
|
40051
|
+
f(callback);
|
40052
|
+
};
|
40053
|
+
|
40054
|
+
/*
|
40055
|
+
* IE10 and above per
|
40056
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64.atob
|
40057
|
+
*/
|
40058
|
+
var atob = function (base64) {
|
40059
|
+
var f = Global.getOrDie('atob');
|
40060
|
+
return f(base64);
|
40061
|
+
};
|
40062
|
+
|
40063
|
+
return {
|
40064
|
+
atob: atob,
|
40065
|
+
requestAnimationFrame: requestAnimationFrame
|
40066
|
+
};
|
40067
|
+
}
|
40068
|
+
);
|
39232
40069
|
/**
|
39233
40070
|
* Conversions.js
|
39234
40071
|
*
|
@@ -39248,9 +40085,10 @@ define(
|
|
39248
40085
|
define(
|
39249
40086
|
'tinymce.core.file.Conversions',
|
39250
40087
|
[
|
39251
|
-
|
40088
|
+
'ephox.sand.api.Window',
|
40089
|
+
'tinymce.core.util.Promise'
|
39252
40090
|
],
|
39253
|
-
function (Promise) {
|
40091
|
+
function (Window, Promise) {
|
39254
40092
|
function blobUriToBlob(url) {
|
39255
40093
|
return new Promise(function (resolve, reject) {
|
39256
40094
|
|
@@ -39308,7 +40146,7 @@ define(
|
|
39308
40146
|
|
39309
40147
|
// Might throw error if data isn't proper base64
|
39310
40148
|
try {
|
39311
|
-
str = atob(uri.data);
|
40149
|
+
str = Window.atob(uri.data);
|
39312
40150
|
} catch (e) {
|
39313
40151
|
resolve(new Blob([]));
|
39314
40152
|
return;
|
@@ -39530,6 +40368,40 @@ define(
|
|
39530
40368
|
};
|
39531
40369
|
}
|
39532
40370
|
);
|
40371
|
+
define(
|
40372
|
+
'ephox.sand.api.URL',
|
40373
|
+
|
40374
|
+
[
|
40375
|
+
'ephox.sand.util.Global'
|
40376
|
+
],
|
40377
|
+
|
40378
|
+
function (Global) {
|
40379
|
+
/*
|
40380
|
+
* IE10 and above per
|
40381
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/URL.createObjectURL
|
40382
|
+
*
|
40383
|
+
* Also Safari 6.1+
|
40384
|
+
* Safari 6.0 has 'webkitURL' instead, but doesn't support flexbox so we
|
40385
|
+
* aren't supporting it anyway
|
40386
|
+
*/
|
40387
|
+
var url = function () {
|
40388
|
+
return Global.getOrDie('URL');
|
40389
|
+
};
|
40390
|
+
|
40391
|
+
var createObjectURL = function (blob) {
|
40392
|
+
return url().createObjectURL(blob);
|
40393
|
+
};
|
40394
|
+
|
40395
|
+
var revokeObjectURL = function (u) {
|
40396
|
+
url().revokeObjectURL(u);
|
40397
|
+
};
|
40398
|
+
|
40399
|
+
return {
|
40400
|
+
createObjectURL: createObjectURL,
|
40401
|
+
revokeObjectURL: revokeObjectURL
|
40402
|
+
};
|
40403
|
+
}
|
40404
|
+
);
|
39533
40405
|
/**
|
39534
40406
|
* Uuid.js
|
39535
40407
|
*
|
@@ -39572,7 +40444,6 @@ define(
|
|
39572
40444
|
}
|
39573
40445
|
);
|
39574
40446
|
|
39575
|
-
defineGlobal("global!URL", URL);
|
39576
40447
|
/**
|
39577
40448
|
* BlobCache.js
|
39578
40449
|
*
|
@@ -39592,12 +40463,12 @@ defineGlobal("global!URL", URL);
|
|
39592
40463
|
define(
|
39593
40464
|
'tinymce.core.file.BlobCache',
|
39594
40465
|
[
|
40466
|
+
'ephox.sand.api.URL',
|
39595
40467
|
'tinymce.core.util.Arr',
|
39596
40468
|
'tinymce.core.util.Fun',
|
39597
|
-
'tinymce.core.util.Uuid'
|
39598
|
-
'global!URL'
|
40469
|
+
'tinymce.core.util.Uuid'
|
39599
40470
|
],
|
39600
|
-
function (Arr, Fun, Uuid
|
40471
|
+
function (URL, Arr, Fun, Uuid) {
|
39601
40472
|
return function () {
|
39602
40473
|
var cache = [], constant = Fun.constant;
|
39603
40474
|
|
@@ -39968,7 +40839,7 @@ define(
|
|
39968
40839
|
var blobInfo = blobCache.getByUri(blobUri);
|
39969
40840
|
|
39970
40841
|
if (!blobInfo) {
|
39971
|
-
blobInfo = Arr.reduce(editor.editorManager.
|
40842
|
+
blobInfo = Arr.reduce(editor.editorManager.get(), function (result, editor) {
|
39972
40843
|
return result || editor.editorUpload && editor.editorUpload.blobCache.getByUri(blobUri);
|
39973
40844
|
}, null);
|
39974
40845
|
}
|
@@ -41145,7 +42016,7 @@ define(
|
|
41145
42016
|
);
|
41146
42017
|
|
41147
42018
|
/**
|
41148
|
-
*
|
42019
|
+
* InsertNewLine.js
|
41149
42020
|
*
|
41150
42021
|
* Released under LGPL License.
|
41151
42022
|
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
@@ -41154,23 +42025,17 @@ define(
|
|
41154
42025
|
* Contributing: http://www.tinymce.com/contributing
|
41155
42026
|
*/
|
41156
42027
|
|
41157
|
-
/**
|
41158
|
-
* Contains logic for handling the enter key to split/generate block elements.
|
41159
|
-
*/
|
41160
42028
|
define(
|
41161
|
-
'tinymce.core.keyboard.
|
42029
|
+
'tinymce.core.keyboard.InsertNewLine',
|
41162
42030
|
[
|
41163
42031
|
'tinymce.core.caret.CaretContainer',
|
41164
42032
|
'tinymce.core.dom.NodeType',
|
41165
42033
|
'tinymce.core.dom.RangeUtils',
|
41166
42034
|
'tinymce.core.dom.TreeWalker',
|
41167
|
-
'tinymce.core.Env',
|
41168
42035
|
'tinymce.core.text.Zwsp',
|
41169
42036
|
'tinymce.core.util.Tools'
|
41170
42037
|
],
|
41171
|
-
function (CaretContainer, NodeType, RangeUtils, TreeWalker,
|
41172
|
-
var isIE = Env.ie && Env.ie < 11;
|
41173
|
-
|
42038
|
+
function (CaretContainer, NodeType, RangeUtils, TreeWalker, Zwsp, Tools) {
|
41174
42039
|
var isEmptyAnchor = function (elm) {
|
41175
42040
|
return elm && elm.nodeName === "A" && Tools.trim(Zwsp.trim(elm.innerText || elm.textContent)).length === 0;
|
41176
42041
|
};
|
@@ -41188,8 +42053,7 @@ define(
|
|
41188
42053
|
};
|
41189
42054
|
|
41190
42055
|
var emptyBlock = function (elm) {
|
41191
|
-
|
41192
|
-
elm.innerHTML = !isIE ? '<br data-mce-bogus="1">' : '';
|
42056
|
+
elm.innerHTML = '<br data-mce-bogus="1">';
|
41193
42057
|
};
|
41194
42058
|
|
41195
42059
|
var containerAndSiblingName = function (container, nodeName) {
|
@@ -41213,19 +42077,6 @@ define(
|
|
41213
42077
|
dom.getContentEditable(node) !== "true";
|
41214
42078
|
};
|
41215
42079
|
|
41216
|
-
// Renders empty block on IE
|
41217
|
-
var renderBlockOnIE = function (dom, selection, block) {
|
41218
|
-
var oldRng;
|
41219
|
-
|
41220
|
-
if (dom.isBlock(block)) {
|
41221
|
-
oldRng = selection.getRng();
|
41222
|
-
block.appendChild(dom.create('span', null, '\u00a0'));
|
41223
|
-
selection.select(block);
|
41224
|
-
block.lastChild.outerHTML = '';
|
41225
|
-
selection.setRng(oldRng);
|
41226
|
-
}
|
41227
|
-
};
|
41228
|
-
|
41229
42080
|
// Remove the first empty inline element of the block so this: <p><b><em></em></b>x</p> becomes this: <p>x</p>
|
41230
42081
|
var trimInlineElementsOnLeftSideOfBlock = function (dom, nonEmptyElementsMap, block) {
|
41231
42082
|
var node = block, firstChilds = [], i;
|
@@ -41285,600 +42136,593 @@ define(
|
|
41285
42136
|
}
|
41286
42137
|
};
|
41287
42138
|
|
41288
|
-
|
41289
|
-
|
41290
|
-
|
41291
|
-
|
41292
|
-
|
41293
|
-
function handleEnterKey(evt) {
|
41294
|
-
var rng, tmpRng, editableRoot, container, offset, parentBlock, documentMode, shiftKey,
|
41295
|
-
newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
|
41296
|
-
|
41297
|
-
// Moves the caret to a suitable position within the root for example in the first non
|
41298
|
-
// pure whitespace text node or before an image
|
41299
|
-
function moveToCaretPosition(root) {
|
41300
|
-
var walker, node, rng, lastNode = root, tempElm;
|
41301
|
-
|
41302
|
-
if (!root) {
|
41303
|
-
return;
|
41304
|
-
}
|
41305
|
-
|
41306
|
-
// Old IE versions doesn't properly render blocks with br elements in them
|
41307
|
-
// For example <p><br></p> wont be rendered correctly in a contentEditable area
|
41308
|
-
// until you remove the br producing <p></p>
|
41309
|
-
if (Env.ie && Env.ie < 9 && parentBlock && parentBlock.firstChild) {
|
41310
|
-
if (parentBlock.firstChild == parentBlock.lastChild && parentBlock.firstChild.tagName == 'BR') {
|
41311
|
-
dom.remove(parentBlock.firstChild);
|
41312
|
-
}
|
41313
|
-
}
|
42139
|
+
// Inserts a BR element if the forced_root_block option is set to false or empty string
|
42140
|
+
var insertBr = function (editor, evt) {
|
42141
|
+
editor.execCommand("InsertLineBreak", false, evt);
|
42142
|
+
};
|
41314
42143
|
|
41315
|
-
|
41316
|
-
|
42144
|
+
// Trims any linebreaks at the beginning of node user for example when pressing enter in a PRE element
|
42145
|
+
var trimLeadingLineBreaks = function (node) {
|
42146
|
+
do {
|
42147
|
+
if (node.nodeType === 3) {
|
42148
|
+
node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, '');
|
42149
|
+
}
|
41317
42150
|
|
41318
|
-
|
41319
|
-
|
41320
|
-
|
41321
|
-
}
|
42151
|
+
node = node.firstChild;
|
42152
|
+
} while (node);
|
42153
|
+
};
|
41322
42154
|
|
41323
|
-
|
42155
|
+
var getEditableRoot = function (dom, node) {
|
42156
|
+
var root = dom.getRoot(), parent, editableRoot;
|
41324
42157
|
|
41325
|
-
|
41326
|
-
|
41327
|
-
|
41328
|
-
|
41329
|
-
|
41330
|
-
|
42158
|
+
// Get all parents until we hit a non editable parent or the root
|
42159
|
+
parent = node;
|
42160
|
+
while (parent !== root && dom.getContentEditable(parent) !== "false") {
|
42161
|
+
if (dom.getContentEditable(parent) === "true") {
|
42162
|
+
editableRoot = parent;
|
42163
|
+
}
|
41331
42164
|
|
41332
|
-
|
41333
|
-
|
42165
|
+
parent = parent.parentNode;
|
42166
|
+
}
|
41334
42167
|
|
41335
|
-
|
41336
|
-
|
41337
|
-
rng.setStart(node, 0);
|
41338
|
-
rng.setEnd(node, 0);
|
41339
|
-
break;
|
41340
|
-
}
|
42168
|
+
return parent !== root ? editableRoot : root;
|
42169
|
+
};
|
41341
42170
|
|
41342
|
-
|
41343
|
-
|
41344
|
-
rng.setEndBefore(node);
|
41345
|
-
break;
|
41346
|
-
}
|
42171
|
+
var setForcedBlockAttrs = function (editor, node) {
|
42172
|
+
var forcedRootBlockName = editor.settings.forced_root_block;
|
41347
42173
|
|
41348
|
-
|
41349
|
-
|
41350
|
-
|
42174
|
+
if (forcedRootBlockName && forcedRootBlockName.toLowerCase() === node.tagName.toLowerCase()) {
|
42175
|
+
editor.dom.setAttribs(node, editor.settings.forced_root_block_attrs);
|
42176
|
+
}
|
42177
|
+
};
|
41351
42178
|
|
41352
|
-
|
41353
|
-
|
41354
|
-
|
41355
|
-
|
41356
|
-
} else {
|
41357
|
-
if (root.nodeName == 'BR') {
|
41358
|
-
if (root.nextSibling && dom.isBlock(root.nextSibling)) {
|
41359
|
-
// Trick on older IE versions to render the caret before the BR between two lists
|
41360
|
-
if (!documentMode || documentMode < 9) {
|
41361
|
-
tempElm = dom.create('br');
|
41362
|
-
root.parentNode.insertBefore(tempElm, root);
|
41363
|
-
}
|
42179
|
+
// Wraps any text nodes or inline elements in the specified forced root block name
|
42180
|
+
var wrapSelfAndSiblingsInDefaultBlock = function (editor, newBlockName, rng, container, offset) {
|
42181
|
+
var newBlock, parentBlock, startNode, node, next, rootBlockName, blockName = newBlockName || 'P';
|
42182
|
+
var dom = editor.dom, editableRoot = getEditableRoot(dom, container);
|
41364
42183
|
|
41365
|
-
|
41366
|
-
|
41367
|
-
|
41368
|
-
|
41369
|
-
rng.setEndAfter(root);
|
41370
|
-
}
|
41371
|
-
} else {
|
41372
|
-
rng.setStart(root, 0);
|
41373
|
-
rng.setEnd(root, 0);
|
41374
|
-
}
|
41375
|
-
}
|
42184
|
+
// Not in a block element or in a table cell or caption
|
42185
|
+
parentBlock = dom.getParent(container, dom.isBlock);
|
42186
|
+
if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
|
42187
|
+
parentBlock = parentBlock || editableRoot;
|
41376
42188
|
|
41377
|
-
|
42189
|
+
if (parentBlock == editor.getBody() || isTableCell(parentBlock)) {
|
42190
|
+
rootBlockName = parentBlock.nodeName.toLowerCase();
|
42191
|
+
} else {
|
42192
|
+
rootBlockName = parentBlock.parentNode.nodeName.toLowerCase();
|
42193
|
+
}
|
41378
42194
|
|
41379
|
-
|
41380
|
-
dom.
|
41381
|
-
|
42195
|
+
if (!parentBlock.hasChildNodes()) {
|
42196
|
+
newBlock = dom.create(blockName);
|
42197
|
+
setForcedBlockAttrs(editor, newBlock);
|
42198
|
+
parentBlock.appendChild(newBlock);
|
42199
|
+
rng.setStart(newBlock, 0);
|
42200
|
+
rng.setEnd(newBlock, 0);
|
42201
|
+
return newBlock;
|
41382
42202
|
}
|
41383
42203
|
|
41384
|
-
|
41385
|
-
|
42204
|
+
// Find parent that is the first child of parentBlock
|
42205
|
+
node = container;
|
42206
|
+
while (node.parentNode != parentBlock) {
|
42207
|
+
node = node.parentNode;
|
42208
|
+
}
|
41386
42209
|
|
41387
|
-
|
41388
|
-
|
41389
|
-
|
42210
|
+
// Loop left to find start node start wrapping at
|
42211
|
+
while (node && !dom.isBlock(node)) {
|
42212
|
+
startNode = node;
|
42213
|
+
node = node.previousSibling;
|
41390
42214
|
}
|
41391
42215
|
|
41392
|
-
|
41393
|
-
|
41394
|
-
|
41395
|
-
|
42216
|
+
if (startNode && editor.schema.isValidChild(rootBlockName, blockName.toLowerCase())) {
|
42217
|
+
newBlock = dom.create(blockName);
|
42218
|
+
setForcedBlockAttrs(editor, newBlock);
|
42219
|
+
startNode.parentNode.insertBefore(newBlock, startNode);
|
41396
42220
|
|
41397
|
-
|
41398
|
-
|
41399
|
-
|
41400
|
-
|
41401
|
-
|
42221
|
+
// Start wrapping until we hit a block
|
42222
|
+
node = startNode;
|
42223
|
+
while (node && !dom.isBlock(node)) {
|
42224
|
+
next = node.nextSibling;
|
42225
|
+
newBlock.appendChild(node);
|
42226
|
+
node = next;
|
41402
42227
|
}
|
41403
42228
|
|
41404
|
-
|
42229
|
+
// Restore range to it's past location
|
42230
|
+
rng.setStart(container, offset);
|
42231
|
+
rng.setEnd(container, offset);
|
42232
|
+
}
|
42233
|
+
}
|
41405
42234
|
|
41406
|
-
|
41407
|
-
|
41408
|
-
dom.setAttrib(block, 'class', null);
|
41409
|
-
} else {
|
41410
|
-
// Clone any parent styles
|
41411
|
-
do {
|
41412
|
-
if (textInlineElements[node.nodeName]) {
|
41413
|
-
// Never clone a caret containers
|
41414
|
-
if (node.id == '_mce_caret') {
|
41415
|
-
continue;
|
41416
|
-
}
|
42235
|
+
return container;
|
42236
|
+
};
|
41417
42237
|
|
41418
|
-
|
41419
|
-
|
42238
|
+
// Adds a BR at the end of blocks that only contains an IMG or INPUT since
|
42239
|
+
// these might be floated and then they won't expand the block
|
42240
|
+
var addBrToBlockIfNeeded = function (dom, block) {
|
42241
|
+
var lastChild;
|
41420
42242
|
|
41421
|
-
|
41422
|
-
|
41423
|
-
block.appendChild(clonedNode);
|
41424
|
-
} else {
|
41425
|
-
caretNode = clonedNode;
|
41426
|
-
block.appendChild(clonedNode);
|
41427
|
-
}
|
41428
|
-
}
|
41429
|
-
} while ((node = node.parentNode) && node != editableRoot);
|
41430
|
-
}
|
42243
|
+
// IE will render the blocks correctly other browsers needs a BR
|
42244
|
+
block.normalize(); // Remove empty text nodes that got left behind by the extract
|
41431
42245
|
|
41432
|
-
|
41433
|
-
|
41434
|
-
|
41435
|
-
|
42246
|
+
// Check if the block is empty or contains a floated last child
|
42247
|
+
lastChild = block.lastChild;
|
42248
|
+
if (!lastChild || (/^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true)))) {
|
42249
|
+
dom.add(block, 'br');
|
42250
|
+
}
|
42251
|
+
};
|
41436
42252
|
|
41437
|
-
|
41438
|
-
|
42253
|
+
var getContainerBlock = function (containerBlock) {
|
42254
|
+
var containerBlockParent = containerBlock.parentNode;
|
42255
|
+
|
42256
|
+
if (/^(LI|DT|DD)$/.test(containerBlockParent.nodeName)) {
|
42257
|
+
return containerBlockParent;
|
42258
|
+
}
|
41439
42259
|
|
41440
|
-
|
41441
|
-
|
41442
|
-
var walker, node, name, normalizedOffset;
|
42260
|
+
return containerBlock;
|
42261
|
+
};
|
41443
42262
|
|
41444
|
-
|
42263
|
+
var isFirstOrLastLi = function (containerBlock, parentBlock, first) {
|
42264
|
+
var node = containerBlock[first ? 'firstChild' : 'lastChild'];
|
41445
42265
|
|
41446
|
-
|
41447
|
-
|
41448
|
-
|
41449
|
-
|
42266
|
+
// Find first/last element since there might be whitespace there
|
42267
|
+
while (node) {
|
42268
|
+
if (node.nodeType == 1) {
|
42269
|
+
break;
|
42270
|
+
}
|
41450
42271
|
|
41451
|
-
|
41452
|
-
|
41453
|
-
return true;
|
41454
|
-
}
|
42272
|
+
node = node[first ? 'nextSibling' : 'previousSibling'];
|
42273
|
+
}
|
41455
42274
|
|
41456
|
-
|
41457
|
-
|
41458
|
-
return true;
|
41459
|
-
}
|
42275
|
+
return node === parentBlock;
|
42276
|
+
};
|
41460
42277
|
|
41461
|
-
|
41462
|
-
|
41463
|
-
|
41464
|
-
|
42278
|
+
var insert = function (editor, evt) {
|
42279
|
+
var tmpRng, editableRoot, container, offset, parentBlock, shiftKey;
|
42280
|
+
var newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
|
42281
|
+
var dom = editor.dom, selection = editor.selection, settings = editor.settings;
|
42282
|
+
var schema = editor.schema, nonEmptyElementsMap = schema.getNonEmptyElements();
|
42283
|
+
var rng = editor.selection.getRng();
|
41465
42284
|
|
41466
|
-
|
41467
|
-
|
42285
|
+
// Moves the caret to a suitable position within the root for example in the first non
|
42286
|
+
// pure whitespace text node or before an image
|
42287
|
+
function moveToCaretPosition(root) {
|
42288
|
+
var walker, node, rng, lastNode = root, tempElm;
|
42289
|
+
var moveCaretBeforeOnEnterElementsMap = schema.getMoveCaretBeforeOnEnterElements();
|
41468
42290
|
|
41469
|
-
|
41470
|
-
|
41471
|
-
|
41472
|
-
walker.prev();
|
41473
|
-
} else if (!start && normalizedOffset == container.nodeValue.length) {
|
41474
|
-
walker.next();
|
41475
|
-
}
|
41476
|
-
}
|
42291
|
+
if (!root) {
|
42292
|
+
return;
|
42293
|
+
}
|
41477
42294
|
|
41478
|
-
|
41479
|
-
|
41480
|
-
// Ignore bogus elements
|
41481
|
-
if (!node.getAttribute('data-mce-bogus')) {
|
41482
|
-
// Keep empty elements like <img /> <input /> but not trailing br:s like <p>text|<br></p>
|
41483
|
-
name = node.nodeName.toLowerCase();
|
41484
|
-
if (nonEmptyElementsMap[name] && name !== 'br') {
|
41485
|
-
return false;
|
41486
|
-
}
|
41487
|
-
}
|
41488
|
-
} else if (node.nodeType === 3 && !/^[ \t\r\n]*$/.test(node.nodeValue)) {
|
41489
|
-
return false;
|
41490
|
-
}
|
42295
|
+
if (/^(LI|DT|DD)$/.test(root.nodeName)) {
|
42296
|
+
var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);
|
41491
42297
|
|
41492
|
-
|
41493
|
-
|
41494
|
-
} else {
|
41495
|
-
walker.next();
|
41496
|
-
}
|
42298
|
+
if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
|
42299
|
+
root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
|
41497
42300
|
}
|
41498
|
-
|
41499
|
-
return true;
|
41500
42301
|
}
|
41501
42302
|
|
41502
|
-
|
41503
|
-
|
41504
|
-
var newBlock, parentBlock, startNode, node, next, rootBlockName, blockName = newBlockName || 'P';
|
42303
|
+
rng = dom.createRng();
|
42304
|
+
root.normalize();
|
41505
42305
|
|
41506
|
-
|
41507
|
-
|
41508
|
-
if (!parentBlock || !canSplitBlock(dom, parentBlock)) {
|
41509
|
-
parentBlock = parentBlock || editableRoot;
|
42306
|
+
if (root.hasChildNodes()) {
|
42307
|
+
walker = new TreeWalker(root, root);
|
41510
42308
|
|
41511
|
-
|
41512
|
-
|
41513
|
-
|
41514
|
-
|
42309
|
+
while ((node = walker.current())) {
|
42310
|
+
if (node.nodeType == 3) {
|
42311
|
+
rng.setStart(node, 0);
|
42312
|
+
rng.setEnd(node, 0);
|
42313
|
+
break;
|
41515
42314
|
}
|
41516
42315
|
|
41517
|
-
if (
|
41518
|
-
|
41519
|
-
|
41520
|
-
|
41521
|
-
rng.setStart(newBlock, 0);
|
41522
|
-
rng.setEnd(newBlock, 0);
|
41523
|
-
return newBlock;
|
42316
|
+
if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
|
42317
|
+
rng.setStartBefore(node);
|
42318
|
+
rng.setEndBefore(node);
|
42319
|
+
break;
|
41524
42320
|
}
|
41525
42321
|
|
41526
|
-
|
41527
|
-
node =
|
41528
|
-
|
41529
|
-
node = node.parentNode;
|
41530
|
-
}
|
42322
|
+
lastNode = node;
|
42323
|
+
node = walker.next();
|
42324
|
+
}
|
41531
42325
|
|
41532
|
-
|
41533
|
-
|
41534
|
-
|
41535
|
-
|
42326
|
+
if (!node) {
|
42327
|
+
rng.setStart(lastNode, 0);
|
42328
|
+
rng.setEnd(lastNode, 0);
|
42329
|
+
}
|
42330
|
+
} else {
|
42331
|
+
if (root.nodeName == 'BR') {
|
42332
|
+
if (root.nextSibling && dom.isBlock(root.nextSibling)) {
|
42333
|
+
rng.setStartBefore(root);
|
42334
|
+
rng.setEndBefore(root);
|
42335
|
+
} else {
|
42336
|
+
rng.setStartAfter(root);
|
42337
|
+
rng.setEndAfter(root);
|
41536
42338
|
}
|
42339
|
+
} else {
|
42340
|
+
rng.setStart(root, 0);
|
42341
|
+
rng.setEnd(root, 0);
|
42342
|
+
}
|
42343
|
+
}
|
41537
42344
|
|
41538
|
-
|
41539
|
-
newBlock = dom.create(blockName);
|
41540
|
-
setForcedBlockAttrs(newBlock);
|
41541
|
-
startNode.parentNode.insertBefore(newBlock, startNode);
|
42345
|
+
selection.setRng(rng);
|
41542
42346
|
|
41543
|
-
|
41544
|
-
|
41545
|
-
|
41546
|
-
|
41547
|
-
newBlock.appendChild(node);
|
41548
|
-
node = next;
|
41549
|
-
}
|
42347
|
+
// Remove tempElm created for old IE:s
|
42348
|
+
dom.remove(tempElm);
|
42349
|
+
selection.scrollIntoView(root);
|
42350
|
+
}
|
41550
42351
|
|
41551
|
-
|
41552
|
-
|
41553
|
-
|
41554
|
-
|
41555
|
-
}
|
42352
|
+
// Creates a new block element by cloning the current one or creating a new one if the name is specified
|
42353
|
+
// This function will also copy any text formatting from the parent block and add it to the new one
|
42354
|
+
function createNewBlock(name) {
|
42355
|
+
var node = container, block, clonedNode, caretNode, textInlineElements = schema.getTextInlineElements();
|
41556
42356
|
|
41557
|
-
|
42357
|
+
if (name || parentBlockName == "TABLE" || parentBlockName == "HR") {
|
42358
|
+
block = dom.create(name || newBlockName);
|
42359
|
+
setForcedBlockAttrs(editor, block);
|
42360
|
+
} else {
|
42361
|
+
block = parentBlock.cloneNode(false);
|
41558
42362
|
}
|
41559
42363
|
|
41560
|
-
|
41561
|
-
function handleEmptyListItem() {
|
41562
|
-
function isFirstOrLastLi(first) {
|
41563
|
-
var node = containerBlock[first ? 'firstChild' : 'lastChild'];
|
42364
|
+
caretNode = block;
|
41564
42365
|
|
41565
|
-
|
41566
|
-
|
41567
|
-
|
41568
|
-
|
42366
|
+
if (settings.keep_styles === false) {
|
42367
|
+
dom.setAttrib(block, 'style', null); // wipe out any styles that came over with the block
|
42368
|
+
dom.setAttrib(block, 'class', null);
|
42369
|
+
} else {
|
42370
|
+
// Clone any parent styles
|
42371
|
+
do {
|
42372
|
+
if (textInlineElements[node.nodeName]) {
|
42373
|
+
// Never clone a caret containers
|
42374
|
+
if (node.id == '_mce_caret') {
|
42375
|
+
continue;
|
41569
42376
|
}
|
41570
42377
|
|
41571
|
-
|
41572
|
-
|
41573
|
-
|
41574
|
-
return node === parentBlock;
|
41575
|
-
}
|
41576
|
-
|
41577
|
-
function getContainerBlock() {
|
41578
|
-
var containerBlockParent = containerBlock.parentNode;
|
42378
|
+
clonedNode = node.cloneNode(false);
|
42379
|
+
dom.setAttrib(clonedNode, 'id', ''); // Remove ID since it needs to be document unique
|
41579
42380
|
|
41580
|
-
|
41581
|
-
|
42381
|
+
if (block.hasChildNodes()) {
|
42382
|
+
clonedNode.appendChild(block.firstChild);
|
42383
|
+
block.appendChild(clonedNode);
|
42384
|
+
} else {
|
42385
|
+
caretNode = clonedNode;
|
42386
|
+
block.appendChild(clonedNode);
|
42387
|
+
}
|
41582
42388
|
}
|
42389
|
+
} while ((node = node.parentNode) && node != editableRoot);
|
42390
|
+
}
|
41583
42391
|
|
41584
|
-
|
41585
|
-
}
|
41586
|
-
|
41587
|
-
if (containerBlock == editor.getBody()) {
|
41588
|
-
return;
|
41589
|
-
}
|
42392
|
+
emptyBlock(caretNode);
|
41590
42393
|
|
41591
|
-
|
41592
|
-
|
41593
|
-
}
|
42394
|
+
return block;
|
42395
|
+
}
|
41594
42396
|
|
41595
|
-
|
42397
|
+
// Returns true/false if the caret is at the start/end of the parent block element
|
42398
|
+
function isCaretAtStartOrEndOfBlock(start) {
|
42399
|
+
var walker, node, name, normalizedOffset;
|
41596
42400
|
|
41597
|
-
|
41598
|
-
if (hasParent(containerBlock, 'LI')) {
|
41599
|
-
// Nested list is inside a LI
|
41600
|
-
dom.insertAfter(newBlock, getContainerBlock());
|
41601
|
-
} else {
|
41602
|
-
// Is first and last list item then replace the OL/UL with a text block
|
41603
|
-
dom.replace(newBlock, containerBlock);
|
41604
|
-
}
|
41605
|
-
} else if (isFirstOrLastLi(true)) {
|
41606
|
-
if (hasParent(containerBlock, 'LI')) {
|
41607
|
-
// List nested in an LI then move the list to a new sibling LI
|
41608
|
-
dom.insertAfter(newBlock, getContainerBlock());
|
41609
|
-
newBlock.appendChild(dom.doc.createTextNode(' ')); // Needed for IE so the caret can be placed
|
41610
|
-
newBlock.appendChild(containerBlock);
|
41611
|
-
} else {
|
41612
|
-
// First LI in list then remove LI and add text block before list
|
41613
|
-
containerBlock.parentNode.insertBefore(newBlock, containerBlock);
|
41614
|
-
}
|
41615
|
-
} else if (isFirstOrLastLi()) {
|
41616
|
-
// Last LI in list then remove LI and add text block after list
|
41617
|
-
dom.insertAfter(newBlock, getContainerBlock());
|
41618
|
-
renderBlockOnIE(dom, selection, newBlock);
|
41619
|
-
} else {
|
41620
|
-
// Middle LI in list the split the list and insert a text block in the middle
|
41621
|
-
// Extract after fragment and insert it after the current block
|
41622
|
-
containerBlock = getContainerBlock();
|
41623
|
-
tmpRng = rng.cloneRange();
|
41624
|
-
tmpRng.setStartAfter(parentBlock);
|
41625
|
-
tmpRng.setEndAfter(containerBlock);
|
41626
|
-
fragment = tmpRng.extractContents();
|
41627
|
-
|
41628
|
-
if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {
|
41629
|
-
newBlock = fragment.firstChild;
|
41630
|
-
dom.insertAfter(fragment, containerBlock);
|
41631
|
-
} else {
|
41632
|
-
dom.insertAfter(fragment, containerBlock);
|
41633
|
-
dom.insertAfter(newBlock, containerBlock);
|
41634
|
-
}
|
41635
|
-
}
|
42401
|
+
normalizedOffset = normalizeZwspOffset(start, container, offset);
|
41636
42402
|
|
41637
|
-
|
41638
|
-
|
41639
|
-
|
42403
|
+
// Caret is in the middle of a text node like "a|b"
|
42404
|
+
if (container.nodeType == 3 && (start ? normalizedOffset > 0 : normalizedOffset < container.nodeValue.length)) {
|
42405
|
+
return false;
|
41640
42406
|
}
|
41641
42407
|
|
41642
|
-
//
|
41643
|
-
|
41644
|
-
|
42408
|
+
// If after the last element in block node edge case for #5091
|
42409
|
+
if (container.parentNode == parentBlock && isAfterLastNodeInContainer && !start) {
|
42410
|
+
return true;
|
41645
42411
|
}
|
41646
42412
|
|
41647
|
-
//
|
41648
|
-
|
41649
|
-
|
41650
|
-
if (node.nodeType === 3) {
|
41651
|
-
node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, '');
|
41652
|
-
}
|
41653
|
-
|
41654
|
-
node = node.firstChild;
|
41655
|
-
} while (node);
|
42413
|
+
// If the caret if before the first element in parentBlock
|
42414
|
+
if (start && container.nodeType == 1 && container == parentBlock.firstChild) {
|
42415
|
+
return true;
|
41656
42416
|
}
|
41657
42417
|
|
41658
|
-
|
41659
|
-
|
41660
|
-
|
41661
|
-
// Get all parents until we hit a non editable parent or the root
|
41662
|
-
parent = node;
|
41663
|
-
while (parent !== root && dom.getContentEditable(parent) !== "false") {
|
41664
|
-
if (dom.getContentEditable(parent) === "true") {
|
41665
|
-
editableRoot = parent;
|
41666
|
-
}
|
41667
|
-
|
41668
|
-
parent = parent.parentNode;
|
41669
|
-
}
|
41670
|
-
|
41671
|
-
return parent !== root ? editableRoot : root;
|
42418
|
+
// Caret can be before/after a table or a hr
|
42419
|
+
if (containerAndSiblingName(container, 'TABLE') || containerAndSiblingName(container, 'HR')) {
|
42420
|
+
return (isAfterLastNodeInContainer && !start) || (!isAfterLastNodeInContainer && start);
|
41672
42421
|
}
|
41673
42422
|
|
41674
|
-
//
|
41675
|
-
|
41676
|
-
function addBrToBlockIfNeeded(block) {
|
41677
|
-
var lastChild;
|
41678
|
-
|
41679
|
-
// IE will render the blocks correctly other browsers needs a BR
|
41680
|
-
if (!isIE) {
|
41681
|
-
block.normalize(); // Remove empty text nodes that got left behind by the extract
|
42423
|
+
// Walk the DOM and look for text nodes or non empty elements
|
42424
|
+
walker = new TreeWalker(container, parentBlock);
|
41682
42425
|
|
41683
|
-
|
41684
|
-
|
41685
|
-
|
41686
|
-
|
41687
|
-
|
42426
|
+
// If caret is in beginning or end of a text block then jump to the next/previous node
|
42427
|
+
if (container.nodeType == 3) {
|
42428
|
+
if (start && normalizedOffset === 0) {
|
42429
|
+
walker.prev();
|
42430
|
+
} else if (!start && normalizedOffset == container.nodeValue.length) {
|
42431
|
+
walker.next();
|
41688
42432
|
}
|
41689
42433
|
}
|
41690
42434
|
|
41691
|
-
|
41692
|
-
|
41693
|
-
|
41694
|
-
|
41695
|
-
|
41696
|
-
|
42435
|
+
while ((node = walker.current())) {
|
42436
|
+
if (node.nodeType === 1) {
|
42437
|
+
// Ignore bogus elements
|
42438
|
+
if (!node.getAttribute('data-mce-bogus')) {
|
42439
|
+
// Keep empty elements like <img /> <input /> but not trailing br:s like <p>text|<br></p>
|
42440
|
+
name = node.nodeName.toLowerCase();
|
42441
|
+
if (nonEmptyElementsMap[name] && name !== 'br') {
|
42442
|
+
return false;
|
42443
|
+
}
|
42444
|
+
}
|
42445
|
+
} else if (node.nodeType === 3 && !/^[ \t\r\n]*$/.test(node.nodeValue)) {
|
42446
|
+
return false;
|
41697
42447
|
}
|
41698
42448
|
|
41699
|
-
|
41700
|
-
|
41701
|
-
// Split container block for example a BLOCKQUOTE at the current blockParent location for example a P
|
41702
|
-
newBlock = dom.split(containerBlock, parentBlock);
|
42449
|
+
if (start) {
|
42450
|
+
walker.prev();
|
41703
42451
|
} else {
|
41704
|
-
|
42452
|
+
walker.next();
|
41705
42453
|
}
|
41706
|
-
|
41707
|
-
moveToCaretPosition(newBlock);
|
41708
42454
|
}
|
41709
42455
|
|
41710
|
-
|
42456
|
+
return true;
|
42457
|
+
}
|
41711
42458
|
|
41712
|
-
|
41713
|
-
|
42459
|
+
// Inserts a block or br before/after or in the middle of a split list of the LI is empty
|
42460
|
+
function handleEmptyListItem() {
|
42461
|
+
if (containerBlock == editor.getBody()) {
|
41714
42462
|
return;
|
41715
42463
|
}
|
41716
42464
|
|
41717
|
-
|
41718
|
-
|
41719
|
-
editor.execCommand('Delete');
|
41720
|
-
return;
|
42465
|
+
if (isNestedList(containerBlock)) {
|
42466
|
+
newBlockName = 'LI';
|
41721
42467
|
}
|
41722
42468
|
|
41723
|
-
|
41724
|
-
|
41725
|
-
|
41726
|
-
|
41727
|
-
|
41728
|
-
|
41729
|
-
documentMode = dom.doc.documentMode;
|
41730
|
-
shiftKey = evt.shiftKey;
|
41731
|
-
|
41732
|
-
// Resolve node index
|
41733
|
-
if (container.nodeType == 1 && container.hasChildNodes()) {
|
41734
|
-
isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
|
41735
|
-
|
41736
|
-
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
|
41737
|
-
if (isAfterLastNodeInContainer && container.nodeType == 3) {
|
41738
|
-
offset = container.nodeValue.length;
|
42469
|
+
newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR');
|
42470
|
+
|
42471
|
+
if (isFirstOrLastLi(containerBlock, parentBlock, true) && isFirstOrLastLi(containerBlock, parentBlock, false)) {
|
42472
|
+
if (hasParent(containerBlock, 'LI')) {
|
42473
|
+
// Nested list is inside a LI
|
42474
|
+
dom.insertAfter(newBlock, getContainerBlock(containerBlock));
|
41739
42475
|
} else {
|
41740
|
-
|
42476
|
+
// Is first and last list item then replace the OL/UL with a text block
|
42477
|
+
dom.replace(newBlock, containerBlock);
|
42478
|
+
}
|
42479
|
+
} else if (isFirstOrLastLi(containerBlock, parentBlock, true)) {
|
42480
|
+
if (hasParent(containerBlock, 'LI')) {
|
42481
|
+
// List nested in an LI then move the list to a new sibling LI
|
42482
|
+
dom.insertAfter(newBlock, getContainerBlock(containerBlock));
|
42483
|
+
newBlock.appendChild(dom.doc.createTextNode(' ')); // Needed for IE so the caret can be placed
|
42484
|
+
newBlock.appendChild(containerBlock);
|
42485
|
+
} else {
|
42486
|
+
// First LI in list then remove LI and add text block before list
|
42487
|
+
containerBlock.parentNode.insertBefore(newBlock, containerBlock);
|
42488
|
+
}
|
42489
|
+
} else if (isFirstOrLastLi(containerBlock, parentBlock, false)) {
|
42490
|
+
// Last LI in list then remove LI and add text block after list
|
42491
|
+
dom.insertAfter(newBlock, getContainerBlock(containerBlock));
|
42492
|
+
} else {
|
42493
|
+
// Middle LI in list the split the list and insert a text block in the middle
|
42494
|
+
// Extract after fragment and insert it after the current block
|
42495
|
+
containerBlock = getContainerBlock(containerBlock);
|
42496
|
+
tmpRng = rng.cloneRange();
|
42497
|
+
tmpRng.setStartAfter(parentBlock);
|
42498
|
+
tmpRng.setEndAfter(containerBlock);
|
42499
|
+
fragment = tmpRng.extractContents();
|
42500
|
+
|
42501
|
+
if (newBlockName === 'LI' && hasFirstChild(fragment, 'LI')) {
|
42502
|
+
newBlock = fragment.firstChild;
|
42503
|
+
dom.insertAfter(fragment, containerBlock);
|
42504
|
+
} else {
|
42505
|
+
dom.insertAfter(fragment, containerBlock);
|
42506
|
+
dom.insertAfter(newBlock, containerBlock);
|
41741
42507
|
}
|
41742
42508
|
}
|
41743
42509
|
|
41744
|
-
|
41745
|
-
|
42510
|
+
dom.remove(parentBlock);
|
42511
|
+
moveToCaretPosition(newBlock);
|
42512
|
+
}
|
41746
42513
|
|
41747
|
-
|
41748
|
-
|
41749
|
-
|
42514
|
+
function insertNewBlockAfter() {
|
42515
|
+
// If the caret is at the end of a header we produce a P tag after it similar to Word unless we are in a hgroup
|
42516
|
+
if (/^(H[1-6]|PRE|FIGURE)$/.test(parentBlockName) && containerBlockName != 'HGROUP') {
|
42517
|
+
newBlock = createNewBlock(newBlockName);
|
42518
|
+
} else {
|
42519
|
+
newBlock = createNewBlock();
|
41750
42520
|
}
|
41751
42521
|
|
41752
|
-
|
42522
|
+
// Split the current container block element if enter is pressed inside an empty inner block element
|
42523
|
+
if (settings.end_container_on_empty_block && canSplitBlock(dom, containerBlock) && dom.isEmpty(parentBlock)) {
|
42524
|
+
// Split container block for example a BLOCKQUOTE at the current blockParent location for example a P
|
42525
|
+
newBlock = dom.split(containerBlock, parentBlock);
|
42526
|
+
} else {
|
42527
|
+
dom.insertAfter(newBlock, parentBlock);
|
42528
|
+
}
|
41753
42529
|
|
41754
|
-
|
41755
|
-
|
41756
|
-
if (!newBlockName || shiftKey) {
|
41757
|
-
insertBr();
|
41758
|
-
}
|
42530
|
+
moveToCaretPosition(newBlock);
|
42531
|
+
}
|
41759
42532
|
|
41760
|
-
|
41761
|
-
|
42533
|
+
// Setup range items and newBlockName
|
42534
|
+
new RangeUtils(dom).normalize(rng);
|
42535
|
+
container = rng.startContainer;
|
42536
|
+
offset = rng.startOffset;
|
42537
|
+
newBlockName = (settings.force_p_newlines ? 'p' : '') || settings.forced_root_block;
|
42538
|
+
newBlockName = newBlockName ? newBlockName.toUpperCase() : '';
|
42539
|
+
shiftKey = evt.shiftKey;
|
42540
|
+
|
42541
|
+
// Resolve node index
|
42542
|
+
if (container.nodeType == 1 && container.hasChildNodes()) {
|
42543
|
+
isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
|
41762
42544
|
|
41763
|
-
|
41764
|
-
|
41765
|
-
|
41766
|
-
|
41767
|
-
|
42545
|
+
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
|
42546
|
+
if (isAfterLastNodeInContainer && container.nodeType == 3) {
|
42547
|
+
offset = container.nodeValue.length;
|
42548
|
+
} else {
|
42549
|
+
offset = 0;
|
41768
42550
|
}
|
42551
|
+
}
|
41769
42552
|
|
41770
|
-
|
41771
|
-
|
41772
|
-
containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
|
42553
|
+
// Get editable root node, normally the body element but sometimes a div or span
|
42554
|
+
editableRoot = getEditableRoot(dom, container);
|
41773
42555
|
|
41774
|
-
|
41775
|
-
|
41776
|
-
|
42556
|
+
// If there is no editable root then enter is done inside a contentEditable false element
|
42557
|
+
if (!editableRoot) {
|
42558
|
+
return;
|
42559
|
+
}
|
41777
42560
|
|
41778
|
-
|
41779
|
-
|
41780
|
-
|
41781
|
-
|
41782
|
-
parentBlockName = containerBlockName;
|
42561
|
+
// If editable root isn't block nor the root of the editor
|
42562
|
+
if (!dom.isBlock(editableRoot) && editableRoot != dom.getRoot()) {
|
42563
|
+
if (!newBlockName || shiftKey) {
|
42564
|
+
insertBr(editor, evt);
|
41783
42565
|
}
|
41784
42566
|
|
41785
|
-
|
41786
|
-
|
41787
|
-
editor.undoManager.add();
|
41788
|
-
}
|
42567
|
+
return;
|
42568
|
+
}
|
41789
42569
|
|
41790
|
-
|
41791
|
-
|
41792
|
-
|
41793
|
-
|
41794
|
-
|
41795
|
-
|
42570
|
+
// Wrap the current node and it's sibling in a default block if it's needed.
|
42571
|
+
// for example this <td>text|<b>text2</b></td> will become this <td><p>text|<b>text2</p></b></td>
|
42572
|
+
// This won't happen if root blocks are disabled or the shiftKey is pressed
|
42573
|
+
if ((newBlockName && !shiftKey) || (!newBlockName && shiftKey)) {
|
42574
|
+
container = wrapSelfAndSiblingsInDefaultBlock(editor, newBlockName, rng, container, offset);
|
42575
|
+
}
|
41796
42576
|
|
41797
|
-
|
41798
|
-
|
41799
|
-
|
41800
|
-
|
41801
|
-
|
42577
|
+
// Find parent block and setup empty block paddings
|
42578
|
+
parentBlock = dom.getParent(container, dom.isBlock);
|
42579
|
+
containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null;
|
42580
|
+
|
42581
|
+
// Setup block names
|
42582
|
+
parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
|
42583
|
+
containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5
|
42584
|
+
|
42585
|
+
// Enter inside block contained within a LI then split or insert before/after LI
|
42586
|
+
if (containerBlockName == 'LI' && !evt.ctrlKey) {
|
42587
|
+
parentBlock = containerBlock;
|
42588
|
+
containerBlock = containerBlock.parentNode;
|
42589
|
+
parentBlockName = containerBlockName;
|
42590
|
+
}
|
42591
|
+
|
42592
|
+
// Handle enter in list item
|
42593
|
+
if (/^(LI|DT|DD)$/.test(parentBlockName)) {
|
42594
|
+
if (!newBlockName && shiftKey) {
|
42595
|
+
insertBr(editor, evt);
|
42596
|
+
return;
|
41802
42597
|
}
|
41803
42598
|
|
41804
|
-
//
|
41805
|
-
if (
|
41806
|
-
|
41807
|
-
|
41808
|
-
return;
|
41809
|
-
}
|
41810
|
-
} else {
|
41811
|
-
// If no root block is configured then insert a BR by default or if the shiftKey is pressed
|
41812
|
-
if ((!newBlockName && !shiftKey && parentBlockName != 'LI') || (newBlockName && shiftKey)) {
|
41813
|
-
insertBr();
|
41814
|
-
return;
|
41815
|
-
}
|
42599
|
+
// Handle enter inside an empty list item
|
42600
|
+
if (dom.isEmpty(parentBlock)) {
|
42601
|
+
handleEmptyListItem();
|
42602
|
+
return;
|
41816
42603
|
}
|
42604
|
+
}
|
41817
42605
|
|
41818
|
-
|
41819
|
-
|
42606
|
+
// Don't split PRE tags but insert a BR instead easier when writing code samples etc
|
42607
|
+
if (parentBlockName == 'PRE' && settings.br_in_pre !== false) {
|
42608
|
+
if (!shiftKey) {
|
42609
|
+
insertBr(editor, evt);
|
42610
|
+
return;
|
42611
|
+
}
|
42612
|
+
} else {
|
42613
|
+
// If no root block is configured then insert a BR by default or if the shiftKey is pressed
|
42614
|
+
if ((!newBlockName && !shiftKey && parentBlockName != 'LI') || (newBlockName && shiftKey)) {
|
42615
|
+
insertBr(editor, evt);
|
41820
42616
|
return;
|
41821
42617
|
}
|
42618
|
+
}
|
41822
42619
|
|
41823
|
-
|
41824
|
-
|
42620
|
+
// If parent block is root then never insert new blocks
|
42621
|
+
if (newBlockName && parentBlock === editor.getBody()) {
|
42622
|
+
return;
|
42623
|
+
}
|
41825
42624
|
|
41826
|
-
|
41827
|
-
|
41828
|
-
newBlock = CaretContainer.showCaretContainerBlock(parentBlock);
|
41829
|
-
if (dom.isEmpty(parentBlock)) {
|
41830
|
-
emptyBlock(parentBlock);
|
41831
|
-
}
|
41832
|
-
moveToCaretPosition(newBlock);
|
41833
|
-
} else if (isCaretAtStartOrEndOfBlock()) {
|
41834
|
-
insertNewBlockAfter();
|
41835
|
-
} else if (isCaretAtStartOrEndOfBlock(true)) {
|
41836
|
-
// Insert new block before
|
41837
|
-
newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);
|
41838
|
-
renderBlockOnIE(dom, selection, newBlock);
|
42625
|
+
// Default block name if it's not configured
|
42626
|
+
newBlockName = newBlockName || 'P';
|
41839
42627
|
|
41840
|
-
|
41841
|
-
|
41842
|
-
|
41843
|
-
|
41844
|
-
|
41845
|
-
|
41846
|
-
|
41847
|
-
|
41848
|
-
|
41849
|
-
|
41850
|
-
|
41851
|
-
|
42628
|
+
// Insert new block before/after the parent block depending on caret location
|
42629
|
+
if (CaretContainer.isCaretContainerBlock(parentBlock)) {
|
42630
|
+
newBlock = CaretContainer.showCaretContainerBlock(parentBlock);
|
42631
|
+
if (dom.isEmpty(parentBlock)) {
|
42632
|
+
emptyBlock(parentBlock);
|
42633
|
+
}
|
42634
|
+
moveToCaretPosition(newBlock);
|
42635
|
+
} else if (isCaretAtStartOrEndOfBlock()) {
|
42636
|
+
insertNewBlockAfter();
|
42637
|
+
} else if (isCaretAtStartOrEndOfBlock(true)) {
|
42638
|
+
// Insert new block before
|
42639
|
+
newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock);
|
41852
42640
|
|
41853
|
-
|
41854
|
-
|
41855
|
-
|
42641
|
+
// Adjust caret position if HR
|
42642
|
+
containerAndSiblingName(parentBlock, 'HR') ? moveToCaretPosition(newBlock) : moveToCaretPosition(parentBlock);
|
42643
|
+
} else {
|
42644
|
+
// Extract after fragment and insert it after the current block
|
42645
|
+
tmpRng = includeZwspInRange(rng).cloneRange();
|
42646
|
+
tmpRng.setEndAfter(parentBlock);
|
42647
|
+
fragment = tmpRng.extractContents();
|
42648
|
+
trimLeadingLineBreaks(fragment);
|
42649
|
+
newBlock = fragment.firstChild;
|
42650
|
+
dom.insertAfter(fragment, parentBlock);
|
42651
|
+
trimInlineElementsOnLeftSideOfBlock(dom, nonEmptyElementsMap, newBlock);
|
42652
|
+
addBrToBlockIfNeeded(dom, parentBlock);
|
41856
42653
|
|
41857
|
-
|
42654
|
+
if (dom.isEmpty(parentBlock)) {
|
42655
|
+
emptyBlock(parentBlock);
|
42656
|
+
}
|
41858
42657
|
|
41859
|
-
|
41860
|
-
|
41861
|
-
|
41862
|
-
|
41863
|
-
|
41864
|
-
|
41865
|
-
|
42658
|
+
newBlock.normalize();
|
42659
|
+
|
42660
|
+
// New block might become empty if it's <p><b>a |</b></p>
|
42661
|
+
if (dom.isEmpty(newBlock)) {
|
42662
|
+
dom.remove(newBlock);
|
42663
|
+
insertNewBlockAfter();
|
42664
|
+
} else {
|
42665
|
+
moveToCaretPosition(newBlock);
|
41866
42666
|
}
|
42667
|
+
}
|
41867
42668
|
|
41868
|
-
|
42669
|
+
dom.setAttrib(newBlock, 'id', ''); // Remove ID since it needs to be document unique
|
41869
42670
|
|
41870
|
-
|
41871
|
-
|
42671
|
+
// Allow custom handling of new blocks
|
42672
|
+
editor.fire('NewBlock', { newBlock: newBlock });
|
42673
|
+
};
|
42674
|
+
|
42675
|
+
return {
|
42676
|
+
insert: insert
|
42677
|
+
};
|
42678
|
+
}
|
42679
|
+
);
|
41872
42680
|
|
42681
|
+
/**
|
42682
|
+
* EnterKey.js
|
42683
|
+
*
|
42684
|
+
* Released under LGPL License.
|
42685
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
42686
|
+
*
|
42687
|
+
* License: http://www.tinymce.com/license
|
42688
|
+
* Contributing: http://www.tinymce.com/contributing
|
42689
|
+
*/
|
42690
|
+
|
42691
|
+
define(
|
42692
|
+
'tinymce.core.keyboard.EnterKey',
|
42693
|
+
[
|
42694
|
+
'tinymce.core.keyboard.InsertNewLine',
|
42695
|
+
'tinymce.core.util.VK'
|
42696
|
+
],
|
42697
|
+
function (InsertNewLine, VK) {
|
42698
|
+
var endTypingLevel = function (undoManager) {
|
42699
|
+
if (undoManager.typing) {
|
41873
42700
|
undoManager.typing = false;
|
41874
42701
|
undoManager.add();
|
41875
42702
|
}
|
42703
|
+
};
|
41876
42704
|
|
41877
|
-
|
41878
|
-
|
41879
|
-
|
41880
|
-
|
41881
|
-
|
42705
|
+
var handleEnterKeyEvent = function (editor, event) {
|
42706
|
+
if (event.isDefaultPrevented()) {
|
42707
|
+
return;
|
42708
|
+
}
|
42709
|
+
|
42710
|
+
event.preventDefault();
|
42711
|
+
|
42712
|
+
endTypingLevel(editor.undoManager);
|
42713
|
+
editor.undoManager.transact(function () {
|
42714
|
+
if (editor.selection.isCollapsed() === false) {
|
42715
|
+
editor.execCommand('Delete');
|
42716
|
+
}
|
42717
|
+
|
42718
|
+
InsertNewLine.insert(editor, event);
|
42719
|
+
});
|
42720
|
+
};
|
42721
|
+
|
42722
|
+
var setup = function (editor) {
|
42723
|
+
editor.on('keydown', function (event) {
|
42724
|
+
if (event.keyCode === VK.ENTER) {
|
42725
|
+
handleEnterKeyEvent(editor, event);
|
41882
42726
|
}
|
41883
42727
|
});
|
41884
42728
|
};
|
@@ -42763,280 +43607,6 @@ define(
|
|
42763
43607
|
}
|
42764
43608
|
);
|
42765
43609
|
|
42766
|
-
define(
|
42767
|
-
'ephox.sugar.impl.Style',
|
42768
|
-
|
42769
|
-
[
|
42770
|
-
|
42771
|
-
],
|
42772
|
-
|
42773
|
-
function () {
|
42774
|
-
// some elements, such as mathml, don't have style attributes
|
42775
|
-
var isSupported = function (dom) {
|
42776
|
-
return dom.style !== undefined;
|
42777
|
-
};
|
42778
|
-
|
42779
|
-
return {
|
42780
|
-
isSupported: isSupported
|
42781
|
-
};
|
42782
|
-
}
|
42783
|
-
);
|
42784
|
-
define(
|
42785
|
-
'ephox.sugar.api.properties.Css',
|
42786
|
-
|
42787
|
-
[
|
42788
|
-
'ephox.katamari.api.Type',
|
42789
|
-
'ephox.katamari.api.Arr',
|
42790
|
-
'ephox.katamari.api.Obj',
|
42791
|
-
'ephox.katamari.api.Option',
|
42792
|
-
'ephox.sugar.api.properties.Attr',
|
42793
|
-
'ephox.sugar.api.node.Body',
|
42794
|
-
'ephox.sugar.api.node.Element',
|
42795
|
-
'ephox.sugar.api.node.Node',
|
42796
|
-
'ephox.sugar.impl.Style',
|
42797
|
-
'ephox.katamari.api.Strings',
|
42798
|
-
'global!Error',
|
42799
|
-
'global!console',
|
42800
|
-
'global!window'
|
42801
|
-
],
|
42802
|
-
|
42803
|
-
function (Type, Arr, Obj, Option, Attr, Body, Element, Node, Style, Strings, Error, console, window) {
|
42804
|
-
var internalSet = function (dom, property, value) {
|
42805
|
-
// This is going to hurt. Apologies.
|
42806
|
-
// JQuery coerces numbers to pixels for certain property names, and other times lets numbers through.
|
42807
|
-
// we're going to be explicit; strings only.
|
42808
|
-
if (!Type.isString(value)) {
|
42809
|
-
console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
|
42810
|
-
throw new Error('CSS value must be a string: ' + value);
|
42811
|
-
}
|
42812
|
-
|
42813
|
-
// removed: support for dom().style[property] where prop is camel case instead of normal property name
|
42814
|
-
if (Style.isSupported(dom)) dom.style.setProperty(property, value);
|
42815
|
-
};
|
42816
|
-
|
42817
|
-
var internalRemove = function (dom, property) {
|
42818
|
-
/*
|
42819
|
-
* IE9 and above - MDN doesn't have details, but here's a couple of random internet claims
|
42820
|
-
*
|
42821
|
-
* http://help.dottoro.com/ljopsjck.php
|
42822
|
-
* http://stackoverflow.com/a/7901886/7546
|
42823
|
-
*/
|
42824
|
-
if (Style.isSupported(dom)) dom.style.removeProperty(property);
|
42825
|
-
};
|
42826
|
-
|
42827
|
-
var set = function (element, property, value) {
|
42828
|
-
var dom = element.dom();
|
42829
|
-
internalSet(dom, property, value);
|
42830
|
-
};
|
42831
|
-
|
42832
|
-
var setAll = function (element, css) {
|
42833
|
-
var dom = element.dom();
|
42834
|
-
|
42835
|
-
Obj.each(css, function (v, k) {
|
42836
|
-
internalSet(dom, k, v);
|
42837
|
-
});
|
42838
|
-
};
|
42839
|
-
|
42840
|
-
var setOptions = function(element, css) {
|
42841
|
-
var dom = element.dom();
|
42842
|
-
|
42843
|
-
Obj.each(css, function (v, k) {
|
42844
|
-
v.fold(function () {
|
42845
|
-
internalRemove(dom, k);
|
42846
|
-
}, function (value) {
|
42847
|
-
internalSet(dom, k, value);
|
42848
|
-
});
|
42849
|
-
});
|
42850
|
-
};
|
42851
|
-
|
42852
|
-
/*
|
42853
|
-
* NOTE: For certain properties, this returns the "used value" which is subtly different to the "computed value" (despite calling getComputedStyle).
|
42854
|
-
* Blame CSS 2.0.
|
42855
|
-
*
|
42856
|
-
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
|
42857
|
-
*/
|
42858
|
-
var get = function (element, property) {
|
42859
|
-
var dom = element.dom();
|
42860
|
-
/*
|
42861
|
-
* IE9 and above per
|
42862
|
-
* https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle
|
42863
|
-
*
|
42864
|
-
* Not in numerosity, because it doesn't memoize and looking this up dynamically in performance critical code would be horrendous.
|
42865
|
-
*
|
42866
|
-
* JQuery has some magic here for IE popups, but we don't really need that.
|
42867
|
-
* It also uses element.ownerDocument.defaultView to handle iframes but that hasn't been required since FF 3.6.
|
42868
|
-
*/
|
42869
|
-
var styles = window.getComputedStyle(dom);
|
42870
|
-
var r = styles.getPropertyValue(property);
|
42871
|
-
|
42872
|
-
// jquery-ism: If r is an empty string, check that the element is not in a document. If it isn't, return the raw value.
|
42873
|
-
// Turns out we do this a lot.
|
42874
|
-
var v = (r === '' && !Body.inBody(element)) ? getUnsafeProperty(dom, property) : r;
|
42875
|
-
|
42876
|
-
// undefined is the more appropriate value for JS. JQuery coerces to an empty string, but screw that!
|
42877
|
-
return v === null ? undefined : v;
|
42878
|
-
};
|
42879
|
-
|
42880
|
-
var getUnsafeProperty = function (dom, property) {
|
42881
|
-
// removed: support for dom().style[property] where prop is camel case instead of normal property name
|
42882
|
-
// empty string is what the browsers (IE11 and Chrome) return when the propertyValue doesn't exists.
|
42883
|
-
return Style.isSupported(dom) ? dom.style.getPropertyValue(property) : '';
|
42884
|
-
};
|
42885
|
-
|
42886
|
-
/*
|
42887
|
-
* Gets the raw value from the style attribute. Useful for retrieving "used values" from the DOM:
|
42888
|
-
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
|
42889
|
-
*
|
42890
|
-
* Returns NONE if the property isn't set, or the value is an empty string.
|
42891
|
-
*/
|
42892
|
-
var getRaw = function (element, property) {
|
42893
|
-
var dom = element.dom();
|
42894
|
-
var raw = getUnsafeProperty(dom, property);
|
42895
|
-
|
42896
|
-
return Option.from(raw).filter(function (r) { return r.length > 0; });
|
42897
|
-
};
|
42898
|
-
|
42899
|
-
var isValidValue = function (tag, property, value) {
|
42900
|
-
var element = Element.fromTag(tag);
|
42901
|
-
set(element, property, value);
|
42902
|
-
var style = getRaw(element, property);
|
42903
|
-
return style.isSome();
|
42904
|
-
};
|
42905
|
-
|
42906
|
-
var remove = function (element, property) {
|
42907
|
-
var dom = element.dom();
|
42908
|
-
|
42909
|
-
internalRemove(dom, property);
|
42910
|
-
|
42911
|
-
if (Attr.has(element, 'style') && Strings.trim(Attr.get(element, 'style')) === '') {
|
42912
|
-
// No more styles left, remove the style attribute as well
|
42913
|
-
Attr.remove(element, 'style');
|
42914
|
-
}
|
42915
|
-
};
|
42916
|
-
|
42917
|
-
var preserve = function (element, f) {
|
42918
|
-
var oldStyles = Attr.get(element, 'style');
|
42919
|
-
var result = f(element);
|
42920
|
-
var restore = oldStyles === undefined ? Attr.remove : Attr.set;
|
42921
|
-
restore(element, 'style', oldStyles);
|
42922
|
-
return result;
|
42923
|
-
};
|
42924
|
-
|
42925
|
-
var copy = function (source, target) {
|
42926
|
-
var sourceDom = source.dom();
|
42927
|
-
var targetDom = target.dom();
|
42928
|
-
if (Style.isSupported(sourceDom) && Style.isSupported(targetDom)) {
|
42929
|
-
targetDom.style.cssText = sourceDom.style.cssText;
|
42930
|
-
}
|
42931
|
-
};
|
42932
|
-
|
42933
|
-
var reflow = function (e) {
|
42934
|
-
/* NOTE:
|
42935
|
-
* do not rely on this return value.
|
42936
|
-
* It's here so the closure compiler doesn't optimise the property access away.
|
42937
|
-
*/
|
42938
|
-
return e.dom().offsetWidth;
|
42939
|
-
};
|
42940
|
-
|
42941
|
-
var transferOne = function (source, destination, style) {
|
42942
|
-
getRaw(source, style).each(function (value) {
|
42943
|
-
// NOTE: We don't want to clobber any existing inline styles.
|
42944
|
-
if (getRaw(destination, style).isNone()) set(destination, style, value);
|
42945
|
-
});
|
42946
|
-
};
|
42947
|
-
|
42948
|
-
var transfer = function (source, destination, styles) {
|
42949
|
-
if (!Node.isElement(source) || !Node.isElement(destination)) return;
|
42950
|
-
Arr.each(styles, function (style) {
|
42951
|
-
transferOne(source, destination, style);
|
42952
|
-
});
|
42953
|
-
};
|
42954
|
-
|
42955
|
-
return {
|
42956
|
-
copy: copy,
|
42957
|
-
set: set,
|
42958
|
-
preserve: preserve,
|
42959
|
-
setAll: setAll,
|
42960
|
-
setOptions: setOptions,
|
42961
|
-
remove: remove,
|
42962
|
-
get: get,
|
42963
|
-
getRaw: getRaw,
|
42964
|
-
isValidValue: isValidValue,
|
42965
|
-
reflow: reflow,
|
42966
|
-
transfer: transfer
|
42967
|
-
};
|
42968
|
-
}
|
42969
|
-
);
|
42970
|
-
|
42971
|
-
/**
|
42972
|
-
* EditorView.js
|
42973
|
-
*
|
42974
|
-
* Released under LGPL License.
|
42975
|
-
* Copyright (c) 1999-2016 Ephox Corp. All rights reserved
|
42976
|
-
*
|
42977
|
-
* License: http://www.tinymce.com/license
|
42978
|
-
* Contributing: http://www.tinymce.com/contributing
|
42979
|
-
*/
|
42980
|
-
|
42981
|
-
define(
|
42982
|
-
'tinymce.core.EditorView',
|
42983
|
-
[
|
42984
|
-
'ephox.katamari.api.Fun',
|
42985
|
-
'ephox.sugar.api.node.Element',
|
42986
|
-
'ephox.sugar.api.properties.Css',
|
42987
|
-
'ephox.sugar.api.search.Traverse'
|
42988
|
-
],
|
42989
|
-
function (Fun, Element, Css, Traverse) {
|
42990
|
-
var getProp = function (propName, elm) {
|
42991
|
-
var rawElm = elm.dom();
|
42992
|
-
return rawElm[propName];
|
42993
|
-
};
|
42994
|
-
|
42995
|
-
var getComputedSizeProp = function (propName, elm) {
|
42996
|
-
return parseInt(Css.get(elm, propName), 10);
|
42997
|
-
};
|
42998
|
-
|
42999
|
-
var getClientWidth = Fun.curry(getProp, 'clientWidth');
|
43000
|
-
var getClientHeight = Fun.curry(getProp, 'clientHeight');
|
43001
|
-
var getMarginTop = Fun.curry(getComputedSizeProp, 'margin-top');
|
43002
|
-
var getMarginLeft = Fun.curry(getComputedSizeProp, 'margin-left');
|
43003
|
-
|
43004
|
-
var getBoundingClientRect = function (elm) {
|
43005
|
-
return elm.dom().getBoundingClientRect();
|
43006
|
-
};
|
43007
|
-
|
43008
|
-
var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
|
43009
|
-
var clientWidth = getClientWidth(bodyElm);
|
43010
|
-
var clientHeight = getClientHeight(bodyElm);
|
43011
|
-
|
43012
|
-
return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
|
43013
|
-
};
|
43014
|
-
|
43015
|
-
var transpose = function (inline, elm, clientX, clientY) {
|
43016
|
-
var clientRect = getBoundingClientRect(elm);
|
43017
|
-
var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;
|
43018
|
-
var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;
|
43019
|
-
var x = clientX - deltaX;
|
43020
|
-
var y = clientY - deltaY;
|
43021
|
-
|
43022
|
-
return { x: x, y: y };
|
43023
|
-
};
|
43024
|
-
|
43025
|
-
// Checks if the specified coordinate is within the visual content area excluding the scrollbars
|
43026
|
-
var isXYInContentArea = function (editor, clientX, clientY) {
|
43027
|
-
var bodyElm = Element.fromDom(editor.getBody());
|
43028
|
-
var targetElm = editor.inline ? bodyElm : Traverse.documentElement(bodyElm);
|
43029
|
-
var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
|
43030
|
-
|
43031
|
-
return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
|
43032
|
-
};
|
43033
|
-
|
43034
|
-
return {
|
43035
|
-
isXYInContentArea: isXYInContentArea
|
43036
|
-
};
|
43037
|
-
}
|
43038
|
-
);
|
43039
|
-
|
43040
43610
|
/**
|
43041
43611
|
* SelectionOverrides.js
|
43042
43612
|
*
|
@@ -44427,7 +44997,11 @@ define(
|
|
44427
44997
|
// Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything
|
44428
44998
|
editor.on('keyup focusin mouseup', function (e) {
|
44429
44999
|
if (e.keyCode != 65 || !VK.metaKeyPressed(e)) {
|
44430
|
-
|
45000
|
+
// We can't normalize on non collapsed ranges on keyboard events since that would cause
|
45001
|
+
// issues with moving the selection over empty paragraphs. See #TINY-1130
|
45002
|
+
if (e.type !== 'keyup' || editor.selection.isCollapsed()) {
|
45003
|
+
selection.normalize();
|
45004
|
+
}
|
44431
45005
|
}
|
44432
45006
|
}, true);
|
44433
45007
|
}
|
@@ -44754,6 +45328,9 @@ define(
|
|
44754
45328
|
define(
|
44755
45329
|
'tinymce.core.init.InitContentBody',
|
44756
45330
|
[
|
45331
|
+
'ephox.sugar.api.dom.Insert',
|
45332
|
+
'ephox.sugar.api.node.Element',
|
45333
|
+
'ephox.sugar.api.properties.Attr',
|
44757
45334
|
'global!document',
|
44758
45335
|
'global!window',
|
44759
45336
|
'tinymce.core.api.Formatter',
|
@@ -44776,11 +45353,19 @@ define(
|
|
44776
45353
|
'tinymce.core.util.Tools'
|
44777
45354
|
],
|
44778
45355
|
function (
|
44779
|
-
document, window, Formatter, CaretContainerInput, DOMUtils, Selection, Serializer, EditorUpload, ErrorReporter, ForceBlocks, DomParser,
|
44780
|
-
NodeChange, SelectionOverrides, UndoManager, Delay, Quirks, Tools
|
45356
|
+
Insert, Element, Attr, document, window, Formatter, CaretContainerInput, DOMUtils, Selection, Serializer, EditorUpload, ErrorReporter, ForceBlocks, DomParser,
|
45357
|
+
Node, Schema, KeyboardOverrides, NodeChange, SelectionOverrides, UndoManager, Delay, Quirks, Tools
|
44781
45358
|
) {
|
44782
45359
|
var DOM = DOMUtils.DOM;
|
44783
45360
|
|
45361
|
+
var appendStyle = function (editor, text) {
|
45362
|
+
var head = Element.fromDom(editor.getDoc().head);
|
45363
|
+
var tag = Element.fromTag('style');
|
45364
|
+
Attr.set(tag, 'type', 'text/css');
|
45365
|
+
Insert.append(tag, Element.fromText(text));
|
45366
|
+
Insert.append(head, tag);
|
45367
|
+
};
|
45368
|
+
|
44784
45369
|
var createParser = function (editor) {
|
44785
45370
|
var parser = new DomParser(editor.settings, editor.schema);
|
44786
45371
|
|
@@ -45034,9 +45619,13 @@ define(
|
|
45034
45619
|
},
|
45035
45620
|
function (urls) {
|
45036
45621
|
initEditor(editor);
|
45037
|
-
ErrorReporter.contentCssError(editor, urls);
|
45038
45622
|
}
|
45039
45623
|
);
|
45624
|
+
|
45625
|
+
// Append specified content CSS last
|
45626
|
+
if (settings.content_style) {
|
45627
|
+
appendStyle(editor, settings.content_style);
|
45628
|
+
}
|
45040
45629
|
};
|
45041
45630
|
|
45042
45631
|
return {
|
@@ -45136,11 +45725,16 @@ define(
|
|
45136
45725
|
}
|
45137
45726
|
};
|
45138
45727
|
|
45728
|
+
var trimLegacyPrefix = function (name) {
|
45729
|
+
// Themes and plugins can be prefixed with - to prevent them from being lazy loaded
|
45730
|
+
return name.replace(/^\-/, '');
|
45731
|
+
};
|
45732
|
+
|
45139
45733
|
var initPlugins = function (editor) {
|
45140
45734
|
var initializedPlugins = [];
|
45141
45735
|
|
45142
|
-
Tools.each(editor.settings.plugins.
|
45143
|
-
initPlugin(editor, initializedPlugins, name);
|
45736
|
+
Tools.each(editor.settings.plugins.split(/[ ,]/), function (name) {
|
45737
|
+
initPlugin(editor, initializedPlugins, trimLegacyPrefix(name));
|
45144
45738
|
});
|
45145
45739
|
};
|
45146
45740
|
|
@@ -45149,7 +45743,8 @@ define(
|
|
45149
45743
|
|
45150
45744
|
if (settings.theme) {
|
45151
45745
|
if (typeof settings.theme != "function") {
|
45152
|
-
settings.theme = settings.theme
|
45746
|
+
settings.theme = trimLegacyPrefix(settings.theme);
|
45747
|
+
|
45153
45748
|
Theme = ThemeManager.get(settings.theme);
|
45154
45749
|
editor.theme = new Theme(editor, ThemeManager.urls[settings.theme]);
|
45155
45750
|
|
@@ -45334,11 +45929,6 @@ define(
|
|
45334
45929
|
});
|
45335
45930
|
}
|
45336
45931
|
|
45337
|
-
// Load specified content CSS last
|
45338
|
-
if (settings.content_style) {
|
45339
|
-
editor.contentStyles.push(settings.content_style);
|
45340
|
-
}
|
45341
|
-
|
45342
45932
|
// Content editable mode ends here
|
45343
45933
|
if (settings.content_editable) {
|
45344
45934
|
return InitContentBody.initContentBody(editor);
|
@@ -47628,6 +48218,8 @@ define(
|
|
47628
48218
|
define(
|
47629
48219
|
'tinymce.core.EditorManager',
|
47630
48220
|
[
|
48221
|
+
'ephox.katamari.api.Arr',
|
48222
|
+
'ephox.katamari.api.Type',
|
47631
48223
|
'tinymce.core.AddOnManager',
|
47632
48224
|
'tinymce.core.dom.DomQuery',
|
47633
48225
|
'tinymce.core.dom.DOMUtils',
|
@@ -47642,13 +48234,14 @@ define(
|
|
47642
48234
|
'tinymce.core.util.Tools',
|
47643
48235
|
'tinymce.core.util.URI'
|
47644
48236
|
],
|
47645
|
-
function (AddOnManager, DomQuery, DOMUtils, Editor, Env, ErrorReporter, FocusManager, LegacyInput, I18n, Observable, Promise, Tools, URI) {
|
48237
|
+
function (Arr, Type, AddOnManager, DomQuery, DOMUtils, Editor, Env, ErrorReporter, FocusManager, LegacyInput, I18n, Observable, Promise, Tools, URI) {
|
47646
48238
|
var DOM = DOMUtils.DOM;
|
47647
48239
|
var explode = Tools.explode, each = Tools.each, extend = Tools.extend;
|
47648
48240
|
var instanceCounter = 0, beforeUnloadDelegate, EditorManager, boundGlobalEvents = false;
|
48241
|
+
var legacyEditors = [], editors = [];
|
47649
48242
|
|
47650
48243
|
function globalEventDelegate(e) {
|
47651
|
-
each(EditorManager.
|
48244
|
+
each(EditorManager.get(), function (editor) {
|
47652
48245
|
if (e.type === 'scroll') {
|
47653
48246
|
editor.fire('ScrollWindow', e);
|
47654
48247
|
} else {
|
@@ -47657,7 +48250,7 @@ define(
|
|
47657
48250
|
});
|
47658
48251
|
}
|
47659
48252
|
|
47660
|
-
function toggleGlobalEvents(
|
48253
|
+
function toggleGlobalEvents(state) {
|
47661
48254
|
if (state !== boundGlobalEvents) {
|
47662
48255
|
if (state) {
|
47663
48256
|
DomQuery(window).on('resize scroll', globalEventDelegate);
|
@@ -47669,30 +48262,32 @@ define(
|
|
47669
48262
|
}
|
47670
48263
|
}
|
47671
48264
|
|
47672
|
-
function removeEditorFromList(
|
47673
|
-
var
|
48265
|
+
function removeEditorFromList(targetEditor) {
|
48266
|
+
var oldEditors = editors;
|
47674
48267
|
|
47675
|
-
delete
|
47676
|
-
|
47677
|
-
|
47678
|
-
|
47679
|
-
editors.splice(i, 1);
|
47680
|
-
removedFromList = true;
|
48268
|
+
delete legacyEditors[targetEditor.id];
|
48269
|
+
for (var i = 0; i < legacyEditors.length; i++) {
|
48270
|
+
if (legacyEditors[i] === targetEditor) {
|
48271
|
+
legacyEditors.splice(i, 1);
|
47681
48272
|
break;
|
47682
48273
|
}
|
47683
48274
|
}
|
47684
48275
|
|
48276
|
+
editors = Arr.filter(editors, function (editor) {
|
48277
|
+
return targetEditor !== editor;
|
48278
|
+
});
|
48279
|
+
|
47685
48280
|
// Select another editor since the active one was removed
|
47686
|
-
if (EditorManager.activeEditor
|
47687
|
-
EditorManager.activeEditor = editors[0];
|
48281
|
+
if (EditorManager.activeEditor === targetEditor) {
|
48282
|
+
EditorManager.activeEditor = editors.length > 0 ? editors[0] : null;
|
47688
48283
|
}
|
47689
48284
|
|
47690
48285
|
// Clear focusedEditor if necessary, so that we don't try to blur the destroyed editor
|
47691
|
-
if (EditorManager.focusedEditor
|
48286
|
+
if (EditorManager.focusedEditor === targetEditor) {
|
47692
48287
|
EditorManager.focusedEditor = null;
|
47693
48288
|
}
|
47694
48289
|
|
47695
|
-
return
|
48290
|
+
return oldEditors.length !== editors.length;
|
47696
48291
|
}
|
47697
48292
|
|
47698
48293
|
function purgeDestroyedEditor(editor) {
|
@@ -47731,7 +48326,7 @@ define(
|
|
47731
48326
|
* @property minorVersion
|
47732
48327
|
* @type String
|
47733
48328
|
*/
|
47734
|
-
minorVersion: '6.
|
48329
|
+
minorVersion: '6.6',
|
47735
48330
|
|
47736
48331
|
/**
|
47737
48332
|
* Release date of TinyMCE build.
|
@@ -47739,18 +48334,15 @@ define(
|
|
47739
48334
|
* @property releaseDate
|
47740
48335
|
* @type String
|
47741
48336
|
*/
|
47742
|
-
releaseDate: '2017-08-
|
48337
|
+
releaseDate: '2017-08-30',
|
47743
48338
|
|
47744
48339
|
/**
|
47745
|
-
* Collection of editor instances.
|
48340
|
+
* Collection of editor instances. Deprecated use tinymce.get() instead.
|
47746
48341
|
*
|
47747
48342
|
* @property editors
|
47748
48343
|
* @type Object
|
47749
|
-
* @example
|
47750
|
-
* for (edId in tinymce.editors)
|
47751
|
-
* tinymce.editors[edId].save();
|
47752
48344
|
*/
|
47753
|
-
editors:
|
48345
|
+
editors: legacyEditors,
|
47754
48346
|
|
47755
48347
|
/**
|
47756
48348
|
* Collection of language pack data.
|
@@ -48106,24 +48698,35 @@ define(
|
|
48106
48698
|
*
|
48107
48699
|
* @method get
|
48108
48700
|
* @param {String/Number} id Editor instance id or index to return.
|
48109
|
-
* @return {tinymce.Editor} Editor instance to return.
|
48701
|
+
* @return {tinymce.Editor/Array} Editor instance to return or array of editor instances.
|
48110
48702
|
* @example
|
48111
|
-
* // Adds an onclick event to an editor by id
|
48703
|
+
* // Adds an onclick event to an editor by id
|
48112
48704
|
* tinymce.get('mytextbox').on('click', function(e) {
|
48113
48705
|
* ed.windowManager.alert('Hello world!');
|
48114
48706
|
* });
|
48115
48707
|
*
|
48708
|
+
* // Adds an onclick event to an editor by index
|
48709
|
+
* tinymce.get(0).on('click', function(e) {
|
48710
|
+
* ed.windowManager.alert('Hello world!');
|
48711
|
+
* });
|
48712
|
+
*
|
48116
48713
|
* // Adds an onclick event to an editor by id (longer version)
|
48117
48714
|
* tinymce.EditorManager.get('mytextbox').on('click', function(e) {
|
48118
48715
|
* ed.windowManager.alert('Hello world!');
|
48119
48716
|
* });
|
48120
48717
|
*/
|
48121
48718
|
get: function (id) {
|
48122
|
-
if (
|
48123
|
-
return
|
48719
|
+
if (arguments.length === 0) {
|
48720
|
+
return editors.slice(0);
|
48721
|
+
} else if (Type.isString(id)) {
|
48722
|
+
return Arr.find(editors, function (editor) {
|
48723
|
+
return editor.id === id;
|
48724
|
+
}).getOr(null);
|
48725
|
+
} else if (Type.isNumber(id)) {
|
48726
|
+
return editors[id] ? editors[id] : null;
|
48727
|
+
} else {
|
48728
|
+
return null;
|
48124
48729
|
}
|
48125
|
-
|
48126
|
-
return id in this.editors ? this.editors[id] : null;
|
48127
48730
|
},
|
48128
48731
|
|
48129
48732
|
/**
|
@@ -48134,13 +48737,25 @@ define(
|
|
48134
48737
|
* @return {tinymce.Editor} The same instance that got passed in.
|
48135
48738
|
*/
|
48136
48739
|
add: function (editor) {
|
48137
|
-
var self = this,
|
48740
|
+
var self = this, existingEditor;
|
48138
48741
|
|
48139
|
-
//
|
48140
|
-
|
48141
|
-
|
48742
|
+
// Prevent existing editors from beeing added again this could happen
|
48743
|
+
// if a user calls createEditor then render or add multiple times.
|
48744
|
+
existingEditor = legacyEditors[editor.id];
|
48745
|
+
if (existingEditor === editor) {
|
48746
|
+
return editor;
|
48747
|
+
}
|
48748
|
+
|
48749
|
+
if (self.get(editor.id) === null) {
|
48750
|
+
// Add to legacy editors array, this is what breaks in HTML5 where ID:s with numbers are valid
|
48751
|
+
// We can't get rid of this strange object and array at the same time since it seems to be used all over the web
|
48752
|
+
legacyEditors[editor.id] = editor;
|
48753
|
+
legacyEditors.push(editor);
|
48754
|
+
|
48755
|
+
editors.push(editor);
|
48756
|
+
}
|
48142
48757
|
|
48143
|
-
toggleGlobalEvents(
|
48758
|
+
toggleGlobalEvents(true);
|
48144
48759
|
|
48145
48760
|
// Doesn't call setActive method since we don't want
|
48146
48761
|
// to fire a bunch of activate/deactivate calls while initializing
|
@@ -48192,7 +48807,7 @@ define(
|
|
48192
48807
|
* @return {tinymce.Editor} The editor that got passed in will be return if it was found otherwise null.
|
48193
48808
|
*/
|
48194
48809
|
remove: function (selector) {
|
48195
|
-
var self = this, i,
|
48810
|
+
var self = this, i, editor;
|
48196
48811
|
|
48197
48812
|
// Remove all editors
|
48198
48813
|
if (!selector) {
|
@@ -48204,11 +48819,11 @@ define(
|
|
48204
48819
|
}
|
48205
48820
|
|
48206
48821
|
// Remove editors by selector
|
48207
|
-
if (
|
48822
|
+
if (Type.isString(selector)) {
|
48208
48823
|
selector = selector.selector || selector;
|
48209
48824
|
|
48210
48825
|
each(DOM.select(selector), function (elm) {
|
48211
|
-
editor =
|
48826
|
+
editor = self.get(elm.id);
|
48212
48827
|
|
48213
48828
|
if (editor) {
|
48214
48829
|
self.remove(editor);
|
@@ -48222,7 +48837,7 @@ define(
|
|
48222
48837
|
editor = selector;
|
48223
48838
|
|
48224
48839
|
// Not in the collection
|
48225
|
-
if (
|
48840
|
+
if (Type.isNull(self.get(editor.id))) {
|
48226
48841
|
return null;
|
48227
48842
|
}
|
48228
48843
|
|
@@ -48230,13 +48845,13 @@ define(
|
|
48230
48845
|
self.fire('RemoveEditor', { editor: editor });
|
48231
48846
|
}
|
48232
48847
|
|
48233
|
-
if (
|
48848
|
+
if (editors.length === 0) {
|
48234
48849
|
DOM.unbind(window, 'beforeunload', beforeUnloadDelegate);
|
48235
48850
|
}
|
48236
48851
|
|
48237
48852
|
editor.remove();
|
48238
48853
|
|
48239
|
-
toggleGlobalEvents(editors
|
48854
|
+
toggleGlobalEvents(editors.length > 0);
|
48240
48855
|
|
48241
48856
|
return editor;
|
48242
48857
|
},
|
@@ -48301,7 +48916,7 @@ define(
|
|
48301
48916
|
* tinyMCE.triggerSave();
|
48302
48917
|
*/
|
48303
48918
|
triggerSave: function () {
|
48304
|
-
each(
|
48919
|
+
each(editors, function (editor) {
|
48305
48920
|
editor.save();
|
48306
48921
|
});
|
48307
48922
|
},
|