tinymce-rails 4.6.3 → 4.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/source/tinymce/tinymce.js +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);
|