spiderfw 0.6.38 → 0.6.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +13 -5
- data/CHANGELOG +23 -0
- data/VERSION +1 -1
- data/apps/core/admin/views/admin.layout.shtml +6 -0
- data/apps/core/auth/controllers/login_controller.rb +1 -1
- data/apps/core/components/assets.rb +55 -6
- data/apps/core/components/public/bootstrap/scss/_variables.scss +5 -2
- data/apps/core/components/public/bootstrap/scss/bootstrap.css +942 -236
- data/apps/core/components/public/bootstrap/scss/responsive.css +187 -30
- data/apps/core/components/public/css/tinymce/skins/lightgray/AbsoluteLayout.less +17 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Animations.less +10 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Button.less +172 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ButtonGroup.less +71 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Checkbox.less +49 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ColorBox.less +6 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ColorButton.less +72 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ColorPicker.less +80 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ComboBox.less +39 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Container.less +9 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Content.Inline.less +4 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Content.Objects.less +166 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Content.less +27 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/CropRect.less +54 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/FieldSet.less +15 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/FitLayout.less +9 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/FloatPanel.less +69 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/FlowLayout.less +36 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Icons.Ie7.less +136 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Icons.less +180 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Iframe.less +6 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ImagePanel.less +20 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/InfoBox.less +71 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Label.less +38 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ListBox.less +26 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Menu.less +34 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/MenuBar.less +32 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/MenuButton.less +34 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/MenuItem.less +142 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Mixins.less +54 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Notification.less +144 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Panel.less +7 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Path.less +45 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Progress.less +34 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Radio.less +1 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Reset.less +32 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ResizeHandle.less +18 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Scrollable.less +44 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/SelectBox.less +6 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Slider.less +29 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Spacer.less +5 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/SplitButton.less +49 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/StackLayout.less +5 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/TabPanel.less +44 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/TextBox.less +41 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Throbber.less +19 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/TinyMCE.less +159 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/ToolTip.less +129 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Variables.less +214 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/Window.less +127 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/content.inline.min.css +1 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/content.min.css +1 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/readme.md +1 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.eot +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.json +1277 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.svg +63 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.ttf +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.json +3381 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.svg +129 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/img/anchor.gif +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/img/loader.gif +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/img/object.gif +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/img/trans.gif +0 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/skin.dev.less +46 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/skin.ie7.dev.less +46 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/skin.ie7.less +2542 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/skin.ie7.min.css +1 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/skin.less +2586 -0
- data/apps/core/components/public/css/tinymce/skins/lightgray/skin.min.css +1 -0
- data/apps/core/components/public/js/bootbox_2/bootbox.js +551 -0
- data/apps/core/components/public/js/jquery/jquery-ui-1.9.2/ui/i18n/jquery.ui.datepicker-it-min.js +4 -0
- data/apps/core/components/public/js/spider.js +7 -3
- data/apps/core/components/public/js/tinymce/classes/AddOnManager.js +265 -0
- data/apps/core/components/public/js/tinymce/classes/Compat.js +90 -0
- data/apps/core/components/public/js/tinymce/classes/DragDropOverrides.js +224 -0
- data/apps/core/components/public/js/tinymce/classes/Editor.js +2221 -0
- data/apps/core/components/public/js/tinymce/classes/EditorCommands.js +1028 -0
- data/apps/core/components/public/js/tinymce/classes/EditorManager.js +715 -0
- data/apps/core/components/public/js/tinymce/classes/EditorObservable.js +204 -0
- data/apps/core/components/public/js/tinymce/classes/EditorUpload.js +191 -0
- data/apps/core/components/public/js/tinymce/classes/EnterKey.js +676 -0
- data/apps/core/components/public/js/tinymce/classes/Env.js +177 -0
- data/apps/core/components/public/js/tinymce/classes/FocusManager.js +266 -0
- data/apps/core/components/public/js/tinymce/classes/ForceBlocks.js +138 -0
- data/apps/core/components/public/js/tinymce/classes/Formatter.js +2378 -0
- data/apps/core/components/public/js/tinymce/classes/LegacyInput.js +82 -0
- data/apps/core/components/public/js/tinymce/classes/Mode.js +54 -0
- data/apps/core/components/public/js/tinymce/classes/NodeChange.js +154 -0
- data/apps/core/components/public/js/tinymce/classes/NotificationManager.js +156 -0
- data/apps/core/components/public/js/tinymce/classes/Register.js +34 -0
- data/apps/core/components/public/js/tinymce/classes/SelectionOverrides.js +810 -0
- data/apps/core/components/public/js/tinymce/classes/Shortcuts.js +172 -0
- data/apps/core/components/public/js/tinymce/classes/UndoManager.js +346 -0
- data/apps/core/components/public/js/tinymce/classes/WindowManager.js +278 -0
- data/apps/core/components/public/js/tinymce/classes/caret/CaretBookmark.js +263 -0
- data/apps/core/components/public/js/tinymce/classes/caret/CaretCandidate.js +86 -0
- data/apps/core/components/public/js/tinymce/classes/caret/CaretContainer.js +151 -0
- data/apps/core/components/public/js/tinymce/classes/caret/CaretPosition.js +371 -0
- data/apps/core/components/public/js/tinymce/classes/caret/CaretUtils.js +302 -0
- data/apps/core/components/public/js/tinymce/classes/caret/CaretWalker.js +215 -0
- data/apps/core/components/public/js/tinymce/classes/caret/FakeCaret.js +192 -0
- data/apps/core/components/public/js/tinymce/classes/caret/LineUtils.js +135 -0
- data/apps/core/components/public/js/tinymce/classes/caret/LineWalker.js +166 -0
- data/apps/core/components/public/js/tinymce/classes/data/Binding.js +79 -0
- data/apps/core/components/public/js/tinymce/classes/data/ObservableArray.js +196 -0
- data/apps/core/components/public/js/tinymce/classes/data/ObservableObject.js +194 -0
- data/apps/core/components/public/js/tinymce/classes/dom/BookmarkManager.js +456 -0
- data/apps/core/components/public/js/tinymce/classes/dom/ControlSelection.js +634 -0
- data/apps/core/components/public/js/tinymce/classes/dom/DOMUtils.js +1853 -0
- data/apps/core/components/public/js/tinymce/classes/dom/Dimensions.js +64 -0
- data/apps/core/components/public/js/tinymce/classes/dom/DomQuery.js +1578 -0
- data/apps/core/components/public/js/tinymce/classes/dom/ElementUtils.js +118 -0
- data/apps/core/components/public/js/tinymce/classes/dom/EventUtils.js +583 -0
- data/apps/core/components/public/js/tinymce/classes/dom/NodePath.js +50 -0
- data/apps/core/components/public/js/tinymce/classes/dom/NodeType.js +110 -0
- data/apps/core/components/public/js/tinymce/classes/dom/Range.js +785 -0
- data/apps/core/components/public/js/tinymce/classes/dom/RangeUtils.js +628 -0
- data/apps/core/components/public/js/tinymce/classes/dom/ScriptLoader.js +254 -0
- data/apps/core/components/public/js/tinymce/classes/dom/Selection.js +1008 -0
- data/apps/core/components/public/js/tinymce/classes/dom/Serializer.js +506 -0
- data/apps/core/components/public/js/tinymce/classes/dom/Sizzle.jQuery.js +23 -0
- data/apps/core/components/public/js/tinymce/classes/dom/Sizzle.js +2039 -0
- data/apps/core/components/public/js/tinymce/classes/dom/StyleSheetLoader.js +190 -0
- data/apps/core/components/public/js/tinymce/classes/dom/TreeWalker.js +127 -0
- data/apps/core/components/public/js/tinymce/classes/dom/TridentSelection.js +508 -0
- data/apps/core/components/public/js/tinymce/classes/file/BlobCache.js +72 -0
- data/apps/core/components/public/js/tinymce/classes/file/Conversions.js +106 -0
- data/apps/core/components/public/js/tinymce/classes/file/ImageScanner.js +145 -0
- data/apps/core/components/public/js/tinymce/classes/file/Uploader.js +193 -0
- data/apps/core/components/public/js/tinymce/classes/fmt/Hooks.js +66 -0
- data/apps/core/components/public/js/tinymce/classes/fmt/Preview.js +151 -0
- data/apps/core/components/public/js/tinymce/classes/geom/ClientRect.js +136 -0
- data/apps/core/components/public/js/tinymce/classes/geom/Rect.js +214 -0
- data/apps/core/components/public/js/tinymce/classes/html/DomParser.js +822 -0
- data/apps/core/components/public/js/tinymce/classes/html/Entities.js +268 -0
- data/apps/core/components/public/js/tinymce/classes/html/Node.js +496 -0
- data/apps/core/components/public/js/tinymce/classes/html/SaxParser.js +474 -0
- data/apps/core/components/public/js/tinymce/classes/html/Schema.js +1004 -0
- data/apps/core/components/public/js/tinymce/classes/html/Serializer.js +158 -0
- data/apps/core/components/public/js/tinymce/classes/html/Styles.js +363 -0
- data/apps/core/components/public/js/tinymce/classes/html/Writer.js +199 -0
- data/apps/core/components/public/js/tinymce/classes/jquery.tinymce.js +377 -0
- data/apps/core/components/public/js/tinymce/classes/text/ExtendingChar.js +53 -0
- data/apps/core/components/public/js/tinymce/classes/text/Zwsp.js +36 -0
- data/apps/core/components/public/js/tinymce/classes/ui/AbsoluteLayout.js +63 -0
- data/apps/core/components/public/js/tinymce/classes/ui/BoxUtils.js +98 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Button.js +199 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ButtonGroup.js +62 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Checkbox.js +162 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ClassList.js +149 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Collection.js +438 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ColorBox.js +72 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ColorButton.js +124 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ColorPicker.js +206 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ComboBox.js +306 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Container.js +506 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Control.js +1301 -0
- data/apps/core/components/public/js/tinymce/classes/ui/DomUtils.js +107 -0
- data/apps/core/components/public/js/tinymce/classes/ui/DragHelper.js +144 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ElementPath.js +79 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Factory.js +105 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FieldSet.js +59 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FilePicker.js +85 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FitLayout.js +48 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FlexLayout.js +246 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FloatPanel.js +409 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FlowLayout.js +46 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Form.js +157 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FormItem.js +56 -0
- data/apps/core/components/public/js/tinymce/classes/ui/FormatControls.js +535 -0
- data/apps/core/components/public/js/tinymce/classes/ui/GridLayout.js +233 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Iframe.js +85 -0
- data/apps/core/components/public/js/tinymce/classes/ui/InfoBox.js +93 -0
- data/apps/core/components/public/js/tinymce/classes/ui/KeyboardNavigation.js +406 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Label.js +144 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Layout.js +120 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ListBox.js +152 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Menu.js +195 -0
- data/apps/core/components/public/js/tinymce/classes/ui/MenuBar.js +33 -0
- data/apps/core/components/public/js/tinymce/classes/ui/MenuButton.js +268 -0
- data/apps/core/components/public/js/tinymce/classes/ui/MenuItem.js +336 -0
- data/apps/core/components/public/js/tinymce/classes/ui/MessageBox.js +202 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Movable.js +200 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Notification.js +154 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Panel.js +67 -0
- data/apps/core/components/public/js/tinymce/classes/ui/PanelButton.js +114 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Path.js +127 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Progress.js +81 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Radio.js +29 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ReflowQueue.js +79 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Resizable.js +68 -0
- data/apps/core/components/public/js/tinymce/classes/ui/ResizeHandle.js +86 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Scrollable.js +141 -0
- data/apps/core/components/public/js/tinymce/classes/ui/SelectBox.js +106 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Selector.js +369 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Slider.js +161 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Spacer.js +39 -0
- data/apps/core/components/public/js/tinymce/classes/ui/SplitButton.js +146 -0
- data/apps/core/components/public/js/tinymce/classes/ui/StackLayout.js +34 -0
- data/apps/core/components/public/js/tinymce/classes/ui/TabPanel.js +178 -0
- data/apps/core/components/public/js/tinymce/classes/ui/TextBox.js +208 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Throbber.js +88 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Toolbar.js +56 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Tooltip.js +73 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Widget.js +151 -0
- data/apps/core/components/public/js/tinymce/classes/ui/Window.js +474 -0
- data/apps/core/components/public/js/tinymce/classes/util/Arr.js +153 -0
- data/apps/core/components/public/js/tinymce/classes/util/Class.js +167 -0
- data/apps/core/components/public/js/tinymce/classes/util/Color.js +235 -0
- data/apps/core/components/public/js/tinymce/classes/util/Delay.js +191 -0
- data/apps/core/components/public/js/tinymce/classes/util/EventDispatcher.js +294 -0
- data/apps/core/components/public/js/tinymce/classes/util/Fun.js +87 -0
- data/apps/core/components/public/js/tinymce/classes/util/I18n.js +116 -0
- data/apps/core/components/public/js/tinymce/classes/util/JSON.js +109 -0
- data/apps/core/components/public/js/tinymce/classes/util/JSONP.js +38 -0
- data/apps/core/components/public/js/tinymce/classes/util/JSONRequest.js +110 -0
- data/apps/core/components/public/js/tinymce/classes/util/LocalStorage.js +213 -0
- data/apps/core/components/public/js/tinymce/classes/util/Observable.js +129 -0
- data/apps/core/components/public/js/tinymce/classes/util/Promise.js +200 -0
- data/apps/core/components/public/js/tinymce/classes/util/Quirks.js +1701 -0
- data/apps/core/components/public/js/tinymce/classes/util/Tools.js +442 -0
- data/apps/core/components/public/js/tinymce/classes/util/URI.js +411 -0
- data/apps/core/components/public/js/tinymce/classes/util/VK.js +37 -0
- data/apps/core/components/public/js/tinymce/classes/util/XHR.js +110 -0
- data/apps/core/components/public/js/tinymce/jquery.tinymce.min.js +1 -0
- data/apps/core/components/public/js/tinymce/langs/it.js +219 -0
- data/apps/core/components/public/js/tinymce/langs/readme.md +3 -0
- data/apps/core/components/public/js/tinymce/license.txt +504 -0
- data/apps/core/components/public/js/tinymce/plugins/advlist/plugin.js +97 -0
- data/apps/core/components/public/js/tinymce/plugins/advlist/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/anchor/plugin.js +55 -0
- data/apps/core/components/public/js/tinymce/plugins/anchor/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/autolink/plugin.js +204 -0
- data/apps/core/components/public/js/tinymce/plugins/autolink/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/autoresize/plugin.js +162 -0
- data/apps/core/components/public/js/tinymce/plugins/autoresize/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/autosave/plugin.js +165 -0
- data/apps/core/components/public/js/tinymce/plugins/autosave/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/bbcode/plugin.js +123 -0
- data/apps/core/components/public/js/tinymce/plugins/bbcode/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/charmap/plugin.js +450 -0
- data/apps/core/components/public/js/tinymce/plugins/charmap/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/code/plugin.js +60 -0
- data/apps/core/components/public/js/tinymce/plugins/code/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Dialog.js +121 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Plugin.js +95 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Prism.js +937 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/classes/Utils.js +33 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/css/prism.css +138 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/plugin.dev.js +141 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/plugin.js +1299 -0
- data/apps/core/components/public/js/tinymce/plugins/codesample/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/colorpicker/plugin.js +112 -0
- data/apps/core/components/public/js/tinymce/plugins/colorpicker/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/css/dialog.css +118 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/buttons.png +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/icons.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/items.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/menu_arrow.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/menu_check.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/progress.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/img/tabs.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/plugin.js +297 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/tiny_mce_popup.js +542 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/editable_selects.js +70 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/form_utils.js +210 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/mctabs.js +164 -0
- data/apps/core/components/public/js/tinymce/plugins/compat3x/utils/validate.js +252 -0
- data/apps/core/components/public/js/tinymce/plugins/contextmenu/plugin.js +88 -0
- data/apps/core/components/public/js/tinymce/plugins/contextmenu/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/directionality/plugin.js +64 -0
- data/apps/core/components/public/js/tinymce/plugins/directionality/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-cool.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-cry.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-embarassed.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-foot-in-mouth.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-frown.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-innocent.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-kiss.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-laughing.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-money-mouth.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-sealed.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-smile.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-surprised.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-tongue-out.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-undecided.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-wink.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/img/smiley-yell.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/plugin.js +65 -0
- data/apps/core/components/public/js/tinymce/plugins/emoticons/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/example/dialog.html +8 -0
- data/apps/core/components/public/js/tinymce/plugins/example/plugin.js +68 -0
- data/apps/core/components/public/js/tinymce/plugins/example/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/example_dependency/plugin.js +22 -0
- data/apps/core/components/public/js/tinymce/plugins/example_dependency/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/fullpage/plugin.js +490 -0
- data/apps/core/components/public/js/tinymce/plugins/fullpage/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/fullscreen/plugin.js +154 -0
- data/apps/core/components/public/js/tinymce/plugins/fullscreen/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/hr/plugin.js +30 -0
- data/apps/core/components/public/js/tinymce/plugins/hr/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/image/plugin.js +630 -0
- data/apps/core/components/public/js/tinymce/plugins/image/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/atomic.js +6 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/browser.js +6 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/demo.js +8 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/config/bolt/prod.js +6 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/plugin.js +2668 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/demo/html/demo.html +16 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/demo/js/Demo.js +92 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/CropRect.js +214 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/Dialog.js +485 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/ImagePanel.js +218 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/Plugin.js +411 -0
- data/apps/core/components/public/js/tinymce/plugins/imagetools/src/main/js/UndoStack.js +57 -0
- data/apps/core/components/public/js/tinymce/plugins/importcss/plugin.js +227 -0
- data/apps/core/components/public/js/tinymce/plugins/importcss/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/insertdatetime/plugin.js +121 -0
- data/apps/core/components/public/js/tinymce/plugins/insertdatetime/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/layer/plugin.js +225 -0
- data/apps/core/components/public/js/tinymce/plugins/layer/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/legacyoutput/plugin.js +211 -0
- data/apps/core/components/public/js/tinymce/plugins/legacyoutput/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/link/plugin.js +403 -0
- data/apps/core/components/public/js/tinymce/plugins/link/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/lists/plugin.js +885 -0
- data/apps/core/components/public/js/tinymce/plugins/lists/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/media/moxieplayer.swf +0 -0
- data/apps/core/components/public/js/tinymce/plugins/media/plugin.js +878 -0
- data/apps/core/components/public/js/tinymce/plugins/media/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/nonbreaking/plugin.js +53 -0
- data/apps/core/components/public/js/tinymce/plugins/nonbreaking/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/noneditable/plugin.js +101 -0
- data/apps/core/components/public/js/tinymce/plugins/noneditable/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/pagebreak/plugin.js +88 -0
- data/apps/core/components/public/js/tinymce/plugins/pagebreak/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/classes/Clipboard.js +672 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/classes/Plugin.js +121 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/classes/Quirks.js +159 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/classes/Utils.js +140 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/classes/WordFilter.js +500 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/plugin.dev.js +142 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/plugin.js +1708 -0
- data/apps/core/components/public/js/tinymce/plugins/paste/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/preview/plugin.js +88 -0
- data/apps/core/components/public/js/tinymce/plugins/preview/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/print/plugin.js +32 -0
- data/apps/core/components/public/js/tinymce/plugins/print/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/save/plugin.js +98 -0
- data/apps/core/components/public/js/tinymce/plugins/save/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/searchreplace/plugin.js +609 -0
- data/apps/core/components/public/js/tinymce/plugins/searchreplace/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/spellchecker/classes/DomTextMatcher.js +480 -0
- data/apps/core/components/public/js/tinymce/plugins/spellchecker/classes/Plugin.js +439 -0
- data/apps/core/components/public/js/tinymce/plugins/spellchecker/plugin.dev.js +139 -0
- data/apps/core/components/public/js/tinymce/plugins/spellchecker/plugin.js +1026 -0
- data/apps/core/components/public/js/tinymce/plugins/spellchecker/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/tabfocus/plugin.js +120 -0
- data/apps/core/components/public/js/tinymce/plugins/tabfocus/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/CellSelection.js +202 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/Dialogs.js +824 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/Plugin.js +599 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/Quirks.js +400 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/ResizeBars.js +984 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/TableGrid.js +941 -0
- data/apps/core/components/public/js/tinymce/plugins/table/classes/Utils.js +36 -0
- data/apps/core/components/public/js/tinymce/plugins/table/plugin.dev.js +142 -0
- data/apps/core/components/public/js/tinymce/plugins/table/plugin.js +4106 -0
- data/apps/core/components/public/js/tinymce/plugins/table/plugin.min.js +2 -0
- data/apps/core/components/public/js/tinymce/plugins/template/plugin.js +270 -0
- data/apps/core/components/public/js/tinymce/plugins/template/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/textcolor/plugin.js +282 -0
- data/apps/core/components/public/js/tinymce/plugins/textcolor/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/textpattern/plugin.js +268 -0
- data/apps/core/components/public/js/tinymce/plugins/textpattern/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/css/visualblocks.css +135 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/address.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/article.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/aside.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/blockquote.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/div.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/dl.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/figure.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h1.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h2.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h3.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h4.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h5.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/h6.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/hgroup.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/ol.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/p.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/pre.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/section.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/img/ul.gif +0 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/plugin.js +86 -0
- data/apps/core/components/public/js/tinymce/plugins/visualblocks/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/visualchars/plugin.js +123 -0
- data/apps/core/components/public/js/tinymce/plugins/visualchars/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/plugins/wordcount/plugin.js +69 -0
- data/apps/core/components/public/js/tinymce/plugins/wordcount/plugin.min.js +1 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/AbsoluteLayout.less +17 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Animations.less +10 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Button.less +172 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ButtonGroup.less +71 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Checkbox.less +49 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ColorBox.less +6 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ColorButton.less +72 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ColorPicker.less +80 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ComboBox.less +39 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Container.less +9 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Content.Inline.less +4 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Content.Objects.less +166 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Content.less +27 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/CropRect.less +54 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/FieldSet.less +15 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/FitLayout.less +9 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/FloatPanel.less +69 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/FlowLayout.less +36 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Icons.Ie7.less +136 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Icons.less +180 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Iframe.less +6 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ImagePanel.less +20 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/InfoBox.less +71 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Label.less +38 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ListBox.less +26 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Menu.less +34 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/MenuBar.less +32 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/MenuButton.less +34 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/MenuItem.less +142 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Mixins.less +54 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Notification.less +144 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Panel.less +7 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Path.less +45 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Progress.less +34 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Radio.less +1 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Reset.less +32 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ResizeHandle.less +18 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Scrollable.less +44 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/SelectBox.less +6 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Slider.less +29 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Spacer.less +5 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/SplitButton.less +49 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/StackLayout.less +5 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/TabPanel.less +44 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/TextBox.less +41 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Throbber.less +19 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/TinyMCE.less +159 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/ToolTip.less +129 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Variables.less +214 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/Window.less +127 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/content.inline.min.css +1 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/content.min.css +1 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/readme.md +1 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.eot +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.json +1277 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.svg +63 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.ttf +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce-small.woff +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.eot +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.json +3381 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.svg +129 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.ttf +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/fonts/tinymce.woff +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/img/anchor.gif +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/img/loader.gif +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/img/object.gif +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/img/trans.gif +0 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/skin.dev.less +46 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/skin.ie7.dev.less +46 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/skin.ie7.less +2542 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/skin.ie7.min.css +1 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/skin.less +2586 -0
- data/apps/core/components/public/js/tinymce/skins/lightgray/skin.min.css +1 -0
- data/apps/core/components/public/js/tinymce/themes/modern/theme.js +878 -0
- data/apps/core/components/public/js/tinymce/themes/modern/theme.min.js +1 -0
- data/apps/core/components/public/js/tinymce/tinymce.dev.js +286 -0
- data/apps/core/components/public/js/tinymce/tinymce.js +45811 -0
- data/apps/core/components/public/js/tinymce/tinymce.min.js +13 -0
- data/apps/core/forms/widgets/form/form.rb +3 -1
- data/apps/core/forms/widgets/form/form.shtml +1 -0
- data/apps/core/forms/widgets/inputs/search_select/search_select.rb +1 -1
- data/apps/core/forms/widgets/inputs/select/select.rb +1 -1
- data/apps/core/forms/widgets/inputs/select/select.shtml +0 -1
- data/apps/messenger/backends/sms/skebby.rb +1 -1
- data/apps/messenger/controllers/mixins/messenger_helper.rb +23 -5
- data/lib/spiderfw/config/options/spider.rb +1 -1
- data/lib/spiderfw/controller/mixins/visual.rb +2 -0
- data/lib/spiderfw/http/adapters/rack.rb +10 -5
- data/lib/spiderfw/http/http.rb +4 -2
- data/lib/spiderfw/model/base_model.rb +4 -4
- data/lib/spiderfw/model/mappers/db_mapper.rb +4 -2
- data/lib/spiderfw/model/storage/db/adapters/mysql.rb +2 -1
- data/lib/spiderfw/model/storage/db/db_storage.rb +4 -0
- data/lib/spiderfw/spider.rb +6 -0
- data/lib/spiderfw/templates/layout.rb +1 -1
- data/lib/spiderfw/utils/monkey/object.rb +3 -0
- data/spider.gemspec +6 -2
- metadata +539 -42
- data/blueprints/.DS_Store +0 -0
@@ -0,0 +1,1701 @@
|
|
1
|
+
/**
|
2
|
+
* Quirks.js
|
3
|
+
*
|
4
|
+
* Released under LGPL License.
|
5
|
+
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
6
|
+
*
|
7
|
+
* License: http://www.tinymce.com/license
|
8
|
+
* Contributing: http://www.tinymce.com/contributing
|
9
|
+
*
|
10
|
+
* @ignore-file
|
11
|
+
*/
|
12
|
+
|
13
|
+
/**
|
14
|
+
* This file includes fixes for various browser quirks it's made to make it easy to add/remove browser specific fixes.
|
15
|
+
*
|
16
|
+
* @private
|
17
|
+
* @class tinymce.util.Quirks
|
18
|
+
*/
|
19
|
+
define("tinymce/util/Quirks", [
|
20
|
+
"tinymce/util/VK",
|
21
|
+
"tinymce/dom/RangeUtils",
|
22
|
+
"tinymce/dom/TreeWalker",
|
23
|
+
"tinymce/dom/NodePath",
|
24
|
+
"tinymce/html/Node",
|
25
|
+
"tinymce/html/Entities",
|
26
|
+
"tinymce/Env",
|
27
|
+
"tinymce/util/Tools",
|
28
|
+
"tinymce/util/Delay",
|
29
|
+
"tinymce/caret/CaretContainer"
|
30
|
+
], function(VK, RangeUtils, TreeWalker, NodePath, Node, Entities, Env, Tools, Delay, CaretContainer) {
|
31
|
+
return function(editor) {
|
32
|
+
var each = Tools.each, $ = editor.$;
|
33
|
+
var BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection,
|
34
|
+
settings = editor.settings, parser = editor.parser, serializer = editor.serializer;
|
35
|
+
var isGecko = Env.gecko, isIE = Env.ie, isWebKit = Env.webkit;
|
36
|
+
var mceInternalUrlPrefix = 'data:text/mce-internal,';
|
37
|
+
var mceInternalDataType = isIE ? 'Text' : 'URL';
|
38
|
+
|
39
|
+
/**
|
40
|
+
* Executes a command with a specific state this can be to enable/disable browser editing features.
|
41
|
+
*/
|
42
|
+
function setEditorCommandState(cmd, state) {
|
43
|
+
try {
|
44
|
+
editor.getDoc().execCommand(cmd, false, state);
|
45
|
+
} catch (ex) {
|
46
|
+
// Ignore
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Returns current IE document mode.
|
52
|
+
*/
|
53
|
+
function getDocumentMode() {
|
54
|
+
var documentMode = editor.getDoc().documentMode;
|
55
|
+
|
56
|
+
return documentMode ? documentMode : 6;
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
* Returns true/false if the event is prevented or not.
|
61
|
+
*
|
62
|
+
* @private
|
63
|
+
* @param {Event} e Event object.
|
64
|
+
* @return {Boolean} true/false if the event is prevented or not.
|
65
|
+
*/
|
66
|
+
function isDefaultPrevented(e) {
|
67
|
+
return e.isDefaultPrevented();
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Sets Text/URL data on the event's dataTransfer object to a special data:text/mce-internal url.
|
72
|
+
* This is to workaround the inability to set custom contentType on IE and Safari.
|
73
|
+
* The editor's selected content is encoded into this url so drag and drop between editors will work.
|
74
|
+
*
|
75
|
+
* @private
|
76
|
+
* @param {DragEvent} e Event object
|
77
|
+
*/
|
78
|
+
function setMceInteralContent(e) {
|
79
|
+
var selectionHtml, internalContent;
|
80
|
+
|
81
|
+
if (e.dataTransfer) {
|
82
|
+
if (editor.selection.isCollapsed() && e.target.tagName == 'IMG') {
|
83
|
+
selection.select(e.target);
|
84
|
+
}
|
85
|
+
|
86
|
+
selectionHtml = editor.selection.getContent();
|
87
|
+
|
88
|
+
// Safari/IE doesn't support custom dataTransfer items so we can only use URL and Text
|
89
|
+
if (selectionHtml.length > 0) {
|
90
|
+
internalContent = mceInternalUrlPrefix + escape(editor.id) + ',' + escape(selectionHtml);
|
91
|
+
e.dataTransfer.setData(mceInternalDataType, internalContent);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Gets content of special data:text/mce-internal url on the event's dataTransfer object.
|
98
|
+
* This is to workaround the inability to set custom contentType on IE and Safari.
|
99
|
+
* The editor's selected content is encoded into this url so drag and drop between editors will work.
|
100
|
+
*
|
101
|
+
* @private
|
102
|
+
* @param {DragEvent} e Event object
|
103
|
+
* @returns {String} mce-internal content
|
104
|
+
*/
|
105
|
+
function getMceInternalContent(e) {
|
106
|
+
var internalContent;
|
107
|
+
|
108
|
+
if (e.dataTransfer) {
|
109
|
+
internalContent = e.dataTransfer.getData(mceInternalDataType);
|
110
|
+
|
111
|
+
if (internalContent && internalContent.indexOf(mceInternalUrlPrefix) >= 0) {
|
112
|
+
internalContent = internalContent.substr(mceInternalUrlPrefix.length).split(',');
|
113
|
+
|
114
|
+
return {
|
115
|
+
id: unescape(internalContent[0]),
|
116
|
+
html: unescape(internalContent[1])
|
117
|
+
};
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
return null;
|
122
|
+
}
|
123
|
+
|
124
|
+
/**
|
125
|
+
* Inserts contents using the paste clipboard command if it's available if it isn't it will fallback
|
126
|
+
* to the core command.
|
127
|
+
*
|
128
|
+
* @private
|
129
|
+
* @param {String} content Content to insert at selection.
|
130
|
+
*/
|
131
|
+
function insertClipboardContents(content) {
|
132
|
+
if (editor.queryCommandSupported('mceInsertClipboardContent')) {
|
133
|
+
editor.execCommand('mceInsertClipboardContent', false, {content: content});
|
134
|
+
} else {
|
135
|
+
editor.execCommand('mceInsertContent', false, content);
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
/**
|
140
|
+
* Fixes a WebKit bug when deleting contents using backspace or delete key.
|
141
|
+
* WebKit will produce a span element if you delete across two block elements.
|
142
|
+
*
|
143
|
+
* Example:
|
144
|
+
* <h1>a</h1><p>|b</p>
|
145
|
+
*
|
146
|
+
* Will produce this on backspace:
|
147
|
+
* <h1>a<span style="<all runtime styles>">b</span></p>
|
148
|
+
*
|
149
|
+
* This fixes the backspace to produce:
|
150
|
+
* <h1>a|b</p>
|
151
|
+
*
|
152
|
+
* See bug: https://bugs.webkit.org/show_bug.cgi?id=45784
|
153
|
+
*
|
154
|
+
* This fixes the following delete scenarios:
|
155
|
+
* 1. Delete by pressing backspace key.
|
156
|
+
* 2. Delete by pressing delete key.
|
157
|
+
* 3. Delete by pressing backspace key with ctrl/cmd (Word delete).
|
158
|
+
* 4. Delete by pressing delete key with ctrl/cmd (Word delete).
|
159
|
+
* 5. Delete by drag/dropping contents inside the editor.
|
160
|
+
* 6. Delete by using Cut Ctrl+X/Cmd+X.
|
161
|
+
* 7. Delete by selecting contents and writing a character.
|
162
|
+
*
|
163
|
+
* This code is a ugly hack since writing full custom delete logic for just this bug
|
164
|
+
* fix seemed like a huge task. I hope we can remove this before the year 2030.
|
165
|
+
*/
|
166
|
+
function cleanupStylesWhenDeleting() {
|
167
|
+
var doc = editor.getDoc(), dom = editor.dom, selection = editor.selection;
|
168
|
+
var MutationObserver = window.MutationObserver, olderWebKit, dragStartRng;
|
169
|
+
|
170
|
+
// Add mini polyfill for older WebKits
|
171
|
+
// TODO: Remove this when old Safari versions gets updated
|
172
|
+
if (!MutationObserver) {
|
173
|
+
olderWebKit = true;
|
174
|
+
|
175
|
+
MutationObserver = function() {
|
176
|
+
var records = [], target;
|
177
|
+
|
178
|
+
function nodeInsert(e) {
|
179
|
+
var target = e.relatedNode || e.target;
|
180
|
+
records.push({target: target, addedNodes: [target]});
|
181
|
+
}
|
182
|
+
|
183
|
+
function attrModified(e) {
|
184
|
+
var target = e.relatedNode || e.target;
|
185
|
+
records.push({target: target, attributeName: e.attrName});
|
186
|
+
}
|
187
|
+
|
188
|
+
this.observe = function(node) {
|
189
|
+
target = node;
|
190
|
+
target.addEventListener('DOMSubtreeModified', nodeInsert, false);
|
191
|
+
target.addEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
|
192
|
+
target.addEventListener('DOMNodeInserted', nodeInsert, false);
|
193
|
+
target.addEventListener('DOMAttrModified', attrModified, false);
|
194
|
+
};
|
195
|
+
|
196
|
+
this.disconnect = function() {
|
197
|
+
target.removeEventListener('DOMSubtreeModified', nodeInsert, false);
|
198
|
+
target.removeEventListener('DOMNodeInsertedIntoDocument', nodeInsert, false);
|
199
|
+
target.removeEventListener('DOMNodeInserted', nodeInsert, false);
|
200
|
+
target.removeEventListener('DOMAttrModified', attrModified, false);
|
201
|
+
};
|
202
|
+
|
203
|
+
this.takeRecords = function() {
|
204
|
+
return records;
|
205
|
+
};
|
206
|
+
};
|
207
|
+
}
|
208
|
+
|
209
|
+
function isTrailingBr(node) {
|
210
|
+
var blockElements = dom.schema.getBlockElements(), rootNode = editor.getBody();
|
211
|
+
|
212
|
+
if (node.nodeName != 'BR') {
|
213
|
+
return false;
|
214
|
+
}
|
215
|
+
|
216
|
+
for (; node != rootNode && !blockElements[node.nodeName]; node = node.parentNode) {
|
217
|
+
if (node.nextSibling) {
|
218
|
+
return false;
|
219
|
+
}
|
220
|
+
}
|
221
|
+
|
222
|
+
return true;
|
223
|
+
}
|
224
|
+
|
225
|
+
function isSiblingsIgnoreWhiteSpace(node1, node2) {
|
226
|
+
var node;
|
227
|
+
|
228
|
+
for (node = node1.nextSibling; node && node != node2; node = node.nextSibling) {
|
229
|
+
if (node.nodeType == 3 && $.trim(node.data).length === 0) {
|
230
|
+
continue;
|
231
|
+
}
|
232
|
+
|
233
|
+
if (node !== node2) {
|
234
|
+
return false;
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
return node === node2;
|
239
|
+
}
|
240
|
+
|
241
|
+
function findCaretNode(node, forward, startNode) {
|
242
|
+
var walker, current, nonEmptyElements;
|
243
|
+
|
244
|
+
nonEmptyElements = dom.schema.getNonEmptyElements();
|
245
|
+
|
246
|
+
walker = new TreeWalker(startNode || node, node);
|
247
|
+
|
248
|
+
while ((current = walker[forward ? 'next' : 'prev']())) {
|
249
|
+
if (nonEmptyElements[current.nodeName] && !isTrailingBr(current)) {
|
250
|
+
return current;
|
251
|
+
}
|
252
|
+
|
253
|
+
if (current.nodeType == 3 && current.data.length > 0) {
|
254
|
+
return current;
|
255
|
+
}
|
256
|
+
}
|
257
|
+
}
|
258
|
+
|
259
|
+
function deleteRangeBetweenTextBlocks(rng) {
|
260
|
+
var startBlock, endBlock, caretNodeBefore, caretNodeAfter, textBlockElements;
|
261
|
+
|
262
|
+
if (rng.collapsed) {
|
263
|
+
return;
|
264
|
+
}
|
265
|
+
|
266
|
+
startBlock = dom.getParent(RangeUtils.getNode(rng.startContainer, rng.startOffset), dom.isBlock);
|
267
|
+
endBlock = dom.getParent(RangeUtils.getNode(rng.endContainer, rng.endOffset), dom.isBlock);
|
268
|
+
textBlockElements = editor.schema.getTextBlockElements();
|
269
|
+
|
270
|
+
if (startBlock == endBlock) {
|
271
|
+
return;
|
272
|
+
}
|
273
|
+
|
274
|
+
if (!textBlockElements[startBlock.nodeName] || !textBlockElements[endBlock.nodeName]) {
|
275
|
+
return;
|
276
|
+
}
|
277
|
+
|
278
|
+
if (dom.getContentEditable(startBlock) === "false" || dom.getContentEditable(endBlock) === "false") {
|
279
|
+
return;
|
280
|
+
}
|
281
|
+
|
282
|
+
rng.deleteContents();
|
283
|
+
|
284
|
+
caretNodeBefore = findCaretNode(startBlock, false);
|
285
|
+
caretNodeAfter = findCaretNode(endBlock, true);
|
286
|
+
|
287
|
+
if (!dom.isEmpty(endBlock)) {
|
288
|
+
$(startBlock).append(endBlock.childNodes);
|
289
|
+
}
|
290
|
+
|
291
|
+
$(endBlock).remove();
|
292
|
+
|
293
|
+
if (caretNodeBefore) {
|
294
|
+
if (caretNodeBefore.nodeType == 1) {
|
295
|
+
if (caretNodeBefore.nodeName == "BR") {
|
296
|
+
rng.setStartBefore(caretNodeBefore);
|
297
|
+
rng.setEndBefore(caretNodeBefore);
|
298
|
+
} else {
|
299
|
+
rng.setStartAfter(caretNodeBefore);
|
300
|
+
rng.setEndAfter(caretNodeBefore);
|
301
|
+
}
|
302
|
+
} else {
|
303
|
+
rng.setStart(caretNodeBefore, caretNodeBefore.data.length);
|
304
|
+
rng.setEnd(caretNodeBefore, caretNodeBefore.data.length);
|
305
|
+
}
|
306
|
+
} else if (caretNodeAfter) {
|
307
|
+
if (caretNodeAfter.nodeType == 1) {
|
308
|
+
rng.setStartBefore(caretNodeAfter);
|
309
|
+
rng.setEndBefore(caretNodeAfter);
|
310
|
+
} else {
|
311
|
+
rng.setStart(caretNodeAfter, 0);
|
312
|
+
rng.setEnd(caretNodeAfter, 0);
|
313
|
+
}
|
314
|
+
}
|
315
|
+
|
316
|
+
selection.setRng(rng);
|
317
|
+
|
318
|
+
return true;
|
319
|
+
}
|
320
|
+
|
321
|
+
function expandBetweenBlocks(rng, isForward) {
|
322
|
+
var caretNode, targetCaretNode, textBlock, targetTextBlock, container, offset;
|
323
|
+
|
324
|
+
if (!rng.collapsed) {
|
325
|
+
return rng;
|
326
|
+
}
|
327
|
+
|
328
|
+
container = rng.startContainer;
|
329
|
+
offset = rng.startOffset;
|
330
|
+
|
331
|
+
if (container.nodeType == 3) {
|
332
|
+
if (isForward) {
|
333
|
+
if (offset < container.data.length) {
|
334
|
+
return rng;
|
335
|
+
}
|
336
|
+
} else {
|
337
|
+
if (offset > 0) {
|
338
|
+
return rng;
|
339
|
+
}
|
340
|
+
}
|
341
|
+
}
|
342
|
+
|
343
|
+
caretNode = RangeUtils.getNode(rng.startContainer, rng.startOffset);
|
344
|
+
textBlock = dom.getParent(caretNode, dom.isBlock);
|
345
|
+
targetCaretNode = findCaretNode(editor.getBody(), isForward, caretNode);
|
346
|
+
targetTextBlock = dom.getParent(targetCaretNode, dom.isBlock);
|
347
|
+
|
348
|
+
if (!caretNode || !targetCaretNode) {
|
349
|
+
return rng;
|
350
|
+
}
|
351
|
+
|
352
|
+
if (targetTextBlock && textBlock != targetTextBlock) {
|
353
|
+
if (!isForward) {
|
354
|
+
if (!isSiblingsIgnoreWhiteSpace(targetTextBlock, textBlock)) {
|
355
|
+
return rng;
|
356
|
+
}
|
357
|
+
|
358
|
+
if (targetCaretNode.nodeType == 1) {
|
359
|
+
if (targetCaretNode.nodeName == "BR") {
|
360
|
+
rng.setStartBefore(targetCaretNode);
|
361
|
+
} else {
|
362
|
+
rng.setStartAfter(targetCaretNode);
|
363
|
+
}
|
364
|
+
} else {
|
365
|
+
rng.setStart(targetCaretNode, targetCaretNode.data.length);
|
366
|
+
}
|
367
|
+
|
368
|
+
if (caretNode.nodeType == 1) {
|
369
|
+
rng.setEnd(caretNode, 0);
|
370
|
+
} else {
|
371
|
+
rng.setEndBefore(caretNode);
|
372
|
+
}
|
373
|
+
} else {
|
374
|
+
if (!isSiblingsIgnoreWhiteSpace(textBlock, targetTextBlock)) {
|
375
|
+
return rng;
|
376
|
+
}
|
377
|
+
|
378
|
+
if (caretNode.nodeType == 1) {
|
379
|
+
if (caretNode.nodeName == "BR") {
|
380
|
+
rng.setStartBefore(caretNode);
|
381
|
+
} else {
|
382
|
+
rng.setStartAfter(caretNode);
|
383
|
+
}
|
384
|
+
} else {
|
385
|
+
rng.setStart(caretNode, caretNode.data.length);
|
386
|
+
}
|
387
|
+
|
388
|
+
if (targetCaretNode.nodeType == 1) {
|
389
|
+
rng.setEnd(targetCaretNode, 0);
|
390
|
+
} else {
|
391
|
+
rng.setEndBefore(targetCaretNode);
|
392
|
+
}
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
return rng;
|
397
|
+
}
|
398
|
+
|
399
|
+
function handleTextBlockMergeDelete(isForward) {
|
400
|
+
var rng = selection.getRng();
|
401
|
+
|
402
|
+
rng = expandBetweenBlocks(rng, isForward);
|
403
|
+
|
404
|
+
if (deleteRangeBetweenTextBlocks(rng)) {
|
405
|
+
return true;
|
406
|
+
}
|
407
|
+
}
|
408
|
+
|
409
|
+
/**
|
410
|
+
* This retains the formatting if the last character is to be deleted.
|
411
|
+
*
|
412
|
+
* Backspace on this: <p><b><i>a|</i></b></p> would become <p>|</p> in WebKit.
|
413
|
+
* With this patch: <p><b><i>|<br></i></b></p>
|
414
|
+
*/
|
415
|
+
function handleLastBlockCharacterDelete(isForward, rng) {
|
416
|
+
var path, blockElm, newBlockElm, clonedBlockElm, sibling,
|
417
|
+
container, offset, br, currentFormatNodes;
|
418
|
+
|
419
|
+
function cloneTextBlockWithFormats(blockElm, node) {
|
420
|
+
currentFormatNodes = $(node).parents().filter(function(idx, node) {
|
421
|
+
return !!editor.schema.getTextInlineElements()[node.nodeName];
|
422
|
+
});
|
423
|
+
|
424
|
+
newBlockElm = blockElm.cloneNode(false);
|
425
|
+
|
426
|
+
currentFormatNodes = Tools.map(currentFormatNodes, function(formatNode) {
|
427
|
+
formatNode = formatNode.cloneNode(false);
|
428
|
+
|
429
|
+
if (newBlockElm.hasChildNodes()) {
|
430
|
+
formatNode.appendChild(newBlockElm.firstChild);
|
431
|
+
newBlockElm.appendChild(formatNode);
|
432
|
+
} else {
|
433
|
+
newBlockElm.appendChild(formatNode);
|
434
|
+
}
|
435
|
+
|
436
|
+
newBlockElm.appendChild(formatNode);
|
437
|
+
|
438
|
+
return formatNode;
|
439
|
+
});
|
440
|
+
|
441
|
+
if (currentFormatNodes.length) {
|
442
|
+
br = dom.create('br');
|
443
|
+
currentFormatNodes[0].appendChild(br);
|
444
|
+
dom.replace(newBlockElm, blockElm);
|
445
|
+
|
446
|
+
rng.setStartBefore(br);
|
447
|
+
rng.setEndBefore(br);
|
448
|
+
editor.selection.setRng(rng);
|
449
|
+
|
450
|
+
return br;
|
451
|
+
}
|
452
|
+
|
453
|
+
return null;
|
454
|
+
}
|
455
|
+
|
456
|
+
function isTextBlock(node) {
|
457
|
+
return node && editor.schema.getTextBlockElements()[node.tagName];
|
458
|
+
}
|
459
|
+
|
460
|
+
if (!rng.collapsed) {
|
461
|
+
return;
|
462
|
+
}
|
463
|
+
|
464
|
+
container = rng.startContainer;
|
465
|
+
offset = rng.startOffset;
|
466
|
+
blockElm = dom.getParent(container, dom.isBlock);
|
467
|
+
if (!isTextBlock(blockElm)) {
|
468
|
+
return;
|
469
|
+
}
|
470
|
+
|
471
|
+
if (container.nodeType == 1) {
|
472
|
+
container = container.childNodes[offset];
|
473
|
+
if (container && container.tagName != 'BR') {
|
474
|
+
return;
|
475
|
+
}
|
476
|
+
|
477
|
+
if (isForward) {
|
478
|
+
sibling = blockElm.nextSibling;
|
479
|
+
} else {
|
480
|
+
sibling = blockElm.previousSibling;
|
481
|
+
}
|
482
|
+
|
483
|
+
if (dom.isEmpty(blockElm) && isTextBlock(sibling) && dom.isEmpty(sibling)) {
|
484
|
+
if (cloneTextBlockWithFormats(blockElm, container)) {
|
485
|
+
dom.remove(sibling);
|
486
|
+
return true;
|
487
|
+
}
|
488
|
+
}
|
489
|
+
} else if (container.nodeType == 3) {
|
490
|
+
path = NodePath.create(blockElm, container);
|
491
|
+
clonedBlockElm = blockElm.cloneNode(true);
|
492
|
+
container = NodePath.resolve(clonedBlockElm, path);
|
493
|
+
|
494
|
+
if (isForward) {
|
495
|
+
if (offset >= container.data.length) {
|
496
|
+
return;
|
497
|
+
}
|
498
|
+
|
499
|
+
container.deleteData(offset, 1);
|
500
|
+
} else {
|
501
|
+
if (offset <= 0) {
|
502
|
+
return;
|
503
|
+
}
|
504
|
+
|
505
|
+
container.deleteData(offset - 1, 1);
|
506
|
+
}
|
507
|
+
|
508
|
+
if (dom.isEmpty(clonedBlockElm)) {
|
509
|
+
return cloneTextBlockWithFormats(blockElm, container);
|
510
|
+
}
|
511
|
+
}
|
512
|
+
}
|
513
|
+
|
514
|
+
function customDelete(isForward) {
|
515
|
+
var mutationObserver, rng, caretElement;
|
516
|
+
|
517
|
+
if (handleTextBlockMergeDelete(isForward)) {
|
518
|
+
return;
|
519
|
+
}
|
520
|
+
|
521
|
+
Tools.each(editor.getBody().getElementsByTagName('*'), function(elm) {
|
522
|
+
// Mark existing spans
|
523
|
+
if (elm.tagName == 'SPAN') {
|
524
|
+
elm.setAttribute('mce-data-marked', 1);
|
525
|
+
}
|
526
|
+
|
527
|
+
// Make sure all elements has a data-mce-style attribute
|
528
|
+
if (!elm.hasAttribute('data-mce-style') && elm.hasAttribute('style')) {
|
529
|
+
editor.dom.setAttrib(elm, 'style', editor.dom.getAttrib(elm, 'style'));
|
530
|
+
}
|
531
|
+
});
|
532
|
+
|
533
|
+
// Observe added nodes and style attribute changes
|
534
|
+
mutationObserver = new MutationObserver(function() {});
|
535
|
+
mutationObserver.observe(editor.getDoc(), {
|
536
|
+
childList: true,
|
537
|
+
attributes: true,
|
538
|
+
subtree: true,
|
539
|
+
attributeFilter: ['style']
|
540
|
+
});
|
541
|
+
|
542
|
+
editor.getDoc().execCommand(isForward ? 'ForwardDelete' : 'Delete', false, null);
|
543
|
+
|
544
|
+
rng = editor.selection.getRng();
|
545
|
+
caretElement = rng.startContainer.parentNode;
|
546
|
+
|
547
|
+
Tools.each(mutationObserver.takeRecords(), function(record) {
|
548
|
+
if (!dom.isChildOf(record.target, editor.getBody())) {
|
549
|
+
return;
|
550
|
+
}
|
551
|
+
|
552
|
+
// Restore style attribute to previous value
|
553
|
+
if (record.attributeName == "style") {
|
554
|
+
var oldValue = record.target.getAttribute('data-mce-style');
|
555
|
+
|
556
|
+
if (oldValue) {
|
557
|
+
record.target.setAttribute("style", oldValue);
|
558
|
+
} else {
|
559
|
+
record.target.removeAttribute("style");
|
560
|
+
}
|
561
|
+
}
|
562
|
+
|
563
|
+
// Remove all spans that aren't marked and retain selection
|
564
|
+
Tools.each(record.addedNodes, function(node) {
|
565
|
+
if (node.nodeName == "SPAN" && !node.getAttribute('mce-data-marked')) {
|
566
|
+
var offset, container;
|
567
|
+
|
568
|
+
if (node == caretElement) {
|
569
|
+
offset = rng.startOffset;
|
570
|
+
container = node.firstChild;
|
571
|
+
}
|
572
|
+
|
573
|
+
dom.remove(node, true);
|
574
|
+
|
575
|
+
if (container) {
|
576
|
+
rng.setStart(container, offset);
|
577
|
+
rng.setEnd(container, offset);
|
578
|
+
editor.selection.setRng(rng);
|
579
|
+
}
|
580
|
+
}
|
581
|
+
});
|
582
|
+
});
|
583
|
+
|
584
|
+
mutationObserver.disconnect();
|
585
|
+
|
586
|
+
// Remove any left over marks
|
587
|
+
Tools.each(editor.dom.select('span[mce-data-marked]'), function(span) {
|
588
|
+
span.removeAttribute('mce-data-marked');
|
589
|
+
});
|
590
|
+
}
|
591
|
+
|
592
|
+
editor.on('keydown', function(e) {
|
593
|
+
var isForward = e.keyCode == DELETE, isMetaOrCtrl = e.ctrlKey || e.metaKey;
|
594
|
+
|
595
|
+
if (!isDefaultPrevented(e) && (isForward || e.keyCode == BACKSPACE)) {
|
596
|
+
var rng = editor.selection.getRng(), container = rng.startContainer, offset = rng.startOffset;
|
597
|
+
|
598
|
+
// Shift+Delete is cut
|
599
|
+
if (isForward && e.shiftKey) {
|
600
|
+
return;
|
601
|
+
}
|
602
|
+
|
603
|
+
if (handleLastBlockCharacterDelete(isForward, rng)) {
|
604
|
+
e.preventDefault();
|
605
|
+
return;
|
606
|
+
}
|
607
|
+
|
608
|
+
// Ignore non meta delete in the where there is text before/after the caret
|
609
|
+
if (!isMetaOrCtrl && rng.collapsed && container.nodeType == 3) {
|
610
|
+
if (isForward ? offset < container.data.length : offset > 0) {
|
611
|
+
return;
|
612
|
+
}
|
613
|
+
}
|
614
|
+
|
615
|
+
e.preventDefault();
|
616
|
+
|
617
|
+
if (isMetaOrCtrl) {
|
618
|
+
editor.selection.getSel().modify("extend", isForward ? "forward" : "backward", e.metaKey ? "lineboundary" : "word");
|
619
|
+
}
|
620
|
+
|
621
|
+
customDelete(isForward);
|
622
|
+
}
|
623
|
+
});
|
624
|
+
|
625
|
+
// Handle case where text is deleted by typing over
|
626
|
+
editor.on('keypress', function(e) {
|
627
|
+
if (!isDefaultPrevented(e) && !selection.isCollapsed() && e.charCode > 31 && !VK.metaKeyPressed(e)) {
|
628
|
+
var rng, currentFormatNodes, fragmentNode, blockParent, caretNode, charText;
|
629
|
+
|
630
|
+
rng = editor.selection.getRng();
|
631
|
+
charText = String.fromCharCode(e.charCode);
|
632
|
+
e.preventDefault();
|
633
|
+
|
634
|
+
// Keep track of current format nodes
|
635
|
+
currentFormatNodes = $(rng.startContainer).parents().filter(function(idx, node) {
|
636
|
+
return !!editor.schema.getTextInlineElements()[node.nodeName];
|
637
|
+
});
|
638
|
+
|
639
|
+
customDelete(true);
|
640
|
+
|
641
|
+
// Check if the browser removed them
|
642
|
+
currentFormatNodes = currentFormatNodes.filter(function(idx, node) {
|
643
|
+
return !$.contains(editor.getBody(), node);
|
644
|
+
});
|
645
|
+
|
646
|
+
// Then re-add them
|
647
|
+
if (currentFormatNodes.length) {
|
648
|
+
fragmentNode = dom.createFragment();
|
649
|
+
|
650
|
+
currentFormatNodes.each(function(idx, formatNode) {
|
651
|
+
formatNode = formatNode.cloneNode(false);
|
652
|
+
|
653
|
+
if (fragmentNode.hasChildNodes()) {
|
654
|
+
formatNode.appendChild(fragmentNode.firstChild);
|
655
|
+
fragmentNode.appendChild(formatNode);
|
656
|
+
} else {
|
657
|
+
caretNode = formatNode;
|
658
|
+
fragmentNode.appendChild(formatNode);
|
659
|
+
}
|
660
|
+
|
661
|
+
fragmentNode.appendChild(formatNode);
|
662
|
+
});
|
663
|
+
|
664
|
+
caretNode.appendChild(editor.getDoc().createTextNode(charText));
|
665
|
+
|
666
|
+
// Prevent edge case where older WebKit would add an extra BR element
|
667
|
+
blockParent = dom.getParent(rng.startContainer, dom.isBlock);
|
668
|
+
if (dom.isEmpty(blockParent)) {
|
669
|
+
$(blockParent).empty().append(fragmentNode);
|
670
|
+
} else {
|
671
|
+
rng.insertNode(fragmentNode);
|
672
|
+
}
|
673
|
+
|
674
|
+
rng.setStart(caretNode.firstChild, 1);
|
675
|
+
rng.setEnd(caretNode.firstChild, 1);
|
676
|
+
editor.selection.setRng(rng);
|
677
|
+
} else {
|
678
|
+
editor.selection.setContent(charText);
|
679
|
+
}
|
680
|
+
}
|
681
|
+
});
|
682
|
+
|
683
|
+
editor.addCommand('Delete', function() {
|
684
|
+
customDelete();
|
685
|
+
});
|
686
|
+
|
687
|
+
editor.addCommand('ForwardDelete', function() {
|
688
|
+
customDelete(true);
|
689
|
+
});
|
690
|
+
|
691
|
+
// Older WebKits doesn't properly handle the clipboard so we can't add the rest
|
692
|
+
if (olderWebKit) {
|
693
|
+
return;
|
694
|
+
}
|
695
|
+
|
696
|
+
editor.on('dragstart', function(e) {
|
697
|
+
dragStartRng = selection.getRng();
|
698
|
+
setMceInteralContent(e);
|
699
|
+
});
|
700
|
+
|
701
|
+
editor.on('drop', function(e) {
|
702
|
+
if (!isDefaultPrevented(e)) {
|
703
|
+
var internalContent = getMceInternalContent(e);
|
704
|
+
|
705
|
+
if (internalContent) {
|
706
|
+
e.preventDefault();
|
707
|
+
|
708
|
+
// Safari has a weird issue where drag/dropping images sometimes
|
709
|
+
// produces a green plus icon. When this happens the caretRangeFromPoint
|
710
|
+
// will return "null" even though the x, y coordinate is correct.
|
711
|
+
// But if we detach the insert from the drop event we will get a proper range
|
712
|
+
Delay.setEditorTimeout(editor, function() {
|
713
|
+
var pointRng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, doc);
|
714
|
+
|
715
|
+
if (dragStartRng) {
|
716
|
+
selection.setRng(dragStartRng);
|
717
|
+
dragStartRng = null;
|
718
|
+
}
|
719
|
+
|
720
|
+
customDelete();
|
721
|
+
selection.setRng(pointRng);
|
722
|
+
insertClipboardContents(internalContent.html);
|
723
|
+
});
|
724
|
+
}
|
725
|
+
}
|
726
|
+
});
|
727
|
+
|
728
|
+
editor.on('cut', function(e) {
|
729
|
+
if (!isDefaultPrevented(e) && e.clipboardData && !editor.selection.isCollapsed()) {
|
730
|
+
e.preventDefault();
|
731
|
+
e.clipboardData.clearData();
|
732
|
+
e.clipboardData.setData('text/html', editor.selection.getContent());
|
733
|
+
e.clipboardData.setData('text/plain', editor.selection.getContent({format: 'text'}));
|
734
|
+
|
735
|
+
// Needed delay for https://code.google.com/p/chromium/issues/detail?id=363288#c3
|
736
|
+
// Nested delete/forwardDelete not allowed on execCommand("cut")
|
737
|
+
// This is ugly but not sure how to work around it otherwise
|
738
|
+
Delay.setEditorTimeout(editor, function() {
|
739
|
+
customDelete(true);
|
740
|
+
});
|
741
|
+
}
|
742
|
+
});
|
743
|
+
}
|
744
|
+
|
745
|
+
/**
|
746
|
+
* Makes sure that the editor body becomes empty when backspace or delete is pressed in empty editors.
|
747
|
+
*
|
748
|
+
* For example:
|
749
|
+
* <p><b>|</b></p>
|
750
|
+
*
|
751
|
+
* Or:
|
752
|
+
* <h1>|</h1>
|
753
|
+
*
|
754
|
+
* Or:
|
755
|
+
* [<h1></h1>]
|
756
|
+
*/
|
757
|
+
function emptyEditorWhenDeleting() {
|
758
|
+
function serializeRng(rng) {
|
759
|
+
var body = dom.create("body");
|
760
|
+
var contents = rng.cloneContents();
|
761
|
+
body.appendChild(contents);
|
762
|
+
return selection.serializer.serialize(body, {format: 'html'});
|
763
|
+
}
|
764
|
+
|
765
|
+
function allContentsSelected(rng) {
|
766
|
+
if (!rng.setStart) {
|
767
|
+
if (rng.item) {
|
768
|
+
return false;
|
769
|
+
}
|
770
|
+
|
771
|
+
var bodyRng = rng.duplicate();
|
772
|
+
bodyRng.moveToElementText(editor.getBody());
|
773
|
+
return RangeUtils.compareRanges(rng, bodyRng);
|
774
|
+
}
|
775
|
+
|
776
|
+
var selection = serializeRng(rng);
|
777
|
+
|
778
|
+
var allRng = dom.createRng();
|
779
|
+
allRng.selectNode(editor.getBody());
|
780
|
+
|
781
|
+
var allSelection = serializeRng(allRng);
|
782
|
+
return selection === allSelection;
|
783
|
+
}
|
784
|
+
|
785
|
+
editor.on('keydown', function(e) {
|
786
|
+
var keyCode = e.keyCode, isCollapsed, body;
|
787
|
+
|
788
|
+
// Empty the editor if it's needed for example backspace at <p><b>|</b></p>
|
789
|
+
if (!isDefaultPrevented(e) && (keyCode == DELETE || keyCode == BACKSPACE)) {
|
790
|
+
isCollapsed = editor.selection.isCollapsed();
|
791
|
+
body = editor.getBody();
|
792
|
+
|
793
|
+
// Selection is collapsed but the editor isn't empty
|
794
|
+
if (isCollapsed && !dom.isEmpty(body)) {
|
795
|
+
return;
|
796
|
+
}
|
797
|
+
|
798
|
+
// Selection isn't collapsed but not all the contents is selected
|
799
|
+
if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) {
|
800
|
+
return;
|
801
|
+
}
|
802
|
+
|
803
|
+
// Manually empty the editor
|
804
|
+
e.preventDefault();
|
805
|
+
editor.setContent('');
|
806
|
+
|
807
|
+
if (body.firstChild && dom.isBlock(body.firstChild)) {
|
808
|
+
editor.selection.setCursorLocation(body.firstChild, 0);
|
809
|
+
} else {
|
810
|
+
editor.selection.setCursorLocation(body, 0);
|
811
|
+
}
|
812
|
+
|
813
|
+
editor.nodeChanged();
|
814
|
+
}
|
815
|
+
});
|
816
|
+
}
|
817
|
+
|
818
|
+
/**
|
819
|
+
* WebKit doesn't select all the nodes in the body when you press Ctrl+A.
|
820
|
+
* IE selects more than the contents <body>[<p>a</p>]</body> instead of <body><p>[a]</p]</body> see bug #6438
|
821
|
+
* This selects the whole body so that backspace/delete logic will delete everything
|
822
|
+
*/
|
823
|
+
function selectAll() {
|
824
|
+
editor.shortcuts.add('meta+a', null, 'SelectAll');
|
825
|
+
}
|
826
|
+
|
827
|
+
/**
|
828
|
+
* WebKit has a weird issue where it some times fails to properly convert keypresses to input method keystrokes.
|
829
|
+
* The IME on Mac doesn't initialize when it doesn't fire a proper focus event.
|
830
|
+
*
|
831
|
+
* This seems to happen when the user manages to click the documentElement element then the window doesn't get proper focus until
|
832
|
+
* you enter a character into the editor.
|
833
|
+
*
|
834
|
+
* It also happens when the first focus in made to the body.
|
835
|
+
*
|
836
|
+
* See: https://bugs.webkit.org/show_bug.cgi?id=83566
|
837
|
+
*/
|
838
|
+
function inputMethodFocus() {
|
839
|
+
if (!editor.settings.content_editable) {
|
840
|
+
// Case 1 IME doesn't initialize if you focus the document
|
841
|
+
// Disabled since it was interferring with the cE=false logic
|
842
|
+
// Also coultn't reproduce the issue on Safari 9
|
843
|
+
/*dom.bind(editor.getDoc(), 'focusin', function() {
|
844
|
+
selection.setRng(selection.getRng());
|
845
|
+
});*/
|
846
|
+
|
847
|
+
// Case 2 IME doesn't initialize if you click the documentElement it also doesn't properly fire the focusin event
|
848
|
+
// Needs to be both down/up due to weird rendering bug on Chrome Windows
|
849
|
+
dom.bind(editor.getDoc(), 'mousedown mouseup', function(e) {
|
850
|
+
var rng;
|
851
|
+
|
852
|
+
if (e.target == editor.getDoc().documentElement) {
|
853
|
+
rng = selection.getRng();
|
854
|
+
editor.getBody().focus();
|
855
|
+
|
856
|
+
if (e.type == 'mousedown') {
|
857
|
+
if (CaretContainer.isCaretContainer(rng.startContainer)) {
|
858
|
+
return;
|
859
|
+
}
|
860
|
+
|
861
|
+
// Edge case for mousedown, drag select and mousedown again within selection on Chrome Windows to render caret
|
862
|
+
selection.placeCaretAt(e.clientX, e.clientY);
|
863
|
+
} else {
|
864
|
+
selection.setRng(rng);
|
865
|
+
}
|
866
|
+
}
|
867
|
+
});
|
868
|
+
}
|
869
|
+
}
|
870
|
+
|
871
|
+
/**
|
872
|
+
* Backspacing in FireFox/IE from a paragraph into a horizontal rule results in a floating text node because the
|
873
|
+
* browser just deletes the paragraph - the browser fails to merge the text node with a horizontal rule so it is
|
874
|
+
* left there. TinyMCE sees a floating text node and wraps it in a paragraph on the key up event (ForceBlocks.js
|
875
|
+
* addRootBlocks), meaning the action does nothing. With this code, FireFox/IE matche the behaviour of other
|
876
|
+
* browsers.
|
877
|
+
*
|
878
|
+
* It also fixes a bug on Firefox where it's impossible to delete HR elements.
|
879
|
+
*/
|
880
|
+
function removeHrOnBackspace() {
|
881
|
+
editor.on('keydown', function(e) {
|
882
|
+
if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
|
883
|
+
// Check if there is any HR elements this is faster since getRng on IE 7 & 8 is slow
|
884
|
+
if (!editor.getBody().getElementsByTagName('hr').length) {
|
885
|
+
return;
|
886
|
+
}
|
887
|
+
|
888
|
+
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
|
889
|
+
var node = selection.getNode();
|
890
|
+
var previousSibling = node.previousSibling;
|
891
|
+
|
892
|
+
if (node.nodeName == 'HR') {
|
893
|
+
dom.remove(node);
|
894
|
+
e.preventDefault();
|
895
|
+
return;
|
896
|
+
}
|
897
|
+
|
898
|
+
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
|
899
|
+
dom.remove(previousSibling);
|
900
|
+
e.preventDefault();
|
901
|
+
}
|
902
|
+
}
|
903
|
+
}
|
904
|
+
});
|
905
|
+
}
|
906
|
+
|
907
|
+
/**
|
908
|
+
* Firefox 3.x has an issue where the body element won't get proper focus if you click out
|
909
|
+
* side it's rectangle.
|
910
|
+
*/
|
911
|
+
function focusBody() {
|
912
|
+
// Fix for a focus bug in FF 3.x where the body element
|
913
|
+
// wouldn't get proper focus if the user clicked on the HTML element
|
914
|
+
if (!window.Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4
|
915
|
+
editor.on('mousedown', function(e) {
|
916
|
+
if (!isDefaultPrevented(e) && e.target.nodeName === "HTML") {
|
917
|
+
var body = editor.getBody();
|
918
|
+
|
919
|
+
// Blur the body it's focused but not correctly focused
|
920
|
+
body.blur();
|
921
|
+
|
922
|
+
// Refocus the body after a little while
|
923
|
+
Delay.setEditorTimeout(editor, function() {
|
924
|
+
body.focus();
|
925
|
+
});
|
926
|
+
}
|
927
|
+
});
|
928
|
+
}
|
929
|
+
}
|
930
|
+
|
931
|
+
/**
|
932
|
+
* WebKit has a bug where it isn't possible to select image, hr or anchor elements
|
933
|
+
* by clicking on them so we need to fake that.
|
934
|
+
*/
|
935
|
+
function selectControlElements() {
|
936
|
+
editor.on('click', function(e) {
|
937
|
+
var target = e.target;
|
938
|
+
|
939
|
+
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
|
940
|
+
// WebKit can't even do simple things like selecting an image
|
941
|
+
// Needs to be the setBaseAndExtend or it will fail to select floated images
|
942
|
+
if (/^(IMG|HR)$/.test(target.nodeName) && dom.getContentEditableParent(target) !== "false") {
|
943
|
+
e.preventDefault();
|
944
|
+
selection.getSel().setBaseAndExtent(target, 0, target, 1);
|
945
|
+
editor.nodeChanged();
|
946
|
+
}
|
947
|
+
|
948
|
+
if (target.nodeName == 'A' && dom.hasClass(target, 'mce-item-anchor')) {
|
949
|
+
e.preventDefault();
|
950
|
+
selection.select(target);
|
951
|
+
}
|
952
|
+
});
|
953
|
+
}
|
954
|
+
|
955
|
+
/**
|
956
|
+
* Fixes a Gecko bug where the style attribute gets added to the wrong element when deleting between two block elements.
|
957
|
+
*
|
958
|
+
* Fixes do backspace/delete on this:
|
959
|
+
* <p>bla[ck</p><p style="color:red">r]ed</p>
|
960
|
+
*
|
961
|
+
* Would become:
|
962
|
+
* <p>bla|ed</p>
|
963
|
+
*
|
964
|
+
* Instead of:
|
965
|
+
* <p style="color:red">bla|ed</p>
|
966
|
+
*/
|
967
|
+
function removeStylesWhenDeletingAcrossBlockElements() {
|
968
|
+
function getAttributeApplyFunction() {
|
969
|
+
var template = dom.getAttribs(selection.getStart().cloneNode(false));
|
970
|
+
|
971
|
+
return function() {
|
972
|
+
var target = selection.getStart();
|
973
|
+
|
974
|
+
if (target !== editor.getBody()) {
|
975
|
+
dom.setAttrib(target, "style", null);
|
976
|
+
|
977
|
+
each(template, function(attr) {
|
978
|
+
target.setAttributeNode(attr.cloneNode(true));
|
979
|
+
});
|
980
|
+
}
|
981
|
+
};
|
982
|
+
}
|
983
|
+
|
984
|
+
function isSelectionAcrossElements() {
|
985
|
+
return !selection.isCollapsed() &&
|
986
|
+
dom.getParent(selection.getStart(), dom.isBlock) != dom.getParent(selection.getEnd(), dom.isBlock);
|
987
|
+
}
|
988
|
+
|
989
|
+
editor.on('keypress', function(e) {
|
990
|
+
var applyAttributes;
|
991
|
+
|
992
|
+
if (!isDefaultPrevented(e) && (e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
|
993
|
+
applyAttributes = getAttributeApplyFunction();
|
994
|
+
editor.getDoc().execCommand('delete', false, null);
|
995
|
+
applyAttributes();
|
996
|
+
e.preventDefault();
|
997
|
+
return false;
|
998
|
+
}
|
999
|
+
});
|
1000
|
+
|
1001
|
+
dom.bind(editor.getDoc(), 'cut', function(e) {
|
1002
|
+
var applyAttributes;
|
1003
|
+
|
1004
|
+
if (!isDefaultPrevented(e) && isSelectionAcrossElements()) {
|
1005
|
+
applyAttributes = getAttributeApplyFunction();
|
1006
|
+
|
1007
|
+
Delay.setEditorTimeout(editor, function() {
|
1008
|
+
applyAttributes();
|
1009
|
+
});
|
1010
|
+
}
|
1011
|
+
});
|
1012
|
+
}
|
1013
|
+
|
1014
|
+
/**
|
1015
|
+
* Screen readers on IE needs to have the role application set on the body.
|
1016
|
+
*/
|
1017
|
+
function ensureBodyHasRoleApplication() {
|
1018
|
+
document.body.setAttribute("role", "application");
|
1019
|
+
}
|
1020
|
+
|
1021
|
+
/**
|
1022
|
+
* Backspacing into a table behaves differently depending upon browser type.
|
1023
|
+
* Therefore, disable Backspace when cursor immediately follows a table.
|
1024
|
+
*/
|
1025
|
+
function disableBackspaceIntoATable() {
|
1026
|
+
editor.on('keydown', function(e) {
|
1027
|
+
if (!isDefaultPrevented(e) && e.keyCode === BACKSPACE) {
|
1028
|
+
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
|
1029
|
+
var previousSibling = selection.getNode().previousSibling;
|
1030
|
+
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") {
|
1031
|
+
e.preventDefault();
|
1032
|
+
return false;
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
}
|
1036
|
+
});
|
1037
|
+
}
|
1038
|
+
|
1039
|
+
/**
|
1040
|
+
* Old IE versions can't properly render BR elements in PRE tags white in contentEditable mode. So this
|
1041
|
+
* logic adds a \n before the BR so that it will get rendered.
|
1042
|
+
*/
|
1043
|
+
function addNewLinesBeforeBrInPre() {
|
1044
|
+
// IE8+ rendering mode does the right thing with BR in PRE
|
1045
|
+
if (getDocumentMode() > 7) {
|
1046
|
+
return;
|
1047
|
+
}
|
1048
|
+
|
1049
|
+
// Enable display: none in area and add a specific class that hides all BR elements in PRE to
|
1050
|
+
// avoid the caret from getting stuck at the BR elements while pressing the right arrow key
|
1051
|
+
setEditorCommandState('RespectVisibilityInDesign', true);
|
1052
|
+
editor.contentStyles.push('.mceHideBrInPre pre br {display: none}');
|
1053
|
+
dom.addClass(editor.getBody(), 'mceHideBrInPre');
|
1054
|
+
|
1055
|
+
// Adds a \n before all BR elements in PRE to get them visual
|
1056
|
+
parser.addNodeFilter('pre', function(nodes) {
|
1057
|
+
var i = nodes.length, brNodes, j, brElm, sibling;
|
1058
|
+
|
1059
|
+
while (i--) {
|
1060
|
+
brNodes = nodes[i].getAll('br');
|
1061
|
+
j = brNodes.length;
|
1062
|
+
while (j--) {
|
1063
|
+
brElm = brNodes[j];
|
1064
|
+
|
1065
|
+
// Add \n before BR in PRE elements on older IE:s so the new lines get rendered
|
1066
|
+
sibling = brElm.prev;
|
1067
|
+
if (sibling && sibling.type === 3 && sibling.value.charAt(sibling.value - 1) != '\n') {
|
1068
|
+
sibling.value += '\n';
|
1069
|
+
} else {
|
1070
|
+
brElm.parent.insert(new Node('#text', 3), brElm, true).value = '\n';
|
1071
|
+
}
|
1072
|
+
}
|
1073
|
+
}
|
1074
|
+
});
|
1075
|
+
|
1076
|
+
// Removes any \n before BR elements in PRE since other browsers and in contentEditable=false mode they will be visible
|
1077
|
+
serializer.addNodeFilter('pre', function(nodes) {
|
1078
|
+
var i = nodes.length, brNodes, j, brElm, sibling;
|
1079
|
+
|
1080
|
+
while (i--) {
|
1081
|
+
brNodes = nodes[i].getAll('br');
|
1082
|
+
j = brNodes.length;
|
1083
|
+
while (j--) {
|
1084
|
+
brElm = brNodes[j];
|
1085
|
+
sibling = brElm.prev;
|
1086
|
+
if (sibling && sibling.type == 3) {
|
1087
|
+
sibling.value = sibling.value.replace(/\r?\n$/, '');
|
1088
|
+
}
|
1089
|
+
}
|
1090
|
+
}
|
1091
|
+
});
|
1092
|
+
}
|
1093
|
+
|
1094
|
+
/**
|
1095
|
+
* Moves style width/height to attribute width/height when the user resizes an image on IE.
|
1096
|
+
*/
|
1097
|
+
function removePreSerializedStylesWhenSelectingControls() {
|
1098
|
+
dom.bind(editor.getBody(), 'mouseup', function() {
|
1099
|
+
var value, node = selection.getNode();
|
1100
|
+
|
1101
|
+
// Moved styles to attributes on IMG eements
|
1102
|
+
if (node.nodeName == 'IMG') {
|
1103
|
+
// Convert style width to width attribute
|
1104
|
+
if ((value = dom.getStyle(node, 'width'))) {
|
1105
|
+
dom.setAttrib(node, 'width', value.replace(/[^0-9%]+/g, ''));
|
1106
|
+
dom.setStyle(node, 'width', '');
|
1107
|
+
}
|
1108
|
+
|
1109
|
+
// Convert style height to height attribute
|
1110
|
+
if ((value = dom.getStyle(node, 'height'))) {
|
1111
|
+
dom.setAttrib(node, 'height', value.replace(/[^0-9%]+/g, ''));
|
1112
|
+
dom.setStyle(node, 'height', '');
|
1113
|
+
}
|
1114
|
+
}
|
1115
|
+
});
|
1116
|
+
}
|
1117
|
+
|
1118
|
+
/**
|
1119
|
+
* Removes a blockquote when backspace is pressed at the beginning of it.
|
1120
|
+
*
|
1121
|
+
* For example:
|
1122
|
+
* <blockquote><p>|x</p></blockquote>
|
1123
|
+
*
|
1124
|
+
* Becomes:
|
1125
|
+
* <p>|x</p>
|
1126
|
+
*/
|
1127
|
+
function removeBlockQuoteOnBackSpace() {
|
1128
|
+
// Add block quote deletion handler
|
1129
|
+
editor.on('keydown', function(e) {
|
1130
|
+
var rng, container, offset, root, parent;
|
1131
|
+
|
1132
|
+
if (isDefaultPrevented(e) || e.keyCode != VK.BACKSPACE) {
|
1133
|
+
return;
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
rng = selection.getRng();
|
1137
|
+
container = rng.startContainer;
|
1138
|
+
offset = rng.startOffset;
|
1139
|
+
root = dom.getRoot();
|
1140
|
+
parent = container;
|
1141
|
+
|
1142
|
+
if (!rng.collapsed || offset !== 0) {
|
1143
|
+
return;
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
while (parent && parent.parentNode && parent.parentNode.firstChild == parent && parent.parentNode != root) {
|
1147
|
+
parent = parent.parentNode;
|
1148
|
+
}
|
1149
|
+
|
1150
|
+
// Is the cursor at the beginning of a blockquote?
|
1151
|
+
if (parent.tagName === 'BLOCKQUOTE') {
|
1152
|
+
// Remove the blockquote
|
1153
|
+
editor.formatter.toggle('blockquote', null, parent);
|
1154
|
+
|
1155
|
+
// Move the caret to the beginning of container
|
1156
|
+
rng = dom.createRng();
|
1157
|
+
rng.setStart(container, 0);
|
1158
|
+
rng.setEnd(container, 0);
|
1159
|
+
selection.setRng(rng);
|
1160
|
+
}
|
1161
|
+
});
|
1162
|
+
}
|
1163
|
+
|
1164
|
+
/**
|
1165
|
+
* Sets various Gecko editing options on mouse down and before a execCommand to disable inline table editing that is broken etc.
|
1166
|
+
*/
|
1167
|
+
function setGeckoEditingOptions() {
|
1168
|
+
function setOpts() {
|
1169
|
+
editor._refreshContentEditable();
|
1170
|
+
|
1171
|
+
setEditorCommandState("StyleWithCSS", false);
|
1172
|
+
setEditorCommandState("enableInlineTableEditing", false);
|
1173
|
+
|
1174
|
+
if (!settings.object_resizing) {
|
1175
|
+
setEditorCommandState("enableObjectResizing", false);
|
1176
|
+
}
|
1177
|
+
}
|
1178
|
+
|
1179
|
+
if (!settings.readonly) {
|
1180
|
+
editor.on('BeforeExecCommand MouseDown', setOpts);
|
1181
|
+
}
|
1182
|
+
}
|
1183
|
+
|
1184
|
+
/**
|
1185
|
+
* Fixes a gecko link bug, when a link is placed at the end of block elements there is
|
1186
|
+
* no way to move the caret behind the link. This fix adds a bogus br element after the link.
|
1187
|
+
*
|
1188
|
+
* For example this:
|
1189
|
+
* <p><b><a href="#">x</a></b></p>
|
1190
|
+
*
|
1191
|
+
* Becomes this:
|
1192
|
+
* <p><b><a href="#">x</a></b><br></p>
|
1193
|
+
*/
|
1194
|
+
function addBrAfterLastLinks() {
|
1195
|
+
function fixLinks() {
|
1196
|
+
each(dom.select('a'), function(node) {
|
1197
|
+
var parentNode = node.parentNode, root = dom.getRoot();
|
1198
|
+
|
1199
|
+
if (parentNode.lastChild === node) {
|
1200
|
+
while (parentNode && !dom.isBlock(parentNode)) {
|
1201
|
+
if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
|
1202
|
+
return;
|
1203
|
+
}
|
1204
|
+
|
1205
|
+
parentNode = parentNode.parentNode;
|
1206
|
+
}
|
1207
|
+
|
1208
|
+
dom.add(parentNode, 'br', {'data-mce-bogus': 1});
|
1209
|
+
}
|
1210
|
+
});
|
1211
|
+
}
|
1212
|
+
|
1213
|
+
editor.on('SetContent ExecCommand', function(e) {
|
1214
|
+
if (e.type == "setcontent" || e.command === 'mceInsertLink') {
|
1215
|
+
fixLinks();
|
1216
|
+
}
|
1217
|
+
});
|
1218
|
+
}
|
1219
|
+
|
1220
|
+
/**
|
1221
|
+
* WebKit will produce DIV elements here and there by default. But since TinyMCE uses paragraphs by
|
1222
|
+
* default we want to change that behavior.
|
1223
|
+
*/
|
1224
|
+
function setDefaultBlockType() {
|
1225
|
+
if (settings.forced_root_block) {
|
1226
|
+
editor.on('init', function() {
|
1227
|
+
setEditorCommandState('DefaultParagraphSeparator', settings.forced_root_block);
|
1228
|
+
});
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
|
1232
|
+
/**
|
1233
|
+
* Deletes the selected image on IE instead of navigating to previous page.
|
1234
|
+
*/
|
1235
|
+
function deleteControlItemOnBackSpace() {
|
1236
|
+
editor.on('keydown', function(e) {
|
1237
|
+
var rng;
|
1238
|
+
|
1239
|
+
if (!isDefaultPrevented(e) && e.keyCode == BACKSPACE) {
|
1240
|
+
rng = editor.getDoc().selection.createRange();
|
1241
|
+
if (rng && rng.item) {
|
1242
|
+
e.preventDefault();
|
1243
|
+
editor.undoManager.beforeChange();
|
1244
|
+
dom.remove(rng.item(0));
|
1245
|
+
editor.undoManager.add();
|
1246
|
+
}
|
1247
|
+
}
|
1248
|
+
});
|
1249
|
+
}
|
1250
|
+
|
1251
|
+
/**
|
1252
|
+
* IE10 doesn't properly render block elements with the right height until you add contents to them.
|
1253
|
+
* This fixes that by adding a padding-right to all empty text block elements.
|
1254
|
+
* See: https://connect.microsoft.com/IE/feedback/details/743881
|
1255
|
+
*/
|
1256
|
+
function renderEmptyBlocksFix() {
|
1257
|
+
var emptyBlocksCSS;
|
1258
|
+
|
1259
|
+
// IE10+
|
1260
|
+
if (getDocumentMode() >= 10) {
|
1261
|
+
emptyBlocksCSS = '';
|
1262
|
+
each('p div h1 h2 h3 h4 h5 h6'.split(' '), function(name, i) {
|
1263
|
+
emptyBlocksCSS += (i > 0 ? ',' : '') + name + ':empty';
|
1264
|
+
});
|
1265
|
+
|
1266
|
+
editor.contentStyles.push(emptyBlocksCSS + '{padding-right: 1px !important}');
|
1267
|
+
}
|
1268
|
+
}
|
1269
|
+
|
1270
|
+
/**
|
1271
|
+
* Old IE versions can't retain contents within noscript elements so this logic will store the contents
|
1272
|
+
* as a attribute and the insert that value as it's raw text when the DOM is serialized.
|
1273
|
+
*/
|
1274
|
+
function keepNoScriptContents() {
|
1275
|
+
if (getDocumentMode() < 9) {
|
1276
|
+
parser.addNodeFilter('noscript', function(nodes) {
|
1277
|
+
var i = nodes.length, node, textNode;
|
1278
|
+
|
1279
|
+
while (i--) {
|
1280
|
+
node = nodes[i];
|
1281
|
+
textNode = node.firstChild;
|
1282
|
+
|
1283
|
+
if (textNode) {
|
1284
|
+
node.attr('data-mce-innertext', textNode.value);
|
1285
|
+
}
|
1286
|
+
}
|
1287
|
+
});
|
1288
|
+
|
1289
|
+
serializer.addNodeFilter('noscript', function(nodes) {
|
1290
|
+
var i = nodes.length, node, textNode, value;
|
1291
|
+
|
1292
|
+
while (i--) {
|
1293
|
+
node = nodes[i];
|
1294
|
+
textNode = nodes[i].firstChild;
|
1295
|
+
|
1296
|
+
if (textNode) {
|
1297
|
+
textNode.value = Entities.decode(textNode.value);
|
1298
|
+
} else {
|
1299
|
+
// Old IE can't retain noscript value so an attribute is used to store it
|
1300
|
+
value = node.attributes.map['data-mce-innertext'];
|
1301
|
+
if (value) {
|
1302
|
+
node.attr('data-mce-innertext', null);
|
1303
|
+
textNode = new Node('#text', 3);
|
1304
|
+
textNode.value = value;
|
1305
|
+
textNode.raw = true;
|
1306
|
+
node.append(textNode);
|
1307
|
+
}
|
1308
|
+
}
|
1309
|
+
}
|
1310
|
+
});
|
1311
|
+
}
|
1312
|
+
}
|
1313
|
+
|
1314
|
+
/**
|
1315
|
+
* IE has an issue where you can't select/move the caret by clicking outside the body if the document is in standards mode.
|
1316
|
+
*/
|
1317
|
+
function fixCaretSelectionOfDocumentElementOnIe() {
|
1318
|
+
var doc = dom.doc, body = doc.body, started, startRng, htmlElm;
|
1319
|
+
|
1320
|
+
// Return range from point or null if it failed
|
1321
|
+
function rngFromPoint(x, y) {
|
1322
|
+
var rng = body.createTextRange();
|
1323
|
+
|
1324
|
+
try {
|
1325
|
+
rng.moveToPoint(x, y);
|
1326
|
+
} catch (ex) {
|
1327
|
+
// IE sometimes throws and exception, so lets just ignore it
|
1328
|
+
rng = null;
|
1329
|
+
}
|
1330
|
+
|
1331
|
+
return rng;
|
1332
|
+
}
|
1333
|
+
|
1334
|
+
// Fires while the selection is changing
|
1335
|
+
function selectionChange(e) {
|
1336
|
+
var pointRng;
|
1337
|
+
|
1338
|
+
// Check if the button is down or not
|
1339
|
+
if (e.button) {
|
1340
|
+
// Create range from mouse position
|
1341
|
+
pointRng = rngFromPoint(e.x, e.y);
|
1342
|
+
|
1343
|
+
if (pointRng) {
|
1344
|
+
// Check if pointRange is before/after selection then change the endPoint
|
1345
|
+
if (pointRng.compareEndPoints('StartToStart', startRng) > 0) {
|
1346
|
+
pointRng.setEndPoint('StartToStart', startRng);
|
1347
|
+
} else {
|
1348
|
+
pointRng.setEndPoint('EndToEnd', startRng);
|
1349
|
+
}
|
1350
|
+
|
1351
|
+
pointRng.select();
|
1352
|
+
}
|
1353
|
+
} else {
|
1354
|
+
endSelection();
|
1355
|
+
}
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
// Removes listeners
|
1359
|
+
function endSelection() {
|
1360
|
+
var rng = doc.selection.createRange();
|
1361
|
+
|
1362
|
+
// If the range is collapsed then use the last start range
|
1363
|
+
if (startRng && !rng.item && rng.compareEndPoints('StartToEnd', rng) === 0) {
|
1364
|
+
startRng.select();
|
1365
|
+
}
|
1366
|
+
|
1367
|
+
dom.unbind(doc, 'mouseup', endSelection);
|
1368
|
+
dom.unbind(doc, 'mousemove', selectionChange);
|
1369
|
+
startRng = started = 0;
|
1370
|
+
}
|
1371
|
+
|
1372
|
+
// Make HTML element unselectable since we are going to handle selection by hand
|
1373
|
+
doc.documentElement.unselectable = true;
|
1374
|
+
|
1375
|
+
// Detect when user selects outside BODY
|
1376
|
+
dom.bind(doc, 'mousedown contextmenu', function(e) {
|
1377
|
+
if (e.target.nodeName === 'HTML') {
|
1378
|
+
if (started) {
|
1379
|
+
endSelection();
|
1380
|
+
}
|
1381
|
+
|
1382
|
+
// Detect vertical scrollbar, since IE will fire a mousedown on the scrollbar and have target set as HTML
|
1383
|
+
htmlElm = doc.documentElement;
|
1384
|
+
if (htmlElm.scrollHeight > htmlElm.clientHeight) {
|
1385
|
+
return;
|
1386
|
+
}
|
1387
|
+
|
1388
|
+
started = 1;
|
1389
|
+
// Setup start position
|
1390
|
+
startRng = rngFromPoint(e.x, e.y);
|
1391
|
+
if (startRng) {
|
1392
|
+
// Listen for selection change events
|
1393
|
+
dom.bind(doc, 'mouseup', endSelection);
|
1394
|
+
dom.bind(doc, 'mousemove', selectionChange);
|
1395
|
+
|
1396
|
+
dom.getRoot().focus();
|
1397
|
+
startRng.select();
|
1398
|
+
}
|
1399
|
+
}
|
1400
|
+
});
|
1401
|
+
}
|
1402
|
+
|
1403
|
+
/**
|
1404
|
+
* Fixes selection issues where the caret can be placed between two inline elements like <b>a</b>|<b>b</b>
|
1405
|
+
* this fix will lean the caret right into the closest inline element.
|
1406
|
+
*/
|
1407
|
+
function normalizeSelection() {
|
1408
|
+
// Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything
|
1409
|
+
editor.on('keyup focusin mouseup', function(e) {
|
1410
|
+
if (e.keyCode != 65 || !VK.metaKeyPressed(e)) {
|
1411
|
+
selection.normalize();
|
1412
|
+
}
|
1413
|
+
}, true);
|
1414
|
+
}
|
1415
|
+
|
1416
|
+
/**
|
1417
|
+
* Forces Gecko to render a broken image icon if it fails to load an image.
|
1418
|
+
*/
|
1419
|
+
function showBrokenImageIcon() {
|
1420
|
+
editor.contentStyles.push(
|
1421
|
+
'img:-moz-broken {' +
|
1422
|
+
'-moz-force-broken-image-icon:1;' +
|
1423
|
+
'min-width:24px;' +
|
1424
|
+
'min-height:24px' +
|
1425
|
+
'}'
|
1426
|
+
);
|
1427
|
+
}
|
1428
|
+
|
1429
|
+
/**
|
1430
|
+
* iOS has a bug where it's impossible to type if the document has a touchstart event
|
1431
|
+
* bound and the user touches the document while having the on screen keyboard visible.
|
1432
|
+
*
|
1433
|
+
* The touch event moves the focus to the parent document while having the caret inside the iframe
|
1434
|
+
* this fix moves the focus back into the iframe document.
|
1435
|
+
*/
|
1436
|
+
function restoreFocusOnKeyDown() {
|
1437
|
+
if (!editor.inline) {
|
1438
|
+
editor.on('keydown', function() {
|
1439
|
+
if (document.activeElement == document.body) {
|
1440
|
+
editor.getWin().focus();
|
1441
|
+
}
|
1442
|
+
});
|
1443
|
+
}
|
1444
|
+
}
|
1445
|
+
|
1446
|
+
/**
|
1447
|
+
* IE 11 has an annoying issue where you can't move focus into the editor
|
1448
|
+
* by clicking on the white area HTML element. We used to be able to to fix this with
|
1449
|
+
* the fixCaretSelectionOfDocumentElementOnIe fix. But since M$ removed the selection
|
1450
|
+
* object it's not possible anymore. So we need to hack in a ungly CSS to force the
|
1451
|
+
* body to be at least 150px. If the user clicks the HTML element out side this 150px region
|
1452
|
+
* we simply move the focus into the first paragraph. Not ideal since you loose the
|
1453
|
+
* positioning of the caret but goot enough for most cases.
|
1454
|
+
*/
|
1455
|
+
function bodyHeight() {
|
1456
|
+
if (!editor.inline) {
|
1457
|
+
editor.contentStyles.push('body {min-height: 150px}');
|
1458
|
+
editor.on('click', function(e) {
|
1459
|
+
var rng;
|
1460
|
+
|
1461
|
+
if (e.target.nodeName == 'HTML') {
|
1462
|
+
// Edge seems to only need focus if we set the range
|
1463
|
+
// the caret will become invisible and moved out of the iframe!!
|
1464
|
+
if (Env.ie > 11) {
|
1465
|
+
editor.getBody().focus();
|
1466
|
+
return;
|
1467
|
+
}
|
1468
|
+
|
1469
|
+
// Need to store away non collapsed ranges since the focus call will mess that up see #7382
|
1470
|
+
rng = editor.selection.getRng();
|
1471
|
+
editor.getBody().focus();
|
1472
|
+
editor.selection.setRng(rng);
|
1473
|
+
editor.selection.normalize();
|
1474
|
+
editor.nodeChanged();
|
1475
|
+
}
|
1476
|
+
});
|
1477
|
+
}
|
1478
|
+
}
|
1479
|
+
|
1480
|
+
/**
|
1481
|
+
* Firefox on Mac OS will move the browser back to the previous page if you press CMD+Left arrow.
|
1482
|
+
* You might then loose all your work so we need to block that behavior and replace it with our own.
|
1483
|
+
*/
|
1484
|
+
function blockCmdArrowNavigation() {
|
1485
|
+
if (Env.mac) {
|
1486
|
+
editor.on('keydown', function(e) {
|
1487
|
+
if (VK.metaKeyPressed(e) && !e.shiftKey && (e.keyCode == 37 || e.keyCode == 39)) {
|
1488
|
+
e.preventDefault();
|
1489
|
+
editor.selection.getSel().modify('move', e.keyCode == 37 ? 'backward' : 'forward', 'lineboundary');
|
1490
|
+
}
|
1491
|
+
});
|
1492
|
+
}
|
1493
|
+
}
|
1494
|
+
|
1495
|
+
/**
|
1496
|
+
* Disables the autolinking in IE 9+ this is then re-enabled by the autolink plugin.
|
1497
|
+
*/
|
1498
|
+
function disableAutoUrlDetect() {
|
1499
|
+
setEditorCommandState("AutoUrlDetect", false);
|
1500
|
+
}
|
1501
|
+
|
1502
|
+
/**
|
1503
|
+
* iOS 7.1 introduced two new bugs:
|
1504
|
+
* 1) It's possible to open links within a contentEditable area by clicking on them.
|
1505
|
+
* 2) If you hold down the finger it will display the link/image touch callout menu.
|
1506
|
+
*/
|
1507
|
+
function tapLinksAndImages() {
|
1508
|
+
editor.on('click', function(e) {
|
1509
|
+
var elm = e.target;
|
1510
|
+
|
1511
|
+
do {
|
1512
|
+
if (elm.tagName === 'A') {
|
1513
|
+
e.preventDefault();
|
1514
|
+
return;
|
1515
|
+
}
|
1516
|
+
} while ((elm = elm.parentNode));
|
1517
|
+
});
|
1518
|
+
|
1519
|
+
editor.contentStyles.push('.mce-content-body {-webkit-touch-callout: none}');
|
1520
|
+
}
|
1521
|
+
|
1522
|
+
/**
|
1523
|
+
* iOS Safari and possible other browsers have a bug where it won't fire
|
1524
|
+
* a click event when a contentEditable is focused. This function fakes click events
|
1525
|
+
* by using touchstart/touchend and measuring the time and distance travelled.
|
1526
|
+
*/
|
1527
|
+
/*
|
1528
|
+
function touchClickEvent() {
|
1529
|
+
editor.on('touchstart', function(e) {
|
1530
|
+
var elm, time, startTouch, changedTouches;
|
1531
|
+
|
1532
|
+
elm = e.target;
|
1533
|
+
time = new Date().getTime();
|
1534
|
+
changedTouches = e.changedTouches;
|
1535
|
+
|
1536
|
+
if (!changedTouches || changedTouches.length > 1) {
|
1537
|
+
return;
|
1538
|
+
}
|
1539
|
+
|
1540
|
+
startTouch = changedTouches[0];
|
1541
|
+
|
1542
|
+
editor.once('touchend', function(e) {
|
1543
|
+
var endTouch = e.changedTouches[0], args;
|
1544
|
+
|
1545
|
+
if (new Date().getTime() - time > 500) {
|
1546
|
+
return;
|
1547
|
+
}
|
1548
|
+
|
1549
|
+
if (Math.abs(startTouch.clientX - endTouch.clientX) > 5) {
|
1550
|
+
return;
|
1551
|
+
}
|
1552
|
+
|
1553
|
+
if (Math.abs(startTouch.clientY - endTouch.clientY) > 5) {
|
1554
|
+
return;
|
1555
|
+
}
|
1556
|
+
|
1557
|
+
args = {
|
1558
|
+
target: elm
|
1559
|
+
};
|
1560
|
+
|
1561
|
+
each('pageX pageY clientX clientY screenX screenY'.split(' '), function(key) {
|
1562
|
+
args[key] = endTouch[key];
|
1563
|
+
});
|
1564
|
+
|
1565
|
+
args = editor.fire('click', args);
|
1566
|
+
|
1567
|
+
if (!args.isDefaultPrevented()) {
|
1568
|
+
// iOS WebKit can't place the caret properly once
|
1569
|
+
// you bind touch events so we need to do this manually
|
1570
|
+
// TODO: Expand to the closest word? Touble tap still works.
|
1571
|
+
editor.selection.placeCaretAt(endTouch.clientX, endTouch.clientY);
|
1572
|
+
editor.nodeChanged();
|
1573
|
+
}
|
1574
|
+
});
|
1575
|
+
});
|
1576
|
+
}
|
1577
|
+
*/
|
1578
|
+
|
1579
|
+
/**
|
1580
|
+
* WebKit has a bug where it will allow forms to be submitted if they are inside a contentEditable element.
|
1581
|
+
* For example this: <form><button></form>
|
1582
|
+
*/
|
1583
|
+
function blockFormSubmitInsideEditor() {
|
1584
|
+
editor.on('init', function() {
|
1585
|
+
editor.dom.bind(editor.getBody(), 'submit', function(e) {
|
1586
|
+
e.preventDefault();
|
1587
|
+
});
|
1588
|
+
});
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
/**
|
1592
|
+
* Sometimes WebKit/Blink generates BR elements with the Apple-interchange-newline class.
|
1593
|
+
*
|
1594
|
+
* Scenario:
|
1595
|
+
* 1) Create a table 2x2.
|
1596
|
+
* 2) Select and copy cells A2-B2.
|
1597
|
+
* 3) Paste and it will add BR element to table cell.
|
1598
|
+
*/
|
1599
|
+
function removeAppleInterchangeBrs() {
|
1600
|
+
parser.addNodeFilter('br', function(nodes) {
|
1601
|
+
var i = nodes.length;
|
1602
|
+
|
1603
|
+
while (i--) {
|
1604
|
+
if (nodes[i].attr('class') == 'Apple-interchange-newline') {
|
1605
|
+
nodes[i].remove();
|
1606
|
+
}
|
1607
|
+
}
|
1608
|
+
});
|
1609
|
+
}
|
1610
|
+
|
1611
|
+
/**
|
1612
|
+
* IE cannot set custom contentType's on drag events, and also does not properly drag/drop between
|
1613
|
+
* editors. This uses a special data:text/mce-internal URL to pass data when drag/drop between editors.
|
1614
|
+
*/
|
1615
|
+
function ieInternalDragAndDrop() {
|
1616
|
+
editor.on('dragstart', function(e) {
|
1617
|
+
setMceInteralContent(e);
|
1618
|
+
});
|
1619
|
+
|
1620
|
+
editor.on('drop', function(e) {
|
1621
|
+
if (!isDefaultPrevented(e)) {
|
1622
|
+
var internalContent = getMceInternalContent(e);
|
1623
|
+
|
1624
|
+
if (internalContent && internalContent.id != editor.id) {
|
1625
|
+
e.preventDefault();
|
1626
|
+
|
1627
|
+
var rng = RangeUtils.getCaretRangeFromPoint(e.x, e.y, editor.getDoc());
|
1628
|
+
selection.setRng(rng);
|
1629
|
+
insertClipboardContents(internalContent.html);
|
1630
|
+
}
|
1631
|
+
}
|
1632
|
+
});
|
1633
|
+
}
|
1634
|
+
|
1635
|
+
// All browsers
|
1636
|
+
removeBlockQuoteOnBackSpace();
|
1637
|
+
emptyEditorWhenDeleting();
|
1638
|
+
|
1639
|
+
// Windows phone will return a range like [body, 0] on mousedown so
|
1640
|
+
// it will always normalize to the wrong location
|
1641
|
+
if (!Env.windowsPhone) {
|
1642
|
+
normalizeSelection();
|
1643
|
+
}
|
1644
|
+
|
1645
|
+
// WebKit
|
1646
|
+
if (isWebKit) {
|
1647
|
+
cleanupStylesWhenDeleting();
|
1648
|
+
inputMethodFocus();
|
1649
|
+
selectControlElements();
|
1650
|
+
setDefaultBlockType();
|
1651
|
+
blockFormSubmitInsideEditor();
|
1652
|
+
disableBackspaceIntoATable();
|
1653
|
+
removeAppleInterchangeBrs();
|
1654
|
+
//touchClickEvent();
|
1655
|
+
|
1656
|
+
// iOS
|
1657
|
+
if (Env.iOS) {
|
1658
|
+
restoreFocusOnKeyDown();
|
1659
|
+
bodyHeight();
|
1660
|
+
tapLinksAndImages();
|
1661
|
+
} else {
|
1662
|
+
selectAll();
|
1663
|
+
}
|
1664
|
+
}
|
1665
|
+
|
1666
|
+
// IE
|
1667
|
+
if (isIE && Env.ie < 11) {
|
1668
|
+
removeHrOnBackspace();
|
1669
|
+
ensureBodyHasRoleApplication();
|
1670
|
+
addNewLinesBeforeBrInPre();
|
1671
|
+
removePreSerializedStylesWhenSelectingControls();
|
1672
|
+
deleteControlItemOnBackSpace();
|
1673
|
+
renderEmptyBlocksFix();
|
1674
|
+
keepNoScriptContents();
|
1675
|
+
fixCaretSelectionOfDocumentElementOnIe();
|
1676
|
+
}
|
1677
|
+
|
1678
|
+
if (Env.ie >= 11) {
|
1679
|
+
bodyHeight();
|
1680
|
+
disableBackspaceIntoATable();
|
1681
|
+
}
|
1682
|
+
|
1683
|
+
if (Env.ie) {
|
1684
|
+
selectAll();
|
1685
|
+
disableAutoUrlDetect();
|
1686
|
+
ieInternalDragAndDrop();
|
1687
|
+
}
|
1688
|
+
|
1689
|
+
// Gecko
|
1690
|
+
if (isGecko) {
|
1691
|
+
removeHrOnBackspace();
|
1692
|
+
focusBody();
|
1693
|
+
removeStylesWhenDeletingAcrossBlockElements();
|
1694
|
+
setGeckoEditingOptions();
|
1695
|
+
addBrAfterLastLinks();
|
1696
|
+
showBrokenImageIcon();
|
1697
|
+
blockCmdArrowNavigation();
|
1698
|
+
disableBackspaceIntoATable();
|
1699
|
+
}
|
1700
|
+
};
|
1701
|
+
});
|