tinymce-rails 4.6.3 → 4.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +2174 -1784
- data/lib/tinymce/rails/version.rb +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/contextmenu/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/imagetools/plugin.js +2 -2
- data/vendor/assets/javascripts/tinymce/plugins/link/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.js +1 -1
- data/vendor/assets/javascripts/tinymce/plugins/preview/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/tinymce.js +15 -15
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ce018de101ce52c7c97b1ec464c50a96f25805a
|
4
|
+
data.tar.gz: 31c037f319b428cecdd48ec343fdd5f28f5259bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83fc0e180593e62c25bcf6fc3b9a3d8d5aa19b747a67173045ee8db0237fca26f43ab826cc03187caf1feee8bfaf43067676bc45b450f398637331b2b575139b
|
7
|
+
data.tar.gz: ea0d70f73da56bca7beb9a6b0e4beb4862247c137a329c35d0ac9127ba47538ad4a09f7bf218633bff60c0a86a35f4819fd8fe1cff862d9dfc37efc504e09452
|
@@ -1,4 +1,4 @@
|
|
1
|
-
// 4.6.
|
1
|
+
// 4.6.4 (2017-06-13)
|
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","tinymce.core.api.Tinymce","tinymce.core.Register","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.Formatter","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.api.Compat","tinymce.core.util.Color","tinymce.core.ui.Api","tinymce.core.util.Arr","tinymce.core.dom.Range","tinymce.core.dom.StyleSheetLoader","tinymce.core.dom.NodeType","tinymce.core.caret.CaretContainer","tinymce.core.text.Zwsp","tinymce.core.caret.CaretBookmark","tinymce.core.caret.CaretPosition","tinymce.core.dom.ScrollIntoView","tinymce.core.dom.TridentSelection","tinymce.core.selection.FragmentReader","tinymce.core.dom.ElementUtils","tinymce.core.util.Fun","tinymce.core.fmt.Preview","tinymce.core.fmt.Hooks","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.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","ephox.katamari.api.Arr","
|
85
|
+
["tinymce.core.api.Main","tinymce.core.api.Tinymce","tinymce.core.Register","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.Formatter","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.api.Compat","tinymce.core.util.Color","tinymce.core.ui.Api","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.katamari.api.Fun","tinymce.core.dom.RangePoint","tinymce.core.caret.CaretBookmark","tinymce.core.caret.CaretPosition","ephox.sugar.api.dom.Compare","ephox.sugar.api.node.Element","tinymce.core.dom.ScrollIntoView","tinymce.core.dom.TridentSelection","tinymce.core.selection.FragmentReader","tinymce.core.dom.ElementUtils","tinymce.core.util.Fun","tinymce.core.fmt.Preview","tinymce.core.fmt.Hooks","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","ephox.katamari.api.Arr","global!Array","global!Error","ephox.katamari.api.Future","ephox.katamari.api.Futures","ephox.katamari.api.Result","tinymce.core.geom.ClientRect","tinymce.core.caret.CaretCandidate","tinymce.core.text.ExtendingChar","ephox.sand.api.Node","ephox.sand.api.PlatformDetection","ephox.sugar.api.search.Selectors","global!console","ephox.sugar.api.dom.Insert","ephox.sugar.api.dom.Replication","ephox.sugar.api.node.Fragment","ephox.sugar.api.node.Node","tinymce.core.dom.ElementType","tinymce.core.dom.Parents","tinymce.core.selection.SelectionUtils","tinymce.core.undo.Fragments","tinymce.core.delete.BlockBoundaryDelete","tinymce.core.delete.BlockRangeDelete","tinymce.core.delete.CefDelete","tinymce.core.delete.InlineBoundaryDelete","tinymce.core.caret.CaretWalker","tinymce.core.dom.RangeNormalizer","tinymce.core.InsertList","tinymce.core.data.ObservableObject","tinymce.core.ui.DomUtils","tinymce.core.ui.BoxUtils","tinymce.core.ui.ClassList","global!window","tinymce.core.init.Init","tinymce.core.PluginManager","tinymce.core.ThemeManager","tinymce.core.content.LinkTargets","tinymce.core.fmt.FontInfo","ephox.katamari.api.Option","global!String","ephox.katamari.api.LazyValue","ephox.katamari.async.Bounce","ephox.katamari.async.AsyncValues","ephox.sand.util.Global","ephox.katamari.api.Thunk","ephox.sand.core.PlatformDetection","global!navigator","ephox.sugar.api.node.NodeTypes","ephox.sugar.api.search.Traverse","ephox.sugar.api.properties.Attr","ephox.sugar.api.dom.InsertAll","ephox.sugar.api.dom.Remove","ephox.katamari.api.Options","tinymce.core.undo.Diff","tinymce.core.delete.BlockBoundary","tinymce.core.delete.MergeBlocks","tinymce.core.delete.DeleteUtils","tinymce.core.caret.CaretUtils","tinymce.core.delete.CefDeleteAction","tinymce.core.delete.DeleteElement","tinymce.core.caret.CaretFinder","tinymce.core.keyboard.BoundaryCaret","tinymce.core.keyboard.BoundaryLocation","tinymce.core.keyboard.BoundarySelection","tinymce.core.keyboard.InlineUtils","tinymce.core.data.Binding","tinymce.core.init.InitContentBody","global!Object","global!setTimeout","ephox.katamari.api.Resolve","ephox.sand.core.Browser","ephox.sand.core.OperatingSystem","ephox.sand.detect.DeviceType","ephox.sand.detect.UaString","ephox.sand.info.PlatformInfo","ephox.katamari.api.Type","ephox.katamari.api.Struct","ephox.sugar.alien.Recurse","ephox.katamari.api.Obj","ephox.sugar.api.search.PredicateFind","tinymce.core.dom.Empty","ephox.katamari.api.Adt","tinymce.core.text.Bidi","tinymce.core.caret.CaretContainerInline","tinymce.core.caret.CaretContainerRemove","tinymce.core.util.LazyEvaluator","ephox.katamari.api.Cell","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.katamari.api.Strings","ephox.katamari.data.Immutable","ephox.katamari.data.MixedBag","ephox.sugar.api.node.Body","ephox.sugar.impl.ClosestOrAncestor","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.EditorView","tinymce.core.keyboard.CefUtils","tinymce.core.dom.NodePath","global!Number","ephox.katamari.str.StrAppend","ephox.katamari.str.StringParts","ephox.katamari.util.BagUtils","ephox.sugar.api.search.SelectorFind","tinymce.core.file.Conversions","global!URL","tinymce.core.keyboard.CefNavigation","tinymce.core.keyboard.MatchKeys","tinymce.core.keyboard.InsertSpace","tinymce.core.dom.Dimensions","tinymce.core.dom.MousePosition","ephox.sugar.api.properties.Css","tinymce.core.caret.LineWalker","ephox.katamari.api.Merger","ephox.sugar.impl.Style"]
|
86
86
|
jsc*/
|
87
87
|
/**
|
88
88
|
* Rect.js
|
@@ -8973,7 +8973,7 @@ define(
|
|
8973
8973
|
textInlineElementsMap = createLookupTable('text_inline_elements', 'span strong b em i font strike u var cite ' +
|
8974
8974
|
'dfn code mark q sup sub samp');
|
8975
8975
|
|
8976
|
-
each((settings.special || 'script noscript style textarea').split(' '), function (name) {
|
8976
|
+
each((settings.special || 'script noscript noframes noembed title style textarea xmp').split(' '), function (name) {
|
8977
8977
|
specialElements[name] = new RegExp('<\/' + name + '[^>]*>', 'gi');
|
8978
8978
|
});
|
8979
8979
|
|
@@ -13672,6 +13672,10 @@ define(
|
|
13672
13672
|
return name.indexOf('data-') === 0 || name.indexOf('aria-') === 0;
|
13673
13673
|
};
|
13674
13674
|
|
13675
|
+
var trimComments = function (text) {
|
13676
|
+
return text.replace(/<!--|-->/g, '');
|
13677
|
+
};
|
13678
|
+
|
13675
13679
|
/**
|
13676
13680
|
* Returns the index of the end tag for a specific start tag. This can be
|
13677
13681
|
* used to skip all children of a parent element from being processed.
|
@@ -13840,6 +13844,11 @@ define(
|
|
13840
13844
|
}
|
13841
13845
|
}
|
13842
13846
|
|
13847
|
+
// Block data or event attributes on elements marked as internal
|
13848
|
+
if (isInternalElement && (name in filteredUrlAttrs || name.indexOf('on') === 0)) {
|
13849
|
+
return;
|
13850
|
+
}
|
13851
|
+
|
13843
13852
|
// Add attribute to list and map
|
13844
13853
|
attrList.map[name] = value;
|
13845
13854
|
attrList.push({
|
@@ -14066,7 +14075,7 @@ define(
|
|
14066
14075
|
|
14067
14076
|
self.comment(value);
|
14068
14077
|
} else if ((value = matches[2])) { // CDATA
|
14069
|
-
self.cdata(value);
|
14078
|
+
self.cdata(trimComments(value));
|
14070
14079
|
} else if ((value = matches[3])) { // DOCTYPE
|
14071
14080
|
self.doctype(value);
|
14072
14081
|
} else if ((value = matches[4])) { // PI
|
@@ -14871,34 +14880,35 @@ define(
|
|
14871
14880
|
});
|
14872
14881
|
}
|
14873
14882
|
|
14874
|
-
if (!settings.allow_unsafe_link_target) {
|
14875
|
-
self.addAttributeFilter('href', function (nodes) {
|
14876
|
-
var i = nodes.length, node;
|
14877
14883
|
|
14878
|
-
|
14879
|
-
|
14880
|
-
return p.length > 0;
|
14881
|
-
});
|
14882
|
-
return parts.concat(['noopener']).join(' ');
|
14883
|
-
};
|
14884
|
+
self.addAttributeFilter('href', function (nodes) {
|
14885
|
+
var i = nodes.length, node;
|
14884
14886
|
|
14885
|
-
|
14886
|
-
|
14887
|
-
|
14888
|
-
|
14889
|
-
|
14890
|
-
|
14891
|
-
|
14892
|
-
|
14887
|
+
var appendRel = function (rel) {
|
14888
|
+
var parts = rel.split(' ').filter(function (p) {
|
14889
|
+
return p.length > 0;
|
14890
|
+
});
|
14891
|
+
return parts.concat(['noopener']).sort().join(' ');
|
14892
|
+
};
|
14893
|
+
|
14894
|
+
var addNoOpener = function (rel) {
|
14895
|
+
var newRel = rel ? Tools.trim(rel) : '';
|
14896
|
+
if (!/\b(noopener)\b/g.test(newRel)) {
|
14897
|
+
return appendRel(newRel);
|
14898
|
+
} else {
|
14899
|
+
return newRel;
|
14900
|
+
}
|
14901
|
+
};
|
14893
14902
|
|
14903
|
+
if (!settings.allow_unsafe_link_target) {
|
14894
14904
|
while (i--) {
|
14895
14905
|
node = nodes[i];
|
14896
14906
|
if (node.name === 'a' && node.attr('target') === '_blank') {
|
14897
14907
|
node.attr('rel', addNoOpener(node.attr('rel')));
|
14898
14908
|
}
|
14899
14909
|
}
|
14900
|
-
}
|
14901
|
-
}
|
14910
|
+
}
|
14911
|
+
});
|
14902
14912
|
|
14903
14913
|
// Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included.
|
14904
14914
|
if (!settings.allow_html_in_named_anchor) {
|
@@ -15894,6 +15904,180 @@ define(
|
|
15894
15904
|
}
|
15895
15905
|
);
|
15896
15906
|
|
15907
|
+
/**
|
15908
|
+
* ClientRect.js
|
15909
|
+
*
|
15910
|
+
* Released under LGPL License.
|
15911
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
15912
|
+
*
|
15913
|
+
* License: http://www.tinymce.com/license
|
15914
|
+
* Contributing: http://www.tinymce.com/contributing
|
15915
|
+
*/
|
15916
|
+
|
15917
|
+
/**
|
15918
|
+
* Utility functions for working with client rects.
|
15919
|
+
*
|
15920
|
+
* @private
|
15921
|
+
* @class tinymce.geom.ClientRect
|
15922
|
+
*/
|
15923
|
+
define(
|
15924
|
+
'tinymce.core.geom.ClientRect',
|
15925
|
+
[
|
15926
|
+
],
|
15927
|
+
function () {
|
15928
|
+
var round = Math.round;
|
15929
|
+
|
15930
|
+
function clone(rect) {
|
15931
|
+
if (!rect) {
|
15932
|
+
return { left: 0, top: 0, bottom: 0, right: 0, width: 0, height: 0 };
|
15933
|
+
}
|
15934
|
+
|
15935
|
+
return {
|
15936
|
+
left: round(rect.left),
|
15937
|
+
top: round(rect.top),
|
15938
|
+
bottom: round(rect.bottom),
|
15939
|
+
right: round(rect.right),
|
15940
|
+
width: round(rect.width),
|
15941
|
+
height: round(rect.height)
|
15942
|
+
};
|
15943
|
+
}
|
15944
|
+
|
15945
|
+
function collapse(clientRect, toStart) {
|
15946
|
+
clientRect = clone(clientRect);
|
15947
|
+
|
15948
|
+
if (toStart) {
|
15949
|
+
clientRect.right = clientRect.left;
|
15950
|
+
} else {
|
15951
|
+
clientRect.left = clientRect.left + clientRect.width;
|
15952
|
+
clientRect.right = clientRect.left;
|
15953
|
+
}
|
15954
|
+
|
15955
|
+
clientRect.width = 0;
|
15956
|
+
|
15957
|
+
return clientRect;
|
15958
|
+
}
|
15959
|
+
|
15960
|
+
function isEqual(rect1, rect2) {
|
15961
|
+
return (
|
15962
|
+
rect1.left === rect2.left &&
|
15963
|
+
rect1.top === rect2.top &&
|
15964
|
+
rect1.bottom === rect2.bottom &&
|
15965
|
+
rect1.right === rect2.right
|
15966
|
+
);
|
15967
|
+
}
|
15968
|
+
|
15969
|
+
function isValidOverflow(overflowY, clientRect1, clientRect2) {
|
15970
|
+
return overflowY >= 0 && overflowY <= Math.min(clientRect1.height, clientRect2.height) / 2;
|
15971
|
+
|
15972
|
+
}
|
15973
|
+
|
15974
|
+
function isAbove(clientRect1, clientRect2) {
|
15975
|
+
if ((clientRect1.bottom - clientRect1.height / 2) < clientRect2.top) {
|
15976
|
+
return true;
|
15977
|
+
}
|
15978
|
+
|
15979
|
+
if (clientRect1.top > clientRect2.bottom) {
|
15980
|
+
return false;
|
15981
|
+
}
|
15982
|
+
|
15983
|
+
return isValidOverflow(clientRect2.top - clientRect1.bottom, clientRect1, clientRect2);
|
15984
|
+
}
|
15985
|
+
|
15986
|
+
function isBelow(clientRect1, clientRect2) {
|
15987
|
+
if (clientRect1.top > clientRect2.bottom) {
|
15988
|
+
return true;
|
15989
|
+
}
|
15990
|
+
|
15991
|
+
if (clientRect1.bottom < clientRect2.top) {
|
15992
|
+
return false;
|
15993
|
+
}
|
15994
|
+
|
15995
|
+
return isValidOverflow(clientRect2.bottom - clientRect1.top, clientRect1, clientRect2);
|
15996
|
+
}
|
15997
|
+
|
15998
|
+
function isLeft(clientRect1, clientRect2) {
|
15999
|
+
return clientRect1.left < clientRect2.left;
|
16000
|
+
}
|
16001
|
+
|
16002
|
+
function isRight(clientRect1, clientRect2) {
|
16003
|
+
return clientRect1.right > clientRect2.right;
|
16004
|
+
}
|
16005
|
+
|
16006
|
+
function compare(clientRect1, clientRect2) {
|
16007
|
+
if (isAbove(clientRect1, clientRect2)) {
|
16008
|
+
return -1;
|
16009
|
+
}
|
16010
|
+
|
16011
|
+
if (isBelow(clientRect1, clientRect2)) {
|
16012
|
+
return 1;
|
16013
|
+
}
|
16014
|
+
|
16015
|
+
if (isLeft(clientRect1, clientRect2)) {
|
16016
|
+
return -1;
|
16017
|
+
}
|
16018
|
+
|
16019
|
+
if (isRight(clientRect1, clientRect2)) {
|
16020
|
+
return 1;
|
16021
|
+
}
|
16022
|
+
|
16023
|
+
return 0;
|
16024
|
+
}
|
16025
|
+
|
16026
|
+
function containsXY(clientRect, clientX, clientY) {
|
16027
|
+
return (
|
16028
|
+
clientX >= clientRect.left &&
|
16029
|
+
clientX <= clientRect.right &&
|
16030
|
+
clientY >= clientRect.top &&
|
16031
|
+
clientY <= clientRect.bottom
|
16032
|
+
);
|
16033
|
+
}
|
16034
|
+
|
16035
|
+
return {
|
16036
|
+
clone: clone,
|
16037
|
+
collapse: collapse,
|
16038
|
+
isEqual: isEqual,
|
16039
|
+
isAbove: isAbove,
|
16040
|
+
isBelow: isBelow,
|
16041
|
+
isLeft: isLeft,
|
16042
|
+
isRight: isRight,
|
16043
|
+
compare: compare,
|
16044
|
+
containsXY: containsXY
|
16045
|
+
};
|
16046
|
+
}
|
16047
|
+
);
|
16048
|
+
|
16049
|
+
/**
|
16050
|
+
* RangePoint.js
|
16051
|
+
*
|
16052
|
+
* Released under LGPL License.
|
16053
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
16054
|
+
*
|
16055
|
+
* License: http://www.tinymce.com/license
|
16056
|
+
* Contributing: http://www.tinymce.com/contributing
|
16057
|
+
*/
|
16058
|
+
|
16059
|
+
define(
|
16060
|
+
'tinymce.core.dom.RangePoint',
|
16061
|
+
[
|
16062
|
+
'ephox.katamari.api.Arr',
|
16063
|
+
'tinymce.core.geom.ClientRect'
|
16064
|
+
],
|
16065
|
+
function (Arr, ClientRect) {
|
16066
|
+
var isXYWithinRange = function (clientX, clientY, range) {
|
16067
|
+
if (range.collapsed) {
|
16068
|
+
return false;
|
16069
|
+
}
|
16070
|
+
|
16071
|
+
return Arr.foldl(range.getClientRects(), function (state, rect) {
|
16072
|
+
return state || ClientRect.containsXY(rect, clientX, clientY);
|
16073
|
+
}, false);
|
16074
|
+
};
|
16075
|
+
|
16076
|
+
return {
|
16077
|
+
isXYWithinRange: isXYWithinRange
|
16078
|
+
};
|
16079
|
+
}
|
16080
|
+
);
|
15897
16081
|
/**
|
15898
16082
|
* ControlSelection.js
|
15899
16083
|
*
|
@@ -15914,13 +16098,15 @@ define(
|
|
15914
16098
|
define(
|
15915
16099
|
'tinymce.core.dom.ControlSelection',
|
15916
16100
|
[
|
15917
|
-
|
15918
|
-
|
15919
|
-
|
15920
|
-
|
15921
|
-
|
16101
|
+
'ephox.katamari.api.Fun',
|
16102
|
+
'tinymce.core.dom.NodeType',
|
16103
|
+
'tinymce.core.dom.RangePoint',
|
16104
|
+
'tinymce.core.Env',
|
16105
|
+
'tinymce.core.util.Delay',
|
16106
|
+
'tinymce.core.util.Tools',
|
16107
|
+
'tinymce.core.util.VK'
|
15922
16108
|
],
|
15923
|
-
function (
|
16109
|
+
function (Fun, NodeType, RangePoint, Env, Delay, Tools, VK) {
|
15924
16110
|
var isContentEditableFalse = NodeType.isContentEditableFalse;
|
15925
16111
|
var isContentEditableTrue = NodeType.isContentEditableTrue;
|
15926
16112
|
|
@@ -15936,6 +16122,23 @@ define(
|
|
15936
16122
|
return null;
|
15937
16123
|
}
|
15938
16124
|
|
16125
|
+
var isImage = function (elm) {
|
16126
|
+
return elm && elm.nodeName === 'IMG';
|
16127
|
+
};
|
16128
|
+
|
16129
|
+
var isEventOnImageOutsideRange = function (evt, range) {
|
16130
|
+
return isImage(evt.target) && !RangePoint.isXYWithinRange(evt.clientX, evt.clientY, range);
|
16131
|
+
};
|
16132
|
+
|
16133
|
+
var contextMenuSelectImage = function (editor, evt) {
|
16134
|
+
var target = evt.target;
|
16135
|
+
|
16136
|
+
if (isEventOnImageOutsideRange(evt, editor.selection.getRng()) && !evt.isDefaultPrevented()) {
|
16137
|
+
evt.preventDefault();
|
16138
|
+
editor.selection.select(target);
|
16139
|
+
}
|
16140
|
+
};
|
16141
|
+
|
15939
16142
|
return function (selection, editor) {
|
15940
16143
|
var dom = editor.dom, each = Tools.each;
|
15941
16144
|
var selectedElm, selectedElmGhost, resizeHelper, resizeHandles, selectedHandle, lastMouseDownEvent;
|
@@ -16471,7 +16674,9 @@ define(
|
|
16471
16674
|
var target = e.target, nodeName = target.nodeName;
|
16472
16675
|
|
16473
16676
|
if (!resizeStarted && /^(TABLE|IMG|HR)$/.test(nodeName) && !isWithinContentEditableFalse(target)) {
|
16474
|
-
|
16677
|
+
if (e.button !== 2) {
|
16678
|
+
editor.selection.select(target, nodeName == 'TABLE');
|
16679
|
+
}
|
16475
16680
|
|
16476
16681
|
// Only fire once since nodeChange is expensive
|
16477
16682
|
if (e.type == 'mousedown') {
|
@@ -16523,6 +16728,7 @@ define(
|
|
16523
16728
|
});
|
16524
16729
|
|
16525
16730
|
editor.on('hide blur', hideResizeRect);
|
16731
|
+
editor.on('contextmenu', Fun.curry(contextMenuSelectImage, editor));
|
16526
16732
|
|
16527
16733
|
// Hide rect on focusout since it would float on top of windows otherwise
|
16528
16734
|
//editor.on('focusout', hideResizeRect);
|
@@ -16737,148 +16943,6 @@ define(
|
|
16737
16943
|
};
|
16738
16944
|
}
|
16739
16945
|
);
|
16740
|
-
/**
|
16741
|
-
* ClientRect.js
|
16742
|
-
*
|
16743
|
-
* Released under LGPL License.
|
16744
|
-
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
16745
|
-
*
|
16746
|
-
* License: http://www.tinymce.com/license
|
16747
|
-
* Contributing: http://www.tinymce.com/contributing
|
16748
|
-
*/
|
16749
|
-
|
16750
|
-
/**
|
16751
|
-
* Utility functions for working with client rects.
|
16752
|
-
*
|
16753
|
-
* @private
|
16754
|
-
* @class tinymce.geom.ClientRect
|
16755
|
-
*/
|
16756
|
-
define(
|
16757
|
-
'tinymce.core.geom.ClientRect',
|
16758
|
-
[
|
16759
|
-
],
|
16760
|
-
function () {
|
16761
|
-
var round = Math.round;
|
16762
|
-
|
16763
|
-
function clone(rect) {
|
16764
|
-
if (!rect) {
|
16765
|
-
return { left: 0, top: 0, bottom: 0, right: 0, width: 0, height: 0 };
|
16766
|
-
}
|
16767
|
-
|
16768
|
-
return {
|
16769
|
-
left: round(rect.left),
|
16770
|
-
top: round(rect.top),
|
16771
|
-
bottom: round(rect.bottom),
|
16772
|
-
right: round(rect.right),
|
16773
|
-
width: round(rect.width),
|
16774
|
-
height: round(rect.height)
|
16775
|
-
};
|
16776
|
-
}
|
16777
|
-
|
16778
|
-
function collapse(clientRect, toStart) {
|
16779
|
-
clientRect = clone(clientRect);
|
16780
|
-
|
16781
|
-
if (toStart) {
|
16782
|
-
clientRect.right = clientRect.left;
|
16783
|
-
} else {
|
16784
|
-
clientRect.left = clientRect.left + clientRect.width;
|
16785
|
-
clientRect.right = clientRect.left;
|
16786
|
-
}
|
16787
|
-
|
16788
|
-
clientRect.width = 0;
|
16789
|
-
|
16790
|
-
return clientRect;
|
16791
|
-
}
|
16792
|
-
|
16793
|
-
function isEqual(rect1, rect2) {
|
16794
|
-
return (
|
16795
|
-
rect1.left === rect2.left &&
|
16796
|
-
rect1.top === rect2.top &&
|
16797
|
-
rect1.bottom === rect2.bottom &&
|
16798
|
-
rect1.right === rect2.right
|
16799
|
-
);
|
16800
|
-
}
|
16801
|
-
|
16802
|
-
function isValidOverflow(overflowY, clientRect1, clientRect2) {
|
16803
|
-
return overflowY >= 0 && overflowY <= Math.min(clientRect1.height, clientRect2.height) / 2;
|
16804
|
-
|
16805
|
-
}
|
16806
|
-
|
16807
|
-
function isAbove(clientRect1, clientRect2) {
|
16808
|
-
if ((clientRect1.bottom - clientRect1.height / 2) < clientRect2.top) {
|
16809
|
-
return true;
|
16810
|
-
}
|
16811
|
-
|
16812
|
-
if (clientRect1.top > clientRect2.bottom) {
|
16813
|
-
return false;
|
16814
|
-
}
|
16815
|
-
|
16816
|
-
return isValidOverflow(clientRect2.top - clientRect1.bottom, clientRect1, clientRect2);
|
16817
|
-
}
|
16818
|
-
|
16819
|
-
function isBelow(clientRect1, clientRect2) {
|
16820
|
-
if (clientRect1.top > clientRect2.bottom) {
|
16821
|
-
return true;
|
16822
|
-
}
|
16823
|
-
|
16824
|
-
if (clientRect1.bottom < clientRect2.top) {
|
16825
|
-
return false;
|
16826
|
-
}
|
16827
|
-
|
16828
|
-
return isValidOverflow(clientRect2.bottom - clientRect1.top, clientRect1, clientRect2);
|
16829
|
-
}
|
16830
|
-
|
16831
|
-
function isLeft(clientRect1, clientRect2) {
|
16832
|
-
return clientRect1.left < clientRect2.left;
|
16833
|
-
}
|
16834
|
-
|
16835
|
-
function isRight(clientRect1, clientRect2) {
|
16836
|
-
return clientRect1.right > clientRect2.right;
|
16837
|
-
}
|
16838
|
-
|
16839
|
-
function compare(clientRect1, clientRect2) {
|
16840
|
-
if (isAbove(clientRect1, clientRect2)) {
|
16841
|
-
return -1;
|
16842
|
-
}
|
16843
|
-
|
16844
|
-
if (isBelow(clientRect1, clientRect2)) {
|
16845
|
-
return 1;
|
16846
|
-
}
|
16847
|
-
|
16848
|
-
if (isLeft(clientRect1, clientRect2)) {
|
16849
|
-
return -1;
|
16850
|
-
}
|
16851
|
-
|
16852
|
-
if (isRight(clientRect1, clientRect2)) {
|
16853
|
-
return 1;
|
16854
|
-
}
|
16855
|
-
|
16856
|
-
return 0;
|
16857
|
-
}
|
16858
|
-
|
16859
|
-
function containsXY(clientRect, clientX, clientY) {
|
16860
|
-
return (
|
16861
|
-
clientX >= clientRect.left &&
|
16862
|
-
clientX <= clientRect.right &&
|
16863
|
-
clientY >= clientRect.top &&
|
16864
|
-
clientY <= clientRect.bottom
|
16865
|
-
);
|
16866
|
-
}
|
16867
|
-
|
16868
|
-
return {
|
16869
|
-
clone: clone,
|
16870
|
-
collapse: collapse,
|
16871
|
-
isEqual: isEqual,
|
16872
|
-
isAbove: isAbove,
|
16873
|
-
isBelow: isBelow,
|
16874
|
-
isLeft: isLeft,
|
16875
|
-
isRight: isRight,
|
16876
|
-
compare: compare,
|
16877
|
-
containsXY: containsXY
|
16878
|
-
};
|
16879
|
-
}
|
16880
|
-
);
|
16881
|
-
|
16882
16946
|
/**
|
16883
16947
|
* ExtendingChar.js
|
16884
16948
|
*
|
@@ -18081,1921 +18145,1921 @@ define(
|
|
18081
18145
|
return BookmarkManager;
|
18082
18146
|
}
|
18083
18147
|
);
|
18084
|
-
/**
|
18085
|
-
* ScrollIntoView.js
|
18086
|
-
*
|
18087
|
-
* Released under LGPL License.
|
18088
|
-
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
18089
|
-
*
|
18090
|
-
* License: http://www.tinymce.com/license
|
18091
|
-
* Contributing: http://www.tinymce.com/contributing
|
18092
|
-
*/
|
18093
|
-
|
18094
18148
|
define(
|
18095
|
-
'
|
18149
|
+
'ephox.katamari.api.Global',
|
18150
|
+
|
18096
18151
|
[
|
18097
|
-
'tinymce.core.dom.NodeType'
|
18098
18152
|
],
|
18099
|
-
function (NodeType) {
|
18100
|
-
var getPos = function (elm) {
|
18101
|
-
var x = 0, y = 0;
|
18102
|
-
|
18103
|
-
var offsetParent = elm;
|
18104
|
-
while (offsetParent && offsetParent.nodeType) {
|
18105
|
-
x += offsetParent.offsetLeft || 0;
|
18106
|
-
y += offsetParent.offsetTop || 0;
|
18107
|
-
offsetParent = offsetParent.offsetParent;
|
18108
|
-
}
|
18109
18153
|
|
18110
|
-
|
18111
|
-
|
18154
|
+
function () {
|
18155
|
+
// Use window object as the global if it's available since CSP will block script evals
|
18156
|
+
if (typeof window !== 'undefined') {
|
18157
|
+
return window;
|
18158
|
+
} else {
|
18159
|
+
return Function('return this;')();
|
18160
|
+
}
|
18161
|
+
}
|
18162
|
+
);
|
18112
18163
|
|
18113
|
-
var fireScrollIntoViewEvent = function (editor, elm, alignToTop) {
|
18114
|
-
var scrollEvent = { elm: elm, alignToTop: alignToTop };
|
18115
|
-
editor.fire('scrollIntoView', scrollEvent);
|
18116
|
-
return scrollEvent.isDefaultPrevented();
|
18117
|
-
};
|
18118
18164
|
|
18119
|
-
|
18120
|
-
|
18165
|
+
define(
|
18166
|
+
'ephox.katamari.api.Resolve',
|
18121
18167
|
|
18122
|
-
|
18123
|
-
|
18124
|
-
|
18168
|
+
[
|
18169
|
+
'ephox.katamari.api.Global'
|
18170
|
+
],
|
18125
18171
|
|
18126
|
-
|
18127
|
-
|
18128
|
-
|
18172
|
+
function (Global) {
|
18173
|
+
/** path :: ([String], JsObj?) -> JsObj */
|
18174
|
+
var path = function (parts, scope) {
|
18175
|
+
var o = scope !== undefined ? scope : Global;
|
18176
|
+
for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i)
|
18177
|
+
o = o[parts[i]];
|
18178
|
+
return o;
|
18179
|
+
};
|
18129
18180
|
|
18130
|
-
|
18131
|
-
|
18132
|
-
|
18181
|
+
/** resolve :: (String, JsObj?) -> JsObj */
|
18182
|
+
var resolve = function (p, scope) {
|
18183
|
+
var parts = p.split('.');
|
18184
|
+
return path(parts, scope);
|
18185
|
+
};
|
18133
18186
|
|
18134
|
-
|
18135
|
-
|
18136
|
-
|
18137
|
-
|
18138
|
-
|
18139
|
-
|
18140
|
-
if (y < viewPortY || y + 25 > viewPortY + viewPortH) {
|
18141
|
-
scrollContainer.scrollTop = y < viewPortY ? y : y - viewPortH + 25;
|
18142
|
-
}
|
18187
|
+
/** step :: (JsObj, String) -> JsObj */
|
18188
|
+
var step = function (o, part) {
|
18189
|
+
if (o[part] === undefined || o[part] === null)
|
18190
|
+
o[part] = {};
|
18191
|
+
return o[part];
|
18192
|
+
};
|
18143
18193
|
|
18144
|
-
|
18145
|
-
|
18146
|
-
|
18194
|
+
/** forge :: ([String], JsObj?) -> JsObj */
|
18195
|
+
var forge = function (parts, target) {
|
18196
|
+
var o = target !== undefined ? target : Global;
|
18197
|
+
for (var i = 0; i < parts.length; ++i)
|
18198
|
+
o = step(o, parts[i]);
|
18199
|
+
return o;
|
18200
|
+
};
|
18147
18201
|
|
18148
|
-
|
18149
|
-
|
18150
|
-
|
18151
|
-
|
18152
|
-
if (y < viewPort.y || y + 25 > viewPortY + viewPortH) {
|
18153
|
-
editor.getWin().scrollTo(0, y < viewPortY ? y : y - viewPortH + 25);
|
18154
|
-
}
|
18202
|
+
/** namespace :: (String, JsObj?) -> JsObj */
|
18203
|
+
var namespace = function (name, target) {
|
18204
|
+
var parts = name.split('.');
|
18205
|
+
return forge(parts, target);
|
18155
18206
|
};
|
18156
18207
|
|
18157
18208
|
return {
|
18158
|
-
|
18209
|
+
path: path,
|
18210
|
+
resolve: resolve,
|
18211
|
+
forge: forge,
|
18212
|
+
namespace: namespace
|
18159
18213
|
};
|
18160
18214
|
}
|
18161
18215
|
);
|
18162
18216
|
|
18163
|
-
/**
|
18164
|
-
* TridentSelection.js
|
18165
|
-
*
|
18166
|
-
* Released under LGPL License.
|
18167
|
-
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
18168
|
-
*
|
18169
|
-
* License: http://www.tinymce.com/license
|
18170
|
-
* Contributing: http://www.tinymce.com/contributing
|
18171
|
-
*/
|
18172
18217
|
|
18173
|
-
/**
|
18174
|
-
* Selection class for old explorer versions. This one fakes the
|
18175
|
-
* native selection object available on modern browsers.
|
18176
|
-
*
|
18177
|
-
* @private
|
18178
|
-
* @class tinymce.dom.TridentSelection
|
18179
|
-
*/
|
18180
18218
|
define(
|
18181
|
-
'
|
18219
|
+
'ephox.sand.util.Global',
|
18220
|
+
|
18182
18221
|
[
|
18222
|
+
'ephox.katamari.api.Resolve'
|
18183
18223
|
],
|
18184
|
-
function () {
|
18185
|
-
function Selection(selection) {
|
18186
|
-
var self = this, dom = selection.dom, FALSE = false;
|
18187
18224
|
|
18188
|
-
|
18189
|
-
|
18190
|
-
|
18225
|
+
function (Resolve) {
|
18226
|
+
var unsafe = function (name, scope) {
|
18227
|
+
return Resolve.resolve(name, scope);
|
18228
|
+
};
|
18191
18229
|
|
18192
|
-
|
18193
|
-
|
18194
|
-
checkRng.collapse(start);
|
18195
|
-
parent = checkRng.parentElement();
|
18230
|
+
var getOrDie = function (name, scope) {
|
18231
|
+
var actual = unsafe(name, scope);
|
18196
18232
|
|
18197
|
-
|
18198
|
-
|
18199
|
-
|
18200
|
-
}
|
18233
|
+
if (actual === undefined) throw name + ' not available on this browser';
|
18234
|
+
return actual;
|
18235
|
+
};
|
18201
18236
|
|
18202
|
-
|
18203
|
-
|
18204
|
-
|
18205
|
-
|
18237
|
+
return {
|
18238
|
+
getOrDie: getOrDie
|
18239
|
+
};
|
18240
|
+
}
|
18241
|
+
);
|
18242
|
+
define(
|
18243
|
+
'ephox.sand.api.Node',
|
18206
18244
|
|
18207
|
-
|
18208
|
-
|
18209
|
-
|
18210
|
-
}
|
18245
|
+
[
|
18246
|
+
'ephox.sand.util.Global'
|
18247
|
+
],
|
18211
18248
|
|
18212
|
-
|
18213
|
-
|
18214
|
-
|
18249
|
+
function (Global) {
|
18250
|
+
/*
|
18251
|
+
* MDN says (yes) for IE, but it's undefined on IE8
|
18252
|
+
*/
|
18253
|
+
var node = function () {
|
18254
|
+
var f = Global.getOrDie('Node');
|
18255
|
+
return f;
|
18256
|
+
};
|
18215
18257
|
|
18216
|
-
|
18217
|
-
|
18218
|
-
|
18258
|
+
/*
|
18259
|
+
* Most of numerosity doesn't alter the methods on the object.
|
18260
|
+
* We're making an exception for Node, because bitwise and is so easy to get wrong.
|
18261
|
+
*
|
18262
|
+
* Might be nice to ADT this at some point instead of having individual methods.
|
18263
|
+
*/
|
18219
18264
|
|
18220
|
-
|
18221
|
-
|
18222
|
-
|
18223
|
-
|
18265
|
+
var compareDocumentPosition = function (a, b, match) {
|
18266
|
+
// Returns: 0 if e1 and e2 are the same node, or a bitmask comparing the positions
|
18267
|
+
// of nodes e1 and e2 in their documents. See the URL below for bitmask interpretation
|
18268
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
18269
|
+
return (a.compareDocumentPosition(b) & match) !== 0;
|
18270
|
+
};
|
18224
18271
|
|
18225
|
-
|
18226
|
-
|
18227
|
-
|
18228
|
-
} else if (position < 0) {
|
18229
|
-
startIndex = index + 1;
|
18230
|
-
} else {
|
18231
|
-
return { node: child };
|
18232
|
-
}
|
18233
|
-
}
|
18272
|
+
var documentPositionPreceding = function (a, b) {
|
18273
|
+
return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_PRECEDING);
|
18274
|
+
};
|
18234
18275
|
|
18235
|
-
|
18236
|
-
|
18237
|
-
|
18238
|
-
if (!child) {
|
18239
|
-
checkRng.moveToElementText(parent);
|
18240
|
-
checkRng.collapse(true);
|
18241
|
-
child = parent;
|
18242
|
-
inside = true;
|
18243
|
-
} else {
|
18244
|
-
checkRng.collapse(false);
|
18245
|
-
}
|
18276
|
+
var documentPositionContainedBy = function (a, b) {
|
18277
|
+
return compareDocumentPosition(a, b, node().DOCUMENT_POSITION_CONTAINED_BY);
|
18278
|
+
};
|
18246
18279
|
|
18247
|
-
|
18248
|
-
|
18249
|
-
|
18250
|
-
|
18251
|
-
|
18252
|
-
|
18253
|
-
|
18254
|
-
|
18280
|
+
return {
|
18281
|
+
documentPositionPreceding: documentPositionPreceding,
|
18282
|
+
documentPositionContainedBy: documentPositionContainedBy
|
18283
|
+
};
|
18284
|
+
}
|
18285
|
+
);
|
18286
|
+
define(
|
18287
|
+
'ephox.katamari.api.Thunk',
|
18255
18288
|
|
18256
|
-
|
18257
|
-
|
18258
|
-
} else {
|
18259
|
-
// Child position is after the selection endpoint
|
18260
|
-
checkRng.collapse(true);
|
18289
|
+
[
|
18290
|
+
],
|
18261
18291
|
|
18262
|
-
|
18263
|
-
// the end of document or parent isn't the right one
|
18264
|
-
offset = 0;
|
18265
|
-
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
|
18266
|
-
if (checkRng.move('character', -1) === 0 || parent != checkRng.parentElement()) {
|
18267
|
-
break;
|
18268
|
-
}
|
18292
|
+
function () {
|
18269
18293
|
|
18270
|
-
|
18271
|
-
|
18294
|
+
var cached = function (f) {
|
18295
|
+
var called = false;
|
18296
|
+
var r;
|
18297
|
+
return function() {
|
18298
|
+
if (!called) {
|
18299
|
+
called = true;
|
18300
|
+
r = f.apply(null, arguments);
|
18272
18301
|
}
|
18302
|
+
return r;
|
18303
|
+
};
|
18304
|
+
};
|
18273
18305
|
|
18274
|
-
|
18275
|
-
|
18306
|
+
return {
|
18307
|
+
cached: cached
|
18308
|
+
};
|
18309
|
+
}
|
18310
|
+
);
|
18276
18311
|
|
18277
|
-
|
18278
|
-
|
18279
|
-
|
18312
|
+
defineGlobal("global!Number", Number);
|
18313
|
+
define(
|
18314
|
+
'ephox.sand.detect.Version',
|
18280
18315
|
|
18281
|
-
|
18282
|
-
|
18283
|
-
|
18284
|
-
|
18285
|
-
|
18316
|
+
[
|
18317
|
+
'ephox.katamari.api.Arr',
|
18318
|
+
'global!Number',
|
18319
|
+
'global!String'
|
18320
|
+
],
|
18286
18321
|
|
18287
|
-
|
18322
|
+
function (Arr, Number, String) {
|
18323
|
+
var firstMatch = function (regexes, s) {
|
18324
|
+
for (var i = 0; i < regexes.length; i++) {
|
18325
|
+
var x = regexes[i];
|
18326
|
+
if (x.test(s)) return x;
|
18327
|
+
}
|
18328
|
+
return undefined;
|
18329
|
+
};
|
18288
18330
|
|
18289
|
-
|
18290
|
-
|
18291
|
-
|
18292
|
-
|
18331
|
+
var find = function (regexes, agent) {
|
18332
|
+
var r = firstMatch(regexes, agent);
|
18333
|
+
if (!r) return { major : 0, minor : 0 };
|
18334
|
+
var group = function(i) {
|
18335
|
+
return Number(agent.replace(r, '$' + i));
|
18336
|
+
};
|
18337
|
+
return nu(group(1), group(2));
|
18338
|
+
};
|
18293
18339
|
|
18294
|
-
|
18295
|
-
|
18340
|
+
var detect = function (versionRegexes, agent) {
|
18341
|
+
var cleanedAgent = String(agent).toLowerCase();
|
18296
18342
|
|
18297
|
-
|
18298
|
-
|
18343
|
+
if (versionRegexes.length === 0) return unknown();
|
18344
|
+
return find(versionRegexes, cleanedAgent);
|
18345
|
+
};
|
18299
18346
|
|
18300
|
-
|
18301
|
-
|
18347
|
+
var unknown = function () {
|
18348
|
+
return nu(0, 0);
|
18349
|
+
};
|
18302
18350
|
|
18303
|
-
|
18304
|
-
|
18305
|
-
|
18306
|
-
}
|
18351
|
+
var nu = function (major, minor) {
|
18352
|
+
return { major: major, minor: minor };
|
18353
|
+
};
|
18307
18354
|
|
18308
|
-
|
18309
|
-
|
18310
|
-
|
18311
|
-
|
18355
|
+
return {
|
18356
|
+
nu: nu,
|
18357
|
+
detect: detect,
|
18358
|
+
unknown: unknown
|
18359
|
+
};
|
18360
|
+
}
|
18361
|
+
);
|
18362
|
+
define(
|
18363
|
+
'ephox.sand.core.Browser',
|
18312
18364
|
|
18313
|
-
|
18314
|
-
|
18365
|
+
[
|
18366
|
+
'ephox.katamari.api.Fun',
|
18367
|
+
'ephox.sand.detect.Version'
|
18368
|
+
],
|
18315
18369
|
|
18316
|
-
|
18317
|
-
|
18318
|
-
|
18319
|
-
|
18370
|
+
function (Fun, Version) {
|
18371
|
+
var edge = 'Edge';
|
18372
|
+
var chrome = 'Chrome';
|
18373
|
+
var ie = 'IE';
|
18374
|
+
var opera = 'Opera';
|
18375
|
+
var firefox = 'Firefox';
|
18376
|
+
var safari = 'Safari';
|
18320
18377
|
|
18321
|
-
|
18322
|
-
|
18323
|
-
|
18324
|
-
|
18325
|
-
|
18326
|
-
}
|
18378
|
+
var isBrowser = function (name, current) {
|
18379
|
+
return function () {
|
18380
|
+
return current === name;
|
18381
|
+
};
|
18382
|
+
};
|
18327
18383
|
|
18328
|
-
|
18329
|
-
|
18384
|
+
var unknown = function () {
|
18385
|
+
return nu({
|
18386
|
+
current: undefined,
|
18387
|
+
version: Version.unknown()
|
18388
|
+
});
|
18389
|
+
};
|
18330
18390
|
|
18331
|
-
|
18332
|
-
|
18333
|
-
|
18334
|
-
nodeValue = sibling.nodeValue;
|
18335
|
-
textNodeOffset += nodeValue.length;
|
18391
|
+
var nu = function (info) {
|
18392
|
+
var current = info.current;
|
18393
|
+
var version = info.version;
|
18336
18394
|
|
18337
|
-
|
18338
|
-
|
18339
|
-
|
18340
|
-
textNodeOffset -= offset;
|
18341
|
-
textNodeOffset = nodeValue.length - textNodeOffset;
|
18342
|
-
break;
|
18343
|
-
}
|
18344
|
-
}
|
18395
|
+
return {
|
18396
|
+
current: current,
|
18397
|
+
version: version,
|
18345
18398
|
|
18346
|
-
|
18347
|
-
|
18348
|
-
|
18349
|
-
|
18350
|
-
|
18399
|
+
// INVESTIGATE: Rename to Edge ?
|
18400
|
+
isEdge: isBrowser(edge, current),
|
18401
|
+
isChrome: isBrowser(chrome, current),
|
18402
|
+
// NOTE: isIe just looks too weird
|
18403
|
+
isIE: isBrowser(ie, current),
|
18404
|
+
isOpera: isBrowser(opera, current),
|
18405
|
+
isFirefox: isBrowser(firefox, current),
|
18406
|
+
isSafari: isBrowser(safari, current)
|
18407
|
+
};
|
18408
|
+
};
|
18351
18409
|
|
18352
|
-
|
18353
|
-
|
18354
|
-
|
18410
|
+
return {
|
18411
|
+
unknown: unknown,
|
18412
|
+
nu: nu,
|
18413
|
+
edge: Fun.constant(edge),
|
18414
|
+
chrome: Fun.constant(chrome),
|
18415
|
+
ie: Fun.constant(ie),
|
18416
|
+
opera: Fun.constant(opera),
|
18417
|
+
firefox: Fun.constant(firefox),
|
18418
|
+
safari: Fun.constant(safari)
|
18419
|
+
};
|
18420
|
+
}
|
18421
|
+
);
|
18422
|
+
define(
|
18423
|
+
'ephox.sand.core.OperatingSystem',
|
18355
18424
|
|
18356
|
-
|
18357
|
-
|
18358
|
-
|
18359
|
-
|
18360
|
-
} else {
|
18361
|
-
domRange[start ? 'setStartAfter' : 'setEndAfter'](sibling);
|
18362
|
-
}
|
18425
|
+
[
|
18426
|
+
'ephox.katamari.api.Fun',
|
18427
|
+
'ephox.sand.detect.Version'
|
18428
|
+
],
|
18363
18429
|
|
18364
|
-
|
18365
|
-
|
18430
|
+
function (Fun, Version) {
|
18431
|
+
var windows = 'Windows';
|
18432
|
+
var ios = 'iOS';
|
18433
|
+
var android = 'Android';
|
18434
|
+
var linux = 'Linux';
|
18435
|
+
var osx = 'OSX';
|
18436
|
+
var solaris = 'Solaris';
|
18437
|
+
var freebsd = 'FreeBSD';
|
18366
18438
|
|
18367
|
-
|
18368
|
-
|
18369
|
-
|
18439
|
+
// Though there is a bit of dupe with this and Browser, trying to
|
18440
|
+
// reuse code makes it much harder to follow and change.
|
18441
|
+
var isOS = function (name, current) {
|
18442
|
+
return function () {
|
18443
|
+
return current === name;
|
18444
|
+
};
|
18445
|
+
};
|
18370
18446
|
|
18371
|
-
|
18372
|
-
|
18373
|
-
|
18374
|
-
|
18375
|
-
|
18376
|
-
|
18377
|
-
}
|
18447
|
+
var unknown = function () {
|
18448
|
+
return nu({
|
18449
|
+
current: undefined,
|
18450
|
+
version: Version.unknown()
|
18451
|
+
});
|
18452
|
+
};
|
18378
18453
|
|
18379
|
-
|
18380
|
-
|
18381
|
-
|
18454
|
+
var nu = function (info) {
|
18455
|
+
var current = info.current;
|
18456
|
+
var version = info.version;
|
18382
18457
|
|
18383
|
-
|
18384
|
-
|
18458
|
+
return {
|
18459
|
+
current: current,
|
18460
|
+
version: version,
|
18385
18461
|
|
18386
|
-
|
18387
|
-
|
18388
|
-
|
18462
|
+
isWindows: isOS(windows, current),
|
18463
|
+
// TODO: Fix capitalisation
|
18464
|
+
isiOS: isOS(ios, current),
|
18465
|
+
isAndroid: isOS(android, current),
|
18466
|
+
isOSX: isOS(osx, current),
|
18467
|
+
isLinux: isOS(linux, current),
|
18468
|
+
isSolaris: isOS(solaris, current),
|
18469
|
+
isFreeBSD: isOS(freebsd, current)
|
18470
|
+
};
|
18471
|
+
};
|
18389
18472
|
|
18390
|
-
|
18391
|
-
|
18392
|
-
|
18393
|
-
}
|
18394
|
-
} catch (ex) {
|
18395
|
-
// IE has a nasty bug where text nodes might throw "invalid argument" when you
|
18396
|
-
// access the nodeValue or other properties of text nodes. This seems to happen when
|
18397
|
-
// text nodes are split into two nodes by a delete/backspace call.
|
18398
|
-
// So let us detect and try to fix it.
|
18399
|
-
if (ex.number == -2147024809) {
|
18400
|
-
// Get the current selection
|
18401
|
-
bookmark = self.getBookmark(2);
|
18402
|
-
|
18403
|
-
// Get start element
|
18404
|
-
tmpRange = ieRange.duplicate();
|
18405
|
-
tmpRange.collapse(true);
|
18406
|
-
element = tmpRange.parentElement();
|
18407
|
-
|
18408
|
-
// Get end element
|
18409
|
-
if (!collapsed) {
|
18410
|
-
tmpRange = ieRange.duplicate();
|
18411
|
-
tmpRange.collapse(false);
|
18412
|
-
element2 = tmpRange.parentElement();
|
18413
|
-
element2.innerHTML = element2.innerHTML;
|
18414
|
-
}
|
18415
|
-
|
18416
|
-
// Remove the broken elements
|
18417
|
-
element.innerHTML = element.innerHTML;
|
18418
|
-
|
18419
|
-
// Restore the selection
|
18420
|
-
self.moveToBookmark(bookmark);
|
18421
|
-
|
18422
|
-
// Since the range has moved we need to re-get it
|
18423
|
-
ieRange = selection.getRng();
|
18473
|
+
return {
|
18474
|
+
unknown: unknown,
|
18475
|
+
nu: nu,
|
18424
18476
|
|
18425
|
-
|
18426
|
-
|
18477
|
+
windows: Fun.constant(windows),
|
18478
|
+
ios: Fun.constant(ios),
|
18479
|
+
android: Fun.constant(android),
|
18480
|
+
linux: Fun.constant(linux),
|
18481
|
+
osx: Fun.constant(osx),
|
18482
|
+
solaris: Fun.constant(solaris),
|
18483
|
+
freebsd: Fun.constant(freebsd)
|
18484
|
+
};
|
18485
|
+
}
|
18486
|
+
);
|
18487
|
+
define(
|
18488
|
+
'ephox.sand.detect.DeviceType',
|
18427
18489
|
|
18428
|
-
|
18429
|
-
|
18430
|
-
|
18431
|
-
}
|
18432
|
-
} else {
|
18433
|
-
throw ex; // Throw other errors
|
18434
|
-
}
|
18435
|
-
}
|
18490
|
+
[
|
18491
|
+
'ephox.katamari.api.Fun'
|
18492
|
+
],
|
18436
18493
|
|
18437
|
-
|
18438
|
-
|
18494
|
+
function (Fun) {
|
18495
|
+
return function (os, browser, userAgent) {
|
18496
|
+
var isiPad = os.isiOS() && /ipad/i.test(userAgent) === true;
|
18497
|
+
var isiPhone = os.isiOS() && !isiPad;
|
18498
|
+
var isAndroid3 = os.isAndroid() && os.version.major === 3;
|
18499
|
+
var isAndroid4 = os.isAndroid() && os.version.major === 4;
|
18500
|
+
var isTablet = isiPad || isAndroid3 || ( isAndroid4 && /mobile/i.test(userAgent) === true );
|
18501
|
+
var isTouch = os.isiOS() || os.isAndroid();
|
18502
|
+
var isPhone = isTouch && !isTablet;
|
18439
18503
|
|
18440
|
-
|
18441
|
-
var rng = selection.getRng(), bookmark = {};
|
18504
|
+
var iOSwebview = browser.isSafari() && os.isiOS() && /safari/i.test(userAgent) === false;
|
18442
18505
|
|
18443
|
-
|
18444
|
-
|
18506
|
+
return {
|
18507
|
+
isiPad : Fun.constant(isiPad),
|
18508
|
+
isiPhone: Fun.constant(isiPhone),
|
18509
|
+
isTablet: Fun.constant(isTablet),
|
18510
|
+
isPhone: Fun.constant(isPhone),
|
18511
|
+
isTouch: Fun.constant(isTouch),
|
18512
|
+
isAndroid: os.isAndroid,
|
18513
|
+
isiOS: os.isiOS,
|
18514
|
+
isWebView: Fun.constant(iOSwebview)
|
18515
|
+
};
|
18516
|
+
};
|
18517
|
+
}
|
18518
|
+
);
|
18519
|
+
define(
|
18520
|
+
'ephox.sand.detect.UaString',
|
18445
18521
|
|
18446
|
-
|
18447
|
-
|
18522
|
+
[
|
18523
|
+
'ephox.katamari.api.Arr',
|
18524
|
+
'ephox.sand.detect.Version',
|
18525
|
+
'global!String'
|
18526
|
+
],
|
18448
18527
|
|
18449
|
-
|
18450
|
-
|
18528
|
+
function (Arr, Version, String) {
|
18529
|
+
var detect = function (candidates, userAgent) {
|
18530
|
+
var agent = String(userAgent).toLowerCase();
|
18531
|
+
return Arr.find(candidates, function (candidate) {
|
18532
|
+
return candidate.search(agent);
|
18533
|
+
});
|
18534
|
+
};
|
18451
18535
|
|
18452
|
-
|
18453
|
-
|
18454
|
-
|
18455
|
-
|
18456
|
-
|
18457
|
-
|
18458
|
-
|
18536
|
+
// They (browser and os) are the same at the moment, but they might
|
18537
|
+
// not stay that way.
|
18538
|
+
var detectBrowser = function (browsers, userAgent) {
|
18539
|
+
return detect(browsers, userAgent).map(function (browser) {
|
18540
|
+
var version = Version.detect(browser.versionRegexes, userAgent);
|
18541
|
+
return {
|
18542
|
+
current: browser.name,
|
18543
|
+
version: version
|
18544
|
+
};
|
18545
|
+
});
|
18546
|
+
};
|
18459
18547
|
|
18460
|
-
|
18461
|
-
|
18462
|
-
|
18548
|
+
var detectOs = function (oses, userAgent) {
|
18549
|
+
return detect(oses, userAgent).map(function (os) {
|
18550
|
+
var version = Version.detect(os.versionRegexes, userAgent);
|
18551
|
+
return {
|
18552
|
+
current: os.name,
|
18553
|
+
version: version
|
18554
|
+
};
|
18555
|
+
});
|
18556
|
+
};
|
18463
18557
|
|
18464
|
-
|
18465
|
-
|
18558
|
+
return {
|
18559
|
+
detectBrowser: detectBrowser,
|
18560
|
+
detectOs: detectOs
|
18561
|
+
};
|
18562
|
+
}
|
18563
|
+
);
|
18564
|
+
define(
|
18565
|
+
'ephox.katamari.str.StrAppend',
|
18466
18566
|
|
18467
|
-
|
18468
|
-
var position;
|
18567
|
+
[
|
18469
18568
|
|
18470
|
-
|
18471
|
-
if (position) {
|
18472
|
-
return {
|
18473
|
-
position: position.position,
|
18474
|
-
offset: position.offset,
|
18475
|
-
indexes: getIndexes(position.node),
|
18476
|
-
inside: position.inside
|
18477
|
-
};
|
18478
|
-
}
|
18479
|
-
}
|
18569
|
+
],
|
18480
18570
|
|
18481
|
-
|
18482
|
-
|
18483
|
-
|
18484
|
-
|
18485
|
-
bookmark.start = getBookmarkEndPoint(true);
|
18571
|
+
function () {
|
18572
|
+
var addToStart = function (str, prefix) {
|
18573
|
+
return prefix + str;
|
18574
|
+
};
|
18486
18575
|
|
18487
|
-
|
18488
|
-
|
18489
|
-
|
18490
|
-
} else {
|
18491
|
-
bookmark.start = { ctrl: true, indexes: getIndexes(rng.item(0)) };
|
18492
|
-
}
|
18493
|
-
}
|
18576
|
+
var addToEnd = function (str, suffix) {
|
18577
|
+
return str + suffix;
|
18578
|
+
};
|
18494
18579
|
|
18495
|
-
|
18496
|
-
|
18580
|
+
var removeFromStart = function (str, numChars) {
|
18581
|
+
return str.substring(numChars);
|
18582
|
+
};
|
18497
18583
|
|
18498
|
-
|
18499
|
-
|
18584
|
+
var removeFromEnd = function (str, numChars) {
|
18585
|
+
return str.substring(0, str.length - numChars);
|
18586
|
+
};
|
18587
|
+
|
18588
|
+
return {
|
18589
|
+
addToStart: addToStart,
|
18590
|
+
addToEnd: addToEnd,
|
18591
|
+
removeFromStart: removeFromStart,
|
18592
|
+
removeFromEnd: removeFromEnd
|
18593
|
+
};
|
18594
|
+
}
|
18595
|
+
);
|
18596
|
+
define(
|
18597
|
+
'ephox.katamari.str.StringParts',
|
18500
18598
|
|
18501
|
-
|
18502
|
-
|
18599
|
+
[
|
18600
|
+
'ephox.katamari.api.Option',
|
18601
|
+
'global!Error'
|
18602
|
+
],
|
18503
18603
|
|
18504
|
-
|
18505
|
-
|
18506
|
-
|
18507
|
-
|
18604
|
+
function (Option, Error) {
|
18605
|
+
/** Return the first 'count' letters from 'str'.
|
18606
|
+
- * e.g. first("abcde", 2) === "ab"
|
18607
|
+
- */
|
18608
|
+
var first = function(str, count) {
|
18609
|
+
return str.substr(0, count);
|
18610
|
+
};
|
18508
18611
|
|
18509
|
-
|
18510
|
-
|
18511
|
-
|
18512
|
-
|
18612
|
+
/** Return the last 'count' letters from 'str'.
|
18613
|
+
* e.g. last("abcde", 2) === "de"
|
18614
|
+
*/
|
18615
|
+
var last = function(str, count) {
|
18616
|
+
return str.substr(str.length - count, str.length);
|
18617
|
+
};
|
18513
18618
|
|
18514
|
-
|
18515
|
-
|
18619
|
+
var head = function(str) {
|
18620
|
+
return str === '' ? Option.none() : Option.some(str.substr(0, 1));
|
18621
|
+
};
|
18516
18622
|
|
18517
|
-
|
18518
|
-
|
18623
|
+
var tail = function(str) {
|
18624
|
+
return str === '' ? Option.none() : Option.some(str.substring(1));
|
18625
|
+
};
|
18519
18626
|
|
18520
|
-
|
18521
|
-
|
18627
|
+
return {
|
18628
|
+
first: first,
|
18629
|
+
last: last,
|
18630
|
+
head: head,
|
18631
|
+
tail: tail
|
18632
|
+
};
|
18633
|
+
}
|
18634
|
+
);
|
18635
|
+
define(
|
18636
|
+
'ephox.katamari.api.Strings',
|
18522
18637
|
|
18523
|
-
|
18524
|
-
|
18638
|
+
[
|
18639
|
+
'ephox.katamari.str.StrAppend',
|
18640
|
+
'ephox.katamari.str.StringParts',
|
18641
|
+
'global!Error'
|
18642
|
+
],
|
18525
18643
|
|
18526
|
-
|
18527
|
-
|
18528
|
-
|
18529
|
-
|
18530
|
-
|
18531
|
-
|
18532
|
-
|
18644
|
+
function (StrAppend, StringParts, Error) {
|
18645
|
+
var checkRange = function(str, substr, start) {
|
18646
|
+
if (substr === '') return true;
|
18647
|
+
if (str.length < substr.length) return false;
|
18648
|
+
var x = str.substr(start, start + substr.length);
|
18649
|
+
return x === substr;
|
18650
|
+
};
|
18533
18651
|
|
18534
|
-
|
18652
|
+
/** Given a string and object, perform template-replacements on the string, as specified by the object.
|
18653
|
+
* Any template fields of the form ${name} are replaced by the string or number specified as obj["name"]
|
18654
|
+
* Based on Douglas Crockford's 'supplant' method for template-replace of strings. Uses different template format.
|
18655
|
+
*/
|
18656
|
+
var supplant = function(str, obj) {
|
18657
|
+
var isStringOrNumber = function(a) {
|
18658
|
+
var t = typeof a;
|
18659
|
+
return t === 'string' || t === 'number';
|
18660
|
+
};
|
18535
18661
|
|
18536
|
-
|
18537
|
-
|
18538
|
-
|
18539
|
-
|
18662
|
+
return str.replace(/\${([^{}]*)}/g,
|
18663
|
+
function (a, b) {
|
18664
|
+
var value = obj[b];
|
18665
|
+
return isStringOrNumber(value) ? value : a;
|
18540
18666
|
}
|
18667
|
+
);
|
18668
|
+
};
|
18541
18669
|
|
18542
|
-
|
18543
|
-
|
18544
|
-
|
18545
|
-
rng.addElement(resolveIndexes(bookmark.start.indexes));
|
18546
|
-
rng.select();
|
18547
|
-
} else {
|
18548
|
-
rng = body.createTextRange();
|
18549
|
-
setBookmarkEndPoint(true);
|
18550
|
-
setBookmarkEndPoint();
|
18551
|
-
rng.select();
|
18552
|
-
}
|
18553
|
-
}
|
18554
|
-
};
|
18670
|
+
var removeLeading = function (str, prefix) {
|
18671
|
+
return startsWith(str, prefix) ? StrAppend.removeFromStart(str, prefix.length) : str;
|
18672
|
+
};
|
18555
18673
|
|
18556
|
-
|
18557
|
-
|
18558
|
-
|
18674
|
+
var removeTrailing = function (str, prefix) {
|
18675
|
+
return endsWith(str, prefix) ? StrAppend.removeFromEnd(str, prefix.length) : str;
|
18676
|
+
};
|
18559
18677
|
|
18560
|
-
|
18561
|
-
|
18678
|
+
var ensureLeading = function (str, prefix) {
|
18679
|
+
return startsWith(str, prefix) ? str : StrAppend.addToStart(str, prefix);
|
18680
|
+
};
|
18562
18681
|
|
18563
|
-
|
18564
|
-
|
18565
|
-
|
18566
|
-
|
18682
|
+
var ensureTrailing = function (str, prefix) {
|
18683
|
+
return endsWith(str, prefix) ? str : StrAppend.addToEnd(str, prefix);
|
18684
|
+
};
|
18685
|
+
|
18686
|
+
var contains = function(str, substr) {
|
18687
|
+
return str.indexOf(substr) !== -1;
|
18688
|
+
};
|
18567
18689
|
|
18568
|
-
|
18569
|
-
|
18570
|
-
|
18571
|
-
|
18690
|
+
var capitalize = function(str) {
|
18691
|
+
return StringParts.head(str).bind(function (head) {
|
18692
|
+
return StringParts.tail(str).map(function (tail) {
|
18693
|
+
return head.toUpperCase() + tail;
|
18694
|
+
});
|
18695
|
+
}).getOr(str);
|
18696
|
+
};
|
18572
18697
|
|
18573
|
-
|
18574
|
-
|
18575
|
-
|
18576
|
-
|
18577
|
-
|
18578
|
-
|
18579
|
-
|
18580
|
-
|
18698
|
+
/** Does 'str' start with 'prefix'?
|
18699
|
+
* Note: all strings start with the empty string.
|
18700
|
+
* More formally, for all strings x, startsWith(x, "").
|
18701
|
+
* This is so that for all strings x and y, startsWith(y + x, y)
|
18702
|
+
*/
|
18703
|
+
var startsWith = function(str, prefix) {
|
18704
|
+
return checkRange(str, prefix, 0);
|
18705
|
+
};
|
18581
18706
|
|
18582
|
-
|
18583
|
-
|
18584
|
-
|
18585
|
-
|
18586
|
-
|
18587
|
-
|
18707
|
+
/** Does 'str' end with 'suffix'?
|
18708
|
+
* Note: all strings end with the empty string.
|
18709
|
+
* More formally, for all strings x, endsWith(x, "").
|
18710
|
+
* This is so that for all strings x and y, endsWith(x + y, y)
|
18711
|
+
*/
|
18712
|
+
var endsWith = function(str, suffix) {
|
18713
|
+
return checkRange(str, suffix, str.length - suffix.length);
|
18714
|
+
};
|
18588
18715
|
|
18589
|
-
|
18590
|
-
|
18591
|
-
|
18592
|
-
|
18593
|
-
|
18594
|
-
marker = container.firstChild;
|
18595
|
-
tmpRng.moveToElementText(marker);
|
18596
|
-
tmpRng.collapse(FALSE); // Collapse false works better than true for some odd reason
|
18597
|
-
}
|
18716
|
+
|
18717
|
+
/** removes all leading and trailing spaces */
|
18718
|
+
var trim = function(str) {
|
18719
|
+
return str.replace(/^\s+|\s+$/g, '');
|
18720
|
+
};
|
18598
18721
|
|
18599
|
-
|
18600
|
-
|
18601
|
-
|
18602
|
-
}
|
18722
|
+
var lTrim = function(str) {
|
18723
|
+
return str.replace(/^\s+/g, '');
|
18724
|
+
};
|
18603
18725
|
|
18604
|
-
|
18605
|
-
|
18606
|
-
|
18607
|
-
endContainer = rng.endContainer;
|
18608
|
-
endOffset = rng.endOffset;
|
18609
|
-
ieRng = body.createTextRange();
|
18726
|
+
var rTrim = function(str) {
|
18727
|
+
return str.replace(/\s+$/g, '');
|
18728
|
+
};
|
18610
18729
|
|
18611
|
-
|
18612
|
-
|
18613
|
-
|
18614
|
-
|
18615
|
-
|
18616
|
-
|
18617
|
-
|
18618
|
-
|
18619
|
-
|
18620
|
-
|
18621
|
-
|
18622
|
-
|
18623
|
-
|
18624
|
-
|
18730
|
+
return {
|
18731
|
+
supplant: supplant,
|
18732
|
+
startsWith: startsWith,
|
18733
|
+
removeLeading: removeLeading,
|
18734
|
+
removeTrailing: removeTrailing,
|
18735
|
+
ensureLeading: ensureLeading,
|
18736
|
+
ensureTrailing: ensureTrailing,
|
18737
|
+
endsWith: endsWith,
|
18738
|
+
contains: contains,
|
18739
|
+
trim: trim,
|
18740
|
+
lTrim: lTrim,
|
18741
|
+
rTrim: rTrim,
|
18742
|
+
capitalize: capitalize
|
18743
|
+
};
|
18744
|
+
}
|
18745
|
+
);
|
18625
18746
|
|
18626
|
-
|
18627
|
-
|
18628
|
-
ieRng.select();
|
18629
|
-
dom.doc.selection.clear();
|
18630
|
-
startContainer.innerHTML = '';
|
18747
|
+
define(
|
18748
|
+
'ephox.sand.info.PlatformInfo',
|
18631
18749
|
|
18632
|
-
|
18633
|
-
|
18634
|
-
|
18635
|
-
|
18636
|
-
}
|
18750
|
+
[
|
18751
|
+
'ephox.katamari.api.Fun',
|
18752
|
+
'ephox.katamari.api.Strings'
|
18753
|
+
],
|
18637
18754
|
|
18638
|
-
|
18639
|
-
|
18640
|
-
}
|
18755
|
+
function (Fun, Strings) {
|
18756
|
+
var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
|
18641
18757
|
|
18642
|
-
|
18643
|
-
|
18644
|
-
|
18645
|
-
|
18646
|
-
|
18647
|
-
ctrlRng.select();
|
18758
|
+
var checkContains = function (target) {
|
18759
|
+
return function (uastring) {
|
18760
|
+
return Strings.contains(uastring, target);
|
18761
|
+
};
|
18762
|
+
};
|
18648
18763
|
|
18649
|
-
|
18650
|
-
|
18651
|
-
|
18652
|
-
|
18653
|
-
|
18654
|
-
|
18655
|
-
|
18656
|
-
// Ignore
|
18657
|
-
}
|
18658
|
-
}
|
18764
|
+
var browsers = [
|
18765
|
+
{
|
18766
|
+
name : 'Edge',
|
18767
|
+
versionRegexes: [/.*?edge\/ ?([0-9]+)\.([0-9]+)$/],
|
18768
|
+
search: function (uastring) {
|
18769
|
+
var monstrosity = Strings.contains(uastring, 'edge/') && Strings.contains(uastring, 'chrome') && Strings.contains(uastring, 'safari') && Strings.contains(uastring, 'applewebkit');
|
18770
|
+
return monstrosity;
|
18659
18771
|
}
|
18772
|
+
},
|
18773
|
+
{
|
18774
|
+
name : 'Chrome',
|
18775
|
+
versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex],
|
18776
|
+
search : function (uastring) {
|
18777
|
+
return Strings.contains(uastring, 'chrome') && !Strings.contains(uastring, 'chromeframe');
|
18778
|
+
}
|
18779
|
+
},
|
18780
|
+
{
|
18781
|
+
name : 'IE',
|
18782
|
+
versionRegexes: [/.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/],
|
18783
|
+
search: function (uastring) {
|
18784
|
+
return Strings.contains(uastring, 'msie') || Strings.contains(uastring, 'trident');
|
18785
|
+
}
|
18786
|
+
},
|
18787
|
+
// INVESTIGATE: Is this still the Opera user agent?
|
18788
|
+
{
|
18789
|
+
name : 'Opera',
|
18790
|
+
versionRegexes: [normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/],
|
18791
|
+
search : checkContains('opera')
|
18792
|
+
},
|
18793
|
+
{
|
18794
|
+
name : 'Firefox',
|
18795
|
+
versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
|
18796
|
+
search : checkContains('firefox')
|
18797
|
+
},
|
18798
|
+
{
|
18799
|
+
name : 'Safari',
|
18800
|
+
versionRegexes: [normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/],
|
18801
|
+
search : function (uastring) {
|
18802
|
+
return (Strings.contains(uastring, 'safari') || Strings.contains(uastring, 'mobile/')) && Strings.contains(uastring, 'applewebkit');
|
18803
|
+
}
|
18804
|
+
}
|
18805
|
+
];
|
18660
18806
|
|
18661
|
-
|
18662
|
-
|
18663
|
-
|
18664
|
-
|
18665
|
-
|
18666
|
-
|
18667
|
-
|
18668
|
-
|
18669
|
-
|
18670
|
-
|
18671
|
-
|
18807
|
+
var oses = [
|
18808
|
+
{
|
18809
|
+
name : 'Windows',
|
18810
|
+
search : checkContains('win'),
|
18811
|
+
versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
|
18812
|
+
},
|
18813
|
+
{
|
18814
|
+
name : 'iOS',
|
18815
|
+
search : function (uastring) {
|
18816
|
+
return Strings.contains(uastring, 'iphone') || Strings.contains(uastring, 'ipad');
|
18817
|
+
},
|
18818
|
+
versionRegexes: [/.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/]
|
18819
|
+
},
|
18820
|
+
{
|
18821
|
+
name : 'Android',
|
18822
|
+
search : checkContains('android'),
|
18823
|
+
versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
|
18824
|
+
},
|
18825
|
+
{
|
18826
|
+
name : 'OSX',
|
18827
|
+
search : checkContains('os x'),
|
18828
|
+
versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
|
18829
|
+
},
|
18830
|
+
{
|
18831
|
+
name : 'Linux',
|
18832
|
+
search : checkContains('linux'),
|
18833
|
+
versionRegexes: [ ]
|
18834
|
+
},
|
18835
|
+
{ name : 'Solaris',
|
18836
|
+
search : checkContains('sunos'),
|
18837
|
+
versionRegexes: [ ]
|
18838
|
+
},
|
18839
|
+
{
|
18840
|
+
name : 'FreeBSD',
|
18841
|
+
search : checkContains('freebsd'),
|
18842
|
+
versionRegexes: [ ]
|
18843
|
+
}
|
18844
|
+
];
|
18672
18845
|
|
18673
|
-
return
|
18846
|
+
return {
|
18847
|
+
browsers: Fun.constant(browsers),
|
18848
|
+
oses: Fun.constant(oses)
|
18849
|
+
};
|
18674
18850
|
}
|
18675
18851
|
);
|
18676
|
-
|
18677
18852
|
define(
|
18678
|
-
'ephox.
|
18853
|
+
'ephox.sand.core.PlatformDetection',
|
18679
18854
|
|
18680
18855
|
[
|
18681
|
-
'
|
18682
|
-
'
|
18856
|
+
'ephox.sand.core.Browser',
|
18857
|
+
'ephox.sand.core.OperatingSystem',
|
18858
|
+
'ephox.sand.detect.DeviceType',
|
18859
|
+
'ephox.sand.detect.UaString',
|
18860
|
+
'ephox.sand.info.PlatformInfo'
|
18683
18861
|
],
|
18684
18862
|
|
18685
|
-
function (
|
18686
|
-
var
|
18687
|
-
|
18688
|
-
var
|
18689
|
-
if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array';
|
18690
|
-
if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string';
|
18691
|
-
return t;
|
18692
|
-
};
|
18863
|
+
function (Browser, OperatingSystem, DeviceType, UaString, PlatformInfo) {
|
18864
|
+
var detect = function (userAgent) {
|
18865
|
+
var browsers = PlatformInfo.browsers();
|
18866
|
+
var oses = PlatformInfo.oses();
|
18693
18867
|
|
18694
|
-
|
18695
|
-
|
18696
|
-
|
18868
|
+
var browser = UaString.detectBrowser(browsers, userAgent).fold(
|
18869
|
+
Browser.unknown,
|
18870
|
+
Browser.nu
|
18871
|
+
);
|
18872
|
+
var os = UaString.detectOs(oses, userAgent).fold(
|
18873
|
+
OperatingSystem.unknown,
|
18874
|
+
OperatingSystem.nu
|
18875
|
+
);
|
18876
|
+
var deviceType = DeviceType(os, browser, userAgent);
|
18877
|
+
|
18878
|
+
return {
|
18879
|
+
browser: browser,
|
18880
|
+
os: os,
|
18881
|
+
deviceType: deviceType
|
18697
18882
|
};
|
18698
18883
|
};
|
18699
18884
|
|
18700
18885
|
return {
|
18701
|
-
|
18702
|
-
isObject: isType('object'),
|
18703
|
-
isArray: isType('array'),
|
18704
|
-
isNull: isType('null'),
|
18705
|
-
isBoolean: isType('boolean'),
|
18706
|
-
isUndefined: isType('undefined'),
|
18707
|
-
isFunction: isType('function'),
|
18708
|
-
isNumber: isType('number')
|
18886
|
+
detect: detect
|
18709
18887
|
};
|
18710
18888
|
}
|
18711
18889
|
);
|
18712
|
-
|
18713
|
-
|
18890
|
+
defineGlobal("global!navigator", navigator);
|
18714
18891
|
define(
|
18715
|
-
'ephox.
|
18892
|
+
'ephox.sand.api.PlatformDetection',
|
18716
18893
|
|
18717
18894
|
[
|
18718
|
-
'ephox.katamari.api.
|
18719
|
-
'ephox.
|
18720
|
-
'global!
|
18721
|
-
'global!Error'
|
18895
|
+
'ephox.katamari.api.Thunk',
|
18896
|
+
'ephox.sand.core.PlatformDetection',
|
18897
|
+
'global!navigator'
|
18722
18898
|
],
|
18723
18899
|
|
18724
|
-
function (
|
18725
|
-
|
18726
|
-
var
|
18727
|
-
return
|
18728
|
-
|
18729
|
-
var values = new Array(arguments.length);
|
18730
|
-
for (var i = 0; i < values.length; i++) values[i] = arguments[i];
|
18731
|
-
|
18732
|
-
if (fields.length !== values.length)
|
18733
|
-
throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
|
18900
|
+
function (Thunk, PlatformDetection, navigator) {
|
18901
|
+
var detect = Thunk.cached(function () {
|
18902
|
+
var userAgent = navigator.userAgent;
|
18903
|
+
return PlatformDetection.detect(userAgent);
|
18904
|
+
});
|
18734
18905
|
|
18735
|
-
|
18736
|
-
|
18737
|
-
struct[name] = Fun.constant(values[i]);
|
18738
|
-
});
|
18739
|
-
return struct;
|
18740
|
-
};
|
18906
|
+
return {
|
18907
|
+
detect: detect
|
18741
18908
|
};
|
18742
18909
|
}
|
18743
18910
|
);
|
18744
|
-
|
18911
|
+
define("global!console", [], function () { if (typeof console === "undefined") console = { log: function () {} }; return console; });
|
18912
|
+
defineGlobal("global!document", document);
|
18745
18913
|
define(
|
18746
|
-
'ephox.
|
18914
|
+
'ephox.sugar.api.node.Element',
|
18747
18915
|
|
18748
18916
|
[
|
18749
|
-
'ephox.katamari.api.
|
18750
|
-
'global!
|
18917
|
+
'ephox.katamari.api.Fun',
|
18918
|
+
'global!Error',
|
18919
|
+
'global!console',
|
18920
|
+
'global!document'
|
18751
18921
|
],
|
18752
18922
|
|
18753
|
-
function (
|
18754
|
-
|
18755
|
-
|
18756
|
-
|
18757
|
-
|
18758
|
-
|
18759
|
-
|
18760
|
-
|
18761
|
-
// This technically means that 'each' and 'find' on IE8 iterate through the object twice.
|
18762
|
-
// This code doesn't run on IE8 much, so it's an acceptable tradeoff.
|
18763
|
-
// If it becomes a problem we can always duplicate the feature detection inside each and find as well.
|
18764
|
-
var slowKeys = function (o) {
|
18765
|
-
var r = [];
|
18766
|
-
for (var i in o) {
|
18767
|
-
if (o.hasOwnProperty(i)) {
|
18768
|
-
r.push(i);
|
18769
|
-
}
|
18770
|
-
}
|
18771
|
-
return r;
|
18772
|
-
};
|
18773
|
-
|
18774
|
-
return fastKeys === undefined ? slowKeys : fastKeys;
|
18775
|
-
})();
|
18776
|
-
|
18777
|
-
|
18778
|
-
var each = function (obj, f) {
|
18779
|
-
var props = keys(obj);
|
18780
|
-
for (var k = 0, len = props.length; k < len; k++) {
|
18781
|
-
var i = props[k];
|
18782
|
-
var x = obj[i];
|
18783
|
-
f(x, i, obj);
|
18923
|
+
function (Fun, Error, console, document) {
|
18924
|
+
var fromHtml = function (html, scope) {
|
18925
|
+
var doc = scope || document;
|
18926
|
+
var div = doc.createElement('div');
|
18927
|
+
div.innerHTML = html;
|
18928
|
+
if (!div.hasChildNodes() || div.childNodes.length > 1) {
|
18929
|
+
console.error('HTML does not have a single root node', html);
|
18930
|
+
throw 'HTML must have a single root node';
|
18784
18931
|
}
|
18932
|
+
return fromDom(div.childNodes[0]);
|
18785
18933
|
};
|
18786
18934
|
|
18787
|
-
|
18788
|
-
|
18789
|
-
|
18790
|
-
|
18791
|
-
k: i,
|
18792
|
-
v: f(x, i, obj)
|
18793
|
-
};
|
18794
|
-
});
|
18935
|
+
var fromTag = function (tag, scope) {
|
18936
|
+
var doc = scope || document;
|
18937
|
+
var node = doc.createElement(tag);
|
18938
|
+
return fromDom(node);
|
18795
18939
|
};
|
18796
18940
|
|
18797
|
-
|
18798
|
-
|
18799
|
-
var
|
18800
|
-
|
18801
|
-
var tuple = f(x, i, obj);
|
18802
|
-
r[tuple.k] = tuple.v;
|
18803
|
-
});
|
18804
|
-
return r;
|
18941
|
+
var fromText = function (text, scope) {
|
18942
|
+
var doc = scope || document;
|
18943
|
+
var node = doc.createTextNode(text);
|
18944
|
+
return fromDom(node);
|
18805
18945
|
};
|
18806
18946
|
|
18807
|
-
|
18808
|
-
|
18809
|
-
var t = {};
|
18810
|
-
var f = {};
|
18811
|
-
each(obj, function(x, i) {
|
18812
|
-
var branch = pred(x, i) ? t : f;
|
18813
|
-
branch[i] = x;
|
18814
|
-
});
|
18947
|
+
var fromDom = function (node) {
|
18948
|
+
if (node === null || node === undefined) throw new Error('Node cannot be null or undefined');
|
18815
18949
|
return {
|
18816
|
-
|
18817
|
-
f: f
|
18950
|
+
dom: Fun.constant(node)
|
18818
18951
|
};
|
18819
18952
|
};
|
18820
18953
|
|
18821
|
-
|
18822
|
-
|
18823
|
-
|
18824
|
-
|
18825
|
-
|
18826
|
-
});
|
18827
|
-
return r;
|
18954
|
+
return {
|
18955
|
+
fromHtml: fromHtml,
|
18956
|
+
fromTag: fromTag,
|
18957
|
+
fromText: fromText,
|
18958
|
+
fromDom: fromDom
|
18828
18959
|
};
|
18960
|
+
}
|
18961
|
+
);
|
18829
18962
|
|
18830
|
-
|
18831
|
-
|
18832
|
-
var props = keys(obj);
|
18833
|
-
for (var k = 0, len = props.length; k < len; k++) {
|
18834
|
-
var i = props[k];
|
18835
|
-
var x = obj[i];
|
18836
|
-
if (pred(x, i, obj)) {
|
18837
|
-
return Option.some(x);
|
18838
|
-
}
|
18839
|
-
}
|
18840
|
-
return Option.none();
|
18841
|
-
};
|
18963
|
+
define(
|
18964
|
+
'ephox.sugar.api.node.NodeTypes',
|
18842
18965
|
|
18843
|
-
|
18844
|
-
var values = function (obj) {
|
18845
|
-
return mapToArray(obj, function (v) {
|
18846
|
-
return v;
|
18847
|
-
});
|
18848
|
-
};
|
18966
|
+
[
|
18849
18967
|
|
18850
|
-
|
18851
|
-
return values(obj).length;
|
18852
|
-
};
|
18968
|
+
],
|
18853
18969
|
|
18970
|
+
function () {
|
18854
18971
|
return {
|
18855
|
-
|
18856
|
-
|
18857
|
-
|
18858
|
-
|
18859
|
-
|
18860
|
-
|
18861
|
-
|
18862
|
-
|
18863
|
-
|
18972
|
+
ATTRIBUTE: 2,
|
18973
|
+
CDATA_SECTION: 4,
|
18974
|
+
COMMENT: 8,
|
18975
|
+
DOCUMENT: 9,
|
18976
|
+
DOCUMENT_TYPE: 10,
|
18977
|
+
DOCUMENT_FRAGMENT: 11,
|
18978
|
+
ELEMENT: 1,
|
18979
|
+
TEXT: 3,
|
18980
|
+
PROCESSING_INSTRUCTION: 7,
|
18981
|
+
ENTITY_REFERENCE: 5,
|
18982
|
+
ENTITY: 6,
|
18983
|
+
NOTATION: 12
|
18864
18984
|
};
|
18865
18985
|
}
|
18866
18986
|
);
|
18867
18987
|
define(
|
18868
|
-
'ephox.
|
18988
|
+
'ephox.sugar.api.search.Selectors',
|
18869
18989
|
|
18870
18990
|
[
|
18871
18991
|
'ephox.katamari.api.Arr',
|
18872
|
-
'ephox.katamari.api.
|
18873
|
-
'
|
18992
|
+
'ephox.katamari.api.Option',
|
18993
|
+
'ephox.sugar.api.node.Element',
|
18994
|
+
'ephox.sugar.api.node.NodeTypes',
|
18995
|
+
'global!Error',
|
18996
|
+
'global!document'
|
18874
18997
|
],
|
18875
18998
|
|
18876
|
-
function (Arr,
|
18877
|
-
|
18878
|
-
|
18879
|
-
|
18999
|
+
function (Arr, Option, Element, NodeTypes, Error, document) {
|
19000
|
+
/*
|
19001
|
+
* There's a lot of code here; the aim is to allow the browser to optimise constant comparisons,
|
19002
|
+
* instead of doing object lookup feature detection on every call
|
19003
|
+
*/
|
19004
|
+
var STANDARD = 0;
|
19005
|
+
var MSSTANDARD = 1;
|
19006
|
+
var WEBKITSTANDARD = 2;
|
19007
|
+
var FIREFOXSTANDARD = 3;
|
18880
19008
|
|
18881
|
-
var
|
18882
|
-
|
18883
|
-
|
19009
|
+
var selectorType = (function () {
|
19010
|
+
var test = document.createElement('span');
|
19011
|
+
// As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function.
|
19012
|
+
// Still check for the others, but do it last.
|
19013
|
+
return test.matches !== undefined ? STANDARD :
|
19014
|
+
test.msMatchesSelector !== undefined ? MSSTANDARD :
|
19015
|
+
test.webkitMatchesSelector !== undefined ? WEBKITSTANDARD :
|
19016
|
+
test.mozMatchesSelector !== undefined ? FIREFOXSTANDARD :
|
19017
|
+
-1;
|
19018
|
+
})();
|
18884
19019
|
|
18885
|
-
var unsuppMessage = function (unsupported) {
|
18886
|
-
throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', '));
|
18887
|
-
};
|
18888
19020
|
|
18889
|
-
var
|
18890
|
-
|
18891
|
-
|
18892
|
-
|
18893
|
-
|
19021
|
+
var ELEMENT = NodeTypes.ELEMENT;
|
19022
|
+
var DOCUMENT = NodeTypes.DOCUMENT;
|
19023
|
+
|
19024
|
+
var is = function (element, selector) {
|
19025
|
+
var elem = element.dom();
|
19026
|
+
if (elem.nodeType !== ELEMENT) return false; // documents have querySelector but not matches
|
19027
|
+
|
19028
|
+
// As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function.
|
19029
|
+
// Still check for the others, but do it last.
|
19030
|
+
else if (selectorType === STANDARD) return elem.matches(selector);
|
19031
|
+
else if (selectorType === MSSTANDARD) return elem.msMatchesSelector(selector);
|
19032
|
+
else if (selectorType === WEBKITSTANDARD) return elem.webkitMatchesSelector(selector);
|
19033
|
+
else if (selectorType === FIREFOXSTANDARD) return elem.mozMatchesSelector(selector);
|
19034
|
+
else throw new Error('Browser lacks native selectors'); // unfortunately we can't throw this on startup :(
|
18894
19035
|
};
|
18895
19036
|
|
18896
|
-
var
|
18897
|
-
|
19037
|
+
var bypassSelector = function (dom) {
|
19038
|
+
// Only elements and documents support querySelector
|
19039
|
+
return dom.nodeType !== ELEMENT && dom.nodeType !== DOCUMENT ||
|
19040
|
+
// IE fix for complex queries on empty nodes: http://jsfiddle.net/spyder/fv9ptr5L/
|
19041
|
+
dom.childElementCount === 0;
|
18898
19042
|
};
|
18899
19043
|
|
18900
|
-
var
|
18901
|
-
var
|
18902
|
-
|
18903
|
-
|
18904
|
-
});
|
19044
|
+
var all = function (selector, scope) {
|
19045
|
+
var base = scope === undefined ? document : scope.dom();
|
19046
|
+
return bypassSelector(base) ? [] : Arr.map(base.querySelectorAll(selector), Element.fromDom);
|
19047
|
+
};
|
18905
19048
|
|
18906
|
-
|
18907
|
-
|
18908
|
-
|
19049
|
+
var one = function (selector, scope) {
|
19050
|
+
var base = scope === undefined ? document : scope.dom();
|
19051
|
+
return bypassSelector(base) ? Option.none() : Option.from(base.querySelector(selector)).map(Element.fromDom);
|
18909
19052
|
};
|
18910
19053
|
|
18911
19054
|
return {
|
18912
|
-
|
18913
|
-
|
18914
|
-
|
18915
|
-
validateStrArr: validateStrArr,
|
18916
|
-
invalidTypeMessage: invalidTypeMessage,
|
18917
|
-
checkDupes: checkDupes
|
19055
|
+
all: all,
|
19056
|
+
is: is,
|
19057
|
+
one: one
|
18918
19058
|
};
|
18919
19059
|
}
|
18920
19060
|
);
|
19061
|
+
|
18921
19062
|
define(
|
18922
|
-
'ephox.
|
19063
|
+
'ephox.sugar.api.dom.Compare',
|
18923
19064
|
|
18924
19065
|
[
|
18925
19066
|
'ephox.katamari.api.Arr',
|
18926
19067
|
'ephox.katamari.api.Fun',
|
18927
|
-
'ephox.
|
18928
|
-
'ephox.
|
18929
|
-
'ephox.
|
18930
|
-
'global!Error',
|
18931
|
-
'global!Object'
|
19068
|
+
'ephox.sand.api.Node',
|
19069
|
+
'ephox.sand.api.PlatformDetection',
|
19070
|
+
'ephox.sugar.api.search.Selectors'
|
18932
19071
|
],
|
18933
19072
|
|
18934
|
-
function (Arr, Fun,
|
18935
|
-
|
18936
|
-
return function (required, optional) {
|
18937
|
-
var everything = required.concat(optional);
|
18938
|
-
if (everything.length === 0) throw new Error('You must specify at least one required or optional field.');
|
18939
|
-
|
18940
|
-
BagUtils.validateStrArr('required', required);
|
18941
|
-
BagUtils.validateStrArr('optional', optional);
|
19073
|
+
function (Arr, Fun, Node, PlatformDetection, Selectors) {
|
18942
19074
|
|
18943
|
-
|
19075
|
+
var eq = function (e1, e2) {
|
19076
|
+
return e1.dom() === e2.dom();
|
19077
|
+
};
|
18944
19078
|
|
18945
|
-
|
18946
|
-
|
19079
|
+
var isEqualNode = function (e1, e2) {
|
19080
|
+
return e1.dom().isEqualNode(e2.dom());
|
19081
|
+
};
|
18947
19082
|
|
18948
|
-
|
18949
|
-
|
18950
|
-
|
18951
|
-
});
|
19083
|
+
var member = function (element, elements) {
|
19084
|
+
return Arr.exists(elements, Fun.curry(eq, element));
|
19085
|
+
};
|
18952
19086
|
|
18953
|
-
|
19087
|
+
// DOM contains() method returns true if e1===e2, we define our contains() to return false (a node does not contain itself).
|
19088
|
+
var regularContains = function (e1, e2) {
|
19089
|
+
var d1 = e1.dom(), d2 = e2.dom();
|
19090
|
+
return d1 === d2 ? false : d1.contains(d2);
|
19091
|
+
};
|
18954
19092
|
|
18955
|
-
|
18956
|
-
|
18957
|
-
|
19093
|
+
var ieContains = function (e1, e2) {
|
19094
|
+
// IE only implements the contains() method for Element nodes.
|
19095
|
+
// It fails for Text nodes, so implement it using compareDocumentPosition()
|
19096
|
+
// https://connect.microsoft.com/IE/feedback/details/780874/node-contains-is-incorrect
|
19097
|
+
// Note that compareDocumentPosition returns CONTAINED_BY if 'e2 *is_contained_by* e1':
|
19098
|
+
// Also, compareDocumentPosition defines a node containing itself as false.
|
19099
|
+
return Node.documentPositionContainedBy(e1.dom(), e2.dom());
|
19100
|
+
};
|
18958
19101
|
|
18959
|
-
|
19102
|
+
var browser = PlatformDetection.detect().browser;
|
18960
19103
|
|
18961
|
-
|
18962
|
-
|
18963
|
-
|
18964
|
-
});
|
19104
|
+
// Returns: true if node e1 contains e2, otherwise false.
|
19105
|
+
// (returns false if e1===e2: A node does not contain itself).
|
19106
|
+
var contains = browser.isIE() ? ieContains : regularContains;
|
18965
19107
|
|
18966
|
-
|
18967
|
-
|
18968
|
-
|
19108
|
+
return {
|
19109
|
+
eq: eq,
|
19110
|
+
isEqualNode: isEqualNode,
|
19111
|
+
member: member,
|
19112
|
+
contains: contains,
|
18969
19113
|
|
18970
|
-
|
18971
|
-
|
19114
|
+
// Only used by DomUniverse. Remove (or should Selectors.is move here?)
|
19115
|
+
is: Selectors.is
|
18972
19116
|
};
|
18973
19117
|
}
|
18974
19118
|
);
|
18975
|
-
define(
|
18976
|
-
'ephox.katamari.api.Struct',
|
18977
19119
|
|
19120
|
+
/**
|
19121
|
+
* ScrollIntoView.js
|
19122
|
+
*
|
19123
|
+
* Released under LGPL License.
|
19124
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
19125
|
+
*
|
19126
|
+
* License: http://www.tinymce.com/license
|
19127
|
+
* Contributing: http://www.tinymce.com/contributing
|
19128
|
+
*/
|
19129
|
+
|
19130
|
+
define(
|
19131
|
+
'tinymce.core.dom.ScrollIntoView',
|
18978
19132
|
[
|
18979
|
-
'
|
18980
|
-
'ephox.katamari.data.MixedBag'
|
19133
|
+
'tinymce.core.dom.NodeType'
|
18981
19134
|
],
|
19135
|
+
function (NodeType) {
|
19136
|
+
var getPos = function (elm) {
|
19137
|
+
var x = 0, y = 0;
|
18982
19138
|
|
18983
|
-
|
18984
|
-
|
18985
|
-
|
18986
|
-
|
19139
|
+
var offsetParent = elm;
|
19140
|
+
while (offsetParent && offsetParent.nodeType) {
|
19141
|
+
x += offsetParent.offsetLeft || 0;
|
19142
|
+
y += offsetParent.offsetTop || 0;
|
19143
|
+
offsetParent = offsetParent.offsetParent;
|
19144
|
+
}
|
19145
|
+
|
19146
|
+
return { x: x, y: y };
|
18987
19147
|
};
|
18988
|
-
}
|
18989
|
-
);
|
18990
19148
|
|
18991
|
-
|
18992
|
-
|
19149
|
+
var fireScrollIntoViewEvent = function (editor, elm, alignToTop) {
|
19150
|
+
var scrollEvent = { elm: elm, alignToTop: alignToTop };
|
19151
|
+
editor.fire('scrollIntoView', scrollEvent);
|
19152
|
+
return scrollEvent.isDefaultPrevented();
|
19153
|
+
};
|
18993
19154
|
|
18994
|
-
|
19155
|
+
var scrollIntoView = function (editor, elm, alignToTop) {
|
19156
|
+
var y, viewPort, dom = editor.dom, root = dom.getRoot(), viewPortY, viewPortH, offsetY = 0;
|
18995
19157
|
|
18996
|
-
|
19158
|
+
if (fireScrollIntoViewEvent(editor, elm, alignToTop)) {
|
19159
|
+
return;
|
19160
|
+
}
|
18997
19161
|
|
18998
|
-
|
18999
|
-
|
19000
|
-
|
19001
|
-
*
|
19002
|
-
* Normally would just use recursion, but JavaScript lacks tail call optimisation.
|
19003
|
-
*
|
19004
|
-
* This is what recursion looks like when manually unravelled :)
|
19005
|
-
*/
|
19006
|
-
var toArray = function (target, f) {
|
19007
|
-
var r = [];
|
19162
|
+
if (!NodeType.isElement(elm)) {
|
19163
|
+
return;
|
19164
|
+
}
|
19008
19165
|
|
19009
|
-
|
19010
|
-
|
19011
|
-
|
19012
|
-
};
|
19166
|
+
if (alignToTop === false) {
|
19167
|
+
offsetY = elm.offsetHeight;
|
19168
|
+
}
|
19013
19169
|
|
19014
|
-
|
19015
|
-
|
19016
|
-
|
19017
|
-
|
19170
|
+
if (root.nodeName !== 'BODY') {
|
19171
|
+
var scrollContainer = editor.selection.getScrollContainer();
|
19172
|
+
if (scrollContainer) {
|
19173
|
+
y = getPos(elm).y - getPos(scrollContainer).y + offsetY;
|
19174
|
+
viewPortH = scrollContainer.clientHeight;
|
19175
|
+
viewPortY = scrollContainer.scrollTop;
|
19176
|
+
if (y < viewPortY || y + 25 > viewPortY + viewPortH) {
|
19177
|
+
scrollContainer.scrollTop = y < viewPortY ? y : y - viewPortH + 25;
|
19178
|
+
}
|
19018
19179
|
|
19019
|
-
|
19180
|
+
return;
|
19181
|
+
}
|
19182
|
+
}
|
19183
|
+
|
19184
|
+
viewPort = dom.getViewPort(editor.getWin());
|
19185
|
+
y = dom.getPos(elm).y + offsetY;
|
19186
|
+
viewPortY = viewPort.y;
|
19187
|
+
viewPortH = viewPort.h;
|
19188
|
+
if (y < viewPort.y || y + 25 > viewPortY + viewPortH) {
|
19189
|
+
editor.getWin().scrollTo(0, y < viewPortY ? y : y - viewPortH + 25);
|
19190
|
+
}
|
19020
19191
|
};
|
19021
19192
|
|
19022
19193
|
return {
|
19023
|
-
|
19194
|
+
scrollIntoView: scrollIntoView
|
19024
19195
|
};
|
19025
19196
|
}
|
19026
19197
|
);
|
19198
|
+
|
19199
|
+
/**
|
19200
|
+
* TridentSelection.js
|
19201
|
+
*
|
19202
|
+
* Released under LGPL License.
|
19203
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
19204
|
+
*
|
19205
|
+
* License: http://www.tinymce.com/license
|
19206
|
+
* Contributing: http://www.tinymce.com/contributing
|
19207
|
+
*/
|
19208
|
+
|
19209
|
+
/**
|
19210
|
+
* Selection class for old explorer versions. This one fakes the
|
19211
|
+
* native selection object available on modern browsers.
|
19212
|
+
*
|
19213
|
+
* @private
|
19214
|
+
* @class tinymce.dom.TridentSelection
|
19215
|
+
*/
|
19027
19216
|
define(
|
19028
|
-
'
|
19217
|
+
'tinymce.core.dom.TridentSelection',
|
19218
|
+
[
|
19219
|
+
],
|
19220
|
+
function () {
|
19221
|
+
function Selection(selection) {
|
19222
|
+
var self = this, dom = selection.dom, FALSE = false;
|
19223
|
+
|
19224
|
+
function getPosition(rng, start) {
|
19225
|
+
var checkRng, startIndex = 0, endIndex, inside,
|
19226
|
+
children, child, offset, index, position = -1, parent;
|
19227
|
+
|
19228
|
+
// Setup test range, collapse it and get the parent
|
19229
|
+
checkRng = rng.duplicate();
|
19230
|
+
checkRng.collapse(start);
|
19231
|
+
parent = checkRng.parentElement();
|
19232
|
+
|
19233
|
+
// Check if the selection is within the right document
|
19234
|
+
if (parent.ownerDocument !== selection.dom.doc) {
|
19235
|
+
return;
|
19236
|
+
}
|
19237
|
+
|
19238
|
+
// IE will report non editable elements as it's parent so look for an editable one
|
19239
|
+
while (parent.contentEditable === "false") {
|
19240
|
+
parent = parent.parentNode;
|
19241
|
+
}
|
19242
|
+
|
19243
|
+
// If parent doesn't have any children then return that we are inside the element
|
19244
|
+
if (!parent.hasChildNodes()) {
|
19245
|
+
return { node: parent, inside: 1 };
|
19246
|
+
}
|
19247
|
+
|
19248
|
+
// Setup node list and endIndex
|
19249
|
+
children = parent.children;
|
19250
|
+
endIndex = children.length - 1;
|
19251
|
+
|
19252
|
+
// Perform a binary search for the position
|
19253
|
+
while (startIndex <= endIndex) {
|
19254
|
+
index = Math.floor((startIndex + endIndex) / 2);
|
19255
|
+
|
19256
|
+
// Move selection to node and compare the ranges
|
19257
|
+
child = children[index];
|
19258
|
+
checkRng.moveToElementText(child);
|
19259
|
+
position = checkRng.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', rng);
|
19260
|
+
|
19261
|
+
// Before/after or an exact match
|
19262
|
+
if (position > 0) {
|
19263
|
+
endIndex = index - 1;
|
19264
|
+
} else if (position < 0) {
|
19265
|
+
startIndex = index + 1;
|
19266
|
+
} else {
|
19267
|
+
return { node: child };
|
19268
|
+
}
|
19269
|
+
}
|
19270
|
+
|
19271
|
+
// Check if child position is before or we didn't find a position
|
19272
|
+
if (position < 0) {
|
19273
|
+
// No element child was found use the parent element and the offset inside that
|
19274
|
+
if (!child) {
|
19275
|
+
checkRng.moveToElementText(parent);
|
19276
|
+
checkRng.collapse(true);
|
19277
|
+
child = parent;
|
19278
|
+
inside = true;
|
19279
|
+
} else {
|
19280
|
+
checkRng.collapse(false);
|
19281
|
+
}
|
19282
|
+
|
19283
|
+
// Walk character by character in text node until we hit the selected range endpoint,
|
19284
|
+
// hit the end of document or parent isn't the right one
|
19285
|
+
// We need to walk char by char since rng.text or rng.htmlText will trim line endings
|
19286
|
+
offset = 0;
|
19287
|
+
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
|
19288
|
+
if (checkRng.move('character', 1) === 0 || parent != checkRng.parentElement()) {
|
19289
|
+
break;
|
19290
|
+
}
|
19291
|
+
|
19292
|
+
offset++;
|
19293
|
+
}
|
19294
|
+
} else {
|
19295
|
+
// Child position is after the selection endpoint
|
19296
|
+
checkRng.collapse(true);
|
19297
|
+
|
19298
|
+
// Walk character by character in text node until we hit the selected range endpoint, hit
|
19299
|
+
// the end of document or parent isn't the right one
|
19300
|
+
offset = 0;
|
19301
|
+
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
|
19302
|
+
if (checkRng.move('character', -1) === 0 || parent != checkRng.parentElement()) {
|
19303
|
+
break;
|
19304
|
+
}
|
19305
|
+
|
19306
|
+
offset++;
|
19307
|
+
}
|
19308
|
+
}
|
19309
|
+
|
19310
|
+
return { node: child, position: position, offset: offset, inside: inside };
|
19311
|
+
}
|
19312
|
+
|
19313
|
+
// Returns a W3C DOM compatible range object by using the IE Range API
|
19314
|
+
function getRange() {
|
19315
|
+
var ieRange = selection.getRng(), domRange = dom.createRng(), element, collapsed, tmpRange, element2, bookmark;
|
19316
|
+
|
19317
|
+
// If selection is outside the current document just return an empty range
|
19318
|
+
element = ieRange.item ? ieRange.item(0) : ieRange.parentElement();
|
19319
|
+
if (element.ownerDocument != dom.doc) {
|
19320
|
+
return domRange;
|
19321
|
+
}
|
19322
|
+
|
19323
|
+
collapsed = selection.isCollapsed();
|
19324
|
+
|
19325
|
+
// Handle control selection
|
19326
|
+
if (ieRange.item) {
|
19327
|
+
domRange.setStart(element.parentNode, dom.nodeIndex(element));
|
19328
|
+
domRange.setEnd(domRange.startContainer, domRange.startOffset + 1);
|
19329
|
+
|
19330
|
+
return domRange;
|
19331
|
+
}
|
19332
|
+
|
19333
|
+
function findEndPoint(start) {
|
19334
|
+
var endPoint = getPosition(ieRange, start), container, offset, textNodeOffset = 0, sibling, undef, nodeValue;
|
19335
|
+
|
19336
|
+
container = endPoint.node;
|
19337
|
+
offset = endPoint.offset;
|
19338
|
+
|
19339
|
+
if (endPoint.inside && !container.hasChildNodes()) {
|
19340
|
+
domRange[start ? 'setStart' : 'setEnd'](container, 0);
|
19341
|
+
return;
|
19342
|
+
}
|
19343
|
+
|
19344
|
+
if (offset === undef) {
|
19345
|
+
domRange[start ? 'setStartBefore' : 'setEndAfter'](container);
|
19346
|
+
return;
|
19347
|
+
}
|
19348
|
+
|
19349
|
+
if (endPoint.position < 0) {
|
19350
|
+
sibling = endPoint.inside ? container.firstChild : container.nextSibling;
|
19351
|
+
|
19352
|
+
if (!sibling) {
|
19353
|
+
domRange[start ? 'setStartAfter' : 'setEndAfter'](container);
|
19354
|
+
return;
|
19355
|
+
}
|
19029
19356
|
|
19030
|
-
|
19031
|
-
|
19357
|
+
if (!offset) {
|
19358
|
+
if (sibling.nodeType == 3) {
|
19359
|
+
domRange[start ? 'setStart' : 'setEnd'](sibling, 0);
|
19360
|
+
} else {
|
19361
|
+
domRange[start ? 'setStartBefore' : 'setEndBefore'](sibling);
|
19362
|
+
}
|
19032
19363
|
|
19033
|
-
|
19034
|
-
|
19035
|
-
if (typeof window !== 'undefined') {
|
19036
|
-
return window;
|
19037
|
-
} else {
|
19038
|
-
return Function('return this;')();
|
19039
|
-
}
|
19040
|
-
}
|
19041
|
-
);
|
19364
|
+
return;
|
19365
|
+
}
|
19042
19366
|
|
19367
|
+
// Find the text node and offset
|
19368
|
+
while (sibling) {
|
19369
|
+
if (sibling.nodeType == 3) {
|
19370
|
+
nodeValue = sibling.nodeValue;
|
19371
|
+
textNodeOffset += nodeValue.length;
|
19043
19372
|
|
19044
|
-
|
19045
|
-
|
19373
|
+
// We are at or passed the position we where looking for
|
19374
|
+
if (textNodeOffset >= offset) {
|
19375
|
+
container = sibling;
|
19376
|
+
textNodeOffset -= offset;
|
19377
|
+
textNodeOffset = nodeValue.length - textNodeOffset;
|
19378
|
+
break;
|
19379
|
+
}
|
19380
|
+
}
|
19046
19381
|
|
19047
|
-
|
19048
|
-
|
19049
|
-
|
19382
|
+
sibling = sibling.nextSibling;
|
19383
|
+
}
|
19384
|
+
} else {
|
19385
|
+
// Find the text node and offset
|
19386
|
+
sibling = container.previousSibling;
|
19050
19387
|
|
19051
|
-
|
19052
|
-
|
19053
|
-
|
19054
|
-
var o = scope !== undefined ? scope : Global;
|
19055
|
-
for (var i = 0; i < parts.length && o !== undefined && o !== null; ++i)
|
19056
|
-
o = o[parts[i]];
|
19057
|
-
return o;
|
19058
|
-
};
|
19388
|
+
if (!sibling) {
|
19389
|
+
return domRange[start ? 'setStartBefore' : 'setEndBefore'](container);
|
19390
|
+
}
|
19059
19391
|
|
19060
|
-
|
19061
|
-
|
19062
|
-
|
19063
|
-
|
19064
|
-
|
19392
|
+
// If there isn't any text to loop then use the first position
|
19393
|
+
if (!offset) {
|
19394
|
+
if (container.nodeType == 3) {
|
19395
|
+
domRange[start ? 'setStart' : 'setEnd'](sibling, container.nodeValue.length);
|
19396
|
+
} else {
|
19397
|
+
domRange[start ? 'setStartAfter' : 'setEndAfter'](sibling);
|
19398
|
+
}
|
19065
19399
|
|
19066
|
-
|
19067
|
-
|
19068
|
-
if (o[part] === undefined || o[part] === null)
|
19069
|
-
o[part] = {};
|
19070
|
-
return o[part];
|
19071
|
-
};
|
19400
|
+
return;
|
19401
|
+
}
|
19072
19402
|
|
19073
|
-
|
19074
|
-
|
19075
|
-
|
19076
|
-
for (var i = 0; i < parts.length; ++i)
|
19077
|
-
o = step(o, parts[i]);
|
19078
|
-
return o;
|
19079
|
-
};
|
19403
|
+
while (sibling) {
|
19404
|
+
if (sibling.nodeType == 3) {
|
19405
|
+
textNodeOffset += sibling.nodeValue.length;
|
19080
19406
|
|
19081
|
-
|
19082
|
-
|
19083
|
-
|
19084
|
-
|
19085
|
-
|
19407
|
+
// We are at or passed the position we where looking for
|
19408
|
+
if (textNodeOffset >= offset) {
|
19409
|
+
container = sibling;
|
19410
|
+
textNodeOffset -= offset;
|
19411
|
+
break;
|
19412
|
+
}
|
19413
|
+
}
|
19086
19414
|
|
19087
|
-
|
19088
|
-
|
19089
|
-
|
19090
|
-
forge: forge,
|
19091
|
-
namespace: namespace
|
19092
|
-
};
|
19093
|
-
}
|
19094
|
-
);
|
19415
|
+
sibling = sibling.previousSibling;
|
19416
|
+
}
|
19417
|
+
}
|
19095
19418
|
|
19419
|
+
domRange[start ? 'setStart' : 'setEnd'](container, textNodeOffset);
|
19420
|
+
}
|
19096
19421
|
|
19097
|
-
|
19098
|
-
|
19422
|
+
try {
|
19423
|
+
// Find start point
|
19424
|
+
findEndPoint(true);
|
19099
19425
|
|
19100
|
-
|
19101
|
-
|
19102
|
-
|
19426
|
+
// Find end point if needed
|
19427
|
+
if (!collapsed) {
|
19428
|
+
findEndPoint();
|
19429
|
+
}
|
19430
|
+
} catch (ex) {
|
19431
|
+
// IE has a nasty bug where text nodes might throw "invalid argument" when you
|
19432
|
+
// access the nodeValue or other properties of text nodes. This seems to happen when
|
19433
|
+
// text nodes are split into two nodes by a delete/backspace call.
|
19434
|
+
// So let us detect and try to fix it.
|
19435
|
+
if (ex.number == -2147024809) {
|
19436
|
+
// Get the current selection
|
19437
|
+
bookmark = self.getBookmark(2);
|
19103
19438
|
|
19104
|
-
|
19105
|
-
|
19106
|
-
|
19107
|
-
|
19439
|
+
// Get start element
|
19440
|
+
tmpRange = ieRange.duplicate();
|
19441
|
+
tmpRange.collapse(true);
|
19442
|
+
element = tmpRange.parentElement();
|
19108
19443
|
|
19109
|
-
|
19110
|
-
|
19444
|
+
// Get end element
|
19445
|
+
if (!collapsed) {
|
19446
|
+
tmpRange = ieRange.duplicate();
|
19447
|
+
tmpRange.collapse(false);
|
19448
|
+
element2 = tmpRange.parentElement();
|
19449
|
+
element2.innerHTML = element2.innerHTML;
|
19450
|
+
}
|
19111
19451
|
|
19112
|
-
|
19113
|
-
|
19114
|
-
};
|
19452
|
+
// Remove the broken elements
|
19453
|
+
element.innerHTML = element.innerHTML;
|
19115
19454
|
|
19116
|
-
|
19117
|
-
|
19118
|
-
};
|
19119
|
-
}
|
19120
|
-
);
|
19121
|
-
define(
|
19122
|
-
'ephox.sand.api.Node',
|
19455
|
+
// Restore the selection
|
19456
|
+
self.moveToBookmark(bookmark);
|
19123
19457
|
|
19124
|
-
|
19125
|
-
|
19126
|
-
],
|
19458
|
+
// Since the range has moved we need to re-get it
|
19459
|
+
ieRange = selection.getRng();
|
19127
19460
|
|
19128
|
-
|
19129
|
-
|
19130
|
-
* MDN says (yes) for IE, but it's undefined on IE8
|
19131
|
-
*/
|
19132
|
-
var node = function () {
|
19133
|
-
var f = Global.getOrDie('Node');
|
19134
|
-
return f;
|
19135
|
-
};
|
19461
|
+
// Find start point
|
19462
|
+
findEndPoint(true);
|
19136
19463
|
|
19137
|
-
|
19138
|
-
|
19139
|
-
|
19140
|
-
|
19141
|
-
|
19142
|
-
|
19464
|
+
// Find end point if needed
|
19465
|
+
if (!collapsed) {
|
19466
|
+
findEndPoint();
|
19467
|
+
}
|
19468
|
+
} else {
|
19469
|
+
throw ex; // Throw other errors
|
19470
|
+
}
|
19471
|
+
}
|
19143
19472
|
|
19144
|
-
|
19145
|
-
|
19146
|
-
// of nodes e1 and e2 in their documents. See the URL below for bitmask interpretation
|
19147
|
-
// https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
|
19148
|
-
return (a.compareDocumentPosition(b) & match) !== 0;
|
19149
|
-
};
|
19473
|
+
return domRange;
|
19474
|
+
}
|
19150
19475
|
|
19151
|
-
|
19152
|
-
|
19153
|
-
};
|
19476
|
+
this.getBookmark = function (type) {
|
19477
|
+
var rng = selection.getRng(), bookmark = {};
|
19154
19478
|
|
19155
|
-
|
19156
|
-
|
19157
|
-
};
|
19479
|
+
function getIndexes(node) {
|
19480
|
+
var parent, root, children, i, indexes = [];
|
19158
19481
|
|
19159
|
-
|
19160
|
-
|
19161
|
-
documentPositionContainedBy: documentPositionContainedBy
|
19162
|
-
};
|
19163
|
-
}
|
19164
|
-
);
|
19165
|
-
define(
|
19166
|
-
'ephox.katamari.api.Thunk',
|
19482
|
+
parent = node.parentNode;
|
19483
|
+
root = dom.getRoot().parentNode;
|
19167
19484
|
|
19168
|
-
|
19169
|
-
|
19485
|
+
while (parent != root && parent.nodeType !== 9) {
|
19486
|
+
children = parent.children;
|
19170
19487
|
|
19171
|
-
|
19488
|
+
i = children.length;
|
19489
|
+
while (i--) {
|
19490
|
+
if (node === children[i]) {
|
19491
|
+
indexes.push(i);
|
19492
|
+
break;
|
19493
|
+
}
|
19494
|
+
}
|
19172
19495
|
|
19173
|
-
|
19174
|
-
|
19175
|
-
|
19176
|
-
|
19177
|
-
|
19178
|
-
called = true;
|
19179
|
-
r = f.apply(null, arguments);
|
19496
|
+
node = parent;
|
19497
|
+
parent = parent.parentNode;
|
19498
|
+
}
|
19499
|
+
|
19500
|
+
return indexes;
|
19180
19501
|
}
|
19181
|
-
return r;
|
19182
|
-
};
|
19183
|
-
};
|
19184
19502
|
|
19185
|
-
|
19186
|
-
|
19187
|
-
};
|
19188
|
-
}
|
19189
|
-
);
|
19503
|
+
function getBookmarkEndPoint(start) {
|
19504
|
+
var position;
|
19190
19505
|
|
19191
|
-
|
19192
|
-
|
19193
|
-
|
19506
|
+
position = getPosition(rng, start);
|
19507
|
+
if (position) {
|
19508
|
+
return {
|
19509
|
+
position: position.position,
|
19510
|
+
offset: position.offset,
|
19511
|
+
indexes: getIndexes(position.node),
|
19512
|
+
inside: position.inside
|
19513
|
+
};
|
19514
|
+
}
|
19515
|
+
}
|
19194
19516
|
|
19195
|
-
|
19196
|
-
|
19197
|
-
|
19198
|
-
|
19199
|
-
|
19517
|
+
// Non ubstructive bookmark
|
19518
|
+
if (type === 2) {
|
19519
|
+
// Handle text selection
|
19520
|
+
if (!rng.item) {
|
19521
|
+
bookmark.start = getBookmarkEndPoint(true);
|
19200
19522
|
|
19201
|
-
|
19202
|
-
|
19203
|
-
|
19204
|
-
|
19205
|
-
|
19206
|
-
|
19207
|
-
|
19208
|
-
};
|
19523
|
+
if (!selection.isCollapsed()) {
|
19524
|
+
bookmark.end = getBookmarkEndPoint();
|
19525
|
+
}
|
19526
|
+
} else {
|
19527
|
+
bookmark.start = { ctrl: true, indexes: getIndexes(rng.item(0)) };
|
19528
|
+
}
|
19529
|
+
}
|
19209
19530
|
|
19210
|
-
|
19211
|
-
var r = firstMatch(regexes, agent);
|
19212
|
-
if (!r) return { major : 0, minor : 0 };
|
19213
|
-
var group = function(i) {
|
19214
|
-
return Number(agent.replace(r, '$' + i));
|
19531
|
+
return bookmark;
|
19215
19532
|
};
|
19216
|
-
return nu(group(1), group(2));
|
19217
|
-
};
|
19218
19533
|
|
19219
|
-
|
19220
|
-
|
19534
|
+
this.moveToBookmark = function (bookmark) {
|
19535
|
+
var rng, body = dom.doc.body;
|
19221
19536
|
|
19222
|
-
|
19223
|
-
|
19224
|
-
};
|
19537
|
+
function resolveIndexes(indexes) {
|
19538
|
+
var node, i, idx, children;
|
19225
19539
|
|
19226
|
-
|
19227
|
-
|
19228
|
-
|
19540
|
+
node = dom.getRoot();
|
19541
|
+
for (i = indexes.length - 1; i >= 0; i--) {
|
19542
|
+
children = node.children;
|
19543
|
+
idx = indexes[i];
|
19229
19544
|
|
19230
|
-
|
19231
|
-
|
19232
|
-
|
19545
|
+
if (idx <= children.length - 1) {
|
19546
|
+
node = children[idx];
|
19547
|
+
}
|
19548
|
+
}
|
19233
19549
|
|
19234
|
-
|
19235
|
-
|
19236
|
-
detect: detect,
|
19237
|
-
unknown: unknown
|
19238
|
-
};
|
19239
|
-
}
|
19240
|
-
);
|
19241
|
-
define(
|
19242
|
-
'ephox.sand.core.Browser',
|
19550
|
+
return node;
|
19551
|
+
}
|
19243
19552
|
|
19244
|
-
|
19245
|
-
|
19246
|
-
'ephox.sand.detect.Version'
|
19247
|
-
],
|
19553
|
+
function setBookmarkEndPoint(start) {
|
19554
|
+
var endPoint = bookmark[start ? 'start' : 'end'], moveLeft, moveRng, undef, offset;
|
19248
19555
|
|
19249
|
-
|
19250
|
-
|
19251
|
-
var chrome = 'Chrome';
|
19252
|
-
var ie = 'IE';
|
19253
|
-
var opera = 'Opera';
|
19254
|
-
var firefox = 'Firefox';
|
19255
|
-
var safari = 'Safari';
|
19556
|
+
if (endPoint) {
|
19557
|
+
moveLeft = endPoint.position > 0;
|
19256
19558
|
|
19257
|
-
|
19258
|
-
|
19259
|
-
return current === name;
|
19260
|
-
};
|
19261
|
-
};
|
19559
|
+
moveRng = body.createTextRange();
|
19560
|
+
moveRng.moveToElementText(resolveIndexes(endPoint.indexes));
|
19262
19561
|
|
19263
|
-
|
19264
|
-
|
19265
|
-
|
19266
|
-
|
19267
|
-
|
19268
|
-
|
19562
|
+
offset = endPoint.offset;
|
19563
|
+
if (offset !== undef) {
|
19564
|
+
moveRng.collapse(endPoint.inside || moveLeft);
|
19565
|
+
moveRng.moveStart('character', moveLeft ? -offset : offset);
|
19566
|
+
} else {
|
19567
|
+
moveRng.collapse(start);
|
19568
|
+
}
|
19269
19569
|
|
19270
|
-
|
19271
|
-
var current = info.current;
|
19272
|
-
var version = info.version;
|
19570
|
+
rng.setEndPoint(start ? 'StartToStart' : 'EndToStart', moveRng);
|
19273
19571
|
|
19274
|
-
|
19275
|
-
|
19276
|
-
|
19572
|
+
if (start) {
|
19573
|
+
rng.collapse(true);
|
19574
|
+
}
|
19575
|
+
}
|
19576
|
+
}
|
19277
19577
|
|
19278
|
-
|
19279
|
-
|
19280
|
-
|
19281
|
-
|
19282
|
-
|
19283
|
-
|
19284
|
-
|
19285
|
-
|
19578
|
+
if (bookmark.start) {
|
19579
|
+
if (bookmark.start.ctrl) {
|
19580
|
+
rng = body.createControlRange();
|
19581
|
+
rng.addElement(resolveIndexes(bookmark.start.indexes));
|
19582
|
+
rng.select();
|
19583
|
+
} else {
|
19584
|
+
rng = body.createTextRange();
|
19585
|
+
setBookmarkEndPoint(true);
|
19586
|
+
setBookmarkEndPoint();
|
19587
|
+
rng.select();
|
19588
|
+
}
|
19589
|
+
}
|
19286
19590
|
};
|
19287
|
-
};
|
19288
19591
|
|
19289
|
-
|
19290
|
-
|
19291
|
-
|
19292
|
-
edge: Fun.constant(edge),
|
19293
|
-
chrome: Fun.constant(chrome),
|
19294
|
-
ie: Fun.constant(ie),
|
19295
|
-
opera: Fun.constant(opera),
|
19296
|
-
firefox: Fun.constant(firefox),
|
19297
|
-
safari: Fun.constant(safari)
|
19298
|
-
};
|
19299
|
-
}
|
19300
|
-
);
|
19301
|
-
define(
|
19302
|
-
'ephox.sand.core.OperatingSystem',
|
19592
|
+
this.addRange = function (rng) {
|
19593
|
+
var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, sibling,
|
19594
|
+
doc = selection.dom.doc, body = doc.body, nativeRng, ctrlElm;
|
19303
19595
|
|
19304
|
-
|
19305
|
-
|
19306
|
-
'ephox.sand.detect.Version'
|
19307
|
-
],
|
19596
|
+
function setEndPoint(start) {
|
19597
|
+
var container, offset, marker, tmpRng, nodes;
|
19308
19598
|
|
19309
|
-
|
19310
|
-
|
19311
|
-
|
19312
|
-
|
19313
|
-
var linux = 'Linux';
|
19314
|
-
var osx = 'OSX';
|
19315
|
-
var solaris = 'Solaris';
|
19316
|
-
var freebsd = 'FreeBSD';
|
19599
|
+
marker = dom.create('a');
|
19600
|
+
container = start ? startContainer : endContainer;
|
19601
|
+
offset = start ? startOffset : endOffset;
|
19602
|
+
tmpRng = ieRng.duplicate();
|
19317
19603
|
|
19318
|
-
|
19319
|
-
|
19320
|
-
|
19321
|
-
|
19322
|
-
return current === name;
|
19323
|
-
};
|
19324
|
-
};
|
19604
|
+
if (container == doc || container == doc.documentElement) {
|
19605
|
+
container = body;
|
19606
|
+
offset = 0;
|
19607
|
+
}
|
19325
19608
|
|
19326
|
-
|
19327
|
-
|
19328
|
-
|
19329
|
-
|
19330
|
-
|
19331
|
-
|
19609
|
+
if (container.nodeType == 3) {
|
19610
|
+
container.parentNode.insertBefore(marker, container);
|
19611
|
+
tmpRng.moveToElementText(marker);
|
19612
|
+
tmpRng.moveStart('character', offset);
|
19613
|
+
dom.remove(marker);
|
19614
|
+
ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng);
|
19615
|
+
} else {
|
19616
|
+
nodes = container.childNodes;
|
19332
19617
|
|
19333
|
-
|
19334
|
-
|
19335
|
-
|
19618
|
+
if (nodes.length) {
|
19619
|
+
if (offset >= nodes.length) {
|
19620
|
+
dom.insertAfter(marker, nodes[nodes.length - 1]);
|
19621
|
+
} else {
|
19622
|
+
container.insertBefore(marker, nodes[offset]);
|
19623
|
+
}
|
19336
19624
|
|
19337
|
-
|
19338
|
-
|
19339
|
-
|
19625
|
+
tmpRng.moveToElementText(marker);
|
19626
|
+
} else if (container.canHaveHTML) {
|
19627
|
+
// Empty node selection for example <div>|</div>
|
19628
|
+
// Setting innerHTML with a span marker then remove that marker seems to keep empty block elements open
|
19629
|
+
container.innerHTML = '<span></span>';
|
19630
|
+
marker = container.firstChild;
|
19631
|
+
tmpRng.moveToElementText(marker);
|
19632
|
+
tmpRng.collapse(FALSE); // Collapse false works better than true for some odd reason
|
19633
|
+
}
|
19340
19634
|
|
19341
|
-
|
19342
|
-
|
19343
|
-
|
19344
|
-
|
19345
|
-
|
19346
|
-
|
19347
|
-
|
19348
|
-
|
19349
|
-
|
19350
|
-
|
19635
|
+
ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng);
|
19636
|
+
dom.remove(marker);
|
19637
|
+
}
|
19638
|
+
}
|
19639
|
+
|
19640
|
+
// Setup some shorter versions
|
19641
|
+
startContainer = rng.startContainer;
|
19642
|
+
startOffset = rng.startOffset;
|
19643
|
+
endContainer = rng.endContainer;
|
19644
|
+
endOffset = rng.endOffset;
|
19645
|
+
ieRng = body.createTextRange();
|
19646
|
+
|
19647
|
+
// If single element selection then try making a control selection out of it
|
19648
|
+
if (startContainer == endContainer && startContainer.nodeType == 1) {
|
19649
|
+
// Trick to place the caret inside an empty block element like <p></p>
|
19650
|
+
if (startOffset == endOffset && !startContainer.hasChildNodes()) {
|
19651
|
+
if (startContainer.canHaveHTML) {
|
19652
|
+
// Check if previous sibling is an empty block if it is then we need to render it
|
19653
|
+
// IE would otherwise move the caret into the sibling instead of the empty startContainer see: #5236
|
19654
|
+
// Example this: <p></p><p>|</p> would become this: <p>|</p><p></p>
|
19655
|
+
sibling = startContainer.previousSibling;
|
19656
|
+
if (sibling && !sibling.hasChildNodes() && dom.isBlock(sibling)) {
|
19657
|
+
sibling.innerHTML = '';
|
19658
|
+
} else {
|
19659
|
+
sibling = null;
|
19660
|
+
}
|
19351
19661
|
|
19352
|
-
|
19353
|
-
|
19354
|
-
|
19662
|
+
startContainer.innerHTML = '<span></span><span></span>';
|
19663
|
+
ieRng.moveToElementText(startContainer.lastChild);
|
19664
|
+
ieRng.select();
|
19665
|
+
dom.doc.selection.clear();
|
19666
|
+
startContainer.innerHTML = '';
|
19355
19667
|
|
19356
|
-
|
19357
|
-
|
19358
|
-
|
19359
|
-
|
19360
|
-
|
19361
|
-
solaris: Fun.constant(solaris),
|
19362
|
-
freebsd: Fun.constant(freebsd)
|
19363
|
-
};
|
19364
|
-
}
|
19365
|
-
);
|
19366
|
-
define(
|
19367
|
-
'ephox.sand.detect.DeviceType',
|
19668
|
+
if (sibling) {
|
19669
|
+
sibling.innerHTML = '';
|
19670
|
+
}
|
19671
|
+
return;
|
19672
|
+
}
|
19368
19673
|
|
19369
|
-
|
19370
|
-
|
19371
|
-
|
19674
|
+
startOffset = dom.nodeIndex(startContainer);
|
19675
|
+
startContainer = startContainer.parentNode;
|
19676
|
+
}
|
19372
19677
|
|
19373
|
-
|
19374
|
-
|
19375
|
-
|
19376
|
-
|
19377
|
-
|
19378
|
-
|
19379
|
-
var isTablet = isiPad || isAndroid3 || ( isAndroid4 && /mobile/i.test(userAgent) === true );
|
19380
|
-
var isTouch = os.isiOS() || os.isAndroid();
|
19381
|
-
var isPhone = isTouch && !isTablet;
|
19678
|
+
if (startOffset == endOffset - 1) {
|
19679
|
+
try {
|
19680
|
+
ctrlElm = startContainer.childNodes[startOffset];
|
19681
|
+
ctrlRng = body.createControlRange();
|
19682
|
+
ctrlRng.addElement(ctrlElm);
|
19683
|
+
ctrlRng.select();
|
19382
19684
|
|
19383
|
-
|
19685
|
+
// Check if the range produced is on the correct element and is a control range
|
19686
|
+
// On IE 8 it will select the parent contentEditable container if you select an inner element see: #5398
|
19687
|
+
nativeRng = selection.getRng();
|
19688
|
+
if (nativeRng.item && ctrlElm === nativeRng.item(0)) {
|
19689
|
+
return;
|
19690
|
+
}
|
19691
|
+
} catch (ex) {
|
19692
|
+
// Ignore
|
19693
|
+
}
|
19694
|
+
}
|
19695
|
+
}
|
19384
19696
|
|
19385
|
-
|
19386
|
-
|
19387
|
-
|
19388
|
-
|
19389
|
-
|
19390
|
-
|
19391
|
-
isAndroid: os.isAndroid,
|
19392
|
-
isiOS: os.isiOS,
|
19393
|
-
isWebView: Fun.constant(iOSwebview)
|
19697
|
+
// Set start/end point of selection
|
19698
|
+
setEndPoint(true);
|
19699
|
+
setEndPoint();
|
19700
|
+
|
19701
|
+
// Select the new range and scroll it into view
|
19702
|
+
ieRng.select();
|
19394
19703
|
};
|
19395
|
-
|
19704
|
+
|
19705
|
+
// Expose range method
|
19706
|
+
this.getRangeAt = getRange;
|
19707
|
+
}
|
19708
|
+
|
19709
|
+
return Selection;
|
19396
19710
|
}
|
19397
19711
|
);
|
19712
|
+
|
19398
19713
|
define(
|
19399
|
-
'ephox.
|
19714
|
+
'ephox.katamari.api.Type',
|
19400
19715
|
|
19401
19716
|
[
|
19402
|
-
'
|
19403
|
-
'ephox.sand.detect.Version',
|
19717
|
+
'global!Array',
|
19404
19718
|
'global!String'
|
19405
19719
|
],
|
19406
19720
|
|
19407
|
-
function (
|
19408
|
-
var
|
19409
|
-
|
19410
|
-
|
19411
|
-
|
19412
|
-
|
19413
|
-
|
19414
|
-
|
19415
|
-
// They (browser and os) are the same at the moment, but they might
|
19416
|
-
// not stay that way.
|
19417
|
-
var detectBrowser = function (browsers, userAgent) {
|
19418
|
-
return detect(browsers, userAgent).map(function (browser) {
|
19419
|
-
var version = Version.detect(browser.versionRegexes, userAgent);
|
19420
|
-
return {
|
19421
|
-
current: browser.name,
|
19422
|
-
version: version
|
19423
|
-
};
|
19424
|
-
});
|
19721
|
+
function (Array, String) {
|
19722
|
+
var typeOf = function(x) {
|
19723
|
+
if (x === null) return 'null';
|
19724
|
+
var t = typeof x;
|
19725
|
+
if (t === 'object' && Array.prototype.isPrototypeOf(x)) return 'array';
|
19726
|
+
if (t === 'object' && String.prototype.isPrototypeOf(x)) return 'string';
|
19727
|
+
return t;
|
19425
19728
|
};
|
19426
19729
|
|
19427
|
-
var
|
19428
|
-
return
|
19429
|
-
|
19430
|
-
|
19431
|
-
current: os.name,
|
19432
|
-
version: version
|
19433
|
-
};
|
19434
|
-
});
|
19730
|
+
var isType = function (type) {
|
19731
|
+
return function (value) {
|
19732
|
+
return typeOf(value) === type;
|
19733
|
+
};
|
19435
19734
|
};
|
19436
19735
|
|
19437
19736
|
return {
|
19438
|
-
|
19439
|
-
|
19737
|
+
isString: isType('string'),
|
19738
|
+
isObject: isType('object'),
|
19739
|
+
isArray: isType('array'),
|
19740
|
+
isNull: isType('null'),
|
19741
|
+
isBoolean: isType('boolean'),
|
19742
|
+
isUndefined: isType('undefined'),
|
19743
|
+
isFunction: isType('function'),
|
19744
|
+
isNumber: isType('number')
|
19440
19745
|
};
|
19441
19746
|
}
|
19442
19747
|
);
|
19443
|
-
define(
|
19444
|
-
'ephox.katamari.str.StrAppend',
|
19445
|
-
|
19446
|
-
[
|
19447
|
-
|
19448
|
-
],
|
19449
19748
|
|
19450
|
-
function () {
|
19451
|
-
var addToStart = function (str, prefix) {
|
19452
|
-
return prefix + str;
|
19453
|
-
};
|
19454
|
-
|
19455
|
-
var addToEnd = function (str, suffix) {
|
19456
|
-
return str + suffix;
|
19457
|
-
};
|
19458
19749
|
|
19459
|
-
var removeFromStart = function (str, numChars) {
|
19460
|
-
return str.substring(numChars);
|
19461
|
-
};
|
19462
|
-
|
19463
|
-
var removeFromEnd = function (str, numChars) {
|
19464
|
-
return str.substring(0, str.length - numChars);
|
19465
|
-
};
|
19466
|
-
|
19467
|
-
return {
|
19468
|
-
addToStart: addToStart,
|
19469
|
-
addToEnd: addToEnd,
|
19470
|
-
removeFromStart: removeFromStart,
|
19471
|
-
removeFromEnd: removeFromEnd
|
19472
|
-
};
|
19473
|
-
}
|
19474
|
-
);
|
19475
19750
|
define(
|
19476
|
-
'ephox.katamari.
|
19751
|
+
'ephox.katamari.data.Immutable',
|
19477
19752
|
|
19478
19753
|
[
|
19479
|
-
'ephox.katamari.api.
|
19754
|
+
'ephox.katamari.api.Arr',
|
19755
|
+
'ephox.katamari.api.Fun',
|
19756
|
+
'global!Array',
|
19480
19757
|
'global!Error'
|
19481
19758
|
],
|
19482
19759
|
|
19483
|
-
function (
|
19484
|
-
|
19485
|
-
|
19486
|
-
|
19487
|
-
|
19488
|
-
|
19489
|
-
|
19490
|
-
|
19491
|
-
/** Return the last 'count' letters from 'str'.
|
19492
|
-
* e.g. last("abcde", 2) === "de"
|
19493
|
-
*/
|
19494
|
-
var last = function(str, count) {
|
19495
|
-
return str.substr(str.length - count, str.length);
|
19496
|
-
};
|
19497
|
-
|
19498
|
-
var head = function(str) {
|
19499
|
-
return str === '' ? Option.none() : Option.some(str.substr(0, 1));
|
19500
|
-
};
|
19760
|
+
function (Arr, Fun, Array, Error) {
|
19761
|
+
return function () {
|
19762
|
+
var fields = arguments;
|
19763
|
+
return function(/* values */) {
|
19764
|
+
// Don't use array slice(arguments), makes the whole function unoptimisable on Chrome
|
19765
|
+
var values = new Array(arguments.length);
|
19766
|
+
for (var i = 0; i < values.length; i++) values[i] = arguments[i];
|
19501
19767
|
|
19502
|
-
|
19503
|
-
|
19504
|
-
};
|
19768
|
+
if (fields.length !== values.length)
|
19769
|
+
throw new Error('Wrong number of arguments to struct. Expected "[' + fields.length + ']", got ' + values.length + ' arguments');
|
19505
19770
|
|
19506
|
-
|
19507
|
-
|
19508
|
-
|
19509
|
-
|
19510
|
-
|
19771
|
+
var struct = {};
|
19772
|
+
Arr.each(fields, function (name, i) {
|
19773
|
+
struct[name] = Fun.constant(values[i]);
|
19774
|
+
});
|
19775
|
+
return struct;
|
19776
|
+
};
|
19511
19777
|
};
|
19512
19778
|
}
|
19513
19779
|
);
|
19780
|
+
|
19514
19781
|
define(
|
19515
|
-
'ephox.katamari.api.
|
19782
|
+
'ephox.katamari.api.Obj',
|
19516
19783
|
|
19517
19784
|
[
|
19518
|
-
'ephox.katamari.
|
19519
|
-
'
|
19520
|
-
'global!Error'
|
19785
|
+
'ephox.katamari.api.Option',
|
19786
|
+
'global!Object'
|
19521
19787
|
],
|
19522
19788
|
|
19523
|
-
function (
|
19524
|
-
|
19525
|
-
|
19526
|
-
|
19527
|
-
|
19528
|
-
|
19529
|
-
|
19530
|
-
|
19531
|
-
/** Given a string and object, perform template-replacements on the string, as specified by the object.
|
19532
|
-
* Any template fields of the form ${name} are replaced by the string or number specified as obj["name"]
|
19533
|
-
* Based on Douglas Crockford's 'supplant' method for template-replace of strings. Uses different template format.
|
19534
|
-
*/
|
19535
|
-
var supplant = function(str, obj) {
|
19536
|
-
var isStringOrNumber = function(a) {
|
19537
|
-
var t = typeof a;
|
19538
|
-
return t === 'string' || t === 'number';
|
19539
|
-
};
|
19789
|
+
function (Option, Object) {
|
19790
|
+
// There are many variations of Object iteration that are faster than the 'for-in' style:
|
19791
|
+
// http://jsperf.com/object-keys-iteration/107
|
19792
|
+
//
|
19793
|
+
// Use the native keys if it is available (IE9+), otherwise fall back to manually filtering
|
19794
|
+
var keys = (function () {
|
19795
|
+
var fastKeys = Object.keys;
|
19540
19796
|
|
19541
|
-
|
19542
|
-
|
19543
|
-
|
19544
|
-
|
19797
|
+
// This technically means that 'each' and 'find' on IE8 iterate through the object twice.
|
19798
|
+
// This code doesn't run on IE8 much, so it's an acceptable tradeoff.
|
19799
|
+
// If it becomes a problem we can always duplicate the feature detection inside each and find as well.
|
19800
|
+
var slowKeys = function (o) {
|
19801
|
+
var r = [];
|
19802
|
+
for (var i in o) {
|
19803
|
+
if (o.hasOwnProperty(i)) {
|
19804
|
+
r.push(i);
|
19805
|
+
}
|
19545
19806
|
}
|
19546
|
-
|
19547
|
-
|
19548
|
-
|
19549
|
-
var removeLeading = function (str, prefix) {
|
19550
|
-
return startsWith(str, prefix) ? StrAppend.removeFromStart(str, prefix.length) : str;
|
19551
|
-
};
|
19552
|
-
|
19553
|
-
var removeTrailing = function (str, prefix) {
|
19554
|
-
return endsWith(str, prefix) ? StrAppend.removeFromEnd(str, prefix.length) : str;
|
19555
|
-
};
|
19556
|
-
|
19557
|
-
var ensureLeading = function (str, prefix) {
|
19558
|
-
return startsWith(str, prefix) ? str : StrAppend.addToStart(str, prefix);
|
19559
|
-
};
|
19560
|
-
|
19561
|
-
var ensureTrailing = function (str, prefix) {
|
19562
|
-
return endsWith(str, prefix) ? str : StrAppend.addToEnd(str, prefix);
|
19563
|
-
};
|
19564
|
-
|
19565
|
-
var contains = function(str, substr) {
|
19566
|
-
return str.indexOf(substr) !== -1;
|
19567
|
-
};
|
19568
|
-
|
19569
|
-
var capitalize = function(str) {
|
19570
|
-
return StringParts.head(str).bind(function (head) {
|
19571
|
-
return StringParts.tail(str).map(function (tail) {
|
19572
|
-
return head.toUpperCase() + tail;
|
19573
|
-
});
|
19574
|
-
}).getOr(str);
|
19575
|
-
};
|
19576
|
-
|
19577
|
-
/** Does 'str' start with 'prefix'?
|
19578
|
-
* Note: all strings start with the empty string.
|
19579
|
-
* More formally, for all strings x, startsWith(x, "").
|
19580
|
-
* This is so that for all strings x and y, startsWith(y + x, y)
|
19581
|
-
*/
|
19582
|
-
var startsWith = function(str, prefix) {
|
19583
|
-
return checkRange(str, prefix, 0);
|
19584
|
-
};
|
19807
|
+
return r;
|
19808
|
+
};
|
19585
19809
|
|
19586
|
-
|
19587
|
-
|
19588
|
-
* More formally, for all strings x, endsWith(x, "").
|
19589
|
-
* This is so that for all strings x and y, endsWith(x + y, y)
|
19590
|
-
*/
|
19591
|
-
var endsWith = function(str, suffix) {
|
19592
|
-
return checkRange(str, suffix, str.length - suffix.length);
|
19593
|
-
};
|
19810
|
+
return fastKeys === undefined ? slowKeys : fastKeys;
|
19811
|
+
})();
|
19594
19812
|
|
19595
|
-
|
19596
|
-
/** removes all leading and trailing spaces */
|
19597
|
-
var trim = function(str) {
|
19598
|
-
return str.replace(/^\s+|\s+$/g, '');
|
19599
|
-
};
|
19600
19813
|
|
19601
|
-
var
|
19602
|
-
|
19814
|
+
var each = function (obj, f) {
|
19815
|
+
var props = keys(obj);
|
19816
|
+
for (var k = 0, len = props.length; k < len; k++) {
|
19817
|
+
var i = props[k];
|
19818
|
+
var x = obj[i];
|
19819
|
+
f(x, i, obj);
|
19820
|
+
}
|
19603
19821
|
};
|
19604
19822
|
|
19605
|
-
|
19606
|
-
|
19823
|
+
/** objectMap :: (JsObj(k, v), (v, k, JsObj(k, v) -> x)) -> JsObj(k, x) */
|
19824
|
+
var objectMap = function (obj, f) {
|
19825
|
+
return tupleMap(obj, function (x, i, obj) {
|
19826
|
+
return {
|
19827
|
+
k: i,
|
19828
|
+
v: f(x, i, obj)
|
19829
|
+
};
|
19830
|
+
});
|
19607
19831
|
};
|
19608
19832
|
|
19609
|
-
|
19610
|
-
|
19611
|
-
|
19612
|
-
|
19613
|
-
|
19614
|
-
|
19615
|
-
|
19616
|
-
|
19617
|
-
contains: contains,
|
19618
|
-
trim: trim,
|
19619
|
-
lTrim: lTrim,
|
19620
|
-
rTrim: rTrim,
|
19621
|
-
capitalize: capitalize
|
19833
|
+
/** tupleMap :: (JsObj(k, v), (v, k, JsObj(k, v) -> { k: x, v: y })) -> JsObj(x, y) */
|
19834
|
+
var tupleMap = function (obj, f) {
|
19835
|
+
var r = {};
|
19836
|
+
each(obj, function (x, i) {
|
19837
|
+
var tuple = f(x, i, obj);
|
19838
|
+
r[tuple.k] = tuple.v;
|
19839
|
+
});
|
19840
|
+
return r;
|
19622
19841
|
};
|
19623
|
-
}
|
19624
|
-
);
|
19625
|
-
|
19626
|
-
define(
|
19627
|
-
'ephox.sand.info.PlatformInfo',
|
19628
|
-
|
19629
|
-
[
|
19630
|
-
'ephox.katamari.api.Fun',
|
19631
|
-
'ephox.katamari.api.Strings'
|
19632
|
-
],
|
19633
|
-
|
19634
|
-
function (Fun, Strings) {
|
19635
|
-
var normalVersionRegex = /.*?version\/\ ?([0-9]+)\.([0-9]+).*/;
|
19636
19842
|
|
19637
|
-
|
19638
|
-
|
19639
|
-
|
19843
|
+
/** bifilter :: (JsObj(k, v), (v, k -> Bool)) -> { t: JsObj(k, v), f: JsObj(k, v) } */
|
19844
|
+
var bifilter = function (obj, pred) {
|
19845
|
+
var t = {};
|
19846
|
+
var f = {};
|
19847
|
+
each(obj, function(x, i) {
|
19848
|
+
var branch = pred(x, i) ? t : f;
|
19849
|
+
branch[i] = x;
|
19850
|
+
});
|
19851
|
+
return {
|
19852
|
+
t: t,
|
19853
|
+
f: f
|
19640
19854
|
};
|
19641
19855
|
};
|
19642
19856
|
|
19643
|
-
|
19644
|
-
|
19645
|
-
|
19646
|
-
|
19647
|
-
|
19648
|
-
|
19649
|
-
|
19650
|
-
}
|
19651
|
-
},
|
19652
|
-
{
|
19653
|
-
name : 'Chrome',
|
19654
|
-
versionRegexes: [/.*?chrome\/([0-9]+)\.([0-9]+).*/, normalVersionRegex],
|
19655
|
-
search : function (uastring) {
|
19656
|
-
return Strings.contains(uastring, 'chrome') && !Strings.contains(uastring, 'chromeframe');
|
19657
|
-
}
|
19658
|
-
},
|
19659
|
-
{
|
19660
|
-
name : 'IE',
|
19661
|
-
versionRegexes: [/.*?msie\ ?([0-9]+)\.([0-9]+).*/, /.*?rv:([0-9]+)\.([0-9]+).*/],
|
19662
|
-
search: function (uastring) {
|
19663
|
-
return Strings.contains(uastring, 'msie') || Strings.contains(uastring, 'trident');
|
19664
|
-
}
|
19665
|
-
},
|
19666
|
-
// INVESTIGATE: Is this still the Opera user agent?
|
19667
|
-
{
|
19668
|
-
name : 'Opera',
|
19669
|
-
versionRegexes: [normalVersionRegex, /.*?opera\/([0-9]+)\.([0-9]+).*/],
|
19670
|
-
search : checkContains('opera')
|
19671
|
-
},
|
19672
|
-
{
|
19673
|
-
name : 'Firefox',
|
19674
|
-
versionRegexes: [/.*?firefox\/\ ?([0-9]+)\.([0-9]+).*/],
|
19675
|
-
search : checkContains('firefox')
|
19676
|
-
},
|
19677
|
-
{
|
19678
|
-
name : 'Safari',
|
19679
|
-
versionRegexes: [normalVersionRegex, /.*?cpu os ([0-9]+)_([0-9]+).*/],
|
19680
|
-
search : function (uastring) {
|
19681
|
-
return (Strings.contains(uastring, 'safari') || Strings.contains(uastring, 'mobile/')) && Strings.contains(uastring, 'applewebkit');
|
19682
|
-
}
|
19683
|
-
}
|
19684
|
-
];
|
19685
|
-
|
19686
|
-
var oses = [
|
19687
|
-
{
|
19688
|
-
name : 'Windows',
|
19689
|
-
search : checkContains('win'),
|
19690
|
-
versionRegexes: [/.*?windows\ nt\ ?([0-9]+)\.([0-9]+).*/]
|
19691
|
-
},
|
19692
|
-
{
|
19693
|
-
name : 'iOS',
|
19694
|
-
search : function (uastring) {
|
19695
|
-
return Strings.contains(uastring, 'iphone') || Strings.contains(uastring, 'ipad');
|
19696
|
-
},
|
19697
|
-
versionRegexes: [/.*?version\/\ ?([0-9]+)\.([0-9]+).*/, /.*cpu os ([0-9]+)_([0-9]+).*/, /.*cpu iphone os ([0-9]+)_([0-9]+).*/]
|
19698
|
-
},
|
19699
|
-
{
|
19700
|
-
name : 'Android',
|
19701
|
-
search : checkContains('android'),
|
19702
|
-
versionRegexes: [/.*?android\ ?([0-9]+)\.([0-9]+).*/]
|
19703
|
-
},
|
19704
|
-
{
|
19705
|
-
name : 'OSX',
|
19706
|
-
search : checkContains('os x'),
|
19707
|
-
versionRegexes: [/.*?os\ x\ ?([0-9]+)_([0-9]+).*/]
|
19708
|
-
},
|
19709
|
-
{
|
19710
|
-
name : 'Linux',
|
19711
|
-
search : checkContains('linux'),
|
19712
|
-
versionRegexes: [ ]
|
19713
|
-
},
|
19714
|
-
{ name : 'Solaris',
|
19715
|
-
search : checkContains('sunos'),
|
19716
|
-
versionRegexes: [ ]
|
19717
|
-
},
|
19718
|
-
{
|
19719
|
-
name : 'FreeBSD',
|
19720
|
-
search : checkContains('freebsd'),
|
19721
|
-
versionRegexes: [ ]
|
19722
|
-
}
|
19723
|
-
];
|
19724
|
-
|
19725
|
-
return {
|
19726
|
-
browsers: Fun.constant(browsers),
|
19727
|
-
oses: Fun.constant(oses)
|
19857
|
+
/** mapToArray :: (JsObj(k, v), (v, k -> a)) -> [a] */
|
19858
|
+
var mapToArray = function (obj, f) {
|
19859
|
+
var r = [];
|
19860
|
+
each(obj, function(value, name) {
|
19861
|
+
r.push(f(value, name));
|
19862
|
+
});
|
19863
|
+
return r;
|
19728
19864
|
};
|
19729
|
-
}
|
19730
|
-
);
|
19731
|
-
define(
|
19732
|
-
'ephox.sand.core.PlatformDetection',
|
19733
|
-
|
19734
|
-
[
|
19735
|
-
'ephox.sand.core.Browser',
|
19736
|
-
'ephox.sand.core.OperatingSystem',
|
19737
|
-
'ephox.sand.detect.DeviceType',
|
19738
|
-
'ephox.sand.detect.UaString',
|
19739
|
-
'ephox.sand.info.PlatformInfo'
|
19740
|
-
],
|
19741
|
-
|
19742
|
-
function (Browser, OperatingSystem, DeviceType, UaString, PlatformInfo) {
|
19743
|
-
var detect = function (userAgent) {
|
19744
|
-
var browsers = PlatformInfo.browsers();
|
19745
|
-
var oses = PlatformInfo.oses();
|
19746
|
-
|
19747
|
-
var browser = UaString.detectBrowser(browsers, userAgent).fold(
|
19748
|
-
Browser.unknown,
|
19749
|
-
Browser.nu
|
19750
|
-
);
|
19751
|
-
var os = UaString.detectOs(oses, userAgent).fold(
|
19752
|
-
OperatingSystem.unknown,
|
19753
|
-
OperatingSystem.nu
|
19754
|
-
);
|
19755
|
-
var deviceType = DeviceType(os, browser, userAgent);
|
19756
19865
|
|
19757
|
-
|
19758
|
-
|
19759
|
-
|
19760
|
-
|
19761
|
-
|
19866
|
+
/** find :: (JsObj(k, v), (v, k, JsObj(k, v) -> Bool)) -> Option v */
|
19867
|
+
var find = function (obj, pred) {
|
19868
|
+
var props = keys(obj);
|
19869
|
+
for (var k = 0, len = props.length; k < len; k++) {
|
19870
|
+
var i = props[k];
|
19871
|
+
var x = obj[i];
|
19872
|
+
if (pred(x, i, obj)) {
|
19873
|
+
return Option.some(x);
|
19874
|
+
}
|
19875
|
+
}
|
19876
|
+
return Option.none();
|
19762
19877
|
};
|
19763
19878
|
|
19764
|
-
|
19765
|
-
|
19879
|
+
/** values :: JsObj(k, v) -> [v] */
|
19880
|
+
var values = function (obj) {
|
19881
|
+
return mapToArray(obj, function (v) {
|
19882
|
+
return v;
|
19883
|
+
});
|
19766
19884
|
};
|
19767
|
-
}
|
19768
|
-
);
|
19769
|
-
defineGlobal("global!navigator", navigator);
|
19770
|
-
define(
|
19771
|
-
'ephox.sand.api.PlatformDetection',
|
19772
|
-
|
19773
|
-
[
|
19774
|
-
'ephox.katamari.api.Thunk',
|
19775
|
-
'ephox.sand.core.PlatformDetection',
|
19776
|
-
'global!navigator'
|
19777
|
-
],
|
19778
19885
|
|
19779
|
-
|
19780
|
-
|
19781
|
-
|
19782
|
-
return PlatformDetection.detect(userAgent);
|
19783
|
-
});
|
19886
|
+
var size = function (obj) {
|
19887
|
+
return values(obj).length;
|
19888
|
+
};
|
19784
19889
|
|
19785
19890
|
return {
|
19786
|
-
|
19891
|
+
bifilter: bifilter,
|
19892
|
+
each: each,
|
19893
|
+
map: objectMap,
|
19894
|
+
mapToArray: mapToArray,
|
19895
|
+
tupleMap: tupleMap,
|
19896
|
+
find: find,
|
19897
|
+
keys: keys,
|
19898
|
+
values: values,
|
19899
|
+
size: size
|
19787
19900
|
};
|
19788
19901
|
}
|
19789
19902
|
);
|
19790
|
-
define("global!console", [], function () { if (typeof console === "undefined") console = { log: function () {} }; return console; });
|
19791
|
-
defineGlobal("global!document", document);
|
19792
19903
|
define(
|
19793
|
-
'ephox.
|
19904
|
+
'ephox.katamari.util.BagUtils',
|
19794
19905
|
|
19795
19906
|
[
|
19796
|
-
'ephox.katamari.api.
|
19797
|
-
'
|
19798
|
-
'global!
|
19799
|
-
'global!document'
|
19907
|
+
'ephox.katamari.api.Arr',
|
19908
|
+
'ephox.katamari.api.Type',
|
19909
|
+
'global!Error'
|
19800
19910
|
],
|
19801
19911
|
|
19802
|
-
function (
|
19803
|
-
var
|
19804
|
-
|
19805
|
-
var div = doc.createElement('div');
|
19806
|
-
div.innerHTML = html;
|
19807
|
-
if (!div.hasChildNodes() || div.childNodes.length > 1) {
|
19808
|
-
console.error('HTML does not have a single root node', html);
|
19809
|
-
throw 'HTML must have a single root node';
|
19810
|
-
}
|
19811
|
-
return fromDom(div.childNodes[0]);
|
19912
|
+
function (Arr, Type, Error) {
|
19913
|
+
var sort = function (arr) {
|
19914
|
+
return arr.slice(0).sort();
|
19812
19915
|
};
|
19813
19916
|
|
19814
|
-
var
|
19815
|
-
|
19816
|
-
var node = doc.createElement(tag);
|
19817
|
-
return fromDom(node);
|
19917
|
+
var reqMessage = function (required, keys) {
|
19918
|
+
throw new Error('All required keys (' + sort(required).join(', ') + ') were not specified. Specified keys were: ' + sort(keys).join(', ') + '.');
|
19818
19919
|
};
|
19819
19920
|
|
19820
|
-
var
|
19821
|
-
|
19822
|
-
var node = doc.createTextNode(text);
|
19823
|
-
return fromDom(node);
|
19921
|
+
var unsuppMessage = function (unsupported) {
|
19922
|
+
throw new Error('Unsupported keys for object: ' + sort(unsupported).join(', '));
|
19824
19923
|
};
|
19825
19924
|
|
19826
|
-
var
|
19827
|
-
if (
|
19828
|
-
|
19829
|
-
|
19830
|
-
};
|
19925
|
+
var validateStrArr = function (label, array) {
|
19926
|
+
if (!Type.isArray(array)) throw new Error('The ' + label + ' fields must be an array. Was: ' + array + '.');
|
19927
|
+
Arr.each(array, function (a) {
|
19928
|
+
if (!Type.isString(a)) throw new Error('The value ' + a + ' in the ' + label + ' fields was not a string.');
|
19929
|
+
});
|
19831
19930
|
};
|
19832
19931
|
|
19833
|
-
|
19834
|
-
|
19835
|
-
fromTag: fromTag,
|
19836
|
-
fromText: fromText,
|
19837
|
-
fromDom: fromDom
|
19932
|
+
var invalidTypeMessage = function (incorrect, type) {
|
19933
|
+
throw new Error('All values need to be of type: ' + type + '. Keys (' + sort(incorrect).join(', ') + ') were not.');
|
19838
19934
|
};
|
19839
|
-
}
|
19840
|
-
);
|
19841
|
-
|
19842
|
-
define(
|
19843
|
-
'ephox.sugar.api.node.NodeTypes',
|
19844
19935
|
|
19845
|
-
|
19936
|
+
var checkDupes = function (everything) {
|
19937
|
+
var sorted = sort(everything);
|
19938
|
+
var dupe = Arr.find(sorted, function (s, i) {
|
19939
|
+
return i < sorted.length -1 && s === sorted[i + 1];
|
19940
|
+
});
|
19846
19941
|
|
19847
|
-
|
19942
|
+
dupe.each(function (d) {
|
19943
|
+
throw new Error('The field: ' + d + ' occurs more than once in the combined fields: [' + sorted.join(', ') + '].');
|
19944
|
+
});
|
19945
|
+
};
|
19848
19946
|
|
19849
|
-
function () {
|
19850
19947
|
return {
|
19851
|
-
|
19852
|
-
|
19853
|
-
|
19854
|
-
|
19855
|
-
|
19856
|
-
|
19857
|
-
ELEMENT: 1,
|
19858
|
-
TEXT: 3,
|
19859
|
-
PROCESSING_INSTRUCTION: 7,
|
19860
|
-
ENTITY_REFERENCE: 5,
|
19861
|
-
ENTITY: 6,
|
19862
|
-
NOTATION: 12
|
19948
|
+
sort: sort,
|
19949
|
+
reqMessage: reqMessage,
|
19950
|
+
unsuppMessage: unsuppMessage,
|
19951
|
+
validateStrArr: validateStrArr,
|
19952
|
+
invalidTypeMessage: invalidTypeMessage,
|
19953
|
+
checkDupes: checkDupes
|
19863
19954
|
};
|
19864
19955
|
}
|
19865
19956
|
);
|
19866
19957
|
define(
|
19867
|
-
'ephox.
|
19958
|
+
'ephox.katamari.data.MixedBag',
|
19868
19959
|
|
19869
19960
|
[
|
19870
19961
|
'ephox.katamari.api.Arr',
|
19962
|
+
'ephox.katamari.api.Fun',
|
19963
|
+
'ephox.katamari.api.Obj',
|
19871
19964
|
'ephox.katamari.api.Option',
|
19872
|
-
'ephox.
|
19873
|
-
'ephox.sugar.api.node.NodeTypes',
|
19965
|
+
'ephox.katamari.util.BagUtils',
|
19874
19966
|
'global!Error',
|
19875
|
-
'global!
|
19967
|
+
'global!Object'
|
19876
19968
|
],
|
19877
19969
|
|
19878
|
-
function (Arr,
|
19879
|
-
|
19880
|
-
|
19881
|
-
|
19882
|
-
|
19883
|
-
var STANDARD = 0;
|
19884
|
-
var MSSTANDARD = 1;
|
19885
|
-
var WEBKITSTANDARD = 2;
|
19886
|
-
var FIREFOXSTANDARD = 3;
|
19970
|
+
function (Arr, Fun, Obj, Option, BagUtils, Error, Object) {
|
19971
|
+
|
19972
|
+
return function (required, optional) {
|
19973
|
+
var everything = required.concat(optional);
|
19974
|
+
if (everything.length === 0) throw new Error('You must specify at least one required or optional field.');
|
19887
19975
|
|
19888
|
-
|
19889
|
-
|
19890
|
-
// As of Chrome 34 / Safari 7.1 / FireFox 34, everyone except IE has the unprefixed function.
|
19891
|
-
// Still check for the others, but do it last.
|
19892
|
-
return test.matches !== undefined ? STANDARD :
|
19893
|
-
test.msMatchesSelector !== undefined ? MSSTANDARD :
|
19894
|
-
test.webkitMatchesSelector !== undefined ? WEBKITSTANDARD :
|
19895
|
-
test.mozMatchesSelector !== undefined ? FIREFOXSTANDARD :
|
19896
|
-
-1;
|
19897
|
-
})();
|
19976
|
+
BagUtils.validateStrArr('required', required);
|
19977
|
+
BagUtils.validateStrArr('optional', optional);
|
19898
19978
|
|
19979
|
+
BagUtils.checkDupes(everything);
|
19899
19980
|
|
19900
|
-
|
19901
|
-
|
19981
|
+
return function (obj) {
|
19982
|
+
var keys = Obj.keys(obj);
|
19902
19983
|
|
19903
|
-
|
19904
|
-
|
19905
|
-
|
19984
|
+
// Ensure all required keys are present.
|
19985
|
+
var allReqd = Arr.forall(required, function (req) {
|
19986
|
+
return Arr.contains(keys, req);
|
19987
|
+
});
|
19906
19988
|
|
19907
|
-
|
19908
|
-
// Still check for the others, but do it last.
|
19909
|
-
else if (selectorType === STANDARD) return elem.matches(selector);
|
19910
|
-
else if (selectorType === MSSTANDARD) return elem.msMatchesSelector(selector);
|
19911
|
-
else if (selectorType === WEBKITSTANDARD) return elem.webkitMatchesSelector(selector);
|
19912
|
-
else if (selectorType === FIREFOXSTANDARD) return elem.mozMatchesSelector(selector);
|
19913
|
-
else throw new Error('Browser lacks native selectors'); // unfortunately we can't throw this on startup :(
|
19914
|
-
};
|
19989
|
+
if (! allReqd) BagUtils.reqMessage(required, keys);
|
19915
19990
|
|
19916
|
-
|
19917
|
-
|
19918
|
-
|
19919
|
-
// IE fix for complex queries on empty nodes: http://jsfiddle.net/spyder/fv9ptr5L/
|
19920
|
-
dom.childElementCount === 0;
|
19921
|
-
};
|
19991
|
+
var unsupported = Arr.filter(keys, function (key) {
|
19992
|
+
return !Arr.contains(everything, key);
|
19993
|
+
});
|
19922
19994
|
|
19923
|
-
|
19924
|
-
var base = scope === undefined ? document : scope.dom();
|
19925
|
-
return bypassSelector(base) ? [] : Arr.map(base.querySelectorAll(selector), Element.fromDom);
|
19926
|
-
};
|
19995
|
+
if (unsupported.length > 0) BagUtils.unsuppMessage(unsupported);
|
19927
19996
|
|
19928
|
-
|
19929
|
-
|
19930
|
-
|
19931
|
-
|
19997
|
+
var r = {};
|
19998
|
+
Arr.each(required, function (req) {
|
19999
|
+
r[req] = Fun.constant(obj[req]);
|
20000
|
+
});
|
19932
20001
|
|
19933
|
-
|
19934
|
-
|
19935
|
-
|
19936
|
-
|
20002
|
+
Arr.each(optional, function (opt) {
|
20003
|
+
r[opt] = Fun.constant(Object.prototype.hasOwnProperty.call(obj, opt) ? Option.some(obj[opt]): Option.none());
|
20004
|
+
});
|
20005
|
+
|
20006
|
+
return r;
|
20007
|
+
};
|
19937
20008
|
};
|
19938
20009
|
}
|
19939
20010
|
);
|
19940
|
-
|
19941
20011
|
define(
|
19942
|
-
'ephox.
|
20012
|
+
'ephox.katamari.api.Struct',
|
19943
20013
|
|
19944
20014
|
[
|
19945
|
-
'ephox.katamari.
|
19946
|
-
'ephox.katamari.
|
19947
|
-
'ephox.sand.api.Node',
|
19948
|
-
'ephox.sand.api.PlatformDetection',
|
19949
|
-
'ephox.sugar.api.search.Selectors'
|
20015
|
+
'ephox.katamari.data.Immutable',
|
20016
|
+
'ephox.katamari.data.MixedBag'
|
19950
20017
|
],
|
19951
20018
|
|
19952
|
-
function (
|
19953
|
-
|
19954
|
-
|
19955
|
-
|
20019
|
+
function (Immutable, MixedBag) {
|
20020
|
+
return {
|
20021
|
+
immutable: Immutable,
|
20022
|
+
immutableBag: MixedBag
|
19956
20023
|
};
|
20024
|
+
}
|
20025
|
+
);
|
19957
20026
|
|
19958
|
-
|
19959
|
-
|
19960
|
-
};
|
20027
|
+
define(
|
20028
|
+
'ephox.sugar.alien.Recurse',
|
19961
20029
|
|
19962
|
-
|
19963
|
-
return Arr.exists(elements, Fun.curry(eq, element));
|
19964
|
-
};
|
20030
|
+
[
|
19965
20031
|
|
19966
|
-
|
19967
|
-
var regularContains = function (e1, e2) {
|
19968
|
-
var d1 = e1.dom(), d2 = e2.dom();
|
19969
|
-
return d1 === d2 ? false : d1.contains(d2);
|
19970
|
-
};
|
20032
|
+
],
|
19971
20033
|
|
19972
|
-
|
19973
|
-
|
19974
|
-
|
19975
|
-
|
19976
|
-
|
19977
|
-
|
19978
|
-
|
19979
|
-
|
20034
|
+
function () {
|
20035
|
+
/**
|
20036
|
+
* Applies f repeatedly until it completes (by returning Option.none()).
|
20037
|
+
*
|
20038
|
+
* Normally would just use recursion, but JavaScript lacks tail call optimisation.
|
20039
|
+
*
|
20040
|
+
* This is what recursion looks like when manually unravelled :)
|
20041
|
+
*/
|
20042
|
+
var toArray = function (target, f) {
|
20043
|
+
var r = [];
|
19980
20044
|
|
19981
|
-
|
20045
|
+
var recurse = function (e) {
|
20046
|
+
r.push(e);
|
20047
|
+
return f(e);
|
20048
|
+
};
|
19982
20049
|
|
19983
|
-
|
19984
|
-
|
19985
|
-
|
20050
|
+
var cur = f(target);
|
20051
|
+
do {
|
20052
|
+
cur = cur.bind(recurse);
|
20053
|
+
} while (cur.isSome());
|
19986
20054
|
|
19987
|
-
|
19988
|
-
|
19989
|
-
isEqualNode: isEqualNode,
|
19990
|
-
member: member,
|
19991
|
-
contains: contains,
|
20055
|
+
return r;
|
20056
|
+
};
|
19992
20057
|
|
19993
|
-
|
19994
|
-
|
20058
|
+
return {
|
20059
|
+
toArray: toArray
|
19995
20060
|
};
|
19996
20061
|
}
|
19997
20062
|
);
|
19998
|
-
|
19999
20063
|
define(
|
20000
20064
|
'ephox.sugar.api.search.Traverse',
|
20001
20065
|
|
@@ -20891,6 +20955,8 @@ define(
|
|
20891
20955
|
define(
|
20892
20956
|
'tinymce.core.dom.Selection',
|
20893
20957
|
[
|
20958
|
+
'ephox.sugar.api.dom.Compare',
|
20959
|
+
'ephox.sugar.api.node.Element',
|
20894
20960
|
'tinymce.core.caret.CaretPosition',
|
20895
20961
|
'tinymce.core.dom.BookmarkManager',
|
20896
20962
|
'tinymce.core.dom.ControlSelection',
|
@@ -20904,18 +20970,24 @@ define(
|
|
20904
20970
|
'tinymce.core.text.Zwsp',
|
20905
20971
|
'tinymce.core.util.Tools'
|
20906
20972
|
],
|
20907
|
-
function (
|
20973
|
+
function (
|
20974
|
+
Compare, Element, CaretPosition, BookmarkManager, ControlSelection, NodeType, RangeUtils, ScrollIntoView, TreeWalker, TridentSelection, Env, FragmentReader,
|
20975
|
+
Zwsp, Tools
|
20976
|
+
) {
|
20908
20977
|
var each = Tools.each, trim = Tools.trim;
|
20909
20978
|
var isIE = Env.ie;
|
20910
20979
|
|
20980
|
+
var isAttachedToDom = function (node) {
|
20981
|
+
return !!(node && node.ownerDocument) && Compare.contains(Element.fromDom(node.ownerDocument), Element.fromDom(node));
|
20982
|
+
};
|
20983
|
+
|
20911
20984
|
var isValidRange = function (rng) {
|
20912
20985
|
if (!rng) {
|
20913
20986
|
return false;
|
20914
20987
|
} else if (rng.select) { // Native IE range still produced by placeCaretAt
|
20915
20988
|
return true;
|
20916
20989
|
} else {
|
20917
|
-
|
20918
|
-
return !!(sc && sc.parentNode && ec && ec.parentNode);
|
20990
|
+
return isAttachedToDom(rng.startContainer) && isAttachedToDom(rng.endContainer);
|
20919
20991
|
}
|
20920
20992
|
};
|
20921
20993
|
|
@@ -37950,20 +38022,20 @@ define(
|
|
37950
38022
|
*/
|
37951
38023
|
|
37952
38024
|
/**
|
37953
|
-
* Contains
|
38025
|
+
* Contains logic for handling keyboard shortcuts.
|
37954
38026
|
*
|
37955
38027
|
* @class tinymce.Shortcuts
|
37956
38028
|
* @example
|
37957
|
-
* editor.shortcuts.add('ctrl+a', function() {});
|
37958
|
-
* editor.shortcuts.add('meta+a', function() {}); // "meta" maps to Command on Mac and Ctrl on PC
|
37959
|
-
* editor.shortcuts.add('ctrl+alt+a', function() {});
|
37960
|
-
* editor.shortcuts.add('access+a', function() {}); // "access" maps to ctrl+alt on Mac and shift+alt on PC
|
38029
|
+
* editor.shortcuts.add('ctrl+a', "description of the shortcut", function() {});
|
38030
|
+
* editor.shortcuts.add('meta+a', "description of the shortcut", function() {}); // "meta" maps to Command on Mac and Ctrl on PC
|
38031
|
+
* editor.shortcuts.add('ctrl+alt+a', "description of the shortcut", function() {});
|
38032
|
+
* editor.shortcuts.add('access+a', "description of the shortcut", function() {}); // "access" maps to ctrl+alt on Mac and shift+alt on PC
|
37961
38033
|
*/
|
37962
38034
|
define(
|
37963
38035
|
'tinymce.core.Shortcuts',
|
37964
38036
|
[
|
37965
|
-
|
37966
|
-
|
38037
|
+
'tinymce.core.util.Tools',
|
38038
|
+
'tinymce.core.Env'
|
37967
38039
|
],
|
37968
38040
|
function (Tools, Env) {
|
37969
38041
|
var each = Tools.each, explode = Tools.explode;
|
@@ -38160,6 +38232,91 @@ define(
|
|
38160
38232
|
}
|
38161
38233
|
);
|
38162
38234
|
|
38235
|
+
/**
|
38236
|
+
* DefaultSettings.js
|
38237
|
+
*
|
38238
|
+
* Released under LGPL License.
|
38239
|
+
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
|
38240
|
+
*
|
38241
|
+
* License: http://www.tinymce.com/license
|
38242
|
+
* Contributing: http://www.tinymce.com/contributing
|
38243
|
+
*/
|
38244
|
+
|
38245
|
+
define(
|
38246
|
+
'tinymce.core.EditorSettings',
|
38247
|
+
[
|
38248
|
+
'tinymce.core.util.Tools'
|
38249
|
+
],
|
38250
|
+
function (Tools) {
|
38251
|
+
var getEditorSettings = function (editor, id, documentBaseUrl, defaultOverrideSettings, settings) {
|
38252
|
+
settings = Tools.extend(
|
38253
|
+
// Default settings
|
38254
|
+
{
|
38255
|
+
id: id,
|
38256
|
+
theme: 'modern',
|
38257
|
+
delta_width: 0,
|
38258
|
+
delta_height: 0,
|
38259
|
+
popup_css: '',
|
38260
|
+
plugins: '',
|
38261
|
+
document_base_url: documentBaseUrl,
|
38262
|
+
add_form_submit_trigger: true,
|
38263
|
+
submit_patch: true,
|
38264
|
+
add_unload_trigger: true,
|
38265
|
+
convert_urls: true,
|
38266
|
+
relative_urls: true,
|
38267
|
+
remove_script_host: true,
|
38268
|
+
object_resizing: true,
|
38269
|
+
doctype: '<!DOCTYPE html>',
|
38270
|
+
visual: true,
|
38271
|
+
font_size_style_values: 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
38272
|
+
|
38273
|
+
// See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
|
38274
|
+
font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
|
38275
|
+
forced_root_block: 'p',
|
38276
|
+
hidden_input: true,
|
38277
|
+
padd_empty_editor: true,
|
38278
|
+
render_ui: true,
|
38279
|
+
indentation: '30px',
|
38280
|
+
inline_styles: true,
|
38281
|
+
convert_fonts_to_spans: true,
|
38282
|
+
indent: 'simple',
|
38283
|
+
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,' +
|
38284
|
+
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
38285
|
+
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,' +
|
38286
|
+
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
38287
|
+
entity_encoding: 'named',
|
38288
|
+
url_converter: editor.convertURL,
|
38289
|
+
url_converter_scope: editor,
|
38290
|
+
ie7_compat: true
|
38291
|
+
},
|
38292
|
+
|
38293
|
+
// tinymce.overrideDefaults settings
|
38294
|
+
defaultOverrideSettings,
|
38295
|
+
|
38296
|
+
// User settings
|
38297
|
+
settings,
|
38298
|
+
|
38299
|
+
// Forced settings
|
38300
|
+
{
|
38301
|
+
validate: true,
|
38302
|
+
content_editable: settings.inline
|
38303
|
+
}
|
38304
|
+
);
|
38305
|
+
|
38306
|
+
// Merge external_plugins
|
38307
|
+
if (defaultOverrideSettings && defaultOverrideSettings.external_plugins && settings.external_plugins) {
|
38308
|
+
settings.external_plugins = Tools.extend({}, defaultOverrideSettings.external_plugins, settings.external_plugins);
|
38309
|
+
}
|
38310
|
+
|
38311
|
+
return settings;
|
38312
|
+
};
|
38313
|
+
|
38314
|
+
return {
|
38315
|
+
getEditorSettings: getEditorSettings
|
38316
|
+
};
|
38317
|
+
}
|
38318
|
+
);
|
38319
|
+
|
38163
38320
|
defineGlobal("global!window", window);
|
38164
38321
|
/**
|
38165
38322
|
* ErrorReporter.js
|
@@ -42053,6 +42210,280 @@ define(
|
|
42053
42210
|
}
|
42054
42211
|
);
|
42055
42212
|
|
42213
|
+
define(
|
42214
|
+
'ephox.sugar.impl.Style',
|
42215
|
+
|
42216
|
+
[
|
42217
|
+
|
42218
|
+
],
|
42219
|
+
|
42220
|
+
function () {
|
42221
|
+
// some elements, such as mathml, don't have style attributes
|
42222
|
+
var isSupported = function (dom) {
|
42223
|
+
return dom.style !== undefined;
|
42224
|
+
};
|
42225
|
+
|
42226
|
+
return {
|
42227
|
+
isSupported: isSupported
|
42228
|
+
};
|
42229
|
+
}
|
42230
|
+
);
|
42231
|
+
define(
|
42232
|
+
'ephox.sugar.api.properties.Css',
|
42233
|
+
|
42234
|
+
[
|
42235
|
+
'ephox.katamari.api.Type',
|
42236
|
+
'ephox.katamari.api.Arr',
|
42237
|
+
'ephox.katamari.api.Obj',
|
42238
|
+
'ephox.katamari.api.Option',
|
42239
|
+
'ephox.sugar.api.properties.Attr',
|
42240
|
+
'ephox.sugar.api.node.Body',
|
42241
|
+
'ephox.sugar.api.node.Element',
|
42242
|
+
'ephox.sugar.api.node.Node',
|
42243
|
+
'ephox.sugar.impl.Style',
|
42244
|
+
'ephox.katamari.api.Strings',
|
42245
|
+
'global!Error',
|
42246
|
+
'global!console',
|
42247
|
+
'global!window'
|
42248
|
+
],
|
42249
|
+
|
42250
|
+
function (Type, Arr, Obj, Option, Attr, Body, Element, Node, Style, Strings, Error, console, window) {
|
42251
|
+
var internalSet = function (dom, property, value) {
|
42252
|
+
// This is going to hurt. Apologies.
|
42253
|
+
// JQuery coerces numbers to pixels for certain property names, and other times lets numbers through.
|
42254
|
+
// we're going to be explicit; strings only.
|
42255
|
+
if (!Type.isString(value)) {
|
42256
|
+
console.error('Invalid call to CSS.set. Property ', property, ':: Value ', value, ':: Element ', dom);
|
42257
|
+
throw new Error('CSS value must be a string: ' + value);
|
42258
|
+
}
|
42259
|
+
|
42260
|
+
// removed: support for dom().style[property] where prop is camel case instead of normal property name
|
42261
|
+
if (Style.isSupported(dom)) dom.style.setProperty(property, value);
|
42262
|
+
};
|
42263
|
+
|
42264
|
+
var internalRemove = function (dom, property) {
|
42265
|
+
/*
|
42266
|
+
* IE9 and above - MDN doesn't have details, but here's a couple of random internet claims
|
42267
|
+
*
|
42268
|
+
* http://help.dottoro.com/ljopsjck.php
|
42269
|
+
* http://stackoverflow.com/a/7901886/7546
|
42270
|
+
*/
|
42271
|
+
if (Style.isSupported(dom)) dom.style.removeProperty(property);
|
42272
|
+
};
|
42273
|
+
|
42274
|
+
var set = function (element, property, value) {
|
42275
|
+
var dom = element.dom();
|
42276
|
+
internalSet(dom, property, value);
|
42277
|
+
};
|
42278
|
+
|
42279
|
+
var setAll = function (element, css) {
|
42280
|
+
var dom = element.dom();
|
42281
|
+
|
42282
|
+
Obj.each(css, function (v, k) {
|
42283
|
+
internalSet(dom, k, v);
|
42284
|
+
});
|
42285
|
+
};
|
42286
|
+
|
42287
|
+
var setOptions = function(element, css) {
|
42288
|
+
var dom = element.dom();
|
42289
|
+
|
42290
|
+
Obj.each(css, function (v, k) {
|
42291
|
+
v.fold(function () {
|
42292
|
+
internalRemove(dom, k);
|
42293
|
+
}, function (value) {
|
42294
|
+
internalSet(dom, k, value);
|
42295
|
+
});
|
42296
|
+
});
|
42297
|
+
};
|
42298
|
+
|
42299
|
+
/*
|
42300
|
+
* NOTE: For certain properties, this returns the "used value" which is subtly different to the "computed value" (despite calling getComputedStyle).
|
42301
|
+
* Blame CSS 2.0.
|
42302
|
+
*
|
42303
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
|
42304
|
+
*/
|
42305
|
+
var get = function (element, property) {
|
42306
|
+
var dom = element.dom();
|
42307
|
+
/*
|
42308
|
+
* IE9 and above per
|
42309
|
+
* https://developer.mozilla.org/en/docs/Web/API/window.getComputedStyle
|
42310
|
+
*
|
42311
|
+
* Not in numerosity, because it doesn't memoize and looking this up dynamically in performance critical code would be horrendous.
|
42312
|
+
*
|
42313
|
+
* JQuery has some magic here for IE popups, but we don't really need that.
|
42314
|
+
* It also uses element.ownerDocument.defaultView to handle iframes but that hasn't been required since FF 3.6.
|
42315
|
+
*/
|
42316
|
+
var styles = window.getComputedStyle(dom);
|
42317
|
+
var r = styles.getPropertyValue(property);
|
42318
|
+
|
42319
|
+
// 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.
|
42320
|
+
// Turns out we do this a lot.
|
42321
|
+
var v = (r === '' && !Body.inBody(element)) ? getUnsafeProperty(dom, property) : r;
|
42322
|
+
|
42323
|
+
// undefined is the more appropriate value for JS. JQuery coerces to an empty string, but screw that!
|
42324
|
+
return v === null ? undefined : v;
|
42325
|
+
};
|
42326
|
+
|
42327
|
+
var getUnsafeProperty = function (dom, property) {
|
42328
|
+
// removed: support for dom().style[property] where prop is camel case instead of normal property name
|
42329
|
+
// empty string is what the browsers (IE11 and Chrome) return when the propertyValue doesn't exists.
|
42330
|
+
return Style.isSupported(dom) ? dom.style.getPropertyValue(property) : '';
|
42331
|
+
};
|
42332
|
+
|
42333
|
+
/*
|
42334
|
+
* Gets the raw value from the style attribute. Useful for retrieving "used values" from the DOM:
|
42335
|
+
* https://developer.mozilla.org/en-US/docs/Web/CSS/used_value
|
42336
|
+
*
|
42337
|
+
* Returns NONE if the property isn't set, or the value is an empty string.
|
42338
|
+
*/
|
42339
|
+
var getRaw = function (element, property) {
|
42340
|
+
var dom = element.dom();
|
42341
|
+
var raw = getUnsafeProperty(dom, property);
|
42342
|
+
|
42343
|
+
return Option.from(raw).filter(function (r) { return r.length > 0; });
|
42344
|
+
};
|
42345
|
+
|
42346
|
+
var isValidValue = function (tag, property, value) {
|
42347
|
+
var element = Element.fromTag(tag);
|
42348
|
+
set(element, property, value);
|
42349
|
+
var style = getRaw(element, property);
|
42350
|
+
return style.isSome();
|
42351
|
+
};
|
42352
|
+
|
42353
|
+
var remove = function (element, property) {
|
42354
|
+
var dom = element.dom();
|
42355
|
+
|
42356
|
+
internalRemove(dom, property);
|
42357
|
+
|
42358
|
+
if (Attr.has(element, 'style') && Strings.trim(Attr.get(element, 'style')) === '') {
|
42359
|
+
// No more styles left, remove the style attribute as well
|
42360
|
+
Attr.remove(element, 'style');
|
42361
|
+
}
|
42362
|
+
};
|
42363
|
+
|
42364
|
+
var preserve = function (element, f) {
|
42365
|
+
var oldStyles = Attr.get(element, 'style');
|
42366
|
+
var result = f(element);
|
42367
|
+
var restore = oldStyles === undefined ? Attr.remove : Attr.set;
|
42368
|
+
restore(element, 'style', oldStyles);
|
42369
|
+
return result;
|
42370
|
+
};
|
42371
|
+
|
42372
|
+
var copy = function (source, target) {
|
42373
|
+
var sourceDom = source.dom();
|
42374
|
+
var targetDom = target.dom();
|
42375
|
+
if (Style.isSupported(sourceDom) && Style.isSupported(targetDom)) {
|
42376
|
+
targetDom.style.cssText = sourceDom.style.cssText;
|
42377
|
+
}
|
42378
|
+
};
|
42379
|
+
|
42380
|
+
var reflow = function (e) {
|
42381
|
+
/* NOTE:
|
42382
|
+
* do not rely on this return value.
|
42383
|
+
* It's here so the closure compiler doesn't optimise the property access away.
|
42384
|
+
*/
|
42385
|
+
return e.dom().offsetWidth;
|
42386
|
+
};
|
42387
|
+
|
42388
|
+
var transferOne = function (source, destination, style) {
|
42389
|
+
getRaw(source, style).each(function (value) {
|
42390
|
+
// NOTE: We don't want to clobber any existing inline styles.
|
42391
|
+
if (getRaw(destination, style).isNone()) set(destination, style, value);
|
42392
|
+
});
|
42393
|
+
};
|
42394
|
+
|
42395
|
+
var transfer = function (source, destination, styles) {
|
42396
|
+
if (!Node.isElement(source) || !Node.isElement(destination)) return;
|
42397
|
+
Arr.each(styles, function (style) {
|
42398
|
+
transferOne(source, destination, style);
|
42399
|
+
});
|
42400
|
+
};
|
42401
|
+
|
42402
|
+
return {
|
42403
|
+
copy: copy,
|
42404
|
+
set: set,
|
42405
|
+
preserve: preserve,
|
42406
|
+
setAll: setAll,
|
42407
|
+
setOptions: setOptions,
|
42408
|
+
remove: remove,
|
42409
|
+
get: get,
|
42410
|
+
getRaw: getRaw,
|
42411
|
+
isValidValue: isValidValue,
|
42412
|
+
reflow: reflow,
|
42413
|
+
transfer: transfer
|
42414
|
+
};
|
42415
|
+
}
|
42416
|
+
);
|
42417
|
+
|
42418
|
+
/**
|
42419
|
+
* EditorView.js
|
42420
|
+
*
|
42421
|
+
* Released under LGPL License.
|
42422
|
+
* Copyright (c) 1999-2016 Ephox Corp. All rights reserved
|
42423
|
+
*
|
42424
|
+
* License: http://www.tinymce.com/license
|
42425
|
+
* Contributing: http://www.tinymce.com/contributing
|
42426
|
+
*/
|
42427
|
+
|
42428
|
+
define(
|
42429
|
+
'tinymce.core.EditorView',
|
42430
|
+
[
|
42431
|
+
'ephox.katamari.api.Fun',
|
42432
|
+
'ephox.sugar.api.node.Element',
|
42433
|
+
'ephox.sugar.api.properties.Css',
|
42434
|
+
'ephox.sugar.api.search.Traverse'
|
42435
|
+
],
|
42436
|
+
function (Fun, Element, Css, Traverse) {
|
42437
|
+
var getProp = function (propName, elm) {
|
42438
|
+
var rawElm = elm.dom();
|
42439
|
+
return rawElm[propName];
|
42440
|
+
};
|
42441
|
+
|
42442
|
+
var getComputedSizeProp = function (propName, elm) {
|
42443
|
+
return parseInt(Css.get(elm, propName), 10);
|
42444
|
+
};
|
42445
|
+
|
42446
|
+
var getClientWidth = Fun.curry(getProp, 'clientWidth');
|
42447
|
+
var getClientHeight = Fun.curry(getProp, 'clientHeight');
|
42448
|
+
var getMarginTop = Fun.curry(getComputedSizeProp, 'margin-top');
|
42449
|
+
var getMarginLeft = Fun.curry(getComputedSizeProp, 'margin-left');
|
42450
|
+
|
42451
|
+
var getBoundingClientRect = function (elm) {
|
42452
|
+
return elm.dom().getBoundingClientRect();
|
42453
|
+
};
|
42454
|
+
|
42455
|
+
var isInsideElementContentArea = function (bodyElm, clientX, clientY) {
|
42456
|
+
var clientWidth = getClientWidth(bodyElm);
|
42457
|
+
var clientHeight = getClientHeight(bodyElm);
|
42458
|
+
|
42459
|
+
return clientX >= 0 && clientY >= 0 && clientX <= clientWidth && clientY <= clientHeight;
|
42460
|
+
};
|
42461
|
+
|
42462
|
+
var transpose = function (inline, elm, clientX, clientY) {
|
42463
|
+
var clientRect = getBoundingClientRect(elm);
|
42464
|
+
var deltaX = inline ? clientRect.left + elm.dom().clientLeft + getMarginLeft(elm) : 0;
|
42465
|
+
var deltaY = inline ? clientRect.top + elm.dom().clientTop + getMarginTop(elm) : 0;
|
42466
|
+
var x = clientX - deltaX;
|
42467
|
+
var y = clientY - deltaY;
|
42468
|
+
|
42469
|
+
return { x: x, y: y };
|
42470
|
+
};
|
42471
|
+
|
42472
|
+
// Checks if the specified coordinate is within the visual content area excluding the scrollbars
|
42473
|
+
var isXYInContentArea = function (editor, clientX, clientY) {
|
42474
|
+
var bodyElm = Element.fromDom(editor.getBody());
|
42475
|
+
var targetElm = editor.inline ? bodyElm : Traverse.documentElement(bodyElm);
|
42476
|
+
var transposedPoint = transpose(editor.inline, targetElm, clientX, clientY);
|
42477
|
+
|
42478
|
+
return isInsideElementContentArea(targetElm, transposedPoint.x, transposedPoint.y);
|
42479
|
+
};
|
42480
|
+
|
42481
|
+
return {
|
42482
|
+
isXYInContentArea: isXYInContentArea
|
42483
|
+
};
|
42484
|
+
}
|
42485
|
+
);
|
42486
|
+
|
42056
42487
|
/**
|
42057
42488
|
* SelectionOverrides.js
|
42058
42489
|
*
|
@@ -42086,16 +42517,18 @@ define(
|
|
42086
42517
|
'tinymce.core.caret.FakeCaret',
|
42087
42518
|
'tinymce.core.caret.LineUtils',
|
42088
42519
|
'tinymce.core.dom.NodeType',
|
42520
|
+
'tinymce.core.dom.RangePoint',
|
42089
42521
|
'tinymce.core.DragDropOverrides',
|
42522
|
+
'tinymce.core.EditorView',
|
42090
42523
|
'tinymce.core.Env',
|
42091
|
-
'tinymce.core.geom.ClientRect',
|
42092
42524
|
'tinymce.core.keyboard.CefUtils',
|
42093
|
-
'tinymce.core.util.Arr',
|
42094
42525
|
'tinymce.core.util.Delay',
|
42095
|
-
'tinymce.core.util.Fun',
|
42096
42526
|
'tinymce.core.util.VK'
|
42097
42527
|
],
|
42098
|
-
function (
|
42528
|
+
function (
|
42529
|
+
CaretContainer, CaretPosition, CaretUtils, CaretWalker, FakeCaret, LineUtils, NodeType, RangePoint, DragDropOverrides, EditorView, Env, CefUtils, Delay,
|
42530
|
+
VK
|
42531
|
+
) {
|
42099
42532
|
var isContentEditableTrue = NodeType.isContentEditableTrue,
|
42100
42533
|
isContentEditableFalse = NodeType.isContentEditableFalse,
|
42101
42534
|
isAfterContentEditableFalse = CaretUtils.isAfterContentEditableFalse,
|
@@ -42186,22 +42619,12 @@ define(
|
|
42186
42619
|
return null;
|
42187
42620
|
}
|
42188
42621
|
|
42189
|
-
function isXYWithinRange(clientX, clientY, range) {
|
42190
|
-
if (range.collapsed) {
|
42191
|
-
return false;
|
42192
|
-
}
|
42193
|
-
|
42194
|
-
return Arr.reduce(range.getClientRects(), function (state, rect) {
|
42195
|
-
return state || ClientRect.containsXY(rect, clientX, clientY);
|
42196
|
-
}, false);
|
42197
|
-
}
|
42198
|
-
|
42199
42622
|
// Some browsers (Chrome) lets you place the caret after a cE=false
|
42200
42623
|
// Make sure we render the caret container in this case
|
42201
|
-
editor.on('mouseup', function () {
|
42624
|
+
editor.on('mouseup', function (e) {
|
42202
42625
|
var range = getRange();
|
42203
42626
|
|
42204
|
-
if (range.collapsed) {
|
42627
|
+
if (range.collapsed && EditorView.isXYInContentArea(editor, e.clientX, e.clientY)) {
|
42205
42628
|
setRange(CefUtils.renderCaretAtRange(editor, range));
|
42206
42629
|
}
|
42207
42630
|
});
|
@@ -42288,6 +42711,10 @@ define(
|
|
42288
42711
|
editor.on('mousedown', function (e) {
|
42289
42712
|
var contentEditableRoot;
|
42290
42713
|
|
42714
|
+
if (EditorView.isXYInContentArea(editor, e.clientX, e.clientY) === false) {
|
42715
|
+
return;
|
42716
|
+
}
|
42717
|
+
|
42291
42718
|
contentEditableRoot = getContentEditableRoot(e.target);
|
42292
42719
|
if (contentEditableRoot) {
|
42293
42720
|
if (isContentEditableFalse(contentEditableRoot)) {
|
@@ -42297,7 +42724,7 @@ define(
|
|
42297
42724
|
removeContentEditableSelection();
|
42298
42725
|
|
42299
42726
|
// Check that we're not attempting a shift + click select within a contenteditable='true' element
|
42300
|
-
if (!(isContentEditableTrue(contentEditableRoot) && e.shiftKey) && !isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) {
|
42727
|
+
if (!(isContentEditableTrue(contentEditableRoot) && e.shiftKey) && !RangePoint.isXYWithinRange(e.clientX, e.clientY, editor.selection.getRng())) {
|
42301
42728
|
editor.selection.placeCaretAt(e.clientX, e.clientY);
|
42302
42729
|
}
|
42303
42730
|
}
|
@@ -43935,6 +44362,10 @@ define(
|
|
43935
44362
|
autoFocus(editor);
|
43936
44363
|
};
|
43937
44364
|
|
44365
|
+
var getStyleSheetLoader = function (editor) {
|
44366
|
+
return editor.inline ? DOM.styleSheetLoader : editor.dom.styleSheetLoader;
|
44367
|
+
};
|
44368
|
+
|
43938
44369
|
var initContentBody = function (editor, skipWrite) {
|
43939
44370
|
var settings = editor.settings, targetElm = editor.getElement(), doc = editor.getDoc(), body, contentCssText;
|
43940
44371
|
|
@@ -44072,7 +44503,7 @@ define(
|
|
44072
44503
|
editor.dom.addStyle(contentCssText);
|
44073
44504
|
}
|
44074
44505
|
|
44075
|
-
editor.
|
44506
|
+
getStyleSheetLoader(editor).loadAll(
|
44076
44507
|
editor.contentCSS,
|
44077
44508
|
function (_) {
|
44078
44509
|
initEditor(editor);
|
@@ -44793,6 +45224,7 @@ define(
|
|
44793
45224
|
'tinymce.core.dom.DOMUtils',
|
44794
45225
|
'tinymce.core.EditorCommands',
|
44795
45226
|
'tinymce.core.EditorObservable',
|
45227
|
+
'tinymce.core.EditorSettings',
|
44796
45228
|
'tinymce.core.Env',
|
44797
45229
|
'tinymce.core.html.Serializer',
|
44798
45230
|
'tinymce.core.init.Render',
|
@@ -44803,10 +45235,7 @@ define(
|
|
44803
45235
|
'tinymce.core.util.URI',
|
44804
45236
|
'tinymce.core.util.Uuid'
|
44805
45237
|
],
|
44806
|
-
function (
|
44807
|
-
AddOnManager, DomQuery, DOMUtils, EditorCommands, EditorObservable, Env, Serializer, Render, Mode,
|
44808
|
-
Shortcuts, Sidebar, Tools, URI, Uuid
|
44809
|
-
) {
|
45238
|
+
function (AddOnManager, DomQuery, DOMUtils, EditorCommands, EditorObservable, EditorSettings, Env, Serializer, Render, Mode, Shortcuts, Sidebar, Tools, URI, Uuid) {
|
44810
45239
|
// Shorten these names
|
44811
45240
|
var DOM = DOMUtils.DOM;
|
44812
45241
|
var extend = Tools.extend, each = Tools.each;
|
@@ -44829,11 +45258,10 @@ define(
|
|
44829
45258
|
* @param {tinymce.EditorManager} editorManager EditorManager instance.
|
44830
45259
|
*/
|
44831
45260
|
function Editor(id, settings, editorManager) {
|
44832
|
-
var self = this, documentBaseUrl, baseUri
|
45261
|
+
var self = this, documentBaseUrl, baseUri;
|
44833
45262
|
|
44834
45263
|
documentBaseUrl = self.documentBaseUrl = editorManager.documentBaseURL;
|
44835
45264
|
baseUri = editorManager.baseURI;
|
44836
|
-
defaultSettings = editorManager.defaultSettings;
|
44837
45265
|
|
44838
45266
|
/**
|
44839
45267
|
* Name/value collection with editor settings.
|
@@ -44844,52 +45272,9 @@ define(
|
|
44844
45272
|
* // Get the value of the theme setting
|
44845
45273
|
* tinymce.activeEditor.windowManager.alert("You are using the " + tinymce.activeEditor.settings.theme + " theme");
|
44846
45274
|
*/
|
44847
|
-
settings =
|
44848
|
-
id: id,
|
44849
|
-
theme: 'modern',
|
44850
|
-
delta_width: 0,
|
44851
|
-
delta_height: 0,
|
44852
|
-
popup_css: '',
|
44853
|
-
plugins: '',
|
44854
|
-
document_base_url: documentBaseUrl,
|
44855
|
-
add_form_submit_trigger: true,
|
44856
|
-
submit_patch: true,
|
44857
|
-
add_unload_trigger: true,
|
44858
|
-
convert_urls: true,
|
44859
|
-
relative_urls: true,
|
44860
|
-
remove_script_host: true,
|
44861
|
-
object_resizing: true,
|
44862
|
-
doctype: '<!DOCTYPE html>',
|
44863
|
-
visual: true,
|
44864
|
-
font_size_style_values: 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
44865
|
-
|
44866
|
-
// See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
|
44867
|
-
font_size_legacy_values: 'xx-small,small,medium,large,x-large,xx-large,300%',
|
44868
|
-
forced_root_block: 'p',
|
44869
|
-
hidden_input: true,
|
44870
|
-
padd_empty_editor: true,
|
44871
|
-
render_ui: true,
|
44872
|
-
indentation: '30px',
|
44873
|
-
inline_styles: true,
|
44874
|
-
convert_fonts_to_spans: true,
|
44875
|
-
indent: 'simple',
|
44876
|
-
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,' +
|
44877
|
-
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
44878
|
-
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,' +
|
44879
|
-
'tfoot,tbody,tr,section,article,hgroup,aside,figure,figcaption,option,optgroup,datalist',
|
44880
|
-
validate: true,
|
44881
|
-
entity_encoding: 'named',
|
44882
|
-
url_converter: self.convertURL,
|
44883
|
-
url_converter_scope: self,
|
44884
|
-
ie7_compat: true
|
44885
|
-
}, defaultSettings, settings);
|
44886
|
-
|
44887
|
-
// Merge external_plugins
|
44888
|
-
if (defaultSettings && defaultSettings.external_plugins && settings.external_plugins) {
|
44889
|
-
settings.external_plugins = extend({}, defaultSettings.external_plugins, settings.external_plugins);
|
44890
|
-
}
|
44891
|
-
|
45275
|
+
settings = EditorSettings.getEditorSettings(self, id, documentBaseUrl, editorManager.defaultSettings, settings);
|
44892
45276
|
self.settings = settings;
|
45277
|
+
|
44893
45278
|
AddOnManager.language = settings.language || 'en';
|
44894
45279
|
AddOnManager.languageLoad = settings.language_load;
|
44895
45280
|
AddOnManager.baseURL = editorManager.baseURL;
|
@@ -44900,7 +45285,7 @@ define(
|
|
44900
45285
|
* @property id
|
44901
45286
|
* @type String
|
44902
45287
|
*/
|
44903
|
-
self.id =
|
45288
|
+
self.id = id;
|
44904
45289
|
|
44905
45290
|
/**
|
44906
45291
|
* State to force the editor to return false on a isDirty call.
|
@@ -44934,7 +45319,7 @@ define(
|
|
44934
45319
|
* // Get absolute URL from the location of document_base_url
|
44935
45320
|
* tinymce.activeEditor.documentBaseURI.toAbsolute('somefile.htm');
|
44936
45321
|
*/
|
44937
|
-
self.documentBaseURI = new URI(settings.document_base_url
|
45322
|
+
self.documentBaseURI = new URI(settings.document_base_url, {
|
44938
45323
|
base_uri: baseUri
|
44939
45324
|
});
|
44940
45325
|
|
@@ -44975,7 +45360,6 @@ define(
|
|
44975
45360
|
self.suffix = editorManager.suffix;
|
44976
45361
|
self.editorManager = editorManager;
|
44977
45362
|
self.inline = settings.inline;
|
44978
|
-
self.settings.content_editable = self.inline;
|
44979
45363
|
|
44980
45364
|
if (settings.cache_suffix) {
|
44981
45365
|
Env.cacheSuffix = settings.cache_suffix.replace(/^[\?\&]+/, '');
|
@@ -45077,6 +45461,9 @@ define(
|
|
45077
45461
|
body.focus();
|
45078
45462
|
}
|
45079
45463
|
} else {
|
45464
|
+
// Restore previous selection before focus to prevent Chrome from
|
45465
|
+
// jumping to the top of the document in long inline editors
|
45466
|
+
self.selection.setRng(self.lastRng);
|
45080
45467
|
body.focus();
|
45081
45468
|
}
|
45082
45469
|
|
@@ -45139,16 +45526,14 @@ define(
|
|
45139
45526
|
* @return {String} Translated string.
|
45140
45527
|
*/
|
45141
45528
|
translate: function (text) {
|
45142
|
-
|
45529
|
+
if (text && Tools.is(text, 'string')) {
|
45530
|
+
var lang = this.settings.language || 'en', i18n = this.editorManager.i18n;
|
45143
45531
|
|
45144
|
-
|
45145
|
-
|
45532
|
+
text = i18n.data[lang + '.' + text] || text.replace(/\{\#([^\}]+)\}/g, function (a, b) {
|
45533
|
+
return i18n.data[lang + '.' + b] || '{#' + b + '}';
|
45534
|
+
});
|
45146
45535
|
}
|
45147
45536
|
|
45148
|
-
text = i18n.data[lang + '.' + text] || text.replace(/\{\#([^\}]+)\}/g, function (a, b) {
|
45149
|
-
return i18n.data[lang + '.' + b] || '{#' + b + '}';
|
45150
|
-
});
|
45151
|
-
|
45152
45537
|
return this.editorManager.translate(text);
|
45153
45538
|
},
|
45154
45539
|
|
@@ -46838,7 +47223,7 @@ define(
|
|
46838
47223
|
* @property minorVersion
|
46839
47224
|
* @type String
|
46840
47225
|
*/
|
46841
|
-
minorVersion: '6.
|
47226
|
+
minorVersion: '6.4',
|
46842
47227
|
|
46843
47228
|
/**
|
46844
47229
|
* Release date of TinyMCE build.
|
@@ -46846,7 +47231,7 @@ define(
|
|
46846
47231
|
* @property releaseDate
|
46847
47232
|
* @type String
|
46848
47233
|
*/
|
46849
|
-
releaseDate: '2017-
|
47234
|
+
releaseDate: '2017-06-13',
|
46850
47235
|
|
46851
47236
|
/**
|
46852
47237
|
* Collection of editor instances.
|
@@ -49652,7 +50037,12 @@ define(
|
|
49652
50037
|
self.panel.show();
|
49653
50038
|
}
|
49654
50039
|
|
49655
|
-
self.panel.
|
50040
|
+
var rel = self.panel.testMoveRel(self.getEl(), settings.popoverAlign || (self.isRtl() ? ['bc-tc', 'bc-tl', 'bc-tr'] : ['bc-tc', 'bc-tr', 'bc-tl']));
|
50041
|
+
|
50042
|
+
self.panel.classes.toggle('start', rel === 'bc-tl');
|
50043
|
+
self.panel.classes.toggle('end', rel === 'bc-tr');
|
50044
|
+
|
50045
|
+
self.panel.moveRel(self.getEl(), rel);
|
49656
50046
|
},
|
49657
50047
|
|
49658
50048
|
/**
|
@@ -51525,7 +51915,7 @@ define(
|
|
51525
51915
|
return fontFamily ? fontFamily.split(',')[0] : '';
|
51526
51916
|
};
|
51527
51917
|
|
51528
|
-
editor.on('nodeChange', function (e) {
|
51918
|
+
editor.on('init nodeChange', function (e) {
|
51529
51919
|
var fontFamily, value = null;
|
51530
51920
|
|
51531
51921
|
fontFamily = FontInfo.getFontFamily(editor.getBody(), e.element);
|
@@ -51555,7 +51945,7 @@ define(
|
|
51555
51945
|
return function () {
|
51556
51946
|
var self = this;
|
51557
51947
|
|
51558
|
-
editor.on('nodeChange', function (e) {
|
51948
|
+
editor.on('init nodeChange', function (e) {
|
51559
51949
|
var px, pt, value = null;
|
51560
51950
|
|
51561
51951
|
px = FontInfo.getFontSize(editor.getBody(), e.element);
|