update tinymce to 3.5.0.1
This commit is contained in:
parent
205c09e4f0
commit
e39014a3a7
26 changed files with 5794 additions and 4903 deletions
|
|
@ -1,1528 +1,1562 @@
|
|||
Version 3.5b2 (2012-03-15)
|
||||
Rewrote the enter key logic to normalize browser behavior.
|
||||
Fixed so enter within PRE elements produces a BR and shift+enter breaks/end the PRE. Can be disabled using the br_in_pre option.
|
||||
Fixed bug where the selection wouldn't be correct after applying formatting and having the caret at the end of the new format node.
|
||||
Fixed bug where the noneditable plugin would process contents on raw input calls for example on undo/redo calls.
|
||||
Fixed bug where WebKit could produce an exception when a bookmark was requested when there wasn't a proper selection.
|
||||
Fixed bug where WebKit would fail to open the image dialog since it would be returning false for a class name instead of a string.
|
||||
Fixed so alignment and indentation works properly when forced_root_blocks is set to false. It will produce a DIV by default.
|
||||
Version 3.5b1 (2012-03-08)
|
||||
Added new event class that is faster and enables support for faking events.
|
||||
Added new self_closing_elements, short_ended_elements, boolean_attributes, non_empty_elements and block_elements options to control the HTML Schema.
|
||||
Added new schema option and support for the HTML5 schema.
|
||||
Added new visualblocks plugin that shows html5 blocks with visual borders.
|
||||
Added new types and selector options to make it easier to create editor instances with different configs.
|
||||
Added new preview of formatting options in various listboxes.
|
||||
Added new preview_styles option that enables control over what gets previewed.
|
||||
Fixed bug where content css would be loaded twice into iframe.
|
||||
Fixed bug where start elements with only whitespace in the attribute part wouldn't be correctly parsed.
|
||||
Fixed bug where the advlink dialog would produce an error about the addSelectAccessibility function not being defined.
|
||||
Fixed bug where the caret would be placed at an incorrect position if span was removed by the invalid_elements setting.
|
||||
Fixed bug where elements inside a white space preserve element like pre didn't inherit the behavior while parsing.
|
||||
Version 3.4.9.x (2012-02-xx)
|
||||
Improved behaviour of backspacing into a table to be consistant across browsers and disable backspace when cursor immediately follows a table.
|
||||
Improved edit CSS style plugin for single and multiple block selection and provide option to apply style to only selected text.
|
||||
Fixed bug in Chrome where moving caret down in table and pasting throws errors.
|
||||
Corrected reference to TinyMCE trim function.
|
||||
Fixed bug where Ignore All in IE did not remove the underline from the selected word.
|
||||
Fixed bug in html source editor word wrap option not wrapping text in Webkit browsers.
|
||||
Fixed bug where it was possible to insert an invalid colour in the color pop-up dialog.
|
||||
Fixed bug in Webkit where if anchor is on last line by itself caret can not be placed after it.
|
||||
Version 3.4.9 (2012-02-23)
|
||||
Added settings to wordcount plugin to configure update rate and checking wordcount on backspace and delete using wordcount_update_rate and wordcount_update_on_delete.
|
||||
Fixed bug in Webkit and IE where deleting empty paragraphs would remove entire editor contents.
|
||||
Fixed bug where pressing enter on end of list item with a heading would create a new item with heading.
|
||||
Fixed edit css style dialog text-decoration none checkbox so it disables other text-decoration options when enabled.
|
||||
Fixed bug in Gecko where undo wasn't added when focus was lost.
|
||||
Fixed bug in Gecko where shift-enter in table cell ending with BR doesn't move caret to new line.
|
||||
Fixed bug where right-click on formatted text in IE selected the entire line.
|
||||
Fixed bug where text ending with space could not be unformatted in IE.
|
||||
Fixed bug where caret formatting would be removed when moving the caret when a selector expression was used.
|
||||
Fixed bug where formatting would be applied to the body element when all contents where selected and format had both inline and selector parts.
|
||||
Fixed bug where the media plugin would throw errors if you had iframe set as an invalid element in config.
|
||||
Fixed bug where the caret would be placed at the top of the document if you inserted a table and undo:ed that operation. Patch contributed by Wesley Walser.
|
||||
Fixed bug where content css files where loaded twice into the iframe.
|
||||
Fixed so elements with comments would be trated as non empty elements. Patch contributed by Arjan Scherpenisse.
|
||||
Version 3.4.8 (2012-02-02)
|
||||
Fixed bug in IE where selected text ending with space cannot be formatted then formatted again to get original text.
|
||||
Fixed bug in IE where images larger than editor area were being deselected when toolbar buttons are clicked.
|
||||
Fixed bug where wrong text align buttons are active when multiple block elements are selected.
|
||||
Fixed bug where selected link not showing in target field of link dialog in some selection cases.
|
||||
Use settings for remove_trailing_br so this can be turned off instead of hard coding the value.
|
||||
Fixed bug in IE where the media plugin displayed null text when some values aren't filled in.
|
||||
Added API method 'onSetAttrib' that fires when the attribute value on a node changes.
|
||||
Fix font size dropdown value not being updated when text already has a font size in the advanced template.
|
||||
Fixed bug in IE where IE doesn't use ARIA attributes properly on options - causing labels to be read out 2 times.
|
||||
Fixed bug where caret cannot be placed after table if table is at end of document in IE.
|
||||
Fixed bug where adding range isn't always successful so we need to check range count otherwise an exception can occur.
|
||||
Added spacebar onclick handler to toolbar buttons to ensure that the accessibility behaviour works correctly.
|
||||
Fixed bug where a stranded bullet point would get created in WebKit.
|
||||
Fixed bug where selecting text in a blockquote and pressing backspace toggles the style.
|
||||
Fixed bug where pressing enter from a heading in IE, the resulting P tag below it shares the style property.
|
||||
Fix white space in between spans from being deleted.
|
||||
Fixed bug where scrollbars where visible in the character map dialog on Gecko.
|
||||
Fixed issue with missing translation for one of the emoticons.
|
||||
Fixed bug where dots in id:s where causing problems. Patch provided by Abhishek Dev.
|
||||
Fixed bug where urls with an at sign in the path wouldn't be parsed correctly. Patch contributed by Jason Grout.
|
||||
Fixed bug where Opera would remove the first character of a inline formatted word if you pressed backspace.
|
||||
Fixed bugs with the autoresize plugin on various browsers and removed the need for the throbber.
|
||||
Fixed performance issue where the contextmenu plugin would try to remove the menu even if it was removed. Patch contributed by mhu.
|
||||
Version 3.4.7 (2011-11-03)
|
||||
Modified the caret formatting behavior to word similar to common desktop wordprocessors like Word or Libre Office.
|
||||
Fixed bug in Webkit - Cursor positioning does not work vertically within a table cell with multiple lines of text.
|
||||
Fixed bug in IE where Inserting a table in IE8 places cursor in the second cell of the first row.
|
||||
Fixed bug in IE where editor in a frame doesn't give focus to the toolbar using ALT-F10.
|
||||
Fix for webkit and gecko so that deleting bullet from start of list outdents inner list items and moves first item into paragraph.
|
||||
Fix new list items in IE8 not displayed on a new line when list contains nested list items.
|
||||
Clear formatting in table cell breaks the cell.
|
||||
Made media type list localisable.
|
||||
Fix out of memory error when using prototype in media dialog.
|
||||
Fixed bug where could not add a space in the middle of a th cell.
|
||||
Fixed bug where adding a bullet between two existing bullets adds an extra one
|
||||
Fixed bug where trying to insert a new entry midway through a bulleted list fails dismally when the next entry is tabbed in.
|
||||
Fixed bug where pressing enter on an empty list item does not outdent properly in FF
|
||||
Fixed bug where adding a heading after a list item in a table cell changes all styles in that cell
|
||||
Fixed bug where hitting enter to exit from a bullet list moves cursor to the top of the page in Firefox.
|
||||
Fixed bug where pressing backspace would not delete HRs in Firefox and IE when next to an empty paragraph.
|
||||
Fixed bug where deleting part of the link text can cause a link with no destination to be saved.
|
||||
Fixed bug where css style border widths wasn't handled correctly in table dialog.
|
||||
Fixed bug where parsing invalid html contents on IE or WebKit could produce an infinite loop.
|
||||
Fixed bug where scripts with custom script types wasn't properly passed though the editor.
|
||||
Fixed issue where some Japanese kanji characters wasn't properly entity encoded when numeric entity mode was enabled.
|
||||
Made emoticons dialog use the keyboard naviation.
|
||||
Added navigation instructions to the symbols dialog.
|
||||
Added ability to set default values for the media plugin.
|
||||
Added new font_size_legacy_values option for converting old font element sizes to span with font-size properties.
|
||||
Fixed bug where the symbols dialog was not accessible.
|
||||
Added quirk for IE ensuring that the body of the document containing tinyMCE has a role="application" for accessibility.
|
||||
Fixed bug where the advanced color picker wasn't working properly on FF 7.
|
||||
Fixed issue where the advanced color picker was producing uppercase hex codes.
|
||||
Fixed bug where IE 8 could throw exceptions if the contents contained resizable content elements.
|
||||
Fixed bug where caret formatting wouldn't be correctly applied to previous sibling on WebKit.
|
||||
Fixed bug where the select boxes for font size/family would loose it's value on WebKit due to recent iOS fixes.
|
||||
Version 3.4.6 (2011-09-29)
|
||||
Fixed bug where list items were being created for empty divs.
|
||||
Added support in Media plugin for audio media using the embed tag
|
||||
Fixed accessibility bugs in WebKit and IE8 where toolbar items were not being read.
|
||||
Added new use_accessible_selects option to ensure accessible list boxes are used in all browsers (custom widget in firefox native on other browsers)
|
||||
Fixed bug where classid attribute was not being checked from embed objects.
|
||||
Fixed bug in jsrobot tests with intermittently failing.
|
||||
Fixed bug where anchors wasn't updated properly if you edited them using IE 8.
|
||||
Fixed bug where input method on WebKit on Mac OS X would fail to initialize when sometimes focusing the editor.
|
||||
Fixed bug where it wasn't possible to select HR elements on WebKit by simply clicking on them.
|
||||
Fixed bug where the media plugin wouldn't work on IE9 when not using the inlinepopups plugin.
|
||||
Fixed bug where hspace,vspace,align and bgcolor would be removed from object elements in the media plugin.
|
||||
Fixed bug where the new youtube format wouldn't be properly parsed by the media plugin.
|
||||
Fixed bug where the style attribute of layers wasn't properly updated on IE and Gecko.
|
||||
Fixed bug where editing contents in a layer would fail on Gecko since contentEditable doesn't inherit properly.
|
||||
Fixed bug where IE 6/7 would produce JS errors when serializing contents containing layers.
|
||||
Version 3.4.5 (2011-09-06)
|
||||
Fixed accessibility bug in WebKit where the right and left arrow keys would update native list boxes.
|
||||
Added new whitespace_elements option to enable users to specify specific elements where the whitespace is preserved.
|
||||
Added new merge_siblings option to formats. This option makes it possible to disable the auto merging of siblings when applying formats.
|
||||
Fixed bug in IE where trailing comma in paste plugin would cause plugin to not run correctly.
|
||||
Fixed bug in WebKit where console messages would be logged when deleting an empty document.
|
||||
Fixed bug in IE8 where caret positioned is on list item instead of paragraph when outdent splits the list
|
||||
Fixed bug with image dialogs not inserting an image if id was omitted from valid_elements.
|
||||
Fixed bug where the selection normalization logic wouldn't properly handle image elements in specific config cases.
|
||||
Fixed bug where the map elements coords attribute would be messed up by IE when serializing the DOM.
|
||||
Fixed bug where IE wouldn't properly handle custom elements when the contents was serialized.
|
||||
Fixed bug where you couldn't move the caret in Gecko if you focused the editor using the API or a UI control.
|
||||
Fixed bug where adjacent links would get merged on IE due to bugs in their link command.
|
||||
Fixed bug where the color split buttons would loose the selection on IE if the editor was placed in a frame/iframe.
|
||||
Fixed bug where floated images in WebKit wouldn't get properly linked.
|
||||
Fixed bug where the fullscreen mode in a separate window wasn't forced into IE9+ standards mode.
|
||||
Fixed bug where pressing enter in an empty editor on WebKit could produce DIV elements instead of P.
|
||||
Fixed bug where spans would get removed incorrectly when merging two blocks on backspace/delete on WebKit.
|
||||
Fixed bug where the editor contents wouldn't be completely removed on backspace/delete on WebKit.
|
||||
Fixed bug where the fullpage plugin wouldn't properly render style elements in the head on IE 6/7.
|
||||
Fixed bug where the nonbreaking_force_tab option in the nonbreaking plugin wouldn't work on Gecko/WebKit.
|
||||
Fixed bug where the isDirty state would become true on non IE browsers if there was an table at the end of the contents.
|
||||
Fixed bug where entities wasn't properly encoded on WebKit when pasting text as plain text.
|
||||
Fixed bug where empty editors would produce an exception of valid_elements didn't include body and forced_root_blocks where disabled.
|
||||
Fixed bug where the fullscreen mode wouldn't retain the header/footer in the fullpage plugin.
|
||||
Fixed issue where the plaintext_mode and plaintext_mode_sticky language keys where swapped.
|
||||
Version 3.4.4 (2011-08-04)
|
||||
Added new html5 audio support. Patch contributed by Ronald M. Clifford.
|
||||
Added mute option for video elements and preload options for video/audio patch contributed by Dmitry Kalinkin.
|
||||
Fixed selection to match visual selection before applying formatting changes.
|
||||
Fixed browser specific bugs in lists for WebKit and IE.
|
||||
Fixed bug where IE would scroll the window if you closed an inline dialog that was larger than the viewport. Patch by Laurence Keijmel.
|
||||
Fixed bug where pasting contents near a span element could remove parts of that span. Patch contributed by Wesley Walser.
|
||||
Fixed bug where formatting change would be lost after pressing enter.
|
||||
Fixed bug in WebKit where deleting across blocks would add extra styles.
|
||||
Fixed bug where moving cursor vertically in tables in WebKit wasn't working.
|
||||
Fixed bug in IE where deleting would cause error in console.
|
||||
Fixed bug where the formatter was not applying formats across list elements.
|
||||
Fixed bug where the wordcount plugin would try and update the wordcount if tinymce had been destroyed.
|
||||
Fixed bug where tabfocus plugin would attempt to focus elements not displayed when their parent element was hidden.
|
||||
Fixed bug where the contentEditable state would sometimes be removed if you deleted contents in Gecko.
|
||||
Fixed bug where inserting contents using mceInsertContent would fail if "span" was disabled in valid_elements.
|
||||
Fixed bug where initialization might fail if some resource on gecko wouldn't load properly and fire the onload event.
|
||||
Fixed bug where ctrl+7/8/9 keys wouldn't properly add the specific formats associated with them.
|
||||
Fixed bug where the HTML tags wasn't properly closed in the style plugins properties dialog.
|
||||
Fixed bug where the list plugin would produce an exception if the user tried to delete an element at the very first location.
|
||||
Version 3.4.3.2 (2011-06-30)
|
||||
Fixed bug where deleting all of a paragraph inside a table cell would behave badly in webkit.
|
||||
Fixed bugs in tests in firefox5 and WebKit.
|
||||
Fixed bug where selection of table cells would produce an exception on Gecko.
|
||||
Fixed bug where the caret wasn't properly rendered on Gecko when the editor was hidden.
|
||||
Fixed bug where pasting plain text into WebKit would produce a pre element it will now produce more semantic markup.
|
||||
Fixed bug where selecting list type formats using the advlist plugin on IE8 would loose editor selection.
|
||||
Fixed bug where forced root blocks logic wouldn't properly pad elements created if they contained data attributes.
|
||||
Fixed bug where it would remove all contents of the editor if you inserted an image when not having a caret in the document.
|
||||
Fixed bug where the YUI compressor wouldn't properly encode strings with only a quote in them.
|
||||
Fixed bug where WebKit on iOS5 wouldn't call nodeChanged when the selection was changed.
|
||||
Fixed bug where mceFocus command wouldn't work properly on Gecko since it didn't focus the body element.
|
||||
Fixed performance issue with the noneditable plugin where it would enable/disable controls to often.
|
||||
Version 3.4.3.1 (2011-06-16)
|
||||
Fixed bug where listboxes were not being handled correctly by JAWS in firefox with the o2k7 skin.
|
||||
Fixed bug where custom buttons were not being rendered correctly when in high contrast mode.
|
||||
Added support for iOS 5 that now supporting contentEditable in it's latest beta.
|
||||
Fixed bug where urls in style attributes with a _ character followed by a number would cause incorrect output.
|
||||
Fixed bug where custom_elements option wasn't working properly on IE browsers.
|
||||
Fixed bug where custom_elements marked as block elements wouldn't get correctly treated as block elements.
|
||||
Fixed bug where attributes with </> wasn't properly encoded as XML entities.
|
||||
Version 3.4.3 (2011-06-09)
|
||||
Fixed bug where deleting backwards before an image into a list would put the cursor in the wrong location.
|
||||
Fixed bug where styles plugin would not apply styles across multiple selected block elements correctly.
|
||||
Fixed bug where cursor would jump to start of document when selection contained empty table cells in IE8.
|
||||
Fixed bug where applied styles wouldn't be kept if you pressed enter twice to produce two paragraphs.
|
||||
Fixed bug where a ghost like caret would appear on Gecko when pressing enter while having a text color applied.
|
||||
Fixed bug where IE would produce absolute urls if you inserted a image/link and reloaded the page.
|
||||
Fixed bug where applying a heading style to a list item would cascade style to children list items.
|
||||
Fixed bug where Editor loses focus when backspacing and changing styles in WebKit.
|
||||
Fixed bug where exception was thrown in tinymce.util.URI when parsing a relative URI and no base_uri setting was provided.
|
||||
Fixed bug where alt-f10 was not always giving focus to the toolbar on Safari.
|
||||
Added new 'allow_html_in_named_anchor' option to allow html to occur within a named anchor tag. Use at own risk.
|
||||
Added plugin dependency support. Will autoload plugins specified as a dependency if they haven't been loaded.
|
||||
Fixed bug where the autolink plugin didn't work with non-English keyboards when pressing ).
|
||||
Added possibility to change properties of all table cells in a column.
|
||||
Added external_image_list option to get images list from user-defined variable or function.
|
||||
Fixed bug where the autoresize plugin wouldn't reduce the editors height on Chrome.
|
||||
Fixed bug where table size inputs were to small for values with size units.
|
||||
Fixed bug where table cell/row size input values were not validated.
|
||||
Fixed bug where menu item line-height would be set to wrong value by external styles.
|
||||
Fixed bug where hasUndo() would return wrong answer.
|
||||
Fixed bug where page title would be set to undefined by fullpage plugin.
|
||||
Fixed bug where HTML5 video properties were not updated in embedded media settings.
|
||||
Fixed bug where HTML comment on the first line would cause an error.
|
||||
Fixed bug where spellchecker menu was positioned incorrectly on IE.
|
||||
Fixed bug where breaking out of list elements on WebKit would produce a DIV instead of P after the list.
|
||||
Fixed bug where pasting from Word in IE9 would add extra BR elements when text was word wrapped.
|
||||
Fixed bug where numeric entities with leading zeros would produce incorrect decoding.
|
||||
Fixed bug where hexadecimal entities wasn't properly decoded.
|
||||
Fixed bug where bookmarks wasn't properly stored/restored on undo/redo.
|
||||
Fixed bug where the mceInsertCommand didn't retain the values of links if they contained non url contents.
|
||||
Fixed bug where the valid_styles option wouldn't be properly used on styles for specific elements.
|
||||
Fixed so contentEditable is used for the body of the editor if it's supported.
|
||||
Fixed so trailing BR elements gets removed even when forced_root_blocks option was set to false/null.
|
||||
Fixed performance issue with mceInsertCommand and inserting very simple contents.
|
||||
Fixed performance issue with older IE version and huge documents by optimizing the forced root blocks logic.
|
||||
Fixed performance issue with table plugin where it checked for selected cells to often.
|
||||
Fixed bug where creating a link on centered/floated image would produce an error on WebKit browsers.
|
||||
Fixed bug where Gecko would remove single paragraphs if there where contents before/after it.
|
||||
Fixed bug where the scrollbar would move up/down when pasting contents using the paste plugin.
|
||||
Version 3.4.2 (2011-04-07)
|
||||
Added new 'paste_text_sticky_default' option to paste plugin, enables you to set the default state for paste as plain text.
|
||||
Added new autoresize_bottom_margin option to autoresize plugin that enables you to add an extra margin at the bottom. Patch contributed by Andrew Ozz.
|
||||
Rewritten the fullpage plugin to handle style contents better and have a more normalized behavior across browsers.
|
||||
Fixed bug where contents inserted with mceInsertContent wasn't parsed using the default dom parser.
|
||||
Fixed bug where blocks containing a single anchor element would be treated as empty.
|
||||
Fixed bug where merging of table cells on IE 6, 7 wouldn't look correctly until the contents was refreshed.
|
||||
Fixed bug where context menu wouldn't work properly on Safari since it was passing out the ctrl key as pressed.
|
||||
Fixed bug where image border color/style values were overwritten by advimage plugin.
|
||||
Fixed bug where setting border in advimage plugin would throw error in IE.
|
||||
Fixed bug where empty anchors list in link settings wasn't hidden.
|
||||
Fixed bug where xhtmlextras popups were missing localized popup-size parameters.
|
||||
Fixed bug where the context menu wouldn't select images on WebKit browsers.
|
||||
Fixed bug where paste plugin wouldn't properly extract the contents on WebKit due to recent changes in browser behavior.
|
||||
Fixed bug where focus of the editor would get on control contents on IE lost due to a bug in the ColorSplitButton control.
|
||||
Fixed bug where contextmenu wasn't disabled on noneditable elements.
|
||||
Fixed bug where getStyle function would trigger error when called on element without style property.
|
||||
Fixed bug where editor fail to load if Javascript Compressor was used.
|
||||
Fixed bug where list-style-type=lower-greek would produce errors in IE<8.
|
||||
Fixed bug where spellchecker plugin would produce errors on IE6-7.
|
||||
Fixed bug where theme_advanced_containers configuration option causes error.
|
||||
Fixed bug where the mceReplaceContent command would produce an error since it didn't correctly handle a return value.
|
||||
Fixed bug where you couldn't enter float point values for em in dialog input fields since it wouldn't be considered a valid size.
|
||||
Fixed bug in xhtmlxtras plugin where it wasn't possible to remove some attributes in the attributes dialog.
|
||||
Version 3.4.1 (2011-03-24)
|
||||
Added significantly improved list handling via the new 'lists' plugin.
|
||||
Added 'autolink' plugin to enable automatically linking URLs. Similar to the behavior IE has by default.
|
||||
Added 'theme_advanced_show_current_color' setting to enable the forecolor and backcolor buttons to continuously show the current text color.
|
||||
Added 'contextmenu_never_use_native' setting to disable the ctrl-right-click showing the native browser context menu behaviour.
|
||||
Added 'paste_enable_default_filters' setting to enable the default paste filters to be disabled.
|
||||
Fixed bug where selection locations on undo/redo didn't work correctly on specific contents.
|
||||
Fixed bug where an exception would be trown on IE when loading TinyMCE inside an iframe.
|
||||
Fixed bug where some ascii numeric entities wasn't properly decoded.
|
||||
Fixed bug where some non western language codes wasn't properly decoded/encoded.
|
||||
Fixed bug where undo levels wasn't created when deleting contents on IE.
|
||||
Fixed bug where the initial undo levels bookmark wasn't updated correctly.
|
||||
Fixed bug where search/replace wouldn't be scoped to editor instances on IE8.
|
||||
Fixed bug where IE9 would produce two br elements after block elements when pasting.
|
||||
Fixed bug where IE would place the caret at an incorrect position after a paste operation.
|
||||
Fixed bug where a paste operation using the keyboard would add an extra undo level.
|
||||
Fixed bug where some attributes/elements wasn't correctly filtered when invalid contents was inserted.
|
||||
Fixed bug where the table plugin couldn't correctly handle invalid table structures.
|
||||
Fixed bug where charset and title of the page were handled incorrectly by the fullpage plugin.
|
||||
Fixed bug where toggle states on some of the list boxes didn't update correctly.
|
||||
Fixed bug where sub/sub wouldn't work correctly when done as a caret action in Chrome 10.
|
||||
Fixed bug where the constrain proportions checkbox wouldn't work in the media plugin.
|
||||
Fixed bug where block elements containing trailing br elements wouldn't treated properly if they where invalid.
|
||||
Fixed bug where the color picker dialog wouldn't be rendered correctly when using the o2k7 theme.
|
||||
Fixed bug where setting border=0 using advimage plugin invalid style attribute content was created in Chrome.
|
||||
Fixed bug with references to non-existing images in css of fullpage plugin.
|
||||
Fixed bug where item could be unselected in spellchecker's language selector.
|
||||
Fixed bug where some mispelled words could be not highlighted using spellchecker plugin.
|
||||
Fixed bug where spellchecking would merge some words on IE.
|
||||
Fixed bug where spellchecker context menu was not always positioned correctly.
|
||||
Fixed bug with empty anchors list in advlink popup when Invisible Elements feature was disabled.
|
||||
Fixed bug where older IE versions wouldn't properly handle some elements if they where placed at the top of editor contents.
|
||||
Fixed bug where selecting the whole table would enable table tools for cells and rows.
|
||||
Fixed bug where it wasn't possible to replace selected contents on IE when pasting using the paste plugin.
|
||||
Fixed bug where setting text color in fullpage plugin doesn't work.
|
||||
Fixed bug where the state of checkboxes in media plugin wouldn't be set correctly.
|
||||
Fixed bug where black spade suit character was not included in special character selector.
|
||||
Fixed bug where setting invalid values for table cell size would throw an error in IE.
|
||||
Fixed bug where spellchecking would remove whitespace characters from PRE block in IE.
|
||||
Fixed bug where HR was inserted inside P elements instead of splitting them.
|
||||
Fixed bug where extra, empty span tags were added when using a format with both selector and inline modes.
|
||||
Fixed bug where bullet lists weren't always detected correctly.
|
||||
Fixed bug where deleting some paragraphs on IE would cause an exception.
|
||||
Fixed bug where the json encoder logic wouldn't properly encode \ characters.
|
||||
Fixed bug where the onChange event would be fired when the editor was first initialized.
|
||||
Fixed bug where mceSelected wouldn't be removed properly from output even if it's an internal class.
|
||||
Fixed issue with table background colors not being transparent. This improves compliance with users browser color preferences.
|
||||
Fixed issue where styles were not included when using the full page plugin.
|
||||
Fixed issue where drag/drop operations wasn't properly added to the undo levels.
|
||||
Fixed issue where colors wasn't correctly applied to elements with underline decoration.
|
||||
Fixed issue where deleting some paragraphs on IE would cause an exception.
|
||||
Version 3.4 (2011-03-10)
|
||||
Added accessibility example with various accessibility options contributed by Ephox.
|
||||
Fixed bug where attributes wasn't properly handled in the xhtmlxtras plugin.
|
||||
Fixed bug where the image.htm had some strange td artifacts probably due to auto merging.
|
||||
Fixed bug where the ToolbarGroup had an missing reference to this in it's destroy method.
|
||||
Fixed bug with the resizeBy function in the advanced theme where it was scaled by the wrong parent.
|
||||
Fixed bug where an exception would be thrown by the element if the page was served in xhtml mode.
|
||||
Fixed bug where mceInsertContent would throw an exception when page was served in xhtml mode.
|
||||
Fixed bug where you couldn't select a forground/background color when page was served in xhtml mode.
|
||||
Fixed bug where the editor would scroll to the toolbar when clicked due to a call to focus in ListBox.
|
||||
Fixed bug where pages with rtl dir wouldn't render split buttons correctly when using the o2k7 theme.
|
||||
Fixed bug where anchor elements with names wasn't properly collapsed as they where in 3.3.x.
|
||||
Fixed bug where WebKit wouldn't properly handle image selection if it was done left to right.
|
||||
Fixed bug where the formatter would align images when the selection range was collapsed.
|
||||
Fixed bug where the image button would be active when the selection range was collapsed.
|
||||
Fixed bug where the element_format option wasn't used by the new (X)HTML serializer logic.
|
||||
Fixed bug where the table cell/row dialogs would produce empty attributes.
|
||||
Fixed bug where the tfoot wouldn't be added to the top of the table.
|
||||
Fixed bug where the formatter would merge siblings with white space between them.
|
||||
Fixed bug where pasting headers and paragraphs would produce an extra paragraph.
|
||||
Fixed bug where the ColorSplitButton would throw an exception if you clicked out side a color.
|
||||
Fixed bug where IE9 wouldn't properly produce new paragraphs on enter if the current paragraph had formatting.
|
||||
Fixed bug where multiple BR elements at end of block elements where removed.
|
||||
Fixed bug where fullscreen plugin wouldn't correctly display the edit area on IE6 for long pages.
|
||||
Fixed bug where paste plugin wouldn't properly encode raw entities when pasting in plain text mode.
|
||||
Fixed bug where the search/replace plugin wouldn't work correctly on IE 9.
|
||||
Fixed so the drop menus doesn't get an outline border visible when focused, patch contributed by Ephox.
|
||||
Fixed so the values entered in the color picker are forced to hex values.
|
||||
Removed dialog workaround for IE 9 beta since the RC is now out and people should upgrade.
|
||||
Removed obsolete calls in various plugins to the mceBeginUndoLevel command.
|
||||
Version 3.4b3 (2011-02-10)
|
||||
Added WAI-ARIA support for the main UI and dialogs this feature was contributed by Ephox.
|
||||
Added iframe support to media plugin in order to handle the new YouTube HTML5 video formats.
|
||||
Fixed bug where anchors would wrap the text contents after it due to a bug in the DomParser logic.
|
||||
Fixed bug where the selected state wouldn't be removed on ListBox controls when a menu item was selected.
|
||||
Fixed bug where IE could throw an unspecified error exception when the getBookmark logic was executed.
|
||||
Fixed bug where IE would throw an invalid argument error when focus was applied to an empty editor instance.
|
||||
Fixed bug where applying inline format wouldn't work if the start cell in the selection was empty.
|
||||
Fixed bug where auto detection logic for YouTube and Google Video wouldn't work in the new media plugin.
|
||||
Fixed bug where td elements would get a colspan/rowspan of 1 when created by the table plugin.
|
||||
Fixed bug where removal/padding of empty elements wasn't handled correctly.
|
||||
Fixed bug where internal elements would show up in element path.
|
||||
Fixed bug where internal elements would get serialized as valid output.
|
||||
Fixed bug where color wasn't correctly applied to anchor elements.
|
||||
Fixed bug where float option in the style plugin dialog wouldn't be handled correctly on WebKit.
|
||||
Fixed bug where the tinymce.dom.TreeWalker prev function wouldn't walk the DOM correctly.
|
||||
Fixed bug where mceInsertContent command could produce empty block elements after the inserted content.
|
||||
Fixed bug where mceInsertContent command wouldn't apply visual aids on tables and similar elements.
|
||||
Fixed bug where empty block elements would get double br bogus elements in them.
|
||||
Fixed bug where the color menu wouldn't apply the color correctly on IE when the viewport was to small.
|
||||
Fixed bug where right clicking out side the body element of the editor iframe would prevent paste from working on IE.
|
||||
Fixed bug where the onContextMenu event wouldn't fire correctly on IE if you clicked out side the body element.
|
||||
Fixed bug where the onContextMenu event wouldn't fire correctly on modern Opera versions that now support it by default.
|
||||
Fixed bug where legacy content wasn't converted correctly when inserted using mceInsertContent or through the source dialog.
|
||||
Fixed bug where resizing images or tables wouldn't update the style attribute correctly or leave data-mce prefixed attributes.
|
||||
Fixed bug where adding links wouldn't work correctly when using TinyMCE jQuery version with jQuery 1.5.
|
||||
Fixed bug where single quotes inside param elements wasn't treated correctly by the media plugin.
|
||||
Fixed bug where pasting plain text in WebKit wouldn't work correctly. It will now auto detect the WebKit bug and use plain text mode.
|
||||
Fixed bug where the DomParser would fail to move out invalid elements within invalid elements on complex contents.
|
||||
Fixed bug where paste as plain text would not decode html entities properly.
|
||||
Fixed bug where large paragraphs would cause incorrect scrolling behavior if you would split them using enter.
|
||||
Fixed bug where the SaxParser wouldn't properly parse some specific short ended elements.
|
||||
Fixed so mceReplaceContent supports caret position and makes sure that the contents inserted gets validated.
|
||||
Fixed so unnecessary traling br elements in blocks gets removed on Gecko/WebKit when using mceInsertContent command.
|
||||
Moved some plugin css contents into the skin content css files to reduce the number of http requests.
|
||||
Moved some plugin specific images into the theme img directory since they can then be shared.
|
||||
Version 3.4b2 (2011-01-13)
|
||||
Added new custom flash player, this player supports mp4 and flv and has skin support.
|
||||
Fixed so mceInsertContent handles context correctly to enforce valid nesting of elements.
|
||||
Fixed bug where scrolling would become jerky on IE on some contents.
|
||||
Fixed bug where paste as plain text would throw exception of missing entities setting.
|
||||
Fixed bug where anchor nodes where removed by the new serializer engine.
|
||||
Fixed bug where IE would crash if when backspace where used on some specific contents.
|
||||
Fixed bug where pasting of plain text in WebKit would result in merging of text lines.
|
||||
Fixed bug where it wasn't possible to delete images or tables using backspace on IE9.
|
||||
Fixed bug where urls in styles would generate a JS error due to incorrect scope.
|
||||
Fixed bug where copy paste from Java applications would produce extra contents in FF on Mac.
|
||||
Fixed bug where the verify_html option wouldn't allow all elements and attributes.
|
||||
Version 3.4b1 (2010-12-20)
|
||||
Added new serialization engine that increases performance and enforces valid output according to the specified schema settings.
|
||||
Added new HTML parser logic used by the serialization engine and can handle malformed html contents.
|
||||
Added new valid_children config option, enables more fine grain control of elements can be inside other elements.
|
||||
Added new entities encoding logic boost performance and will only encode entities based on context i.e. attributes/text nodes.
|
||||
Added new protect setting that enables users to protect template items from being removed by the serializer logic.
|
||||
Added new {$caret} marker for the mceInsertContent command. Makes it possible to move the caret to a specific position when inserting contents.
|
||||
Added new validation of anchor names. Only valid W3C names will be accepted.
|
||||
Replaced the internal _mce_ prefixed attributes to the more standard HTML5 data-mce- prefix. This will also resolve future browser santiaztion issues.
|
||||
Fixed bug where the paste plugin wouldn't convert Word lists with more than 9 items to real ol lists. Patch contributed by Mike (yogaboy).
|
||||
Fixed bug where clicking on a format title would produce errors if the current selection didn't have any formats.
|
||||
Fixed bug where paste of simple texts wouldn't work correctly in Gecko using the paste plugin since it keeps block formatting.
|
||||
Fixed bug where confirm dialogs didn't display correctly due to resent IE9 fixes.
|
||||
Fixed bug where spaces in URLs wouldn't be properly encoded to %20 if the user entered them in the link dialogs. Patch contributed by Ephox.
|
||||
Fixed bug where the image alignment buttons wouldn't reposition the resize handles on FF due to a browser issue. Patch contributed by Ephox.
|
||||
Fixed bug where the compareBoundaryPoints method of the IE Range class didn't work correctly. Patch contributed by Ephox.
|
||||
Fixed bug where selection of elements using double click wouldn't select the clicked element but rather the parent node on FF. Patch contributed by Ephox.
|
||||
Fixed bug where IE would scroll the user to the current selection causing parent document to scroll as well. Patch contributed by Ephox.
|
||||
Fixed bug where style compression would incorrectly compress items with different values. It now only compresses if the values are the same. Patch contributed by Ephox.
|
||||
Fixed bug where FF would add non breaking spaces outside TD elements if formatting was applied to table cells. Patch contributed by Ephox.
|
||||
Fixed bug where the caret position would be lost on WebKit browsers if you pasted images multiple times. Patch contributed by Ephox.
|
||||
Fixed bug where non word contents like * would be counted as words in the wordcount pluging. Patch contributed by David Balatero.
|
||||
Fixed bug where the toggle absolute button in the layer plugin wouldn't remove the existing internal style attribute first.
|
||||
Fixed bug where the autosave plugin would generate an exception on IE if the user had disabled userdata persistence.
|
||||
Fixed bug where the paste plugin would remove dashed classes on IE since the regexps didn't include that character.
|
||||
Fixed bug where applying text color would not add spans inside link elements. This is needed due to CSS style inheritance.
|
||||
Fixed bug where applying block formats to empty elements wouldn't render correctly on IE.
|
||||
Fixed bug where the searchreplace plugin would add a f or r character when shortcuts where used on IE while using default dialogs.
|
||||
Fixed bug where Opera wouldn't load scripts correctly since the onreadystate would fire even though the script wasn't loaded.
|
||||
Fixed issue where wouldn't be handled correctly in the bbcode plugin if entity_encoding was set to raw.
|
||||
Fixed issue where contents would flicker since the content css files where asynchronously loaded.
|
||||
Fixed bug where WebKit wouldn't create links on images with a float style.
|
||||
Version 3.3.9.3 (2010-12-20)
|
||||
Fixed issue where WebKit wouldn't correctly apply ins/del in xhtmlxtras plugin.
|
||||
Fixed bug where paste as plaintext on WebKit wouldn't produce br and p elements correctly.
|
||||
Fixed bug where the confirm dialog texts would be incorrectly placed due to recent IE 9 workarounds in the window.css.
|
||||
Fixed bug where applying text color would not add spans inside link elements. This is needed due to CSS style inheritance.
|
||||
Version 3.3.9.2 (2010-09-29)
|
||||
Fixed bug where placing the caret in IE 9 beta 1 would not work correctly if you clicked out side the document body element.
|
||||
Fixed bug where IE 9 beta 1 wouldn't resize the editor correctly since the events didn't fire as previous versions did.
|
||||
Fixed bug where FF would produce an error message when being rendered inside a hidden div element.
|
||||
Fixed bug where resize logic could produce a cookie with a width/height less than the size of the container.
|
||||
Fixed bug where content_css wouldn't populate the styles dropdown correctly.
|
||||
Version 3.3.9.1 (2010-09-23)
|
||||
Fixed bug where WebKit browsers wouldn't activate the image button when images where selected.
|
||||
Fixed bug where Opera Presto 10.60 deletes elements when restoring bookmarks.
|
||||
Fixed bug where IE9 beta1 doesn't handle regexp replacement values correctly.
|
||||
Fixed bug where IE9 beta1 didn't render the inline dialogs correctly due to a bug with CSS clip.
|
||||
Fixed bug where IE9 beta1 would produce error messages on load since they removed the document.recalc method.
|
||||
Fixed bug where IE9 beta1 would produce <html xmlns=""> since they haven't implemented document.implementation.createDocument correctly.
|
||||
Fixed bug where IE9 beta1 would searchreplace doesn't work since their native DOM Range doesn't have a find method.
|
||||
Fixed bug where IE9 beta1 would render the source view incorrectly due to incorrect viewport size measurements.
|
||||
Fixed bug where IE9 beta1 would crash when running the basic functionality unit tests.
|
||||
Fixed bug where IE9 beta1 would wrap elements in blocks correctly due to changes to the selection object.
|
||||
Fixed bug where IE9 beta1 would fail to insert contents since they havn't implemented the createContextualFragment method in their DOM Range.
|
||||
Fixed bug where IE9 beta1 would fail to handle image selection since they currently doesn't support control selections in their DOM Range.
|
||||
Fixed bug where IE9 beta1 would fail to load scripts since they fire the onload event before the scripts are parsed and executed.
|
||||
Version 3.3.9 (2010-09-08)
|
||||
Fixed bug where inserting table rows into a table with subtable would produce an incorrect column count.
|
||||
Fixed bug where the selection of cells in a table with subtables could produce invalid selections.
|
||||
Fixed bug where the table plugin would produce a script error if you tried to move the caret before a first child table.
|
||||
Fixed bug where the keep_styles feature on IE would move the caret to an incorrect location at the end of list blocks.
|
||||
Fixed so attributes from legacy elements such as font gets retained when they get converted to spans.
|
||||
Fixed minor issue where the select boxes wouldn't be set the not set by default in the table dialog.
|
||||
Version 3.3.8 (2010-06-30)
|
||||
On IE8+ and FireFox 3.5+, dragging an image now correctly adds an undo
|
||||
event.
|
||||
Fixed bug where WebKit would not move the caret to a correct position after a paste operation.
|
||||
Fixed bug where WebKit would produce a div wrapper element when pasting some contents.
|
||||
Fixed bug where the visual chars and nonbreaking plugin wouldn't show nbsp elements correctly.
|
||||
Fixed bug where the format states would be enabled even after the format was removed.
|
||||
Fixed bug where the delete key would move the caret to an incorrect position.
|
||||
Fixed bug where it wasn't possible to toggle of the current font size/family/style by clicking the title item.
|
||||
Fixed bug where the abbr element wouldn't get serialized correctly on IE6.
|
||||
Fixed so that the examples checks if they are executed from the local file system since that might not work properly.
|
||||
Version 3.3.7 (2010-06-10)
|
||||
Fixed bug where context menu would produce an error on IE if you right clicked twice and left clicked once.
|
||||
Fixed bug where resizing of the window on WebKit browsers in fullscreen mode wouldn't position the statusbar correctly.
|
||||
Fixed bug where IE would produce an error if the editor was empty and you where undoing to that initial level.
|
||||
Fixed bug where setting the table background on gecko would produce \" entities inside the url style property.
|
||||
Fixed bug where the button states wouldn't be updated correctly on IE if you placed the caret inside the new element.
|
||||
Fixed bug where undo levels wasn't properly added after applying styles or font sizes.
|
||||
Fixed bug where IE would throw an error if you used "select all" on empty elements and applied formatting to that.
|
||||
Fixed bug where IE could select one extra character when you did a bookmark call on a caret location.
|
||||
Fixed bug where IE could produce a script error on delete since it would sometimes produce an invalid DOM.
|
||||
Fixed bug where IE would return the wrong start element if the whole element was selected.
|
||||
Fixed bug where formatting states wasn't updated on IE if you pressed enter at the end of a block with formatting.
|
||||
Fixed bug where submenus for the context menu wasn't removed correctly when the editor was destroyed.
|
||||
Fixed bug where Gecko could select the wrong element after applying format to multiple elements.
|
||||
Fixed bug where Gecko would delete parts of the previous element if the selection range was a element selection.
|
||||
Fixed bug where Gecko would not merge paragraph elements correctly if they contained br elements.
|
||||
Fixed bug where the cleanup button could produce span artifacts if you pressed it twice in a row.
|
||||
Fixed bug where the fullpage plugin header/footer would be have it's header reseted to it's initial state on undo.
|
||||
Fixed bug where an empty paragraph would be collapsed if you performed a cleanup while having the caret inside it.
|
||||
Fixed a few memory leaks on IE especially with drop menus in listboxes and the spellchecker.
|
||||
Fixed so formats applied to the current caret gets merged to reduce the number of output elements.
|
||||
Added the latest version of Sizzle for the CSS selector logic to fix a compatibility issue with prototype.
|
||||
Version 3.3.6 (2010-05-20)
|
||||
Fixed bug where a editor.focus call could produce errors on IE in very specific scenarios.
|
||||
Fixed bug where Gecko would produce an error if you unformatted text inside an empty element.
|
||||
Fixed bug where IE would produce an error if the caret was placed before a table and you used the align buttons.
|
||||
Fixed bug where the font size drop down didn't display the a preview correctly.
|
||||
Fixed bug where the paste plugin wouldn't include all contents some times on WebKit browsers.
|
||||
Fixed bug where the plain text mode toggle wouldn't work properly on WebKit.
|
||||
Fixed bug where the editors statusbar would become invisible when you resized the window in fullscreen mode.
|
||||
Version 3.3.5.1 (2010-05-07)
|
||||
Fixed a critical bug with the fullscreen plugin. Produced error messages when the state was toggled on/off.
|
||||
Version 3.3.5 (2010-05-06)
|
||||
Added new merge_with_parents option to formats, enables the control of removal of elements with similar parents.
|
||||
Fixed so the default behavior for applying classes isn't a toggle state but the old behavior from before the 3.3 release.
|
||||
Fixed bug where selecting contents using double click on Gecko would produce errors when using removing format.
|
||||
Fixed bug where the IE DOM could get messed up when non valid contents was pasted into the editor.
|
||||
Fixed bug where merging selected table cells using the context menu didn't work as expected.
|
||||
Fixed bug where some nestled formatting would be applied incorrectly.
|
||||
Fixed bug with enter in list items when using the force_br_newlines mode on WebKit patch contributed by Ryan Koopmans.
|
||||
Fixed bug where undo/redo could produce js errors on some specific operations.
|
||||
Fixed bug where the theme_advanced_font_sizes didn't work as before 3.3 when complex settings where used.
|
||||
Fixed bug where the table plugin would copy cell/row id attributes when making new rows/cells.
|
||||
Version 3.3.4 (2010-04-27)
|
||||
Fixed bug where fullscreen plugin would add two editor instances to EditorManager collection.
|
||||
Fixed bug where it was difficult to enter text on non western languages such as Japanese on IE.
|
||||
Fixed bug where removing contents from nodes could result in an exception when using undo/redo.
|
||||
Fixed bug with selection of images inside layers or other resizable containers on IE.
|
||||
Fixed so editors isn't initialized on iPhone/iPad devices since they don't have caret support.
|
||||
Version 3.3.3 (2010-04-19)
|
||||
Added new script_loaded callback function setting for the jQuery plugin.
|
||||
Added various fixes and new rpc methods for the spellchecker plugin. Patch contributed by Michael Peters.
|
||||
Removed some unnecessary inline style information from some of the dialogs.
|
||||
Fixed some issues with the chaining for the TinyMCE jQuery plugin.
|
||||
Fixed so any extra arguments passed to patched jQuery functions gets passed through. Patch contributed by Lee Henson.
|
||||
Fixed so spellchecking/contextmenu can be toggled on/off if the browser has native spellchecker support.
|
||||
Fixed bug where some texts in the new paste plugin wasn't placed in language pack.
|
||||
Fixed bug where IE would produce an incorrect information message when cutting.
|
||||
Fixed bug where removing items using the xhtmlxtras plugin wouldn't work correctly.
|
||||
Fixed bug where setting table background images would add extra quotes on Gecko.
|
||||
Fixed bug where shortcut for bold/italic/underline wouldn't work properly on WebKit.
|
||||
Fixed bug where IE would produce an error message if only contents was an image tag and bold was used.
|
||||
Fixed bug where the caret would move if alignment was applied to empty block elements.
|
||||
Fixed bug where some shortcut key commands wouldn't apply formatting correctly.
|
||||
Version 3.3.2 (2010-03-25)
|
||||
Fixed bug where it was possible to scale the editor iframe smaller than the editor UI.
|
||||
Fixed bug where some of the resizing option didn't work with the new live resize.
|
||||
Fixed bug where the format listbox didn't show nestled formats correctly.
|
||||
Fixed bug where the native listboxes didn't work correctly.
|
||||
Fixed bug where font size selection in using the legacyoutput plugin would produce errors.
|
||||
Fixed so block and blockquote formats remove their matching element regardless of it's attributes.
|
||||
Version 3.3.1 (2010-03-18)
|
||||
Added new live resize feature, the editor contents is now visible while resizing.
|
||||
Fixed bug where some valid_element patterns would produce an unknown property error.
|
||||
Fixed bug where it wasn't possible to toggle off blockquotes.
|
||||
Fixed bug where an undo level wasn't produced when applying formatting using the styles dropdown.
|
||||
Fixed bug where IE 6/7 wouldn't perform caret formatting due to a focus/event bug in IE.
|
||||
Fixed bug where undo/redo wasn't restoring the previous selection correctly.
|
||||
Fixed bug where the caret would become invisible if you resized the editor in latest Gecko.
|
||||
Fixed bug where the class attribute wasn't completely removed in IE 6/7 when the removeClass function was used.
|
||||
Fixed so the matchNode method of the Formatter class returns the matched format rule.
|
||||
Fixed so it's possible to apply formatting to both blocks and as inline elements.
|
||||
Version 3.3 (2010-03-10)
|
||||
Fixed bug where backspace on a table on IE would produce an empty tbody and some JS exceptions.
|
||||
Fixed bug where some redundant children wasn't removed properly when applying inline styles to them.
|
||||
Fixed bug where Chrome would produce incorect dialog sizes if the inlinepopups plugin wasn't used.
|
||||
Fixed bug where spans with different classes would get merged if they where siblings to each other.
|
||||
Fixed bug where IE 8 would crash if you used the spellchecker.
|
||||
Fixed bug where Input Method for non western languages didn't work correctly.
|
||||
Fixed bug where the UI would render incorrectly in FF 3.6 on Mac due to a bug n their rendering engine.
|
||||
Fixed bug where WebKit wouldn't scroll down correctly if Shift+Enter was used. Patch contributed by Thomas Andersen.
|
||||
Version 3.3rc1 (2010-02-23)
|
||||
Fixed bug with new legacyoutput plugin not working correctly on it's own.
|
||||
Fixed bug some performance issues with removing text formats.
|
||||
Fixed bug where TinyMCE specific attributes wasn't removed properly by remove format.
|
||||
Fixed bug where it wasn't possible to align images within inline elements.
|
||||
Fixed bug where Ctrl+Delete/Backspace would produce an invalid argument exception on IE.
|
||||
Fixed bug where the search/replace logic could produce an infinite loop on IE for reverse searches.
|
||||
Fixed bug where cloning formats in cells didn't work properly on IE.
|
||||
Fixed bug where IE6 would produce a horizontal scroll bar.
|
||||
Fixed so remove jQuery method removes the TinyMCE instance as well as the specified textarea.
|
||||
Fixed so selected rows and cells gets updated using the row/cell properties dialogs.
|
||||
Version 3.3b2 (2010-02-04)
|
||||
Fixed bug where sometimes img elements would be removed by split method in DOMUtils.
|
||||
Fixed bug where merging of span elements could occur on bookmark nodes.
|
||||
Fixed bug where classes wasn't properly removed when removeformat was used on IE 6.
|
||||
Fixed bug where multiple calls to an tinyMCE.init with mode set to exact could produce the same unique ID.
|
||||
Fixed bug with the IE selection implementation when it was feeded an document range.
|
||||
Fixed bug where block elements formatting wasn't properly removed by removeformat on all browsers.
|
||||
Fixed bug where selection location was lost if you performed a manual cleanup.
|
||||
Fixed bug where removeformat wouldn't remove span elements within styled block elements.
|
||||
Fixed bug where an error would be thrown if you clicked on the separator lines in menus.
|
||||
Fixed bug with the jQuery plugin adding always adding a querystring value to other resources.
|
||||
Fixed bug where IE would produce an error message if you had an empty editor instance.
|
||||
Fixed bug where Shift+Enter didn't produce br elements on WebKit browsers.
|
||||
Fixed bug where a temporary marker element wasn't removed by the paste plugin.
|
||||
Fixed bug where inserting a table would produce two undo levels instead of one.
|
||||
Version 3.3b1 (2010-01-25)
|
||||
Added new text formatting engine. Fixes a lot of browser quirks and adds new possibilities.
|
||||
Added new advlist plugin that enables you to set the formats of list elements.
|
||||
Added new paste plugin logic that enables you to retain style information from Office.
|
||||
Added new autosave plugin logic that automatically saves contents in local storage.
|
||||
Added new valid_styles option. Adds the possibility to restrict styles and their order.
|
||||
Added new theme_advanced_runtime_fontsize option to display the runtime font size in font size select box.
|
||||
Added new jquery plugin version that handles the gzip compressor amongst other things. Contributed by Speednet.
|
||||
Added new $ function to tinymce namespace and editor instances for the jQuery build.
|
||||
Added the possibility to get editors by index as well as name in the tinyMCE.editors collection.
|
||||
Fixed so the contents inside the editor renders in standards mode by default.
|
||||
Fixed bug where it wasn't possible to move the caret on short documents running in standards mode on IE.
|
||||
Fixed bug where the decode method of the DOMUtils class could end up in an endless loop.
|
||||
Fixed bug where it was possible to bypass the paste cleanup on non IE browsers if you clicked while pasting.
|
||||
Fixed bug where some attributes wasn't serialized correctly on IE if wildcard attribute patters where used.
|
||||
Fixed bug where entity decoding was performed on strings that didn't have any valid entities in them.
|
||||
Fixed bugs with the insertNode method of the IE DOMRange implementation. Patch contributed by Scott McNaught.
|
||||
Rewrote the getBookmark/moveToBookmark selection logic to boost performance on larger documents.
|
||||
Rewrote the table plugin to include new cell selection logic and fixed various bugs and issues.
|
||||
Merged the tinyMCE, tinymce and tinymce.EditorManager into the same instance makes more sense.
|
||||
Removed browser setting since the browser support for TinyMCE is not far better than it was when that setting was introduced.
|
||||
Changed the mce_ attribute prefix to the more standard _mce_ prefix. This is similar to browser vendors prefixes.
|
||||
Optimized performance with named entities on Gecko. Regexp replace was executing very slowly probably due to a Gecko bug.
|
||||
Optimized performance of the IE specific selection/range implementation.
|
||||
Removed the safari plugin since we now replaced all text formatting logic to custom code.
|
||||
Version 3.2.7 (2009-09-22)
|
||||
Fixed bug where uppercase paragraphs could still produce an invalid DOM tree on IE.
|
||||
Fixed bug where split command didn't work on WebKit since the node serializer needs a real document to work with.
|
||||
Fixed bug where it was impossible in Gecko to place the caret before a table if it was the first one.
|
||||
Fixed bug where linking to urls like ../../ would produce an extra traling slash ../..//.
|
||||
Fixed bug where the template cdate functionality was using an old 2.x API call. Patch contributed by vectorjohn.
|
||||
Fixed bug where urls to the same site but different protocol would be converted when relative_urls where set to false. Patch contributed by Ted Rust.
|
||||
Fixed bug where the paste plugin would remove mceItem prefixed classes.
|
||||
Fixed bug where the paste plugin would sometimes add items in a reverse order on WebKit.
|
||||
Fixed bug where the paste buttons would present an error message on Gecko even if you changed user.js. Patch contributed by Todd (teeaykay).
|
||||
Fixed bug where Opera would crash if you had tables incorrectly placed inside paragraphs.
|
||||
Fixed bug where styles elements wasn't properly processed if you had bad input HTML.
|
||||
Fixed bug where style attributes wasn't properly forced into a specific format.
|
||||
Fixed bug and issues with boolean attributes like checked, nowrap etc.
|
||||
Fixed bug where input elements could override attributes on form elements.
|
||||
Fixed bug where script or style elements could get modified by the DOMUtils processHTML method.
|
||||
Fixed bug where the selected attribute could get lost when force root blocks logic got executed on IE. Patch contributed by Attila Mezei-Horvati.
|
||||
Fixed bug where getAttribs method didn't handle boolean attributes correctly on IE.
|
||||
Fixed so the paste from word dialog is presented if you paste content on an IE with to restrictive security settings.
|
||||
Fixed so the paste_strip_class_attributes option is set to none by default in the paste plugin.
|
||||
Removed default border=0 on tables for the default value of valid_elements.
|
||||
Version 3.2.6 (2009-08-19)
|
||||
Added new wordcount plugin, this will display the number of typed words as you write. Contributed by Andrew Ozz.
|
||||
Added new getNext and getPrev methods to DOM utils. These will return the first matching sibling.
|
||||
Fixed bug where it was impossible to place the caret after a table on Gecko. It will now add a paragraph after tables.
|
||||
Fixed bug where inline dialogs would fail if used in a window opened using a showModalDialog. Patch contributed by Derek Britt.
|
||||
Fixed bug where IE could sometimes render a unknown runtime error on invalid input HTML.
|
||||
Fixed bug where some incorrectly placed tables wouldn't be moved outside the paragraphs on IE.
|
||||
Fixed bug where uppercase script/style element wouldn't be handled correctly and converted to valid lowercase.
|
||||
Fixed bug where some WebKit versions on Mac OS X would produce issues with hidden select fields.
|
||||
Fixed bug where the media plugin would fail on WebKit since the node wasn't properly imported to the right document.
|
||||
Fixed bug where absolute URLs for the TinyMCE script using a base href element would cause loading problems in IE 6/7.
|
||||
Fixed bug where pasting using the paste plugin wasn't possible on IE with to restrictive security settings.
|
||||
Fixed bug where pasting of whitespace was impossible using the new custom paste method.
|
||||
Fixed bug where pasting on some WebKit browsers would not work if you pasted specific contents due to a WebKit bug.
|
||||
Fixed bug where doctypes with multiple lines would not be parsed correctly by the fullpage plugin. Patch contributed by Colin.
|
||||
Fixed bug where the autoresize plugin would break the fullscreen functionality.
|
||||
Fixed bug where tables would be chopped up running on IE using invalid contents and pasting paragraphs into a cell.
|
||||
Fixed bug where the each method of jQuery build didn't iterate styleSheets. We now use the TinyMCE API one instead.
|
||||
Fixed bug where auto switching to paragraphs after headers some times failed in Gecko.
|
||||
Fixed so all editor options gets passed to the Serializer class. Patch contributed by Jasper Mattsson.
|
||||
Fixed so script/style blocks isn't wrapped in paragraphs as other inline elements.
|
||||
Fixed so the XHR requests sends the X-Requested-With HTTP header.
|
||||
Fixed so the data url scheme is handled in the tinymce.util.URI class.
|
||||
Changed inline documentation to use moxiedoc style comments.
|
||||
Removed the compat2x plugin people should have upgraded to the 3.x API by now. 3.0 was released more then a year ago.
|
||||
Re-added Gecko specific message for users who doesn't understand the security concept regarding paste.
|
||||
Version 3.2.5 (2009-06-29)
|
||||
Added new jQuery plugin for the jQuery specific package. This enables you to more easily load and use TinyMCE.
|
||||
Added new autoresize plugin contributed by Peter Dekkers. This plugin will auto resize the editor to the size of the contents.
|
||||
Fixed so all packages have the same directory structure. Previous releases had a different structure for the production package.
|
||||
Fixed so the paste from word dialog forces the contents to be processed as word contents even if it's not.
|
||||
Fixed so the jQuery build adapter build works. It's currently only excluding Sizzle.
|
||||
Fixed so noscript element contents is retained during the editing process.
|
||||
Fixed bug where the getBookmark method would need a "simple" string input when the documented way is a boolean.
|
||||
Fixed bug where invalid contents could break the fix_table_elements logic.
|
||||
Fixed bug where Sizzle specific attributes would be serialized if the valid_elements was set to *[*].
|
||||
Fixed bug where IE would produce an error if you specified a relative content_css and opened the paste dialog.
|
||||
Fixed bug where pasting images on IE would produce broken images if they came from an external site.
|
||||
Fixed bug where memory was leaked if you add/remove controls dynamically. Some event handlers wasn't removed properly.
|
||||
Fixed bug where domain relaxing wasn't treated correctly if you added it after the TinyMCE script element.
|
||||
Fixed bug where the activeEditor wasn't set to null if the last editor instance was removed.
|
||||
Fixed bug where IE was leaking memory on the onbeforeunload event due to some recently introduced logic. Patch contributed by Options.
|
||||
Fixed bug where inserting tables in Safari 4 didn't work due to a new WebKit bug where some element names are reserved.
|
||||
Fixed bug where URLs having a :// value in the query string would make it absolute regardless of URL settings.
|
||||
Fixed the WebKit specific bug where DOM Ranges would fail if the node wasn't attached to something in a different way.
|
||||
Removed the auto_resize option and the resizeToContent method from the tinymce.Editor class. Use the new autoresize plugin instead.
|
||||
Version 3.2.4.1 (2009-05-25)
|
||||
Fixed bug where Gecko browsers would produce an extra space after for example strong when loaded from sub domains.
|
||||
Fixed bug where script elements would be removed if they where placed inside a paragraph element.
|
||||
Fixed bug where IE 8 would produce 1 item remaining when loading CSS files dynamically with an empty cache.
|
||||
Fixed bug where bound events would be removed from other editor instances if a specific one was removed.
|
||||
Fixed various bugs and issues with script and style elements inside the editor.
|
||||
Fixed so all script contents gets wrapped in CDATA sections so that they can be parsed using a XML parser.
|
||||
Fixed so it's impossible for elements marked as closed to have child nodes rendered in output.
|
||||
Version 3.2.4 (2009-05-21)
|
||||
Added new paste_remove_styles/paste_remove_styles_if_webkit option to paste plugin concept contributed by Hadrien Gardeur.
|
||||
Added new functionality to paste plugin contributed by Scott Eade aka monkeybrain.
|
||||
Added new paste_block_drop option to the paste plugin this is disabled by default and will block any drag/drop event.
|
||||
Added new bind/unbind methods to DOMUtils these works like Event.add/Event.remove but is easier to access.
|
||||
Added new paste_dialog_width/paste_dialog_height options to paste pluign. Enables you to change the dialog sizes.
|
||||
Fixed bug on IE 8 where it would sometimes produce a "1 item remaining" status message that would never finish.
|
||||
Fixed bug on Safari 4 beta that would produce DOM Range exceptions on the DOMUtils split method since the browser has a bug.
|
||||
Fixed bug where the paste plugin could accidentally think that some word sentences was supposed to be list elements.
|
||||
Fixed bug where paste plugin would produce one extra empty undo level on some browsers.
|
||||
Fixed bug where spans wasn't produced correctly on new line when the keep_styles option was enabled.
|
||||
Fixed bug where the caret would be placed at the beginning of contents in IE 8 if you selected colors from the color pickers.
|
||||
Fixed so the Event class is a normal class instead of a static one. The tinymce.dom.Event is now a global instance of that class.
|
||||
Fixed so internal events for instances gets removed when the DOMUtils instance is removed.
|
||||
Fixed so preventDefault and stopPropagation methods can be used on the event object in all browsers.
|
||||
Version 3.2.3.1 (2009-05-05)
|
||||
Fixed bug where paragraphs containing form elements such as input or textarea would be removed.
|
||||
Fixed bug where some IE versions would produce a wrapper function for events attributes.
|
||||
Fixed bug where table cell contents could be removed if you pressed return/enter at the end of the cell contents.
|
||||
Fixed bug where the paste plugin would remove a extra character if the selection range was collapsed.
|
||||
Fixed bug where creating tables with % width wouldn't be handled correctly on WebKit browsers.
|
||||
Version 3.2.3 (2009-04-23)
|
||||
Added new paste plugin logic. This new version will autodetect Word contents and clean it up.
|
||||
Added a optional root element argument to getPos so you can tell it where to stop the calculation.
|
||||
Added new DOM ready logic to remove the usage of document.write. We now use basically the same method as jQuery.
|
||||
Fixed bug where WebKit browsers would fail when selecting all contents in the area using Ctrl+A.
|
||||
Fixed bug where IE would produce paragraphs with empty inline style elements.
|
||||
Fixed bug where WebKit browsers would fail when inserting tables with a non pixel width.
|
||||
Fixed bug where block elements could get a redundant br element at the end of the element.
|
||||
Fixed bug where the tabfocus plugin only worked with a single editor instance on page.
|
||||
Fixed bug where IE 8 was loosing caret position if the selection was collapsed and a menu was clicked.
|
||||
Fixed bug with application/xhtml+xml mode where menus wasn't working properly.
|
||||
Fixed bug where the onstop workaround fix for IE would produce errors in an ASP update panel.
|
||||
Fixed bug where the submit function override could produce errors if executed in the wrong scope.
|
||||
Fixed bug where the area element wasn't closed by a short ending.
|
||||
Fixed various number issues in the style plugins properties dialog. Contributed by datpaulchen.
|
||||
Fixed issues with size suffix values in the style plugin dialog.
|
||||
Fixed issue where hasDuplicate variable would leak out to the global space due to a bug in the Sizzle engine.
|
||||
Fixed issue where the paste event would fire a dialog warning on IE since we extracted the text contents.
|
||||
Updated Sizzle engine to the latest version, this version fixes a few bugs that was reported.
|
||||
Version 3.2.2.3 (2009-03-26)
|
||||
Fixed regression bug with the getPos method, it would return invalid if the view port was to small.
|
||||
Version 3.2.2.2 (2009-03-25)
|
||||
Fixed so the DOMUtils getPos method can be used cross documents if needed.
|
||||
Fixed bug where undo/redo wasn't working correctly in Gecko browsers.
|
||||
Version 3.2.2.1 (2009-03-19)
|
||||
Added support for tel: URL prefixes. Even though this doesn't match any official RFC.
|
||||
Fixed so the select method of the Selection class selects the first best suitable contents.
|
||||
Fixed bug where the regexps for www. prefixes for link and advlink dialogs would match wwwX.
|
||||
Fixed bug where the preview dialog would fail to open if the content_css wasn't defined. Patch contributed by David Bildström (ChronoZ).
|
||||
Fixed bug where editors wasn't converted in application/xhtml+xml mode due to an issue with Sizzle.
|
||||
Fixed bug where alignment would fail if multiple lines where selected.
|
||||
Updated Sizzle engine to the latest version, this version fixes a few bugs that was reported.
|
||||
Version 3.2.2 (2009-03-05)
|
||||
Added new CSS selector engine. Sizzle the same one that jQuery and other libraries are using.
|
||||
Added new is and getParents methods to the DOMUtils class. These use the new Sizzle engine to select elements.
|
||||
Added new removeformat_selector option, enables you to specify a CSS selector pattern of elements to remove when using removeformat.
|
||||
Fixed so the getParent method can take CSS expressions when selecting it's parents.
|
||||
Added new ant based build process, includes a new javabased preprocessor and a yuicompressor ant task.
|
||||
Moved the tab_focus logic into a plugin called tabfocus, so the old tab_focus option has been removed from the core.
|
||||
Replaced the TinyMCE custom unit testing framework with Qunit and rewrote all tests to match the new logic.
|
||||
Moved the examples/testcases to a root directory called tests since it now includes slickspeed.
|
||||
Fixed bug where nbsp wasn't replaced correctly in ForceBlocks.js. Patch contributed by thorn.
|
||||
Fixed bug where an dom exception would be thrown in Gecko when the theme_advanced_path path was set to false under xml application mode.
|
||||
Fixed bug where it was impossible to get out of a link at the end of a block element in Gecko.
|
||||
Fixed bug where the latest WebKit nightly would fail when changing font size and font family.
|
||||
Fixed bug where the latest WebKit nightly would fail when opening dialogs due to changes to the arguments object.
|
||||
Fixed bug where paragraphs wasn't added to elements positioned absolute using classes.
|
||||
Fixed bug where font size values with dot's like 1.4em would produce a class instead of the style value.
|
||||
Fixed bug where IE 8 would return an incorrect position for elements.
|
||||
Fixed bug where IE 8 would render colorpicker/filepicker icons incorrectly.
|
||||
Fixed bug where trailing slashes for directories in URLs would be removed.
|
||||
Fixed bug where autostart and other boolean values in the media dialog wouldn't be stored/parsed correctly.
|
||||
Fixed bug where the repaint call for the media plugin wouldn't be executed due to a typo in the source.
|
||||
Fixed bug where id attribute of object elements wasn't kept intact by the media plugin.
|
||||
Fixed bug where preview of embeded elements when the media_use_script option was used would fail.
|
||||
Fixed bug where inlinepopups could be rendered at an incorrect location on IE 6 while dragging.
|
||||
Fixed bug where the blocker shim could be placed at an incorrect location on IE 6.
|
||||
Fixed bug where the multiple and size attributes of select elements would produce incorrect values while running in IE.
|
||||
Fixed bug where IE would loose the caret position is you selected a color from the color drop down.
|
||||
Fixed bug where remove format wouldn't work on IE since it couldn't remove span elements that had style information.
|
||||
Fixed bug where Opera was removing links when removing formatting from selected contents.
|
||||
Fixed bug where paragraphs could be produced inside non positional elements styled with the CSS position value of static.
|
||||
Fixed bug where removeformat wouldn't work if you selected part of a span in IE.
|
||||
Fixed bug where media plugin didn't retain the style attribute on embed/object elements.
|
||||
Fixed bug where auto focus on empty editor instances could produce strange results if you inserted an image into it.
|
||||
Fixed bug where characters would be removed in FF when inserted with the mceInsertContent or selection.setContent methods.
|
||||
Fixed bug where warning message of missing paste support wasn't displayed on WebKit browsers.
|
||||
Fixed bug where anchor links could include other links. The selected range is now unlinked before adding news links to it.
|
||||
Fixed memory leak when TinyMCE was used with prototype. Patch contributed by James Ots.
|
||||
Fixed so the non documented fullpage_hide_in_source_view option for the fullpage plugin works again in the 3.x branch.
|
||||
Fixed so tables doesn't get inserted into paragraphs by default since it's not W3C valid. Can be disabled by using the fix_table_elements option.
|
||||
Fixed so the source view dialog sets a source_view state to the event object. Enables plugins to intercept the source view mode.
|
||||
Fixed various validation issues with the html dialogs and pages.
|
||||
Removed ask mode option since there is way better ways of doing this now. Use the add/remove control methods instead.
|
||||
Removed logic for compatibility with Safari 2.x, this browser is no longer supported since no one is using it.
|
||||
Removed the auto domain relaxing feature. If loading scripts cross sub domains it's better to specify the document.domain by hand.
|
||||
Version 3.2.1.1 (2008-11-27)
|
||||
Added new theme_advanced_default_background_color/theme_advanced_default_foreground_color options. Patch contributed by David Bildström (ChronoZ).
|
||||
Fixed font style formatting compatibility issue with Adobe Air.
|
||||
Fixed so legacy font elements get converted into spans even if cleanup_on_startup isn't enabled.
|
||||
Fixed bug where pre elements could be incorrectly modified by an IE bug workaround. Patch contributed by hu vime.
|
||||
Fixed bug where input elements inside inlinepopups wasn't editable in Firefox 2.
|
||||
Fixed bug where the xhtmlxtras plugin wasn't replacing attribute values correctly.
|
||||
Fixed bug where menu buttons in skin variants would look strange due to IE 8 fixes.
|
||||
Fixed bug where WebKit browsers would on backspace take you back to the previous page if the editor was empty.
|
||||
Fixed bug where DOMUtils decode method wouldn't handle strings larger than 4096kb due to node chunking.
|
||||
Fixed bug where meta key wasn't handled as ctrl key on Mac OS X for custom keyboard short cuts.
|
||||
Fixed bug where init event would get fired twice on WebKit on Mac OS X.
|
||||
Version 3.2.1 (2008-11-04)
|
||||
Added support for custom icon image for drop menus. Use icon_src to set a custom image directly.
|
||||
Added new media_strict option to media plugin. Enables you to control if the flash embed is strict or not. Enabled by default.
|
||||
Fixed so the editors script files gets dynamically loaded without using XHR or eval.
|
||||
Fixed so the media plugin outputs valid XHTML object elements for Flash movies. Can be disabled with the media_strict option.
|
||||
Fixed so dynamic loading doesn't require eval calls on non IE browsers for better Air support.
|
||||
Fixed bug where the editor wasn't treated as empty if the remaining paragraph had attributes.
|
||||
Fixed bug where id's of elements was removed ones they got wrapped in paragraphs. Patch contributed by ChronoZ.
|
||||
Fixed bug where WebKit browsers where placing list elements inside paragraph elements.
|
||||
Fixed bug where inserting images or links would produce absolute urls on WebKit browsers.
|
||||
Fixed bug where values for checked, readonly, disabled and selected attributes was incorrect on IE.
|
||||
Fixed bug where positive values for checked, readonly, disabled and selected attributes wasn't forced to valid values.
|
||||
Fixed bug where selecting the first option in a native select box would produce an undefined error.
|
||||
Fixed bug where tabindex 32768 could be outputted on IE if element attributes where cloned.
|
||||
Fixed bug where the media dialogs preview window would display incorrect contents due to duplicate clsid prefixes.
|
||||
Fixed bug where non pixel or percent heights for textarea elements would produce errors on IE.
|
||||
Fixed bug where cdata sections in script elements wasn't handled correctly.
|
||||
Fixed bug where nowrap of table cells would produce a 65535 value output.
|
||||
Fixed bug where media plugin would produce an error if you selected the first item in the items list.
|
||||
Fixed bug where media plugin would modify links with the item _value in them.
|
||||
Fixed so table width/height is better forced if inline_styles is enabled. Patch contributed by daKmoR.
|
||||
Fixed css for IE 8 such as opacity and other rendering quirks.
|
||||
Version 3.2.0.2 (2008-10-02)
|
||||
Fixed bug where the SelectBox and NativeSelectBox wasn't updated correctly if undefined was passed to them.
|
||||
Fixed bug where the style dropdown wasn't correctly changed back to it's original state when element had no class.
|
||||
Fixed bug where multiple pending font styles wasn't handled correctly.
|
||||
Fixed so you can disable all auto css loading for dialogs by setting the popups_css option to false.
|
||||
Version 3.2.0.1 (2008-09-17)
|
||||
Fixed bug where font sizes and faces wouldn't be changed correctly when there was a parent with a different style.
|
||||
Fixed bug where adding fonts to the same selection would produce redundant spans.
|
||||
Version 3.2 (2008-09-11)
|
||||
Added new text style support, it will now use span elements internally instead of font elements.
|
||||
Added new improved support for the theme_advanced_font_sizes option, check the Wiki for details.
|
||||
Added new keep_style setting that maintains the text style on return/enter on non IE browsers, enabled by default.
|
||||
Added new onBeforeSetContent/onBeforeGetContent/onSetContent/onGetContent events to the Selection class.
|
||||
Added new selectByIndex method to ListBox class. This enables you to select list items by an index instead of a value.
|
||||
Added new possibility to the select method of the ListBox class. This can now have a selector function as it's value argument.
|
||||
Added new possibility to skip the loading of popups css by setting the feature popup_css to the value false.
|
||||
Added new possibility to skip translation of popups by setting the translate_i18n feature to false.
|
||||
Added new element_format option enables you to produce HTML element endings instead of XHTML. But we are still in the XHTML is better camp.
|
||||
Added missing allowfullscreen and quality options for flash elements, this will now get correctly stored.
|
||||
Fixed bug where table cell dialog didn't close properly unless the accessibility_warnings option was set to false.
|
||||
Fixed bug where the modal dialog blocker element for inlinepopups wasn't placed at a correct location if the page had scroll.
|
||||
Fixed bug where non inline dialogs didn't close correctly if the inlinepopups plugin was used.
|
||||
Fixed bug where non inline dialogs could make the modal dialog blocker to work incorrectly.
|
||||
Fixed bug where style select wasn't populated correctly if you pressed the arrow. Patch by Hari Karam Singh.
|
||||
Fixed bug where toggling the fullscreen mode didn't restore scrollbars on IE when the editor was inside a frame. Patch by Jacob Barrett.
|
||||
Fixed bug where inserting flash contents using the template plugin didn't work correctly.
|
||||
Fixed bug where inserting flash contents using the selection.setContent or mceInsertContent command didn't work correctly.
|
||||
Fixed bug where IE would produce an exception if a comment started with -.
|
||||
Fixed bug where the blockquote button would wrap lists incorrectly on non IE browsers.
|
||||
Fixed bug where Opera would display BR elements in the element path.
|
||||
Fixed bug where xhtmlxtras didn't insert elements correctly on IE.
|
||||
Fixed bug where the buttons wasn't activated correctly in the xhtmlxtras plugin.
|
||||
Fixed bug where adding an object as the style attribute for the dom setAttribs method wouldn't work.
|
||||
Fixed bug where the background color would bleed out to parent container element in Gecko.
|
||||
Fixed bug where the insert column actions for tables would fail if you did it in a thead or tfoot. Patch contributed by T Andersen (tan73).
|
||||
Fixed bug where event blocker element wasn't positioned correctly for the inlinepopups plugin.
|
||||
Fixed bug where pasting from Office 2007 would produce an odd comment in the contents.
|
||||
Fixed bug where the paste as plain text could remove an extra character. Patch contributed by Speednet.
|
||||
Fixed bug where some characters where missing for the paste_replace_list option. Patch contributed by Speednet.
|
||||
Fixed bug where removing non existing editor instances by the mceRemoveControl command would produce an error.
|
||||
Fixed bug where meta elements with the name description would produce errors in IE.
|
||||
Fixed bug where color and background colors wouldn't be updated properly.
|
||||
Fixed bug where the createMenuButton of tinymce.ControlManager didn't implement the last class argument.
|
||||
Fixed bug where the editor_css option was relative from the TinyMCE installation directory not the current page.
|
||||
Fixed bug where elements wouldn't be padded if the element contained bogus br elements. For example TD elements.
|
||||
Fixed bug where parsing of <body > in fullpage plugin would produce an error.
|
||||
Fixed bug where relative urls with just ./ would become an empty string.
|
||||
Fixed bug where outdent button would be disabled if inline_styles where set to false.
|
||||
Fixed bug where replace with an empty search string would produce an error on IE.
|
||||
Fixed bug where restoring the overflow state of the body in fullscreen plugin running on IE would produce vertical scrollbars.
|
||||
Fixed bug where pressing return/enter in list items would sometimes move the caret the to top of the content area in FF.
|
||||
Fixed bug where the style listbox wouldn't be updated correctly if you used the use_native_selects option.
|
||||
Fixed bug where WebKit browsers would produce a div element when ending list elements using return.
|
||||
Fixed so translation of popup contents only occurs if it's needed.
|
||||
Optimized the URI object in regards or converting absolute URIs to relative URIs.
|
||||
Version 3.1.1 (2008-08-18)
|
||||
Added new getSize method to DOMUtils it will return the dimensions only of an element.
|
||||
Added new alert/confirm methods to the tinyMCEPopup class to prevent focus problems and also to shorten method calls.
|
||||
Added new plugin_preview_inline option to preview plugin to enable/disable native/inline dialogs.
|
||||
Added new readonly option. If this is set the editor will only display the contents for the user.
|
||||
Added missing tabindex and accesskey to input elements in the default valid_elements setup.
|
||||
Updated firebug lite to 1.2, to enable it use the tiny_mce_dev.js?debug=1 on the development package.
|
||||
Fixed so the preview dialog in the preview plugin uses inline dialogs/popups.
|
||||
Fixed so CDATA sections remains intact through the serialization process of the DOM tree.
|
||||
Fixed various issues with the getAttrib command. It will now return more correct values.
|
||||
Fixed bug where the embed element wasn't properly parsed in the media plugin it now supports 3 formats.
|
||||
Fixed bug where the noshade attribute was serialized incorrectly on IE.
|
||||
Fixed bug where editing an existing link element didn't force it relative.
|
||||
Fixed bug where image link creation fails on Safari if the image is aligned.
|
||||
Fixed bug where it was possible to scroll the fullscreen mode in Opera 9.50.
|
||||
Fixed bug where removal of center image alignment would fail. Patch contributed by Andrew Ozz.
|
||||
Fixed bug where inlinedialogs didn't work properly if the doctype was incorrect in IE.
|
||||
Fixed bug where cross domain loading didn't work correctly in Opera 9.50.
|
||||
Fixed bug where breaking huge text blocks with return/enter key would scroll to end of block.
|
||||
Fixed bug where replace button kept inserting the replacement text even if there is no more matches.
|
||||
Fixed bug with fullpage plugin where value wasn't set correctly. Patch contributed by Pascal Chantelois.
|
||||
Fixed bug where the dom utils setAttrib method call could produce an exception if the input was null/false.
|
||||
Fixed bug where pressing backspace would sometimes remove one extra character in Gecko browsers.
|
||||
Fixed bug where the native confirm/alert boxes would move focus to parent document if fired in dialogs.
|
||||
Fixed bug where Opera 9.50 was telling you that the selection is collapsed even when it isn't.
|
||||
Fixed bug where mceInsertContent would break up existing elements in Opera and Gecko.
|
||||
Fixed bug where TinyMCE fails to detect some keyboard combos on Mac, contributed by MattyRob.
|
||||
Fixed bug where replace all didn't move the caret to beginning of text before searching.
|
||||
Fixed bug where the oninit callback wasn't executed correctly when the strict_loading_mode option was used, thanks goes to Nicholas Oxhoej.
|
||||
Fixed bug where a access denied exception was thrown if some other script specified document.domain before loading TinyMCE.
|
||||
Fixed so setting language to empty string will skip language loading if translations are made by some backend.
|
||||
Fixed so dialog_type is automatically modal if you use the inlinepopups plugin use dialog_type : "window" to re-enable the old behavior.
|
||||
Version 3.1.0.1 (2008-06-18)
|
||||
Fixed bug where the Opera line break fix didn't work correctly on Mac OS X and Unix.
|
||||
Fixed bug where IE was producing the default value the maxlength attribute of input elements.
|
||||
Version 3.1.0 (2008-06-17)
|
||||
Fixed bug where the paste as text didn't work correctly it encoded produced paragraphs and br elements.
|
||||
Fixed bug where embed element in XHTML style didn't work correctly in the media plugin.
|
||||
Fixed bug where style elements was forced empty in IE. The will now be wrapped in a comment just like script elements.
|
||||
Fixed bug where some script elements wrapped in CDATA could fail to be serialized correctly.
|
||||
Fixed bug where FF 3 produced -moz- internal styles in some style attributes.
|
||||
Fixed bug where query strings and external URLs didn't work correctly in style attributes.
|
||||
Fixed bug where shape attribute of area elements got serialized as rect regardless of it's initial value in IE 6.
|
||||
Fixed bug where selection of elements inside layers would fail in IE since focus was moved to the document body.
|
||||
Fixed bug where pressing enter/return in an editable select box would produce an __mce_add_custom__ class value.
|
||||
Fixed bug where changing font size of text placed inside a colored text chunk would remove the parent node.
|
||||
Fixed bug where Opera 9.5 final produced a strange line break behavior due to a workaround for previous Opera versions.
|
||||
Fixed bug where text/background color would produce a strange focus problem when you tried to click on the body in IE.
|
||||
Fixed issue where selecting the title of an listbox equals the old 2.x behavior of changing the value to an empty string.
|
||||
Fixed issue where it was common for the media plugin to break if the _value attribute wasn't added for the param element.
|
||||
Fixed issue where the wrong parent editor instance might be updated if you use fullscreen mode in an incorrect way.
|
||||
Fixed issue where Safari was producing a warning about the base element not being closed correctly.
|
||||
Removed redundant form element name matching from regexp in the DOMUtils class.
|
||||
Version 3.0.9 (2008-06-02)
|
||||
Added new contextmenu_offset_x/contextmenu_offset_y options for the contextmenu plugin.
|
||||
Added cite attribute to the default rule for the blockquote element.
|
||||
Added support for using arrow keys for selection of items in listboxes.
|
||||
Added support for using arrow keys for selection of items in dropmenus.
|
||||
Fixed bug where blockformat change on elements with BR inside them didn't change correctly on Firefox.
|
||||
Fixed bug where removing table rows inside thead or tfoot would remove the whole table if it was the last one.
|
||||
Fixed bug where XHR synchronous mode didn't execute the callback handlers synchronously.
|
||||
Fixed bug where setting border to 0 didn't add border: 0 to the style attribute when using the advimage dialog.
|
||||
Fixed bug where the selection of images and table cells didn't work correctly when the editor is placed in a frame and running on IE.
|
||||
Fixed bug where the store/restore of a selection didn't work correctly in non IE browsers.
|
||||
Fixed bug where only the first element would be invalid for the invalid_elements option.
|
||||
Fixed bug where paste as plain text didn't encode the characters correctly when they where inserted.
|
||||
Fixed bug where HTML source window couldn't be maximized on Gecko when the maximizable feature was enabled.
|
||||
Fixed bug where color selection using the color picker could produce exception in IE.
|
||||
Fixed bug where font size changes could produce produce extra redundant elements.
|
||||
Fixed bug where IE could produce unknown runtime error if you replaced a image with another image from a separate frame.
|
||||
Fixed bug where the domLoaded state for the Event class wasn't set correctly if the editor was loaded dynamically using the gzip compressor.
|
||||
Fixed bug where handling of the base element for a page would produce incorrect urls. Based on a patch contributed by John LeSueur.
|
||||
Fixed bug where table constraint alert boxes was presented with an empty value and wasn't the skinned inline ones.
|
||||
Fixed bug where the onChange event wasn't fired when the form was submitted. It's now also triggered when the save method is called.
|
||||
Fixed bug where encoding set to xml didn't work as expected. It now encodes the contents into XML entities.
|
||||
Fixed bug where numrows didn't work correctly for the merge cells dialog of the table plugin.
|
||||
Fixed bug where the onGetContent event was fired even when the no_events flag was set.
|
||||
Fixed bug where the preview panels for the advimage and the media plugin could overflow on Safari and FF 3.
|
||||
Fixed bug where the editing and removal of abbr elements using the xhtmlxtras plugin working correctly on IE.
|
||||
Fixed bug where save button in the save plugin didn't work correctly on IE.
|
||||
Fixed bug where dragging layers didn't work as expected since it would snap back to it's original location if you saved.
|
||||
Fixed bug where the description of the template plugin dialog wasn't updated correctly.
|
||||
Fixed bug where the values for frame and rules in the table dialogs where swapped.
|
||||
Fixed bug where the elements like ins, del, cite, acronym and abbr didn't have the default editing style as the old 2.x branch.
|
||||
Fixed bug where ask mode would lock the focused textarea if you pressed cancel in the confirm dialog on FF 3.
|
||||
Fixed bug where ask mode would produce contents for empty textareas if you reloaded the page.
|
||||
Fixed so the onGetContent event gets the full pass through object just like the other events.
|
||||
Fixed so attributes for block elements remains the same when you change format of a element.
|
||||
Version 3.0.8 (2008-04-30)
|
||||
Fixed bug where IE would produce an error if textareas without names where converted.
|
||||
Fixed bug where editor wasn't forced empty when there was only a single br or empty paragraph left.
|
||||
Fixed bug where IE would produce an warning message if object elements where produced in the media plugins preview running on https.
|
||||
Fixed bug where new addVer function didn't handle hash items correctly. Patch contributed by Mirek Burkon.
|
||||
Fixed bug where font_size_style_values option wasn't applied correctly to fonts inside the editor.
|
||||
Fixed bug where image selection could be lost if a image was edited using context menu on IE.
|
||||
Fixed bug where style values wasn't updated properly due to an invalid regexp.
|
||||
Fixed bug where IE 6 where displaying warning message about insecure items when inserting an image while using https. Patch contributed by Norifumi Sunaoka.
|
||||
Fixed bug where IE was producing an auto save message if you selected a color from the color split button.
|
||||
Fixed bug where backspace sometimes would move the caret to the end of the previous block in Gecko.
|
||||
Fixed bug where the rowlayout manager didn't work as described in the documentation.
|
||||
Fixed bug where the default options for the fullpage plugin wasn't applied correctly.
|
||||
Fixed bug where selection would jump one character if you applied a styles to a words in non IE browsers.
|
||||
Fixed bug where undo levels wasn't added correctly if you went back in undo history and added a new event.
|
||||
Fixed bug where font size dropdown didn't mark the selected size in IE.
|
||||
Fixed bug where the size of the editor was determined using clientWidth instead of offsetWidth.
|
||||
Fixed so the onchange event doesn't fire on the initial undo level, it will also fire when the editor is blurred.
|
||||
Fixed so the advhr plugin produces XHTML valid output instead of non standard attributes.
|
||||
Fixed so blockquote gets converted into [quote] in when the bbcode plugin is enabled.
|
||||
Fixed so theme_advanced_font_sizes can be named for example Font 1=1, Font 2=2 etc.
|
||||
Fixed so editor_selector/editor_deselector can be regexps. By default only strings are allowed not part regexps like before.
|
||||
Fixed so that the version suffix is optional. It still requires the build process so you need to export it manually.
|
||||
Fixed so it's possible to tab to table cells in non Gecko browsers and also produce new rows if you tab at the end of a table. Contributed by Josh Peek.
|
||||
Version 3.0.7 (2008-04-14)
|
||||
Added new version suffix to all internal GET requests to make sure that the users cache gets cleared correctly.
|
||||
Fixed issue with isDirty returning true event if it wasn't dirty on IE due to changes in tables during initialization.
|
||||
Fixed memory leak in IE where if a page was unloaded before all images on the page was loaded it would leak.
|
||||
Fixed bug in IE where underline and strikethrough could produce an exception error message.
|
||||
Fixed bug where inserting paragraphs in totally empty table cells would produce odd effects.
|
||||
Fixed bug where layer style data wasn't updated correctly due to some performance enhancements with the DOM serializer.
|
||||
Fixed bug where it would convert the wrong element if there was two elements with the same name and id on the page.
|
||||
Fixed bug where it was possible to add style information to the body element using the style plugin.
|
||||
Fixed bug where Gecko would add an extra undo level some times due to the blur event.
|
||||
Fixed bug where the underline icon would get active if the caret was inside a link element.
|
||||
Fixed bug where merging th cells not working correctly. Patch contributed by André R.
|
||||
Fixed bug where forecolorpicker and backcolorpicker buttons where rendered incorrectly when the o2k7 skin was used.
|
||||
Fixed bug where comment couldn't contain -- since it's invalid markup. It will now at least not break on those invalid comments.
|
||||
Fixed bug where apos wasn't handled correctly in IE. It will now convert apos to ' on IE since that browser doesn't support that entity.
|
||||
Fixed bug where entities wasn't encoded correctly inside pre elements since they where protected from whitespace removal.
|
||||
Fixed bug where color split buttons where rendered incorrectly on IE6 when using the non default theme.
|
||||
Fixed so caret is placed after links ones they are created, to improve usability of the editor.
|
||||
Fixed so you can select tables by clicking on it's borders in non IE browsers to normalize the behavior.
|
||||
Fixed so the menus can be toggled by clicking once more on the icon in listboxes, menubuttons and splitbuttons based on code contributed by Josh Peek.
|
||||
Fixed so buttons can be labeled, currently only works with the default skin, so it's kind of experimental. Patch contributed by Daniel Insley.
|
||||
Fixed so forecolorpicker and backcolorpicker remembers the last selected color. Patch contributed by Shane Tomlinson.
|
||||
Fixed so that you can only execute the mceAddEditor command once for the same instance name.
|
||||
Fixed so command functions added with addCommand can pass though the call to default handles if it returns true.
|
||||
Version 3.0.6.2 (2008-04-07)
|
||||
Fixed bug where empty tables couldn't be edited correctly on non IE browsers if they where loaded into the editor.
|
||||
Fixed bug where it was impossible to resize layers correctly in IE since it thought it was an image.
|
||||
Fixed bug where an editor instance was stealing focus in IE resulting in a scroll to the editor on page reloads.
|
||||
Fixed bug where Safari was crashing on Mac OS X if you closed dialogs using the Esc key.
|
||||
Version 3.0.6.1 (2008-04-04)
|
||||
Added support for the missing mceAddFrameControl command. The input for this command has changed so consult the Wiki.
|
||||
Fixed bug where sub menus for the drop menus would leave an empty element behind.
|
||||
Fixed memory leak in IE if the editor was placed in a frame or iframe.
|
||||
Version 3.0.6 (2008-04-03)
|
||||
Added elements to the default value of valid_elements option. It now contains all XHTML strict elements and a few transitional.
|
||||
Added more accessibility fixes, it's now possible to navigate and close list boxes and split button menus with the keyboard.
|
||||
Added missing getInfo method to the contextmenu and safari plugin, this caused problems for the Drupal module.
|
||||
Added new inlinepopups_zindex option to the inlinepopups plugin so that you can configure the default start z-index.
|
||||
Added new setControlType method to the tinymce.ControlManager class. This method enables you to override the default classes.
|
||||
Added ability to specific an optional control class to use instead of the default one for the ControlManager methods. Based on concept by Josh Peek.
|
||||
Fixed bug where attribute rules for the DOM Serializer couldn't contain - or _ characters in their names.
|
||||
Fixed bug where inlinepopups event blocker and modal dialog blocker elements produced vertical scrollbars.
|
||||
Fixed bug where there was a rendering issue with quirks mode in Safari moving the resize handle to an incorrect position.
|
||||
Fixed bug with forecolor/backcolor controls on IE. Sometimes elements positioned relative will generate display errors.
|
||||
Fixed bug where a p2 was leaking out in the global name space when you selected a color from the forecolor/backcolor controls.
|
||||
Fixed bug where empty paragraphs didn't work as expected in browsers other than IE.
|
||||
Fixed bug where the load method of the tinymce.dom.ScriptLoader didn't check if the file was already loaded.
|
||||
Fixed bug where the load method for the PluginManager and ThemeManager didn't check if a plugin/theme by a specific name was all ready loaded.
|
||||
Fixed bug where the theme_advanced_link_targets option didn't work correctly with the advanced themes link dialog. Patch contributed by Arnold B.
|
||||
Fixed bug where the style command would merge classes into empty span elements.
|
||||
Fixed bug where the style command would remove empty span elements outside the current selection.
|
||||
Fixed bug where the fix for the Safari backspace bug removed all editor contents if it was filled with empty paragraphs.
|
||||
Fixed bug where alert and confirm boxes opened by the inlinepopups plugin would produce an exception if domain relaxing was used.
|
||||
Fixed bug where Safari was adding style attributes to all elements when you paste them into the editor.
|
||||
Fixed bug where the spellchecker menus was visually incorrect since the space for the non existing icon was still there.
|
||||
Fixed bug where remove_linebreaks option didn't remove line breaks inside the text contents of a element.
|
||||
Fixed bug where Safari 3.1 was introducing _mc_tmp into paragraphs due to the new querySelectorAll and a TinyMCE specific workaround.
|
||||
Fixed bug where getParam method in the Editor class was returning incorrect objects and would mess up the font drop down. Patch contributed by speednet.
|
||||
Fixed bug where the table dialog would produce an exception in IE when you edited tables since it tried to place focus in a disabled field.
|
||||
Fixed bug where class attribute on some span elements was removed on cleanup.
|
||||
Fixed bug where resizing the editor in IE could produce an exception if the editor width/height got to be a negative value.
|
||||
Fixed bug where wmv files wouldn't play since the src param was used instead of the url param.
|
||||
Fixed bug where br elements would be added here and there in Gecko. Geckos internal _moz_dirty br elements where serialized as well.
|
||||
Fixed bug where editing named anchors would produce two anchors instead of one updated one.
|
||||
Fixed bug where arrow and function keys didn't work when an noneditable element was focused within the editor.
|
||||
Fixed bug where the dispatcher could produce an exception if the listener list was altered inside an event callback.
|
||||
Fixed bug where it was impossible to totally empty the editor contents on Safari due to an mistreatment of nbsp as whitespace. Patch contributed by Andrew Ozz.
|
||||
Fixed bug where TinyMCE would not convert textareas with the same name attribute value. It will now generate an unique id for those textareas.
|
||||
Fixed bug where backspace/delete key was deleting td elements inside tables while running on Gecko.
|
||||
Fixed bug where Firefox 3.0b4 and Opera 9.26 where scrolling to the top of document when pressing return/enter.
|
||||
Fixed bug where the template plugin wasn't just inserting the mceTmpl tagged element.
|
||||
Fixed bug where the alert method of the default WindowManager implementation didn't translate input language strings like the inlinepopups dialog does.
|
||||
Fixed bugs with the backspace behavior in Gecko. The caret was placed on incorrect locations in the DOM sometimes.
|
||||
Fixed so advimage dialog and table dialogs has support for editable select boxes for the class value.
|
||||
Fixed so the media, pagebreak and spellchecker doesn't load it's default content.css file if the content_css option is set to false.
|
||||
Fixed so the paste_use_dialog option works again it's enabled by default but can be disabled on IE. Patch contributed by Speednet.
|
||||
Fixed so that the fullscreen editor is focused when switching fullscreen editing on.
|
||||
Fixed so it's possible to edit images and links inside tables using the context menu.
|
||||
Fixed so table dialogs and the advanced image dialog doesn't loose selection in IE if the dialogs where navigated/submitted with the keyboard.
|
||||
Fixed so the theme_advanced_blockformats options can have named items for example title 1=h1;title 2=h2.
|
||||
Fixed so it's possible to add a custom editor_css for the simple theme.
|
||||
Fixed quirks with directionality rtl, patch contributed by Andrew Ozz.
|
||||
Fixed so the inlinepopups default start zIndex is 300000.
|
||||
Fixed typo in media plugin Shockware is now replaced with Shockwave.
|
||||
Fixed psuedo memory leak in IE with the replaceChild method inside the DOMUtils.replace method.
|
||||
Fixed so memory is released when an editor instance is removed from page.
|
||||
Optimized the color split button menus so that they use less event handlers.
|
||||
Removed the util/mclayer.js file since it's no longer used by any of the TinyMCE dialogs and is considered deprecated.
|
||||
Version 3.0.5 (2008-03-12)
|
||||
Added new black skin variant to the o2k7 skin contributed by Stefan Moonen.
|
||||
Added new explode method to the tinymce core class. This does a split but removed whitespace it also defaults to a , delimiter.
|
||||
Added new detection logic for IE 8 standards mode into the DOMUtils class strMode can now be checked to see if that mode is on/off.
|
||||
Added new noscale option value for the scale select box for Flash in the media plugin.
|
||||
Fixed bug where the menu for the ColorSplitButton wasn't removed when the editor was removed.
|
||||
Fixed bug where font colors couldn't be edited correctly since the style of the element didn't get updated correctly.
|
||||
Fixed bug where class of elements would get lost when TinyMCE was fixing incorrect HTML markup.
|
||||
Fixed bug where table editing would produce double height values.
|
||||
Fixed bug where width style value wouldn't be removed if you switched width unit from cm/em to pixels or percent.
|
||||
Fixed bug where the search/replace input box wasn't auto focused like the other dialogs.
|
||||
Fixed bug where the old mceAddControl command would use the fullscreen settings next time it created an instance.
|
||||
Fixed bug where multiple lines where added to the target cell if you merged multiple empty cells.
|
||||
Fixed bug where drop down menus would be incorrectly positioned inside scrollable divs.
|
||||
Fixed bug where the separators of the silver skin variant didn't display correctly in IE 6.
|
||||
Fixed bug where createStyleSheet seems to load scripts at opposite order in some IE versions.
|
||||
Fixed bug where directionality could produce odd results for the UI and the dialogs.
|
||||
Fixed bug where the DOM serializer wouldn't serialize custom namespaced attributes in IE 6 using the *[*] valid elements rule.
|
||||
Fixed bug where table caption would be inserted after the thead element if you swapped a tr to be inside the thead.
|
||||
Fixed bug where the youtube detection logic for the media plugin was to generic.
|
||||
Fixed so the deprecated and undocumented theme_advanced_path_location set to none won't hide the whole statusbar.
|
||||
Fixed so most input lists can have whitespace in them they are now split using the new tinymce.explode method.
|
||||
Fixed so the popup_css and popup_css_add URLs are relative to where the current document is located.
|
||||
Fixed various bugs and quirks with the store/restore selection logic.
|
||||
Fixed so the editor starts in IE 8 standards mode but still that browser is very very buggy.
|
||||
Fixed so dialog_type set to modal will block the background and other inline windows and only give access to the front most window.
|
||||
Version 3.0.4.1 (2008-03-08)
|
||||
Fixed critical bug where it was impossible to edit images when inlinepopups where used due to lost selection in IE.
|
||||
Version 3.0.4 (2008-03-07)
|
||||
Added new option constrain_menus, this enables you to force view port constraints on all menus. Contributed by Shane Tomlinson.
|
||||
Fixed bug where table background wasn't visible inside the editor due to a default CSS rule overriding the style attribute.
|
||||
Fixed bug where links would get a null class added if no styles was used in IE.
|
||||
Fixed bug where spellchecker was auto focusing the editor in IE.
|
||||
Fixed bug where document.domain would produce invalid argument if the editor was loaded in IE6 over a network UNC path.
|
||||
Fixed bug where table height attribute was used, this is deprecated in XHTML so it now adds it as an style.
|
||||
Fixed bug where textareas with style values would produce error in IE.
|
||||
Fixed so the first element in each dialog is focused by default to enhance keyboard usage.
|
||||
Fixed so you can add a mceFocus class to elements to make it auto focused.
|
||||
Fixed so you can close dialogs using the esc key.
|
||||
Fixed so you can press return/enter to submit the action of each dialog.
|
||||
Fixed so tabbing inside an inline popups wont focus the resize anchor elements.
|
||||
Fixed so you can press ok in inline alert messages using the return/enter key.
|
||||
Fixed so textareas can be set to non px or % sizes for example em, cm, pt etc.
|
||||
Fixed so non pixel values can be used in width/height properties for tables.
|
||||
Fixed so the custom context menu can be disabled by holding down ctrl key while clicking.
|
||||
Fixed so the layout for the o2k7 skin looks better if you don't have separators before and after list boxes.
|
||||
Fixed so the sub classes get a copy of the super class constructor function to ease up type checking.
|
||||
Fixed so font sizes for the format block previews are normalized according to http://www.w3.org/TR/CSS21/sample.html (it can be overridden).
|
||||
Fixed so font sizes for h1-h6 in the default content.css is normalized according to http://www.w3.org/TR/CSS21/sample.html (it can be overridden).
|
||||
Version 3.0.3 (2008-03-03)
|
||||
Fixed bug where an error about document.domain would be thrown if TinyMCE was loaded using a different port.
|
||||
Fixed bug where mode exact would convert textareas without id or name if the elements option was omitted.
|
||||
Fixed bug where the caret could be placed at an incorrect location when backspace was used in Gecko.
|
||||
Fixed bug where local file:// URLs where converted into absolute domain URLs.
|
||||
Fixed bug where an error was produced if a editor was removed inside an editor command.
|
||||
Fixed bug where force_p_newlines didn't effect the paste plugin correctly.
|
||||
Fixed bug where the paste plugin was producing an exception on IE if you pasted contents with middots.
|
||||
Fixed bug where delete key could produce exceptions in Gecko sometimes due to the fix for the table cell bug.
|
||||
Fixed bug where the layer plugin would produce an visual add class called mceVisualAid this one is now renamed to mceItemVisualAid to mark it internal.
|
||||
Fixed bug where TinyMCE wouldn't initialize properly if ActiveX controls was disabled in IE.
|
||||
Fixed bug where tables and other elements that had visual aids on them would produce an extra space after any custom class names.
|
||||
Fixed bug where search with an empty string would produce some odd "invalid pointer" error in IE.
|
||||
Fixed bug where elements like menus where placed at incorrect positions in Opera 9.26.
|
||||
Fixed bug where IE was loosing focus of the editor when you clicked some dropmenu and if it was placed in a frame or iframe.
|
||||
Fixed bug where focus of images could be lost in IE if you focused the accessibility confirm dialog in the advimage plugin.
|
||||
Fixed bug where nestled font elements would produce odd output like missing font elements.
|
||||
Fixed bug where text colors and styles got removed if invalid_elements included the font element.
|
||||
Fixed bug where text-decoration set to underline or line-through would remove other styles from span elements.
|
||||
Fixed bug where editor contents like \n\n would be incorrectly handled and processed as real line feeds.
|
||||
Fixed bug where incorrectly encoded urls with ampersands in them would be decoded incorrectly.
|
||||
Optimized the DOMUtils decode method to be a lot faster if the string doesn't have any entities to decode.
|
||||
Version 3.0.2.1 (2008-02-26)
|
||||
Fixed alert/confirm dialogs so they display correctly.
|
||||
Version 3.0.2 (2008-02-26)
|
||||
Added new body_id option that enables you to specify the id of the body inside the editor iframe based on ideas by David Bildström (ChronoZ).
|
||||
Added new body_class option that enables you to set the class for the body of the editor iframe based on ideas by David Bildström (ChronoZ).
|
||||
Added new CSS class to the default content.css files mceForceColors that forces white background and black text can be used with the body_class option.
|
||||
Added new type parameter to the Editor.getParam function to reduce redundant logic for parsing hash tables.
|
||||
Added new isDone method to the ScriptLoaded class, this enables you to check if a script has been loaded or not.
|
||||
Added new resizeTo and resizeBy methods for the advanced theme. Can be called using tinyMCE.activeEditor.theme.resizeTo(w, h);
|
||||
Added new skin_variant option this can be used to extend existing skins with slight modifications like color.
|
||||
Added new variant of the o2k7 skin called "silver" based on a contribution made by Stefan Moonen.
|
||||
Fixed bug where the template plugin might produce errors if the template_mdate_classes wasn't configured.
|
||||
Fixed bug where the media plugin didn't convert the URLs for movies once they where inserted.
|
||||
Fixed bug where the style field for the advlink dialog didn't work correctly if you edited an existing link.
|
||||
Fixed bug where alignment of toolbars would fail in editor was uses in a quirks mode on IE, fix contributed by Peter Wood & Art Lawry.
|
||||
Fixed bug where initialization of multiple editors at the same time using the mceAddControl method would produce errors.
|
||||
Fixed bug where initialization of editors using mceAddControl command or new tinymce.Editor calls would fail during page load.
|
||||
Fixed bug where the check for domain relaxing could fail if the document.domain property was changed by another script.
|
||||
Fixed bug where textareas couldn't be named description or any other name that matches the meta elements in IE and Opera.
|
||||
Fixed bug where the element path would fail sometimes in IE due to "unknown runtime error" on innerHTML.
|
||||
Fixed bug where Safari would crash if you was hiding the editor before serializing the contents.
|
||||
Fixed bug where the editor wasn't scaled propertly in fullscreen mode using the old fullscreen_new_window option.
|
||||
Fixed bug where render method didn't load language packs in IE and Opera if you rendered an editor during page load.
|
||||
Fixed bug where resizing the browser window in fullscreen didn't resize the editor.
|
||||
Fixed bug where the blockquote command didn't move the caret inside the new empty blockquote if you used it on an empty document.
|
||||
Fixed bug where auto in a style width/height for the textarea would produce an editor with the size value of 100. Fix contributed by Shane Tomlinson.
|
||||
Fixed bug where restoration of selection at the beginning of an element could fail in Gecko.
|
||||
Fixed bug where caret restoration after a cleanup could place the it at an incorrect location.
|
||||
Fixed bug where delete key inside td elements would delete the cell in Gecko.
|
||||
Fixed so the blockquote button toggles individual lines. This behavior is a bit more like the old indentation behavior in the 2.x branch.
|
||||
Fixed so the dialog language packs only gets loaded the first time you open a dialog.
|
||||
Fixed so all classes in the whole UI is prefixed with "mce" to avoid collisions, use the skin converter to update your existing skins.
|
||||
Fixed so all classes in the inlinepopups logic is prefixed with "mce" to avoid collisions, use the skin converter to update your existing skins.
|
||||
Fixed so that the window in fullscreen mode can be resized when fullscreen_new_window option is enabled.
|
||||
Fixed so blockquote elements are formatted in the source output with an linefeed before and after it.
|
||||
Optimized the editor initialization by reducing the number of calls to getBookmark/moveToBookmark.
|
||||
Version 3.0.1 (2008-02-21)
|
||||
Added spellchecker plugin into the main package, but without any backend can be specified with the spellchecker_rpc_url option.
|
||||
Added src attribute for script elements to the default valid_elements option value.
|
||||
Added extra parameter to the class_filter callback it can now also filter out classes based on the whole CSS rule.
|
||||
Added support for domain relaxing, TinyMCE can now be loaded from an remote domain as long as they are on the same root domain.
|
||||
Added support for custom elements the new custom_elements option enables you to add non HTML elements to the editor.
|
||||
Added support for the W3C Selectors API that was added to latest nightly build of WebKit.
|
||||
Fixed bug where some object param element wasn't stored correctly using the media plugin.
|
||||
Fixed bug where Opera was scrolling to top of page is drop menus on list boxes where displayed.
|
||||
Fixed bug where IE6 was crashing if a format block was used on a container with anchor elements.
|
||||
Fixed bug where spans with font sizes wasn't handled correctly when editor was loading contents.
|
||||
Fixed bug where mode exact couldn't convert editors with name only. Id is no longer required but recommended.
|
||||
Fixed bug where the mceInsertRawHTML command produced an extra undo level.
|
||||
Fixed bug where the specific_textareas mode didn't work correctly this is the same thing as textareas now.
|
||||
Fixed bug where the values of input elements in the HTML page of dialogs pages where changed in IE.
|
||||
Fixed bug where fullscreen and fullpage plugins didn't work well together.
|
||||
Fixed bug where embed elements wasn't handled properly in the media plugin.
|
||||
Fixed bug where style information on span elements gets munged when fonts are converted to spans.
|
||||
Fixed bug where some entities in element attributes where encoded incorrectly in the latest WebKit build.
|
||||
Fixed bug where initialization would fail in IE if there where two input elements with the name submit in the form.
|
||||
Fixed bug where fullscreen mode didn't work correctly in IE when the fullscreen_new_window option was used.
|
||||
Fixed bug where invalid contents like an ul inside a p element would produce odd results in IE.
|
||||
Fixed bug where Opera 9.2x was placing the drop menus at incorrect locations if the editor was placed in a table.
|
||||
Fixed bug where Opera was producing odd results if enter/return was pressed while having forced_root_blocks disabled.
|
||||
Fixed bug where layer plugin was stealing focus in IE on initialization.
|
||||
Fixed bug where body attributes wasn't set properly in the fullpage plugin, fix contributed by Hiroaki Kawai.
|
||||
Fixed bug where insert image and insert link dialogs where producing an extra level in the undo history.
|
||||
Fixed bug where Gecko would produce an error if empty elements like <div></div> where inserted using mceInsertContent.
|
||||
Fixed bug where center alignment of images produced odd results inside table cells.
|
||||
Fixed bug where center alignment of images couldn't be toggled correctly.
|
||||
Fixed bug where alignment of images inside tables would produce double float style items in IE if the fix_table_elements option was enabled.
|
||||
Fixed bug where a variable called 'v' was polluting the global namespace. Objects tinymce and tinyMCE are the only ones allowed to be global.
|
||||
Fixed bug where insert table from context menu couldn't insert new tables inside existing tables.
|
||||
Fixed bug where Safari wouldn't produce br elements on enter when the force_br_newlines option was enabled.
|
||||
Fixed bug where switching cell type in table cell dialog would produce odd attributes in IE.
|
||||
Fixed bug where Gecko was outputting internal attributes if valid_elements where set to "*[*]".
|
||||
Fixed bug where the style plugin would produce non hex colors inside the dialog when running on Gecko.
|
||||
Fixed bug where an empty src value for insert image would remove the currently selected image if it wasn't and image element.
|
||||
Fixed bug where hidden input elements would break the logic for the tab_focus option.
|
||||
Fixed bug where save button wasn't working correctly in fullscreen mode.
|
||||
Fixed bug where the editor was forced to be placed in a form element if the save_onsavecallback option was used.
|
||||
Fixed bug where upper case param attributes wasn't parsed correctly in the media plugin.
|
||||
Fixed bug where render method of tinymce.Editor class would produce an exception if the strict_loading_mode option was omitted.
|
||||
Fixed bug where nodeChanged event could be fired while the editor was loading and there for produce an exception in FF.
|
||||
Fixed bug where no undo levels where added if the user created new table rows using the tab key on Gecko.
|
||||
Fixed bug where tables would be broken if you selected a different block format for contents withing an table cell.
|
||||
Fixed bug where the render method of the tinymce.Editor class didn't setup the tinymce.EditorManager.settings object correctly.
|
||||
Fixed bug where the advanced image dialog would go to the first tab if the alternative image was changed using the file browser link.
|
||||
Fixed bug where the forced_root_block option would produce BR elements inside empty blocks if the block wasn't a paragraph.
|
||||
Fixed bug where the forced_root_block doesn't work correctly on IE if the specified element was something else than paragraphs.
|
||||
Fixed bug where selection of images would get lost if user selected something from the context menu in IE.
|
||||
Fixed bug where the context menu plugin would pollute the global namespace with two variables p1 and p2.
|
||||
Fixed compatibility issue with Mootools, it is destroying document.getElementById on unload in IE. (Mantra: You don't own the internal objects).
|
||||
Fixed bugs where dialogs/tabs and other UI elements where rendered incorrectly in Firefox 3.
|
||||
Fixed so the auto CSS class importer is compatible with 2.x.
|
||||
Fixed so the editor UI and inlinedialogs works correctly with the YUI CSS reset package.
|
||||
Fixed so header and footer elements are forced to lower case when the fullpage plugin is used.
|
||||
Fixed so load prefixes "-" for plugins and themes isn't required if the plugin/theme was loaded by the ThemeManager/PluginManager.
|
||||
Fixed so the JSONRequest uses application/json content type to make Ruby on rails happy.
|
||||
Fixed so the CSS rule is more exact for the body in the default content.css files. Body is now defined as "body.mceContentBody" instead of just "body".
|
||||
Fixed so the tiny_mce_dev.js uses XHR instead of document.write to load scripts to resolve an issue with Opera 9.50.
|
||||
Fixed so language pack loading can be disabled by setting the language option to false. Can be useful for systems with their own language pack management.
|
||||
Version 3.0 (2008-01-30)
|
||||
Added map and area elements to the default valid_elements list and also some indentation rules.
|
||||
Fixed bug where empty paragraphs wasn't padded when loading contents.
|
||||
Fixed bug where the RowLayout manager didn't work at all.
|
||||
Fixed bug where style attribute data would get messed up in advimage dialog.
|
||||
Fixed bug where the table dialogs class select wasn't updated correctly.
|
||||
Fixed bug where elements would get extra whitespace around on insert when body was present in valid_elements.
|
||||
Fixed bug where coords attribute of the area element wasn't handled properly in IE.
|
||||
Fixed bug where Safari didn't produce BR elements on shift+return.
|
||||
Fixed bug where force blocks would cast odd invalid attribute exception in IE.
|
||||
Fixed bug where media plugin would produce extra whitespace before and after objects.
|
||||
Fixed bug where cleanup_callback could break the contents of the editor. But use the new event system instead of this option.
|
||||
Fixed bug where the tab_focus option didn't work between editor instanced. You can now tab between editors.
|
||||
Fixed bug where the load function of the ScriptLoader class didn't load single files without the load que as it was supposed to.
|
||||
Fixed bug where the execcommand_callback parameter order was incorrect. Recommendation use the new addCommand method.
|
||||
Fixed bug where range.select calls sometimes failed on some IE versions.
|
||||
Fixed bug where Safari was scrolling to top of document when enter/returned was pressed.
|
||||
Fixed bug where fullscreen_new_window option didn't work correctly.
|
||||
Fixed bug where the nonbreaking plugin inserted an space instead of an non breaking space the first time.
|
||||
Fixed bug where the visualization of non breaking spaces where visual in element path.
|
||||
Fixed so the focus is restored to the editor after inserting an custom character.
|
||||
Fixed so the isNotDirty state is set to false if a new undo level is added.
|
||||
Fixed so pointless style information for borders gets removed in IE.
|
||||
Fixed so the resize button has a se-resize cursor css value.
|
||||
Version 3.0rc2 (2008-01-18)
|
||||
Added new fix_nesting option to fix bug #1867292, this is disabled by default.
|
||||
Added new indentation option enables you to specify how much each indent/outdent call will add/remove.
|
||||
Added easier support for enabling/disabling icon columns on drop menues.
|
||||
Added new menu button control class. This control is very similar to the splitbutton but without any onclick action.
|
||||
Added support for previous tab focus (shift+tab). The tab_focus setting now takes two items next and previous element.
|
||||
Fixed bug where iframes inside the editor got removed in Firefox on initial load.
|
||||
Fixed bug where the CSS for abbr elements wasn't applied correctly in IE.
|
||||
Fixed bug where mceAddControl on element inside a hidden container produced errors.
|
||||
Fixed bug where closed anchors like <a /> produced strange results.
|
||||
Fixed bug where caret would jump to the top of the editor if enter was pressed a the end of a list.
|
||||
Fixed bug where remove editor failed if the editor wasn't properly initialized.
|
||||
Fixed bug where render call on for a non existing element produced exception.
|
||||
Fixed bug where parent window was hidden when the color picker was used in a non inlinepopups setup.
|
||||
Fixed bug where onchange event wasn't fired correctly on IE when color picker was used in dialogs.
|
||||
Fixed bug where save plugin could not save contents if the converted element wasn't an textarea.
|
||||
Fixed bug where events might be fired even after an editor instance was removed such as blur events.
|
||||
Fixed bug where an exception about undefined undo levels could be throwed sometimes.
|
||||
Fixed bug where the plugin_preview_pageurl option didn't work.
|
||||
Fixed bug where adding/removing an editor instance very fast could produce problems.
|
||||
Fixed bug where the link button was highlighted when an anchor element was selected.
|
||||
Fixed bug where the selected contents where removed if a new anchor element was added.
|
||||
Fixed bug where splitbuttons where rendered one pixel down in the default theme.
|
||||
Fixed bug where some buttons where placed at incorrect positions in the o2k7 theme.
|
||||
Fixed bug that made it impossible to visually disable a custom button that used an image instead of CSS sprites.
|
||||
Fixed bug where it wasn't possible to press delete/backspace if the editor was added+removed and re-added due to a FF bug.
|
||||
Fixed bug where an entities option with only 38,amp,60,lt,62,gt would fail in IE.
|
||||
Fixed bug where innerHTML sometimes generated unknown runtime error on IE.
|
||||
Fixed bug where content_css files wasn't loaded in the template preview iframe.
|
||||
Fixed bug where scroll position was incorrect when toggling fullscreen mode.
|
||||
Fixed bug where restoration of overflow didn't work correctly when disabling fullscreen mode in Opera.
|
||||
Fixed bug where drop menus where places at incorrect locations if the editor was placed in a scrollable container element.
|
||||
Fixed bug where hideMenu didn't hide sub menus correctly. It will now hide all menus recursively.
|
||||
Fixed so theme_advanced_path_location can be used in init options for compatibility reasons.
|
||||
Fixed so the drop menu colors matches the rest of o2k7 theme.
|
||||
Fixed so the preview example.html file is updated to the new 3.x API.
|
||||
Fixed so the margins are the same by default inside the editable area between IE and other browsers.
|
||||
Fixed so editor contents gets stored before it the onSubmit event is fired.
|
||||
Version 3.0rc1 (2008-01-08)
|
||||
Added new classes for toolbar rows in advanced theme mceToolbarRow1..n enabled you to change appearance of individual rows.
|
||||
Added auto detection for the strict_loading_mode option when running in application/xhtml+xml mode on Gecko.
|
||||
Optimized the HTML serializer by bundling some post process methods together.
|
||||
Fixed so that the toolbars have unique IDs, enables you to alter the toolbars using the ControlManager and the DOM.
|
||||
Fixed bug where delta values for dialog sizes in language packs didn't work correctly due to missing string to number casting.
|
||||
Fixed bug where paragraph generation logic didn't handle hr or table elements correctly if they where the only element.
|
||||
Fixed bug where some elements got extra linebreaks added after or before it in HTML output.
|
||||
Fixed bug where it was hard to modify existing style data on table rows and table cells.
|
||||
Fixed bug where the dom.getRect method didn't handle non pixel values correctly.
|
||||
Fixed bug where strikethrough and underline couldn't be toggled on existing span elements.
|
||||
Fixed bug where the postprocessor searched for nsbp instead of nbsp entities.
|
||||
Fixed bug where it was impossible to edit links that had child elements within them.
|
||||
Fixed bug where it was possible to click on the parent item of a submenu.
|
||||
Fixed bug where mouseover/mouseout images couldn't be removed in advimage dialog.
|
||||
Fixed bug where drop menus didn't work when running in application/xhtml+xml mode.
|
||||
Fixed bug where Opera added doctype to output in application/xhtml+xml mode.
|
||||
Fixed bug where some DOM methods didn't work correctly in the application/xhtml+xml mode.
|
||||
Fixed bug where the inlinepopups didn't work correctly in the application/xhtml+xml mode.
|
||||
Fixed bug where the ColorSplitButton didn't display correctly in the application/xhtml+xml mode.
|
||||
Fixed bug where the UI layout was incorrect on Gecko browsers when running in application/xhtml+xml mode.
|
||||
Fixed bug where the word paste plugin produced exception while running in application/xhtml+xml mode.
|
||||
Fixed bug where there wasn't any hidden input element generated for divs while running in application/xhtml+xml mode.
|
||||
Fixed bug where indentation of script/style/pre elements where incorrect.
|
||||
Fixed bug where script element contents was removed in IE.
|
||||
Fixed bug where script element contents got entity encoded.
|
||||
Fixed bug where you couldn't edit existing element styles using the styles plugin.
|
||||
Fixed bug where styles wasn't updated properly sometimes due to an performance enhancement.
|
||||
Fixed bug where font sizes couldn't be changed using the style plugin.
|
||||
Fixed bug where an error was produced in Gecko browsers when switching back from fullscreen mode.
|
||||
Fixed bug where Opera was producing br elements after elements like h3.
|
||||
Fixed bug where TinyMCE couldn't be loaded on a page using - characters in it's URL.
|
||||
Fixed bug where the editor container element was forced to have a specific name.
|
||||
Fixed bug with force_br_newlines option on Firefox, even though it should never be used (Read FAQ).
|
||||
Fixed bug where onclick event had an return true; prefix added when creating an popup.
|
||||
Fixed bug where the theme_advanced_statusbar_location option couldn't handle the value "none".
|
||||
Fixed issue with URLs with multiple at characters for example an Zope URI.
|
||||
Fixed so simple and advanced themes doesn't collide.
|
||||
Fixed so a elements gets removed when the href field is left empty, the href attribute is required in a link after all.
|
||||
Fixed so img elements gets removed when the src field is left empty, the src attribute is required for all images after all.
|
||||
Removed the indent and encode methods from the tinymce.dom.Serializer class due to performance enhancement and reduction of the API size.
|
||||
Version 3.0b3 (2007-12-14)
|
||||
Added new getElement method to Editor class, returns the element that was replaced with the editor instance.
|
||||
Added new unavailable prefix for disabled controls for accessibility reasons.
|
||||
Fixed bug where regexp patterns couldn't be used for the editor_selector/editor_deselector options.
|
||||
Fixed bug where the DOM wasn't properly initialized before the onInit event was executed in popups.
|
||||
Fixed bug where font sizes where reduced by font size actions on previous spans in Safari.
|
||||
Fixed bug where HR elements got places at the wrong location in IE.
|
||||
Fixed bug where align/justify didn't work correctly on multiple paragraphs.
|
||||
Fixed bug with missing translation for cell scope settings.
|
||||
Fixed bug where selection/caret position was lost on some table actions.
|
||||
Fixed bug where editor instances couldn't be added to hidden div elements.
|
||||
Fixed bug where list elements in Safari would get an odd ID attribute.
|
||||
Fixed bug where IE would return <html/> when the editor was completely empty.
|
||||
Fixed bug where accessibility title attribute for access keys wasn't setup properly.
|
||||
Fixed bug where forecolorpicker and backcolorpicker control names wasn't working.
|
||||
Fixed bug where inserting template content didn't work in Safari due to selection exception.
|
||||
Fixed bug where absolute URLs to remote hosts couldn't be used for background images.
|
||||
Fixed bug where mysterious span elements where produced in Safari when injecting HTML contents.
|
||||
Fixed bug where the media plugin didn't work correctly on the latest Opera 9.24.
|
||||
Fixed bug where indentation of HTML output wasn't applied to all block elements.
|
||||
Fixed bug where Safari was production DOM exception if you pressed enter in an empty editor.
|
||||
Fixed bug where media plugin didn't parse script tags correctly patch contributed by Mathieu Campagna.
|
||||
Fixed bug where the drop menus of list boxes like blockformat could produce scrolling of the page.
|
||||
Fixed bug where the drop menus where placed at an incorrect location if TinyMCE was placed in a scrollable div.
|
||||
Fixed bug where submit buttons couldn't be named submit, it's not recommended to name submit buttons submit anyway.
|
||||
Fixed bug where the stylelistbox produced an exception if there was only one class in the list box.
|
||||
Fixed bug where the stylelistbox wasn't updated correctly when the current class was removed.
|
||||
Fixed bug where the formatblock command sometimes removed the body element.
|
||||
Fixed bug where fullscreen switching in IE sometimes produced an exception when the spellchecker plugin was enabled.
|
||||
Fixed issue where FF produced an empty paragraph when the editor was completely empty.
|
||||
Fixed issue with size of image dialog in the advanced theme.
|
||||
Fixed issues with the bbcode plugin it now also handles spans and the [font] rule.
|
||||
Fixed so the style compression feature is a bit smarter to resolve issues with Opera.
|
||||
Reintroduced the remove_linebreaks option, this is enabled by default.
|
||||
Version 3.0b2 (2007-11-29)
|
||||
Added type and compact attributes to the default valid_elements list for the ul and ol elements.
|
||||
Added missing accessibility support to native list boxes in both the toolbar and dialogs.
|
||||
Added missing access key for the element path for accessibility reasons.
|
||||
Fixed support for loading themes from external URLs.
|
||||
Fixed bug where setOuterHTML didn't work correctly when multiple elements where passed to it.
|
||||
Fixed bug with visualchars plugin was moving elements around in the DOM.
|
||||
Fixed bug with DIV elements that got converted into editors on IE.
|
||||
Fixed bug with paste plugin using the old event API.
|
||||
Fixed bug where the spellchecker was removing the word when it was ignored.
|
||||
Fixed bug where fullscreen wasn't working properly.
|
||||
Fixed bug where the base href element and attribute was ignored.
|
||||
Fixed bug where redo function didn't work in IE.
|
||||
Fixed bug where content_css didn't work as previous 2.x branch.
|
||||
Fixed bug where preview dialog was throwing errors if the content_css wasn't defined.
|
||||
Fixed bug where the theme_advanced_path option didn't work like the 2.x branch.
|
||||
Fixed bug where the theme_advanced_statusbar_location was called theme_advanced_status_location.
|
||||
Fixed bug where the strict_loading_mode option didn't work if you created editors dynamically without using the EditorManager.
|
||||
Fixed bug where some language values wasn't translated such as insert and update in dialogs.
|
||||
Fixed bug where some image attributes wasn't stored correctly when inserting an image.
|
||||
Fixed bug where fullscreen mode didn't restore scrollbars when disabled.
|
||||
Fixed bug where there was no visual representation for tab focus in toolbars on IE.
|
||||
Fixed bug where HR elements wasn't treated as block elements so forced_root_block would fail on these.
|
||||
Fixed bug where autosave presented warning message even when the form was submitted normally.
|
||||
Fixed typo of openBrower it's now openBrowser in form_utils.js.
|
||||
Fixed various HTML problems like missing TD elements and duplicated doctypes.
|
||||
Fixed default values for theme_advanced_resize_horizontal, theme_advanced_resizing_use_cookie to be 2.x compatible.
|
||||
Moved spellchecker JS files into the development package.
|
||||
Removed support for theme_advanced_path_location since the theme_advanced_statusbar_location is the correct option name.
|
||||
Version 3.0b1 (2007-11-21)
|
||||
Added new tab_focus option, that enables you to specify a element id or that the next element to be focused on tab key down.
|
||||
Added new addQueryValueHandler method to the tinymce.Editor class.
|
||||
Added new class_filter option, this enables you to specify a function that can filter out CSS classes for the styles list box.
|
||||
Added support form [url=url]title[/url] to the bbcode plugin.
|
||||
Renamed the addCommandQueryState method in the tinymce.Editor class to addQueryStateHandler.
|
||||
Renamed loadQue to loadQueue, to correct spelling.
|
||||
Removed the createDOM method from the window manager and replace it with a createInstance method.
|
||||
Removed the add to beginning of class attribute parameter of the DOMUtils.addClass method.
|
||||
Fixed bug with the forced_root_block option, didn't work correctly with multiple inline elements.
|
||||
Fixed bug where image dialogs replaced the current image element with a new one even when it was updated.
|
||||
Fixed bug where the submit trigger wasn't executed when divs where converted into editor instances.
|
||||
Fixed bug where div elements that got converted into editors didn't get a hidden input element generated for them.
|
||||
Fixed bug where the the media_use_script option for the media plugin wasn't working correctly.
|
||||
Fixed bug where the font size and font family listboxes wasn't updated correctly on Safari.
|
||||
Fixed bug where the height of the fieldset in default image dialog for the advanced theme was to small.
|
||||
Fixed bug where the font sizes behaved incorrectly after a cleanup on Safari.
|
||||
Fixed bug where formatblock didn't work correctly in Safari on some elements.
|
||||
Fixed bug where template plugin didn't insert content correctly unless some options where specified.
|
||||
Fixed bug where charmap on Safari produced scrollbars.
|
||||
Fixed bug where there was white artifacts in some dialogs due to missing background color.
|
||||
Fixed bug where port was added to all external URLs if the editor was loaded from a custom port.
|
||||
Fixed bug where the context menus got duplicated on Safari 3.0.4 on Mac OS X.
|
||||
Fixed bug where dialogs like paste from word was huge on Firefox.
|
||||
Fixed bug with media plugin not working with windows media objects.
|
||||
Fixed bug where a forever loop was created if multiple instances where submitted using form.submit.
|
||||
Fixed bug with editing a table produce error in IE when inlinepopups where used.
|
||||
Fixed bug where the style plugin generated ugly looking style information in IE.
|
||||
Fixed bug where the inline dialogs that got opened while in fullscreen mode wasn't visible.
|
||||
Fixed bug where it was difficult to place the caret inside the word paste dialog.
|
||||
Fixed bug where Opera produced strange border in the word paste dialog.
|
||||
Fixed bug where viewport constraints could move a inlinepopup to a negative x, y position if the viewport was to small.
|
||||
Fixed bug where template plugin was producing an error due to a deprecated API call.
|
||||
Fixed bug where drag drop of images failed in Gecko if a document_base_url was specified.
|
||||
Fixed bug where Firefox 3 failed to apply block formats like H1-H6 it still breaks on DIVs this has been reported to bugzilla.
|
||||
Fixed bug where IE was producing a warning dialog about non secure items when running TinyMCE over HTTPS.
|
||||
Fixed bug where the onbeforeunload event was triggered when menus or dialogs where opened.
|
||||
Fixed bug where the fullscreen mode of the HTML view source box threw an error.
|
||||
Fixed bug where the mceFocus command didn't work correctly.
|
||||
Fixed bug where the selection could get lost in IE using inlinepopups.
|
||||
Fixed so the body of the editor area has the mceContentBody class just like the 2.x branch.
|
||||
Fixed so the media icon gets active when a media element is selected.
|
||||
Version 3.0a3 (2007-11-13)
|
||||
Added new experimental jQuery and Prototype framework adapters to the development package.
|
||||
Added new translation.html file for the development package. Helps with the internationalization of TinyMCE.
|
||||
Added new setup callback option, use this callback to add events to TinyMCE. This method is recommended over the old callbacks.
|
||||
Added new API documetation to all classes, functions, events, properties to the Wiki with examples etc.
|
||||
Added new init method to all plugins and themes, since it's shorter to write and it mimics interface capable languages better.
|
||||
Fixed various CSS issues in the default skin such as alignment of split buttons and separators.
|
||||
Fixed issues with mod_security. It didn't like that a content type of text/javascript was forced in a XHR.
|
||||
Fixed all events so that they now pass the sender object as it's first argument.
|
||||
Fixed some DOM methods so they now can take an array as input.
|
||||
Fixed so addButton and the methods of the ControlManager uses less arguments and it now uses a settings object instead.
|
||||
Fixed various issues with the tinymce.util.URI class.
|
||||
Fixed bug in IE and Safari and the on demand gzip loading feature.
|
||||
Fixed bug with moving inline windows sometimes failed in IE6.
|
||||
Fixed bug where save_callback function wasn't executed at all.
|
||||
Fixed bug where inlinepopups produces scrollbars if windows where moved to the corners of the browser.
|
||||
Fixed bug where view HTML source failed when inserting a embedded media object.
|
||||
Fixed bug where the listbox menus didn't display correctly on IE6.
|
||||
Fixed bug where undo level wasn't added when editor was blurred.
|
||||
Fixed bug where spellchecker wasn't disabled when fullscreen mode was enabled.
|
||||
Fixed bug where Firefox could crash some times when the user switched to fullscreen mode.
|
||||
Fixed bug where tinymce.ui.DropMenu didn't remove all item data when an item was removed from the menu.
|
||||
Fixed bug where anchor list in advlink dialog wasn't populated correctly in Safari.
|
||||
Fixed bug where it wasn't possible to edit tables in IE when inlinepopups was enabled.
|
||||
Fixed bug where it wasn't possible to change the table width of an existing table.
|
||||
Fixed bug where xhtmlxtras like abbr didn't work correctly on IE.
|
||||
Fixed bug where IE6 had some graphics rendering issues with the inlinepopups.
|
||||
Fixed bug where inlinepopup windows where moved incorrectly when they were boundary checked for min width.
|
||||
Fixed bug where textareas without id or name couldn't be converted into editor instances.
|
||||
Fixed bug where TinyMCE was stealing element focus on IE.
|
||||
Fixed bug where the getParam method didn't handle false values correctly.
|
||||
Fixed bug where inlinepopups was clipped by other TinyMCE instances or relative elements in IE.
|
||||
Fixed bug where the contextmenu was clipped by other TinyMCE instances or relative elements in IE.
|
||||
Fixed bug where listbox menus was clipped by other TinyMCE instances or relative elements in IE.
|
||||
Fixed bug where listboxes wasn't updated correctly when the a value wasn't found by select.
|
||||
Fixed various CSS issues that produced odd rendering bugs in IE.
|
||||
Fixed issues with tinymce.ui.DropMenu class, it required some optional settings to be specified.
|
||||
Fixed so multiple blockquotes can be removed with a easier method than before.
|
||||
Optimized some of the core API to boost performance.
|
||||
Removed some functions from the core API that wasn't needed.
|
||||
Version 3.0a2 (2007-11-02)
|
||||
Fixed critical bug where IE generaded an error on a hasAttribute call in the serialization engine.
|
||||
Fixed critical bug where some dialogs didn't open in the non dev package.
|
||||
Fixed bug when using the theme_advanced_styles option. Error was thrown in some dialogs.
|
||||
Fixed bug where the close buttons produced an error when native windows where used.
|
||||
Fixed bug in default skin so that split buttons gets activated correctly.
|
||||
Fixed so plugins can be loaded from external urls outsite the plugins directory.
|
||||
Version 3.0a1 (2007-11-01)
|
||||
Rewrote the core and most of the plugins and themes from scratch.
|
||||
Added new and improved serialization engine, faster and more powerful.
|
||||
Added new internal event system, things like editor.onClick.add(func).
|
||||
Added new inlinepopups plugin, the dialogs are now skinnable and uses clearlooks2 as default.
|
||||
Added new contextmenu plugin, context menus can now have submenus and plugins can add items on the fly.
|
||||
Added new skin support for the simple and advanced themes you can alter the whole UI using CSS.
|
||||
Added new o2k7 skin for the simple and advanced themes.
|
||||
Added new custom list boxes for font size/format/style etc with preview support.
|
||||
Added new UI management, enabled plugins to create controls like splitbuttons or menus easier.
|
||||
Added new JSON parser/serializer and JSON-RPC class to the core API.
|
||||
Added new cookie utility class to the core API.
|
||||
Added new Unit testing class to the core API only available in dev mode.
|
||||
Added new firebug lite integration when loading the dev version of TinyMCE.
|
||||
Added new Safari plugin, fixes lots compatibility of issues with Safari 3.x.
|
||||
Added new URI/URL parsing it now handles the hole RFC and even some exceptions.
|
||||
Added new pagebreak plugin, enables you to insert pagebreak comments like <!-- pagebreak -->
|
||||
Added new on demand loading of plugins and themes. Enables you to load and init TinyMCE at any time.
|
||||
Added new throbber/progress visualization a plugin can show/hide this when it's needed.
|
||||
Added new blockquote button. Enables you to wrap paragraphs in blockquotes.
|
||||
Added new compat2x plugin. Will provide a TinyMCE 2.x API for older plugins.
|
||||
Added new theme_advanced_resizing_min_width, theme_advanced_resizing_min_height options.
|
||||
Added new theme_advanced_resizing_max_height, theme_advanced_resizing_max_height options.
|
||||
Added new use_native_selects option. Enables you to toggle native listboxes on and off.
|
||||
Added new docs_url option enables you to specify where the TinyMCE user documentation is located.
|
||||
Added new frame and rules options for the table dialog.
|
||||
Added new global rule for valid_elements/extended_valid_elements enables you to specify global attributes for all elements.
|
||||
Added new deny attribute rule characher so it's possible to deny global attribute rules on specific elements.
|
||||
Added new unit tests in the dev package of TinyMCE. Runs tests on the core API, commands and settings of the editor.
|
||||
Readded the inline_styles option and enabled it by default so deprecated attributes are no longer used.
|
||||
Removed all button images and replaced them with CSS sprite images. Reduces the number of requests needed.
|
||||
Removed lots of language files and merged them into the base language files. Reduces the number of requests needed.
|
||||
Removed lots of unnecessary files and merged many of them together to reduce requests and improve loading speed.
|
||||
Reduced the over all script size by 33% and the number of files/requests by 75% so it loads a lot faster.
|
||||
Fixed so convert_fonts_to_spans are enabled by default. So no more font tags.
|
||||
Fixed so underline and strikethrough uses spans instread of deprecated U and STRIKE elements.
|
||||
Fixed so indent/outdent adds/removed margin-left instead of blockquotes.
|
||||
Fixed so alignment of paragraphs results in a text-align style value instead of the deprecated align attribute.
|
||||
Fixed so alignment of images uses float or vertical-align style values instead of the deprecated align attribute.
|
||||
Fixed so all classes from @import stylesheets gets imported into the editor.
|
||||
Fixed so the directionality can toggle the dir attribute on and off.
|
||||
Fixed so the fullscreen_settings can be used for all types of fullscreen modes.
|
||||
Fixed so the advanced HR dialog gets displayed when inserting a HR not only on edit.
|
||||
Fixed bug where word wrap didn't work in the source editor on Safari.
|
||||
Fixed so non HTML elements can be used within the editor such as <myns:tag>
|
||||
Fixed various memory leaks in IE and reduced the unload cleanups needed.
|
||||
Fixed so the preformatted option adds an invisible container pre tag inside the editor.
|
||||
Renamed the _template plugin to example and updated it to use the new 3.x API.
|
||||
Version 3.5.0.1 (2012-05-10)
|
||||
Fixed bug where selection normalization logic would break the selections of parent elements using the element path.
|
||||
Fixed bug where the autolink plugin would include trailing dots in domain names in the link creation.
|
||||
Fixed bug where the autolink plugin would produce an error on older IE versions when pressing enter.
|
||||
Fixed bug where old IE versions would throw an error during initialization when the editor was placed in an size restricted div.
|
||||
Version 3.5 (2012-05-03)
|
||||
Fixed menu rendering issue if the document was in rtl mode.
|
||||
Fixed bug where the hide function would throw an error about a missing variable.
|
||||
Fixed bug where autolink wouldn't convert URLs when hitting enter on IE due to the new enter key logic.
|
||||
Fixed bug where formatting using shortcuts like ctrl+b wouldn't work properly the first time.
|
||||
Fixed bug where selection.setContent after a formatter call wouldn't generate formatted contents.
|
||||
Fixed bug where whitespace would be removed before/after invalid_elements when they where removed.
|
||||
Fixed bug where updating styles using the theme image dialog in non inline mode on IE9 would produce errors.
|
||||
Fixed bug where IE 8 would produce an error when using the contextmenu plugin.
|
||||
Fixed bug where delete/backspace could remove contents of noneditable elements.
|
||||
Fixed so background color in style preview gets computed from body element if the current style element is transparent.
|
||||
Version 3.5b3 (2012-03-29)
|
||||
Added cancel button to colour picker dialog.
|
||||
Added figure and figcaption to the html5 visualblocks plugin.
|
||||
Added default alignment options for the figure element.
|
||||
Fixed bug where empty inline elements within block elements would sometimes produce a br child element.
|
||||
Fixed bug where urls pointing to the same domain as the current one would cause undefined errors. Patch contributed by Paul Giberson.
|
||||
Fixed bug where enter inside an editable element inside an non editable element would split the element.
|
||||
Fixed bug where cut/copy/paste of noneditable elements didn't work.
|
||||
Fixed bug where backspace would sometimes produce font elements on WebKit.
|
||||
Fixed bug where WebKit would produce spans out of various inline elements when using backspace.
|
||||
Fixed bug where IE9 wouldn't properly update image styles when images where resized.
|
||||
Fixed bug where drag/drop of noneditable elements didn't work correctly.
|
||||
Fixed bug where applying formatting to all contents wouldn't work correctly when an end point was inside an empty bock. Patch contributed by Jose Luiz.
|
||||
Fixed bug where IE10 removed the scopeName from the DOM element interface and there for it produced an undefined string in element path.
|
||||
Fixed bug where the caret would be placed at an incorrect location if you applied block formatting while having the caret at the end of the block.
|
||||
Fixed bug where applying column changes using the cell dialog would only update the first column. Patch contributed by krzyko.
|
||||
Fixed bug where the visualblocks plugin would force editor focus if it was turned on by default.
|
||||
Fixed bug where the tabfocus plugin would tab to iframes these are now ignored.
|
||||
Fixed bug where format drop down list wouldn't show the currently active format for a parent element.
|
||||
Fixed bug where paste of plain text in IE 9 would remove the new line characters from text.
|
||||
Fixed bug where the menu buttons/split button menus wouldn't be opened at the right location on older IE versions.
|
||||
Fixed bug where Gecko browsers wouldn't properly display the right format when having the selection as specific places.
|
||||
Fixed bug where shift+enter inside the body when having forced_root_blocks set to false would throw an error.
|
||||
Fixed bug where the jQuery plugin would break the attr method of jQuery 1.7.2. Patch contributed by Markus Kemmerling.
|
||||
Fixed so options like content_css accepts and array as well as a comma separated string as input.
|
||||
Restructured the internal logic to make it more separate from Editor.js.
|
||||
Updated the Sizzle engine to the latest version.
|
||||
Version 3.5b2 (2012-03-15)
|
||||
Rewrote the enter key logic to normalize browser behavior.
|
||||
Fixed so enter within PRE elements produces a BR and shift+enter breaks/end the PRE. Can be disabled using the br_in_pre option.
|
||||
Fixed bug where the selection wouldn't be correct after applying formatting and having the caret at the end of the new format node.
|
||||
Fixed bug where the noneditable plugin would process contents on raw input calls for example on undo/redo calls.
|
||||
Fixed bug where WebKit could produce an exception when a bookmark was requested when there wasn't a proper selection.
|
||||
Fixed bug where WebKit would fail to open the image dialog since it would be returning false for a class name instead of a string.
|
||||
Fixed so alignment and indentation works properly when forced_root_blocks is set to false. It will produce a DIV by default.
|
||||
Version 3.5b1 (2012-03-08)
|
||||
Added new event class that is faster and enables support for faking events.
|
||||
Added new self_closing_elements, short_ended_elements, boolean_attributes, non_empty_elements and block_elements options to control the HTML Schema.
|
||||
Added new schema option and support for the HTML5 schema.
|
||||
Added new visualblocks plugin that shows html5 blocks with visual borders.
|
||||
Added new types and selector options to make it easier to create editor instances with different configs.
|
||||
Added new preview of formatting options in various listboxes.
|
||||
Added new preview_styles option that enables control over what gets previewed.
|
||||
Fixed bug where content css would be loaded twice into iframe.
|
||||
Fixed bug where start elements with only whitespace in the attribute part wouldn't be correctly parsed.
|
||||
Fixed bug where the advlink dialog would produce an error about the addSelectAccessibility function not being defined.
|
||||
Fixed bug where the caret would be placed at an incorrect position if span was removed by the invalid_elements setting.
|
||||
Fixed bug where elements inside a white space preserve element like pre didn't inherit the behavior while parsing.
|
||||
Version 3.4.9 (2012-02-23)
|
||||
Added settings to wordcount plugin to configure update rate and checking wordcount on backspace and delete using wordcount_update_rate and wordcount_update_on_delete.
|
||||
Fixed bug in Webkit and IE where deleting empty paragraphs would remove entire editor contents.
|
||||
Fixed bug where pressing enter on end of list item with a heading would create a new item with heading.
|
||||
Fixed edit css style dialog text-decoration none checkbox so it disables other text-decoration options when enabled.
|
||||
Fixed bug in Gecko where undo wasn't added when focus was lost.
|
||||
Fixed bug in Gecko where shift-enter in table cell ending with BR doesn't move caret to new line.
|
||||
Fixed bug where right-click on formatted text in IE selected the entire line.
|
||||
Fixed bug where text ending with space could not be unformatted in IE.
|
||||
Fixed bug where caret formatting would be removed when moving the caret when a selector expression was used.
|
||||
Fixed bug where formatting would be applied to the body element when all contents where selected and format had both inline and selector parts.
|
||||
Fixed bug where the media plugin would throw errors if you had iframe set as an invalid element in config.
|
||||
Fixed bug where the caret would be placed at the top of the document if you inserted a table and undo:ed that operation. Patch contributed by Wesley Walser.
|
||||
Fixed bug where content css files where loaded twice into the iframe.
|
||||
Fixed so elements with comments would be trated as non empty elements. Patch contributed by Arjan Scherpenisse.
|
||||
Version 3.4.8 (2012-02-02)
|
||||
Fixed bug in IE where selected text ending with space cannot be formatted then formatted again to get original text.
|
||||
Fixed bug in IE where images larger than editor area were being deselected when toolbar buttons are clicked.
|
||||
Fixed bug where wrong text align buttons are active when multiple block elements are selected.
|
||||
Fixed bug where selected link not showing in target field of link dialog in some selection cases.
|
||||
Use settings for remove_trailing_br so this can be turned off instead of hard coding the value.
|
||||
Fixed bug in IE where the media plugin displayed null text when some values aren't filled in.
|
||||
Added API method 'onSetAttrib' that fires when the attribute value on a node changes.
|
||||
Fix font size dropdown value not being updated when text already has a font size in the advanced template.
|
||||
Fixed bug in IE where IE doesn't use ARIA attributes properly on options - causing labels to be read out 2 times.
|
||||
Fixed bug where caret cannot be placed after table if table is at end of document in IE.
|
||||
Fixed bug where adding range isn't always successful so we need to check range count otherwise an exception can occur.
|
||||
Added spacebar onclick handler to toolbar buttons to ensure that the accessibility behaviour works correctly.
|
||||
Fixed bug where a stranded bullet point would get created in WebKit.
|
||||
Fixed bug where selecting text in a blockquote and pressing backspace toggles the style.
|
||||
Fixed bug where pressing enter from a heading in IE, the resulting P tag below it shares the style property.
|
||||
Fix white space in between spans from being deleted.
|
||||
Fixed bug where scrollbars where visible in the character map dialog on Gecko.
|
||||
Fixed issue with missing translation for one of the emoticons.
|
||||
Fixed bug where dots in id:s where causing problems. Patch provided by Abhishek Dev.
|
||||
Fixed bug where urls with an at sign in the path wouldn't be parsed correctly. Patch contributed by Jason Grout.
|
||||
Fixed bug where Opera would remove the first character of a inline formatted word if you pressed backspace.
|
||||
Fixed bugs with the autoresize plugin on various browsers and removed the need for the throbber.
|
||||
Fixed performance issue where the contextmenu plugin would try to remove the menu even if it was removed. Patch contributed by mhu.
|
||||
Version 3.4.7 (2011-11-03)
|
||||
Modified the caret formatting behavior to word similar to common desktop wordprocessors like Word or Libre Office.
|
||||
Fixed bug in Webkit - Cursor positioning does not work vertically within a table cell with multiple lines of text.
|
||||
Fixed bug in IE where Inserting a table in IE8 places cursor in the second cell of the first row.
|
||||
Fixed bug in IE where editor in a frame doesn't give focus to the toolbar using ALT-F10.
|
||||
Fix for webkit and gecko so that deleting bullet from start of list outdents inner list items and moves first item into paragraph.
|
||||
Fix new list items in IE8 not displayed on a new line when list contains nested list items.
|
||||
Clear formatting in table cell breaks the cell.
|
||||
Made media type list localisable.
|
||||
Fix out of memory error when using prototype in media dialog.
|
||||
Fixed bug where could not add a space in the middle of a th cell.
|
||||
Fixed bug where adding a bullet between two existing bullets adds an extra one
|
||||
Fixed bug where trying to insert a new entry midway through a bulleted list fails dismally when the next entry is tabbed in.
|
||||
Fixed bug where pressing enter on an empty list item does not outdent properly in FF
|
||||
Fixed bug where adding a heading after a list item in a table cell changes all styles in that cell
|
||||
Fixed bug where hitting enter to exit from a bullet list moves cursor to the top of the page in Firefox.
|
||||
Fixed bug where pressing backspace would not delete HRs in Firefox and IE when next to an empty paragraph.
|
||||
Fixed bug where deleting part of the link text can cause a link with no destination to be saved.
|
||||
Fixed bug where css style border widths wasn't handled correctly in table dialog.
|
||||
Fixed bug where parsing invalid html contents on IE or WebKit could produce an infinite loop.
|
||||
Fixed bug where scripts with custom script types wasn't properly passed though the editor.
|
||||
Fixed issue where some Japanese kanji characters wasn't properly entity encoded when numeric entity mode was enabled.
|
||||
Made emoticons dialog use the keyboard naviation.
|
||||
Added navigation instructions to the symbols dialog.
|
||||
Added ability to set default values for the media plugin.
|
||||
Added new font_size_legacy_values option for converting old font element sizes to span with font-size properties.
|
||||
Fixed bug where the symbols dialog was not accessible.
|
||||
Added quirk for IE ensuring that the body of the document containing tinyMCE has a role="application" for accessibility.
|
||||
Fixed bug where the advanced color picker wasn't working properly on FF 7.
|
||||
Fixed issue where the advanced color picker was producing uppercase hex codes.
|
||||
Fixed bug where IE 8 could throw exceptions if the contents contained resizable content elements.
|
||||
Fixed bug where caret formatting wouldn't be correctly applied to previous sibling on WebKit.
|
||||
Fixed bug where the select boxes for font size/family would loose it's value on WebKit due to recent iOS fixes.
|
||||
Version 3.4.6 (2011-09-29)
|
||||
Fixed bug where list items were being created for empty divs.
|
||||
Added support in Media plugin for audio media using the embed tag
|
||||
Fixed accessibility bugs in WebKit and IE8 where toolbar items were not being read.
|
||||
Added new use_accessible_selects option to ensure accessible list boxes are used in all browsers (custom widget in firefox native on other browsers)
|
||||
Fixed bug where classid attribute was not being checked from embed objects.
|
||||
Fixed bug in jsrobot tests with intermittently failing.
|
||||
Fixed bug where anchors wasn't updated properly if you edited them using IE 8.
|
||||
Fixed bug where input method on WebKit on Mac OS X would fail to initialize when sometimes focusing the editor.
|
||||
Fixed bug where it wasn't possible to select HR elements on WebKit by simply clicking on them.
|
||||
Fixed bug where the media plugin wouldn't work on IE9 when not using the inlinepopups plugin.
|
||||
Fixed bug where hspace,vspace,align and bgcolor would be removed from object elements in the media plugin.
|
||||
Fixed bug where the new youtube format wouldn't be properly parsed by the media plugin.
|
||||
Fixed bug where the style attribute of layers wasn't properly updated on IE and Gecko.
|
||||
Fixed bug where editing contents in a layer would fail on Gecko since contentEditable doesn't inherit properly.
|
||||
Fixed bug where IE 6/7 would produce JS errors when serializing contents containing layers.
|
||||
Version 3.4.5 (2011-09-06)
|
||||
Fixed accessibility bug in WebKit where the right and left arrow keys would update native list boxes.
|
||||
Added new whitespace_elements option to enable users to specify specific elements where the whitespace is preserved.
|
||||
Added new merge_siblings option to formats. This option makes it possible to disable the auto merging of siblings when applying formats.
|
||||
Fixed bug in IE where trailing comma in paste plugin would cause plugin to not run correctly.
|
||||
Fixed bug in WebKit where console messages would be logged when deleting an empty document.
|
||||
Fixed bug in IE8 where caret positioned is on list item instead of paragraph when outdent splits the list
|
||||
Fixed bug with image dialogs not inserting an image if id was omitted from valid_elements.
|
||||
Fixed bug where the selection normalization logic wouldn't properly handle image elements in specific config cases.
|
||||
Fixed bug where the map elements coords attribute would be messed up by IE when serializing the DOM.
|
||||
Fixed bug where IE wouldn't properly handle custom elements when the contents was serialized.
|
||||
Fixed bug where you couldn't move the caret in Gecko if you focused the editor using the API or a UI control.
|
||||
Fixed bug where adjacent links would get merged on IE due to bugs in their link command.
|
||||
Fixed bug where the color split buttons would loose the selection on IE if the editor was placed in a frame/iframe.
|
||||
Fixed bug where floated images in WebKit wouldn't get properly linked.
|
||||
Fixed bug where the fullscreen mode in a separate window wasn't forced into IE9+ standards mode.
|
||||
Fixed bug where pressing enter in an empty editor on WebKit could produce DIV elements instead of P.
|
||||
Fixed bug where spans would get removed incorrectly when merging two blocks on backspace/delete on WebKit.
|
||||
Fixed bug where the editor contents wouldn't be completely removed on backspace/delete on WebKit.
|
||||
Fixed bug where the fullpage plugin wouldn't properly render style elements in the head on IE 6/7.
|
||||
Fixed bug where the nonbreaking_force_tab option in the nonbreaking plugin wouldn't work on Gecko/WebKit.
|
||||
Fixed bug where the isDirty state would become true on non IE browsers if there was an table at the end of the contents.
|
||||
Fixed bug where entities wasn't properly encoded on WebKit when pasting text as plain text.
|
||||
Fixed bug where empty editors would produce an exception of valid_elements didn't include body and forced_root_blocks where disabled.
|
||||
Fixed bug where the fullscreen mode wouldn't retain the header/footer in the fullpage plugin.
|
||||
Fixed issue where the plaintext_mode and plaintext_mode_sticky language keys where swapped.
|
||||
Version 3.4.4 (2011-08-04)
|
||||
Added new html5 audio support. Patch contributed by Ronald M. Clifford.
|
||||
Added mute option for video elements and preload options for video/audio patch contributed by Dmitry Kalinkin.
|
||||
Fixed selection to match visual selection before applying formatting changes.
|
||||
Fixed browser specific bugs in lists for WebKit and IE.
|
||||
Fixed bug where IE would scroll the window if you closed an inline dialog that was larger than the viewport. Patch by Laurence Keijmel.
|
||||
Fixed bug where pasting contents near a span element could remove parts of that span. Patch contributed by Wesley Walser.
|
||||
Fixed bug where formatting change would be lost after pressing enter.
|
||||
Fixed bug in WebKit where deleting across blocks would add extra styles.
|
||||
Fixed bug where moving cursor vertically in tables in WebKit wasn't working.
|
||||
Fixed bug in IE where deleting would cause error in console.
|
||||
Fixed bug where the formatter was not applying formats across list elements.
|
||||
Fixed bug where the wordcount plugin would try and update the wordcount if tinymce had been destroyed.
|
||||
Fixed bug where tabfocus plugin would attempt to focus elements not displayed when their parent element was hidden.
|
||||
Fixed bug where the contentEditable state would sometimes be removed if you deleted contents in Gecko.
|
||||
Fixed bug where inserting contents using mceInsertContent would fail if "span" was disabled in valid_elements.
|
||||
Fixed bug where initialization might fail if some resource on gecko wouldn't load properly and fire the onload event.
|
||||
Fixed bug where ctrl+7/8/9 keys wouldn't properly add the specific formats associated with them.
|
||||
Fixed bug where the HTML tags wasn't properly closed in the style plugins properties dialog.
|
||||
Fixed bug where the list plugin would produce an exception if the user tried to delete an element at the very first location.
|
||||
Version 3.4.3.2 (2011-06-30)
|
||||
Fixed bug where deleting all of a paragraph inside a table cell would behave badly in webkit.
|
||||
Fixed bugs in tests in firefox5 and WebKit.
|
||||
Fixed bug where selection of table cells would produce an exception on Gecko.
|
||||
Fixed bug where the caret wasn't properly rendered on Gecko when the editor was hidden.
|
||||
Fixed bug where pasting plain text into WebKit would produce a pre element it will now produce more semantic markup.
|
||||
Fixed bug where selecting list type formats using the advlist plugin on IE8 would loose editor selection.
|
||||
Fixed bug where forced root blocks logic wouldn't properly pad elements created if they contained data attributes.
|
||||
Fixed bug where it would remove all contents of the editor if you inserted an image when not having a caret in the document.
|
||||
Fixed bug where the YUI compressor wouldn't properly encode strings with only a quote in them.
|
||||
Fixed bug where WebKit on iOS5 wouldn't call nodeChanged when the selection was changed.
|
||||
Fixed bug where mceFocus command wouldn't work properly on Gecko since it didn't focus the body element.
|
||||
Fixed performance issue with the noneditable plugin where it would enable/disable controls to often.
|
||||
Version 3.4.3.1 (2011-06-16)
|
||||
Fixed bug where listboxes were not being handled correctly by JAWS in firefox with the o2k7 skin.
|
||||
Fixed bug where custom buttons were not being rendered correctly when in high contrast mode.
|
||||
Added support for iOS 5 that now supporting contentEditable in it's latest beta.
|
||||
Fixed bug where urls in style attributes with a _ character followed by a number would cause incorrect output.
|
||||
Fixed bug where custom_elements option wasn't working properly on IE browsers.
|
||||
Fixed bug where custom_elements marked as block elements wouldn't get correctly treated as block elements.
|
||||
Fixed bug where attributes with </> wasn't properly encoded as XML entities.
|
||||
Version 3.4.3 (2011-06-09)
|
||||
Fixed bug where deleting backwards before an image into a list would put the cursor in the wrong location.
|
||||
Fixed bug where styles plugin would not apply styles across multiple selected block elements correctly.
|
||||
Fixed bug where cursor would jump to start of document when selection contained empty table cells in IE8.
|
||||
Fixed bug where applied styles wouldn't be kept if you pressed enter twice to produce two paragraphs.
|
||||
Fixed bug where a ghost like caret would appear on Gecko when pressing enter while having a text color applied.
|
||||
Fixed bug where IE would produce absolute urls if you inserted a image/link and reloaded the page.
|
||||
Fixed bug where applying a heading style to a list item would cascade style to children list items.
|
||||
Fixed bug where Editor loses focus when backspacing and changing styles in WebKit.
|
||||
Fixed bug where exception was thrown in tinymce.util.URI when parsing a relative URI and no base_uri setting was provided.
|
||||
Fixed bug where alt-f10 was not always giving focus to the toolbar on Safari.
|
||||
Added new 'allow_html_in_named_anchor' option to allow html to occur within a named anchor tag. Use at own risk.
|
||||
Added plugin dependency support. Will autoload plugins specified as a dependency if they haven't been loaded.
|
||||
Fixed bug where the autolink plugin didn't work with non-English keyboards when pressing ).
|
||||
Added possibility to change properties of all table cells in a column.
|
||||
Added external_image_list option to get images list from user-defined variable or function.
|
||||
Fixed bug where the autoresize plugin wouldn't reduce the editors height on Chrome.
|
||||
Fixed bug where table size inputs were to small for values with size units.
|
||||
Fixed bug where table cell/row size input values were not validated.
|
||||
Fixed bug where menu item line-height would be set to wrong value by external styles.
|
||||
Fixed bug where hasUndo() would return wrong answer.
|
||||
Fixed bug where page title would be set to undefined by fullpage plugin.
|
||||
Fixed bug where HTML5 video properties were not updated in embedded media settings.
|
||||
Fixed bug where HTML comment on the first line would cause an error.
|
||||
Fixed bug where spellchecker menu was positioned incorrectly on IE.
|
||||
Fixed bug where breaking out of list elements on WebKit would produce a DIV instead of P after the list.
|
||||
Fixed bug where pasting from Word in IE9 would add extra BR elements when text was word wrapped.
|
||||
Fixed bug where numeric entities with leading zeros would produce incorrect decoding.
|
||||
Fixed bug where hexadecimal entities wasn't properly decoded.
|
||||
Fixed bug where bookmarks wasn't properly stored/restored on undo/redo.
|
||||
Fixed bug where the mceInsertCommand didn't retain the values of links if they contained non url contents.
|
||||
Fixed bug where the valid_styles option wouldn't be properly used on styles for specific elements.
|
||||
Fixed so contentEditable is used for the body of the editor if it's supported.
|
||||
Fixed so trailing BR elements gets removed even when forced_root_blocks option was set to false/null.
|
||||
Fixed performance issue with mceInsertCommand and inserting very simple contents.
|
||||
Fixed performance issue with older IE version and huge documents by optimizing the forced root blocks logic.
|
||||
Fixed performance issue with table plugin where it checked for selected cells to often.
|
||||
Fixed bug where creating a link on centered/floated image would produce an error on WebKit browsers.
|
||||
Fixed bug where Gecko would remove single paragraphs if there where contents before/after it.
|
||||
Fixed bug where the scrollbar would move up/down when pasting contents using the paste plugin.
|
||||
Version 3.4.2 (2011-04-07)
|
||||
Added new 'paste_text_sticky_default' option to paste plugin, enables you to set the default state for paste as plain text.
|
||||
Added new autoresize_bottom_margin option to autoresize plugin that enables you to add an extra margin at the bottom. Patch contributed by Andrew Ozz.
|
||||
Rewritten the fullpage plugin to handle style contents better and have a more normalized behavior across browsers.
|
||||
Fixed bug where contents inserted with mceInsertContent wasn't parsed using the default dom parser.
|
||||
Fixed bug where blocks containing a single anchor element would be treated as empty.
|
||||
Fixed bug where merging of table cells on IE 6, 7 wouldn't look correctly until the contents was refreshed.
|
||||
Fixed bug where context menu wouldn't work properly on Safari since it was passing out the ctrl key as pressed.
|
||||
Fixed bug where image border color/style values were overwritten by advimage plugin.
|
||||
Fixed bug where setting border in advimage plugin would throw error in IE.
|
||||
Fixed bug where empty anchors list in link settings wasn't hidden.
|
||||
Fixed bug where xhtmlextras popups were missing localized popup-size parameters.
|
||||
Fixed bug where the context menu wouldn't select images on WebKit browsers.
|
||||
Fixed bug where paste plugin wouldn't properly extract the contents on WebKit due to recent changes in browser behavior.
|
||||
Fixed bug where focus of the editor would get on control contents on IE lost due to a bug in the ColorSplitButton control.
|
||||
Fixed bug where contextmenu wasn't disabled on noneditable elements.
|
||||
Fixed bug where getStyle function would trigger error when called on element without style property.
|
||||
Fixed bug where editor fail to load if Javascript Compressor was used.
|
||||
Fixed bug where list-style-type=lower-greek would produce errors in IE<8.
|
||||
Fixed bug where spellchecker plugin would produce errors on IE6-7.
|
||||
Fixed bug where theme_advanced_containers configuration option causes error.
|
||||
Fixed bug where the mceReplaceContent command would produce an error since it didn't correctly handle a return value.
|
||||
Fixed bug where you couldn't enter float point values for em in dialog input fields since it wouldn't be considered a valid size.
|
||||
Fixed bug in xhtmlxtras plugin where it wasn't possible to remove some attributes in the attributes dialog.
|
||||
Version 3.4.1 (2011-03-24)
|
||||
Added significantly improved list handling via the new 'lists' plugin.
|
||||
Added 'autolink' plugin to enable automatically linking URLs. Similar to the behavior IE has by default.
|
||||
Added 'theme_advanced_show_current_color' setting to enable the forecolor and backcolor buttons to continuously show the current text color.
|
||||
Added 'contextmenu_never_use_native' setting to disable the ctrl-right-click showing the native browser context menu behaviour.
|
||||
Added 'paste_enable_default_filters' setting to enable the default paste filters to be disabled.
|
||||
Fixed bug where selection locations on undo/redo didn't work correctly on specific contents.
|
||||
Fixed bug where an exception would be trown on IE when loading TinyMCE inside an iframe.
|
||||
Fixed bug where some ascii numeric entities wasn't properly decoded.
|
||||
Fixed bug where some non western language codes wasn't properly decoded/encoded.
|
||||
Fixed bug where undo levels wasn't created when deleting contents on IE.
|
||||
Fixed bug where the initial undo levels bookmark wasn't updated correctly.
|
||||
Fixed bug where search/replace wouldn't be scoped to editor instances on IE8.
|
||||
Fixed bug where IE9 would produce two br elements after block elements when pasting.
|
||||
Fixed bug where IE would place the caret at an incorrect position after a paste operation.
|
||||
Fixed bug where a paste operation using the keyboard would add an extra undo level.
|
||||
Fixed bug where some attributes/elements wasn't correctly filtered when invalid contents was inserted.
|
||||
Fixed bug where the table plugin couldn't correctly handle invalid table structures.
|
||||
Fixed bug where charset and title of the page were handled incorrectly by the fullpage plugin.
|
||||
Fixed bug where toggle states on some of the list boxes didn't update correctly.
|
||||
Fixed bug where sub/sub wouldn't work correctly when done as a caret action in Chrome 10.
|
||||
Fixed bug where the constrain proportions checkbox wouldn't work in the media plugin.
|
||||
Fixed bug where block elements containing trailing br elements wouldn't treated properly if they where invalid.
|
||||
Fixed bug where the color picker dialog wouldn't be rendered correctly when using the o2k7 theme.
|
||||
Fixed bug where setting border=0 using advimage plugin invalid style attribute content was created in Chrome.
|
||||
Fixed bug with references to non-existing images in css of fullpage plugin.
|
||||
Fixed bug where item could be unselected in spellchecker's language selector.
|
||||
Fixed bug where some mispelled words could be not highlighted using spellchecker plugin.
|
||||
Fixed bug where spellchecking would merge some words on IE.
|
||||
Fixed bug where spellchecker context menu was not always positioned correctly.
|
||||
Fixed bug with empty anchors list in advlink popup when Invisible Elements feature was disabled.
|
||||
Fixed bug where older IE versions wouldn't properly handle some elements if they where placed at the top of editor contents.
|
||||
Fixed bug where selecting the whole table would enable table tools for cells and rows.
|
||||
Fixed bug where it wasn't possible to replace selected contents on IE when pasting using the paste plugin.
|
||||
Fixed bug where setting text color in fullpage plugin doesn't work.
|
||||
Fixed bug where the state of checkboxes in media plugin wouldn't be set correctly.
|
||||
Fixed bug where black spade suit character was not included in special character selector.
|
||||
Fixed bug where setting invalid values for table cell size would throw an error in IE.
|
||||
Fixed bug where spellchecking would remove whitespace characters from PRE block in IE.
|
||||
Fixed bug where HR was inserted inside P elements instead of splitting them.
|
||||
Fixed bug where extra, empty span tags were added when using a format with both selector and inline modes.
|
||||
Fixed bug where bullet lists weren't always detected correctly.
|
||||
Fixed bug where deleting some paragraphs on IE would cause an exception.
|
||||
Fixed bug where the json encoder logic wouldn't properly encode \ characters.
|
||||
Fixed bug where the onChange event would be fired when the editor was first initialized.
|
||||
Fixed bug where mceSelected wouldn't be removed properly from output even if it's an internal class.
|
||||
Fixed issue with table background colors not being transparent. This improves compliance with users browser color preferences.
|
||||
Fixed issue where styles were not included when using the full page plugin.
|
||||
Fixed issue where drag/drop operations wasn't properly added to the undo levels.
|
||||
Fixed issue where colors wasn't correctly applied to elements with underline decoration.
|
||||
Fixed issue where deleting some paragraphs on IE would cause an exception.
|
||||
Version 3.4 (2011-03-10)
|
||||
Added accessibility example with various accessibility options contributed by Ephox.
|
||||
Fixed bug where attributes wasn't properly handled in the xhtmlxtras plugin.
|
||||
Fixed bug where the image.htm had some strange td artifacts probably due to auto merging.
|
||||
Fixed bug where the ToolbarGroup had an missing reference to this in it's destroy method.
|
||||
Fixed bug with the resizeBy function in the advanced theme where it was scaled by the wrong parent.
|
||||
Fixed bug where an exception would be thrown by the element if the page was served in xhtml mode.
|
||||
Fixed bug where mceInsertContent would throw an exception when page was served in xhtml mode.
|
||||
Fixed bug where you couldn't select a forground/background color when page was served in xhtml mode.
|
||||
Fixed bug where the editor would scroll to the toolbar when clicked due to a call to focus in ListBox.
|
||||
Fixed bug where pages with rtl dir wouldn't render split buttons correctly when using the o2k7 theme.
|
||||
Fixed bug where anchor elements with names wasn't properly collapsed as they where in 3.3.x.
|
||||
Fixed bug where WebKit wouldn't properly handle image selection if it was done left to right.
|
||||
Fixed bug where the formatter would align images when the selection range was collapsed.
|
||||
Fixed bug where the image button would be active when the selection range was collapsed.
|
||||
Fixed bug where the element_format option wasn't used by the new (X)HTML serializer logic.
|
||||
Fixed bug where the table cell/row dialogs would produce empty attributes.
|
||||
Fixed bug where the tfoot wouldn't be added to the top of the table.
|
||||
Fixed bug where the formatter would merge siblings with white space between them.
|
||||
Fixed bug where pasting headers and paragraphs would produce an extra paragraph.
|
||||
Fixed bug where the ColorSplitButton would throw an exception if you clicked out side a color.
|
||||
Fixed bug where IE9 wouldn't properly produce new paragraphs on enter if the current paragraph had formatting.
|
||||
Fixed bug where multiple BR elements at end of block elements where removed.
|
||||
Fixed bug where fullscreen plugin wouldn't correctly display the edit area on IE6 for long pages.
|
||||
Fixed bug where paste plugin wouldn't properly encode raw entities when pasting in plain text mode.
|
||||
Fixed bug where the search/replace plugin wouldn't work correctly on IE 9.
|
||||
Fixed so the drop menus doesn't get an outline border visible when focused, patch contributed by Ephox.
|
||||
Fixed so the values entered in the color picker are forced to hex values.
|
||||
Removed dialog workaround for IE 9 beta since the RC is now out and people should upgrade.
|
||||
Removed obsolete calls in various plugins to the mceBeginUndoLevel command.
|
||||
Version 3.4b3 (2011-02-10)
|
||||
Added WAI-ARIA support for the main UI and dialogs this feature was contributed by Ephox.
|
||||
Added iframe support to media plugin in order to handle the new YouTube HTML5 video formats.
|
||||
Fixed bug where anchors would wrap the text contents after it due to a bug in the DomParser logic.
|
||||
Fixed bug where the selected state wouldn't be removed on ListBox controls when a menu item was selected.
|
||||
Fixed bug where IE could throw an unspecified error exception when the getBookmark logic was executed.
|
||||
Fixed bug where IE would throw an invalid argument error when focus was applied to an empty editor instance.
|
||||
Fixed bug where applying inline format wouldn't work if the start cell in the selection was empty.
|
||||
Fixed bug where auto detection logic for YouTube and Google Video wouldn't work in the new media plugin.
|
||||
Fixed bug where td elements would get a colspan/rowspan of 1 when created by the table plugin.
|
||||
Fixed bug where removal/padding of empty elements wasn't handled correctly.
|
||||
Fixed bug where internal elements would show up in element path.
|
||||
Fixed bug where internal elements would get serialized as valid output.
|
||||
Fixed bug where color wasn't correctly applied to anchor elements.
|
||||
Fixed bug where float option in the style plugin dialog wouldn't be handled correctly on WebKit.
|
||||
Fixed bug where the tinymce.dom.TreeWalker prev function wouldn't walk the DOM correctly.
|
||||
Fixed bug where mceInsertContent command could produce empty block elements after the inserted content.
|
||||
Fixed bug where mceInsertContent command wouldn't apply visual aids on tables and similar elements.
|
||||
Fixed bug where empty block elements would get double br bogus elements in them.
|
||||
Fixed bug where the color menu wouldn't apply the color correctly on IE when the viewport was to small.
|
||||
Fixed bug where right clicking out side the body element of the editor iframe would prevent paste from working on IE.
|
||||
Fixed bug where the onContextMenu event wouldn't fire correctly on IE if you clicked out side the body element.
|
||||
Fixed bug where the onContextMenu event wouldn't fire correctly on modern Opera versions that now support it by default.
|
||||
Fixed bug where legacy content wasn't converted correctly when inserted using mceInsertContent or through the source dialog.
|
||||
Fixed bug where resizing images or tables wouldn't update the style attribute correctly or leave data-mce prefixed attributes.
|
||||
Fixed bug where adding links wouldn't work correctly when using TinyMCE jQuery version with jQuery 1.5.
|
||||
Fixed bug where single quotes inside param elements wasn't treated correctly by the media plugin.
|
||||
Fixed bug where pasting plain text in WebKit wouldn't work correctly. It will now auto detect the WebKit bug and use plain text mode.
|
||||
Fixed bug where the DomParser would fail to move out invalid elements within invalid elements on complex contents.
|
||||
Fixed bug where paste as plain text would not decode html entities properly.
|
||||
Fixed bug where large paragraphs would cause incorrect scrolling behavior if you would split them using enter.
|
||||
Fixed bug where the SaxParser wouldn't properly parse some specific short ended elements.
|
||||
Fixed so mceReplaceContent supports caret position and makes sure that the contents inserted gets validated.
|
||||
Fixed so unnecessary traling br elements in blocks gets removed on Gecko/WebKit when using mceInsertContent command.
|
||||
Moved some plugin css contents into the skin content css files to reduce the number of http requests.
|
||||
Moved some plugin specific images into the theme img directory since they can then be shared.
|
||||
Version 3.4b2 (2011-01-13)
|
||||
Added new custom flash player, this player supports mp4 and flv and has skin support.
|
||||
Fixed so mceInsertContent handles context correctly to enforce valid nesting of elements.
|
||||
Fixed bug where scrolling would become jerky on IE on some contents.
|
||||
Fixed bug where paste as plain text would throw exception of missing entities setting.
|
||||
Fixed bug where anchor nodes where removed by the new serializer engine.
|
||||
Fixed bug where IE would crash if when backspace where used on some specific contents.
|
||||
Fixed bug where pasting of plain text in WebKit would result in merging of text lines.
|
||||
Fixed bug where it wasn't possible to delete images or tables using backspace on IE9.
|
||||
Fixed bug where urls in styles would generate a JS error due to incorrect scope.
|
||||
Fixed bug where copy paste from Java applications would produce extra contents in FF on Mac.
|
||||
Fixed bug where the verify_html option wouldn't allow all elements and attributes.
|
||||
Version 3.4b1 (2010-12-20)
|
||||
Added new serialization engine that increases performance and enforces valid output according to the specified schema settings.
|
||||
Added new HTML parser logic used by the serialization engine and can handle malformed html contents.
|
||||
Added new valid_children config option, enables more fine grain control of elements can be inside other elements.
|
||||
Added new entities encoding logic boost performance and will only encode entities based on context i.e. attributes/text nodes.
|
||||
Added new protect setting that enables users to protect template items from being removed by the serializer logic.
|
||||
Added new {$caret} marker for the mceInsertContent command. Makes it possible to move the caret to a specific position when inserting contents.
|
||||
Added new validation of anchor names. Only valid W3C names will be accepted.
|
||||
Replaced the internal _mce_ prefixed attributes to the more standard HTML5 data-mce- prefix. This will also resolve future browser santiaztion issues.
|
||||
Fixed bug where the paste plugin wouldn't convert Word lists with more than 9 items to real ol lists. Patch contributed by Mike (yogaboy).
|
||||
Fixed bug where clicking on a format title would produce errors if the current selection didn't have any formats.
|
||||
Fixed bug where paste of simple texts wouldn't work correctly in Gecko using the paste plugin since it keeps block formatting.
|
||||
Fixed bug where confirm dialogs didn't display correctly due to resent IE9 fixes.
|
||||
Fixed bug where spaces in URLs wouldn't be properly encoded to %20 if the user entered them in the link dialogs. Patch contributed by Ephox.
|
||||
Fixed bug where the image alignment buttons wouldn't reposition the resize handles on FF due to a browser issue. Patch contributed by Ephox.
|
||||
Fixed bug where the compareBoundaryPoints method of the IE Range class didn't work correctly. Patch contributed by Ephox.
|
||||
Fixed bug where selection of elements using double click wouldn't select the clicked element but rather the parent node on FF. Patch contributed by Ephox.
|
||||
Fixed bug where IE would scroll the user to the current selection causing parent document to scroll as well. Patch contributed by Ephox.
|
||||
Fixed bug where style compression would incorrectly compress items with different values. It now only compresses if the values are the same. Patch contributed by Ephox.
|
||||
Fixed bug where FF would add non breaking spaces outside TD elements if formatting was applied to table cells. Patch contributed by Ephox.
|
||||
Fixed bug where the caret position would be lost on WebKit browsers if you pasted images multiple times. Patch contributed by Ephox.
|
||||
Fixed bug where non word contents like * would be counted as words in the wordcount pluging. Patch contributed by David Balatero.
|
||||
Fixed bug where the toggle absolute button in the layer plugin wouldn't remove the existing internal style attribute first.
|
||||
Fixed bug where the autosave plugin would generate an exception on IE if the user had disabled userdata persistence.
|
||||
Fixed bug where the paste plugin would remove dashed classes on IE since the regexps didn't include that character.
|
||||
Fixed bug where applying text color would not add spans inside link elements. This is needed due to CSS style inheritance.
|
||||
Fixed bug where applying block formats to empty elements wouldn't render correctly on IE.
|
||||
Fixed bug where the searchreplace plugin would add a f or r character when shortcuts where used on IE while using default dialogs.
|
||||
Fixed bug where Opera wouldn't load scripts correctly since the onreadystate would fire even though the script wasn't loaded.
|
||||
Fixed issue where wouldn't be handled correctly in the bbcode plugin if entity_encoding was set to raw.
|
||||
Fixed issue where contents would flicker since the content css files where asynchronously loaded.
|
||||
Fixed bug where WebKit wouldn't create links on images with a float style.
|
||||
Version 3.3.9.3 (2010-12-20)
|
||||
Fixed issue where WebKit wouldn't correctly apply ins/del in xhtmlxtras plugin.
|
||||
Fixed bug where paste as plaintext on WebKit wouldn't produce br and p elements correctly.
|
||||
Fixed bug where the confirm dialog texts would be incorrectly placed due to recent IE 9 workarounds in the window.css.
|
||||
Fixed bug where applying text color would not add spans inside link elements. This is needed due to CSS style inheritance.
|
||||
Version 3.3.9.2 (2010-09-29)
|
||||
Fixed bug where placing the caret in IE 9 beta 1 would not work correctly if you clicked out side the document body element.
|
||||
Fixed bug where IE 9 beta 1 wouldn't resize the editor correctly since the events didn't fire as previous versions did.
|
||||
Fixed bug where FF would produce an error message when being rendered inside a hidden div element.
|
||||
Fixed bug where resize logic could produce a cookie with a width/height less than the size of the container.
|
||||
Fixed bug where content_css wouldn't populate the styles dropdown correctly.
|
||||
Version 3.3.9.1 (2010-09-23)
|
||||
Fixed bug where WebKit browsers wouldn't activate the image button when images where selected.
|
||||
Fixed bug where Opera Presto 10.60 deletes elements when restoring bookmarks.
|
||||
Fixed bug where IE9 beta1 doesn't handle regexp replacement values correctly.
|
||||
Fixed bug where IE9 beta1 didn't render the inline dialogs correctly due to a bug with CSS clip.
|
||||
Fixed bug where IE9 beta1 would produce error messages on load since they removed the document.recalc method.
|
||||
Fixed bug where IE9 beta1 would produce <html xmlns=""> since they haven't implemented document.implementation.createDocument correctly.
|
||||
Fixed bug where IE9 beta1 would searchreplace doesn't work since their native DOM Range doesn't have a find method.
|
||||
Fixed bug where IE9 beta1 would render the source view incorrectly due to incorrect viewport size measurements.
|
||||
Fixed bug where IE9 beta1 would crash when running the basic functionality unit tests.
|
||||
Fixed bug where IE9 beta1 would wrap elements in blocks correctly due to changes to the selection object.
|
||||
Fixed bug where IE9 beta1 would fail to insert contents since they havn't implemented the createContextualFragment method in their DOM Range.
|
||||
Fixed bug where IE9 beta1 would fail to handle image selection since they currently doesn't support control selections in their DOM Range.
|
||||
Fixed bug where IE9 beta1 would fail to load scripts since they fire the onload event before the scripts are parsed and executed.
|
||||
Version 3.3.9 (2010-09-08)
|
||||
Fixed bug where inserting table rows into a table with subtable would produce an incorrect column count.
|
||||
Fixed bug where the selection of cells in a table with subtables could produce invalid selections.
|
||||
Fixed bug where the table plugin would produce a script error if you tried to move the caret before a first child table.
|
||||
Fixed bug where the keep_styles feature on IE would move the caret to an incorrect location at the end of list blocks.
|
||||
Fixed so attributes from legacy elements such as font gets retained when they get converted to spans.
|
||||
Fixed minor issue where the select boxes wouldn't be set the not set by default in the table dialog.
|
||||
Version 3.3.8 (2010-06-30)
|
||||
On IE8+ and FireFox 3.5+, dragging an image now correctly adds an undo
|
||||
event.
|
||||
Fixed bug where WebKit would not move the caret to a correct position after a paste operation.
|
||||
Fixed bug where WebKit would produce a div wrapper element when pasting some contents.
|
||||
Fixed bug where the visual chars and nonbreaking plugin wouldn't show nbsp elements correctly.
|
||||
Fixed bug where the format states would be enabled even after the format was removed.
|
||||
Fixed bug where the delete key would move the caret to an incorrect position.
|
||||
Fixed bug where it wasn't possible to toggle of the current font size/family/style by clicking the title item.
|
||||
Fixed bug where the abbr element wouldn't get serialized correctly on IE6.
|
||||
Fixed so that the examples checks if they are executed from the local file system since that might not work properly.
|
||||
Version 3.3.7 (2010-06-10)
|
||||
Fixed bug where context menu would produce an error on IE if you right clicked twice and left clicked once.
|
||||
Fixed bug where resizing of the window on WebKit browsers in fullscreen mode wouldn't position the statusbar correctly.
|
||||
Fixed bug where IE would produce an error if the editor was empty and you where undoing to that initial level.
|
||||
Fixed bug where setting the table background on gecko would produce \" entities inside the url style property.
|
||||
Fixed bug where the button states wouldn't be updated correctly on IE if you placed the caret inside the new element.
|
||||
Fixed bug where undo levels wasn't properly added after applying styles or font sizes.
|
||||
Fixed bug where IE would throw an error if you used "select all" on empty elements and applied formatting to that.
|
||||
Fixed bug where IE could select one extra character when you did a bookmark call on a caret location.
|
||||
Fixed bug where IE could produce a script error on delete since it would sometimes produce an invalid DOM.
|
||||
Fixed bug where IE would return the wrong start element if the whole element was selected.
|
||||
Fixed bug where formatting states wasn't updated on IE if you pressed enter at the end of a block with formatting.
|
||||
Fixed bug where submenus for the context menu wasn't removed correctly when the editor was destroyed.
|
||||
Fixed bug where Gecko could select the wrong element after applying format to multiple elements.
|
||||
Fixed bug where Gecko would delete parts of the previous element if the selection range was a element selection.
|
||||
Fixed bug where Gecko would not merge paragraph elements correctly if they contained br elements.
|
||||
Fixed bug where the cleanup button could produce span artifacts if you pressed it twice in a row.
|
||||
Fixed bug where the fullpage plugin header/footer would be have it's header reseted to it's initial state on undo.
|
||||
Fixed bug where an empty paragraph would be collapsed if you performed a cleanup while having the caret inside it.
|
||||
Fixed a few memory leaks on IE especially with drop menus in listboxes and the spellchecker.
|
||||
Fixed so formats applied to the current caret gets merged to reduce the number of output elements.
|
||||
Added the latest version of Sizzle for the CSS selector logic to fix a compatibility issue with prototype.
|
||||
Version 3.3.6 (2010-05-20)
|
||||
Fixed bug where a editor.focus call could produce errors on IE in very specific scenarios.
|
||||
Fixed bug where Gecko would produce an error if you unformatted text inside an empty element.
|
||||
Fixed bug where IE would produce an error if the caret was placed before a table and you used the align buttons.
|
||||
Fixed bug where the font size drop down didn't display the a preview correctly.
|
||||
Fixed bug where the paste plugin wouldn't include all contents some times on WebKit browsers.
|
||||
Fixed bug where the plain text mode toggle wouldn't work properly on WebKit.
|
||||
Fixed bug where the editors statusbar would become invisible when you resized the window in fullscreen mode.
|
||||
Version 3.3.5.1 (2010-05-07)
|
||||
Fixed a critical bug with the fullscreen plugin. Produced error messages when the state was toggled on/off.
|
||||
Version 3.3.5 (2010-05-06)
|
||||
Added new merge_with_parents option to formats, enables the control of removal of elements with similar parents.
|
||||
Fixed so the default behavior for applying classes isn't a toggle state but the old behavior from before the 3.3 release.
|
||||
Fixed bug where selecting contents using double click on Gecko would produce errors when using removing format.
|
||||
Fixed bug where the IE DOM could get messed up when non valid contents was pasted into the editor.
|
||||
Fixed bug where merging selected table cells using the context menu didn't work as expected.
|
||||
Fixed bug where some nestled formatting would be applied incorrectly.
|
||||
Fixed bug with enter in list items when using the force_br_newlines mode on WebKit patch contributed by Ryan Koopmans.
|
||||
Fixed bug where undo/redo could produce js errors on some specific operations.
|
||||
Fixed bug where the theme_advanced_font_sizes didn't work as before 3.3 when complex settings where used.
|
||||
Fixed bug where the table plugin would copy cell/row id attributes when making new rows/cells.
|
||||
Version 3.3.4 (2010-04-27)
|
||||
Fixed bug where fullscreen plugin would add two editor instances to EditorManager collection.
|
||||
Fixed bug where it was difficult to enter text on non western languages such as Japanese on IE.
|
||||
Fixed bug where removing contents from nodes could result in an exception when using undo/redo.
|
||||
Fixed bug with selection of images inside layers or other resizable containers on IE.
|
||||
Fixed so editors isn't initialized on iPhone/iPad devices since they don't have caret support.
|
||||
Version 3.3.3 (2010-04-19)
|
||||
Added new script_loaded callback function setting for the jQuery plugin.
|
||||
Added various fixes and new rpc methods for the spellchecker plugin. Patch contributed by Michael Peters.
|
||||
Removed some unnecessary inline style information from some of the dialogs.
|
||||
Fixed some issues with the chaining for the TinyMCE jQuery plugin.
|
||||
Fixed so any extra arguments passed to patched jQuery functions gets passed through. Patch contributed by Lee Henson.
|
||||
Fixed so spellchecking/contextmenu can be toggled on/off if the browser has native spellchecker support.
|
||||
Fixed bug where some texts in the new paste plugin wasn't placed in language pack.
|
||||
Fixed bug where IE would produce an incorrect information message when cutting.
|
||||
Fixed bug where removing items using the xhtmlxtras plugin wouldn't work correctly.
|
||||
Fixed bug where setting table background images would add extra quotes on Gecko.
|
||||
Fixed bug where shortcut for bold/italic/underline wouldn't work properly on WebKit.
|
||||
Fixed bug where IE would produce an error message if only contents was an image tag and bold was used.
|
||||
Fixed bug where the caret would move if alignment was applied to empty block elements.
|
||||
Fixed bug where some shortcut key commands wouldn't apply formatting correctly.
|
||||
Version 3.3.2 (2010-03-25)
|
||||
Fixed bug where it was possible to scale the editor iframe smaller than the editor UI.
|
||||
Fixed bug where some of the resizing option didn't work with the new live resize.
|
||||
Fixed bug where the format listbox didn't show nestled formats correctly.
|
||||
Fixed bug where the native listboxes didn't work correctly.
|
||||
Fixed bug where font size selection in using the legacyoutput plugin would produce errors.
|
||||
Fixed so block and blockquote formats remove their matching element regardless of it's attributes.
|
||||
Version 3.3.1 (2010-03-18)
|
||||
Added new live resize feature, the editor contents is now visible while resizing.
|
||||
Fixed bug where some valid_element patterns would produce an unknown property error.
|
||||
Fixed bug where it wasn't possible to toggle off blockquotes.
|
||||
Fixed bug where an undo level wasn't produced when applying formatting using the styles dropdown.
|
||||
Fixed bug where IE 6/7 wouldn't perform caret formatting due to a focus/event bug in IE.
|
||||
Fixed bug where undo/redo wasn't restoring the previous selection correctly.
|
||||
Fixed bug where the caret would become invisible if you resized the editor in latest Gecko.
|
||||
Fixed bug where the class attribute wasn't completely removed in IE 6/7 when the removeClass function was used.
|
||||
Fixed so the matchNode method of the Formatter class returns the matched format rule.
|
||||
Fixed so it's possible to apply formatting to both blocks and as inline elements.
|
||||
Version 3.3 (2010-03-10)
|
||||
Fixed bug where backspace on a table on IE would produce an empty tbody and some JS exceptions.
|
||||
Fixed bug where some redundant children wasn't removed properly when applying inline styles to them.
|
||||
Fixed bug where Chrome would produce incorect dialog sizes if the inlinepopups plugin wasn't used.
|
||||
Fixed bug where spans with different classes would get merged if they where siblings to each other.
|
||||
Fixed bug where IE 8 would crash if you used the spellchecker.
|
||||
Fixed bug where Input Method for non western languages didn't work correctly.
|
||||
Fixed bug where the UI would render incorrectly in FF 3.6 on Mac due to a bug n their rendering engine.
|
||||
Fixed bug where WebKit wouldn't scroll down correctly if Shift+Enter was used. Patch contributed by Thomas Andersen.
|
||||
Version 3.3rc1 (2010-02-23)
|
||||
Fixed bug with new legacyoutput plugin not working correctly on it's own.
|
||||
Fixed bug some performance issues with removing text formats.
|
||||
Fixed bug where TinyMCE specific attributes wasn't removed properly by remove format.
|
||||
Fixed bug where it wasn't possible to align images within inline elements.
|
||||
Fixed bug where Ctrl+Delete/Backspace would produce an invalid argument exception on IE.
|
||||
Fixed bug where the search/replace logic could produce an infinite loop on IE for reverse searches.
|
||||
Fixed bug where cloning formats in cells didn't work properly on IE.
|
||||
Fixed bug where IE6 would produce a horizontal scroll bar.
|
||||
Fixed so remove jQuery method removes the TinyMCE instance as well as the specified textarea.
|
||||
Fixed so selected rows and cells gets updated using the row/cell properties dialogs.
|
||||
Version 3.3b2 (2010-02-04)
|
||||
Fixed bug where sometimes img elements would be removed by split method in DOMUtils.
|
||||
Fixed bug where merging of span elements could occur on bookmark nodes.
|
||||
Fixed bug where classes wasn't properly removed when removeformat was used on IE 6.
|
||||
Fixed bug where multiple calls to an tinyMCE.init with mode set to exact could produce the same unique ID.
|
||||
Fixed bug with the IE selection implementation when it was feeded an document range.
|
||||
Fixed bug where block elements formatting wasn't properly removed by removeformat on all browsers.
|
||||
Fixed bug where selection location was lost if you performed a manual cleanup.
|
||||
Fixed bug where removeformat wouldn't remove span elements within styled block elements.
|
||||
Fixed bug where an error would be thrown if you clicked on the separator lines in menus.
|
||||
Fixed bug with the jQuery plugin adding always adding a querystring value to other resources.
|
||||
Fixed bug where IE would produce an error message if you had an empty editor instance.
|
||||
Fixed bug where Shift+Enter didn't produce br elements on WebKit browsers.
|
||||
Fixed bug where a temporary marker element wasn't removed by the paste plugin.
|
||||
Fixed bug where inserting a table would produce two undo levels instead of one.
|
||||
Version 3.3b1 (2010-01-25)
|
||||
Added new text formatting engine. Fixes a lot of browser quirks and adds new possibilities.
|
||||
Added new advlist plugin that enables you to set the formats of list elements.
|
||||
Added new paste plugin logic that enables you to retain style information from Office.
|
||||
Added new autosave plugin logic that automatically saves contents in local storage.
|
||||
Added new valid_styles option. Adds the possibility to restrict styles and their order.
|
||||
Added new theme_advanced_runtime_fontsize option to display the runtime font size in font size select box.
|
||||
Added new jquery plugin version that handles the gzip compressor amongst other things. Contributed by Speednet.
|
||||
Added new $ function to tinymce namespace and editor instances for the jQuery build.
|
||||
Added the possibility to get editors by index as well as name in the tinyMCE.editors collection.
|
||||
Fixed so the contents inside the editor renders in standards mode by default.
|
||||
Fixed bug where it wasn't possible to move the caret on short documents running in standards mode on IE.
|
||||
Fixed bug where the decode method of the DOMUtils class could end up in an endless loop.
|
||||
Fixed bug where it was possible to bypass the paste cleanup on non IE browsers if you clicked while pasting.
|
||||
Fixed bug where some attributes wasn't serialized correctly on IE if wildcard attribute patters where used.
|
||||
Fixed bug where entity decoding was performed on strings that didn't have any valid entities in them.
|
||||
Fixed bugs with the insertNode method of the IE DOMRange implementation. Patch contributed by Scott McNaught.
|
||||
Rewrote the getBookmark/moveToBookmark selection logic to boost performance on larger documents.
|
||||
Rewrote the table plugin to include new cell selection logic and fixed various bugs and issues.
|
||||
Merged the tinyMCE, tinymce and tinymce.EditorManager into the same instance makes more sense.
|
||||
Removed browser setting since the browser support for TinyMCE is not far better than it was when that setting was introduced.
|
||||
Changed the mce_ attribute prefix to the more standard _mce_ prefix. This is similar to browser vendors prefixes.
|
||||
Optimized performance with named entities on Gecko. Regexp replace was executing very slowly probably due to a Gecko bug.
|
||||
Optimized performance of the IE specific selection/range implementation.
|
||||
Removed the safari plugin since we now replaced all text formatting logic to custom code.
|
||||
Version 3.2.7 (2009-09-22)
|
||||
Fixed bug where uppercase paragraphs could still produce an invalid DOM tree on IE.
|
||||
Fixed bug where split command didn't work on WebKit since the node serializer needs a real document to work with.
|
||||
Fixed bug where it was impossible in Gecko to place the caret before a table if it was the first one.
|
||||
Fixed bug where linking to urls like ../../ would produce an extra traling slash ../..//.
|
||||
Fixed bug where the template cdate functionality was using an old 2.x API call. Patch contributed by vectorjohn.
|
||||
Fixed bug where urls to the same site but different protocol would be converted when relative_urls where set to false. Patch contributed by Ted Rust.
|
||||
Fixed bug where the paste plugin would remove mceItem prefixed classes.
|
||||
Fixed bug where the paste plugin would sometimes add items in a reverse order on WebKit.
|
||||
Fixed bug where the paste buttons would present an error message on Gecko even if you changed user.js. Patch contributed by Todd (teeaykay).
|
||||
Fixed bug where Opera would crash if you had tables incorrectly placed inside paragraphs.
|
||||
Fixed bug where styles elements wasn't properly processed if you had bad input HTML.
|
||||
Fixed bug where style attributes wasn't properly forced into a specific format.
|
||||
Fixed bug and issues with boolean attributes like checked, nowrap etc.
|
||||
Fixed bug where input elements could override attributes on form elements.
|
||||
Fixed bug where script or style elements could get modified by the DOMUtils processHTML method.
|
||||
Fixed bug where the selected attribute could get lost when force root blocks logic got executed on IE. Patch contributed by Attila Mezei-Horvati.
|
||||
Fixed bug where getAttribs method didn't handle boolean attributes correctly on IE.
|
||||
Fixed so the paste from word dialog is presented if you paste content on an IE with to restrictive security settings.
|
||||
Fixed so the paste_strip_class_attributes option is set to none by default in the paste plugin.
|
||||
Removed default border=0 on tables for the default value of valid_elements.
|
||||
Version 3.2.6 (2009-08-19)
|
||||
Added new wordcount plugin, this will display the number of typed words as you write. Contributed by Andrew Ozz.
|
||||
Added new getNext and getPrev methods to DOM utils. These will return the first matching sibling.
|
||||
Fixed bug where it was impossible to place the caret after a table on Gecko. It will now add a paragraph after tables.
|
||||
Fixed bug where inline dialogs would fail if used in a window opened using a showModalDialog. Patch contributed by Derek Britt.
|
||||
Fixed bug where IE could sometimes render a unknown runtime error on invalid input HTML.
|
||||
Fixed bug where some incorrectly placed tables wouldn't be moved outside the paragraphs on IE.
|
||||
Fixed bug where uppercase script/style element wouldn't be handled correctly and converted to valid lowercase.
|
||||
Fixed bug where some WebKit versions on Mac OS X would produce issues with hidden select fields.
|
||||
Fixed bug where the media plugin would fail on WebKit since the node wasn't properly imported to the right document.
|
||||
Fixed bug where absolute URLs for the TinyMCE script using a base href element would cause loading problems in IE 6/7.
|
||||
Fixed bug where pasting using the paste plugin wasn't possible on IE with to restrictive security settings.
|
||||
Fixed bug where pasting of whitespace was impossible using the new custom paste method.
|
||||
Fixed bug where pasting on some WebKit browsers would not work if you pasted specific contents due to a WebKit bug.
|
||||
Fixed bug where doctypes with multiple lines would not be parsed correctly by the fullpage plugin. Patch contributed by Colin.
|
||||
Fixed bug where the autoresize plugin would break the fullscreen functionality.
|
||||
Fixed bug where tables would be chopped up running on IE using invalid contents and pasting paragraphs into a cell.
|
||||
Fixed bug where the each method of jQuery build didn't iterate styleSheets. We now use the TinyMCE API one instead.
|
||||
Fixed bug where auto switching to paragraphs after headers some times failed in Gecko.
|
||||
Fixed so all editor options gets passed to the Serializer class. Patch contributed by Jasper Mattsson.
|
||||
Fixed so script/style blocks isn't wrapped in paragraphs as other inline elements.
|
||||
Fixed so the XHR requests sends the X-Requested-With HTTP header.
|
||||
Fixed so the data url scheme is handled in the tinymce.util.URI class.
|
||||
Changed inline documentation to use moxiedoc style comments.
|
||||
Removed the compat2x plugin people should have upgraded to the 3.x API by now. 3.0 was released more then a year ago.
|
||||
Re-added Gecko specific message for users who doesn't understand the security concept regarding paste.
|
||||
Version 3.2.5 (2009-06-29)
|
||||
Added new jQuery plugin for the jQuery specific package. This enables you to more easily load and use TinyMCE.
|
||||
Added new autoresize plugin contributed by Peter Dekkers. This plugin will auto resize the editor to the size of the contents.
|
||||
Fixed so all packages have the same directory structure. Previous releases had a different structure for the production package.
|
||||
Fixed so the paste from word dialog forces the contents to be processed as word contents even if it's not.
|
||||
Fixed so the jQuery build adapter build works. It's currently only excluding Sizzle.
|
||||
Fixed so noscript element contents is retained during the editing process.
|
||||
Fixed bug where the getBookmark method would need a "simple" string input when the documented way is a boolean.
|
||||
Fixed bug where invalid contents could break the fix_table_elements logic.
|
||||
Fixed bug where Sizzle specific attributes would be serialized if the valid_elements was set to *[*].
|
||||
Fixed bug where IE would produce an error if you specified a relative content_css and opened the paste dialog.
|
||||
Fixed bug where pasting images on IE would produce broken images if they came from an external site.
|
||||
Fixed bug where memory was leaked if you add/remove controls dynamically. Some event handlers wasn't removed properly.
|
||||
Fixed bug where domain relaxing wasn't treated correctly if you added it after the TinyMCE script element.
|
||||
Fixed bug where the activeEditor wasn't set to null if the last editor instance was removed.
|
||||
Fixed bug where IE was leaking memory on the onbeforeunload event due to some recently introduced logic. Patch contributed by Options.
|
||||
Fixed bug where inserting tables in Safari 4 didn't work due to a new WebKit bug where some element names are reserved.
|
||||
Fixed bug where URLs having a :// value in the query string would make it absolute regardless of URL settings.
|
||||
Fixed the WebKit specific bug where DOM Ranges would fail if the node wasn't attached to something in a different way.
|
||||
Removed the auto_resize option and the resizeToContent method from the tinymce.Editor class. Use the new autoresize plugin instead.
|
||||
Version 3.2.4.1 (2009-05-25)
|
||||
Fixed bug where Gecko browsers would produce an extra space after for example strong when loaded from sub domains.
|
||||
Fixed bug where script elements would be removed if they where placed inside a paragraph element.
|
||||
Fixed bug where IE 8 would produce 1 item remaining when loading CSS files dynamically with an empty cache.
|
||||
Fixed bug where bound events would be removed from other editor instances if a specific one was removed.
|
||||
Fixed various bugs and issues with script and style elements inside the editor.
|
||||
Fixed so all script contents gets wrapped in CDATA sections so that they can be parsed using a XML parser.
|
||||
Fixed so it's impossible for elements marked as closed to have child nodes rendered in output.
|
||||
Version 3.2.4 (2009-05-21)
|
||||
Added new paste_remove_styles/paste_remove_styles_if_webkit option to paste plugin concept contributed by Hadrien Gardeur.
|
||||
Added new functionality to paste plugin contributed by Scott Eade aka monkeybrain.
|
||||
Added new paste_block_drop option to the paste plugin this is disabled by default and will block any drag/drop event.
|
||||
Added new bind/unbind methods to DOMUtils these works like Event.add/Event.remove but is easier to access.
|
||||
Added new paste_dialog_width/paste_dialog_height options to paste pluign. Enables you to change the dialog sizes.
|
||||
Fixed bug on IE 8 where it would sometimes produce a "1 item remaining" status message that would never finish.
|
||||
Fixed bug on Safari 4 beta that would produce DOM Range exceptions on the DOMUtils split method since the browser has a bug.
|
||||
Fixed bug where the paste plugin could accidentally think that some word sentences was supposed to be list elements.
|
||||
Fixed bug where paste plugin would produce one extra empty undo level on some browsers.
|
||||
Fixed bug where spans wasn't produced correctly on new line when the keep_styles option was enabled.
|
||||
Fixed bug where the caret would be placed at the beginning of contents in IE 8 if you selected colors from the color pickers.
|
||||
Fixed so the Event class is a normal class instead of a static one. The tinymce.dom.Event is now a global instance of that class.
|
||||
Fixed so internal events for instances gets removed when the DOMUtils instance is removed.
|
||||
Fixed so preventDefault and stopPropagation methods can be used on the event object in all browsers.
|
||||
Version 3.2.3.1 (2009-05-05)
|
||||
Fixed bug where paragraphs containing form elements such as input or textarea would be removed.
|
||||
Fixed bug where some IE versions would produce a wrapper function for events attributes.
|
||||
Fixed bug where table cell contents could be removed if you pressed return/enter at the end of the cell contents.
|
||||
Fixed bug where the paste plugin would remove a extra character if the selection range was collapsed.
|
||||
Fixed bug where creating tables with % width wouldn't be handled correctly on WebKit browsers.
|
||||
Version 3.2.3 (2009-04-23)
|
||||
Added new paste plugin logic. This new version will autodetect Word contents and clean it up.
|
||||
Added a optional root element argument to getPos so you can tell it where to stop the calculation.
|
||||
Added new DOM ready logic to remove the usage of document.write. We now use basically the same method as jQuery.
|
||||
Fixed bug where WebKit browsers would fail when selecting all contents in the area using Ctrl+A.
|
||||
Fixed bug where IE would produce paragraphs with empty inline style elements.
|
||||
Fixed bug where WebKit browsers would fail when inserting tables with a non pixel width.
|
||||
Fixed bug where block elements could get a redundant br element at the end of the element.
|
||||
Fixed bug where the tabfocus plugin only worked with a single editor instance on page.
|
||||
Fixed bug where IE 8 was loosing caret position if the selection was collapsed and a menu was clicked.
|
||||
Fixed bug with application/xhtml+xml mode where menus wasn't working properly.
|
||||
Fixed bug where the onstop workaround fix for IE would produce errors in an ASP update panel.
|
||||
Fixed bug where the submit function override could produce errors if executed in the wrong scope.
|
||||
Fixed bug where the area element wasn't closed by a short ending.
|
||||
Fixed various number issues in the style plugins properties dialog. Contributed by datpaulchen.
|
||||
Fixed issues with size suffix values in the style plugin dialog.
|
||||
Fixed issue where hasDuplicate variable would leak out to the global space due to a bug in the Sizzle engine.
|
||||
Fixed issue where the paste event would fire a dialog warning on IE since we extracted the text contents.
|
||||
Updated Sizzle engine to the latest version, this version fixes a few bugs that was reported.
|
||||
Version 3.2.2.3 (2009-03-26)
|
||||
Fixed regression bug with the getPos method, it would return invalid if the view port was to small.
|
||||
Version 3.2.2.2 (2009-03-25)
|
||||
Fixed so the DOMUtils getPos method can be used cross documents if needed.
|
||||
Fixed bug where undo/redo wasn't working correctly in Gecko browsers.
|
||||
Version 3.2.2.1 (2009-03-19)
|
||||
Added support for tel: URL prefixes. Even though this doesn't match any official RFC.
|
||||
Fixed so the select method of the Selection class selects the first best suitable contents.
|
||||
Fixed bug where the regexps for www. prefixes for link and advlink dialogs would match wwwX.
|
||||
Fixed bug where the preview dialog would fail to open if the content_css wasn't defined. Patch contributed by David Bildström (ChronoZ).
|
||||
Fixed bug where editors wasn't converted in application/xhtml+xml mode due to an issue with Sizzle.
|
||||
Fixed bug where alignment would fail if multiple lines where selected.
|
||||
Updated Sizzle engine to the latest version, this version fixes a few bugs that was reported.
|
||||
Version 3.2.2 (2009-03-05)
|
||||
Added new CSS selector engine. Sizzle the same one that jQuery and other libraries are using.
|
||||
Added new is and getParents methods to the DOMUtils class. These use the new Sizzle engine to select elements.
|
||||
Added new removeformat_selector option, enables you to specify a CSS selector pattern of elements to remove when using removeformat.
|
||||
Fixed so the getParent method can take CSS expressions when selecting it's parents.
|
||||
Added new ant based build process, includes a new javabased preprocessor and a yuicompressor ant task.
|
||||
Moved the tab_focus logic into a plugin called tabfocus, so the old tab_focus option has been removed from the core.
|
||||
Replaced the TinyMCE custom unit testing framework with Qunit and rewrote all tests to match the new logic.
|
||||
Moved the examples/testcases to a root directory called tests since it now includes slickspeed.
|
||||
Fixed bug where nbsp wasn't replaced correctly in ForceBlocks.js. Patch contributed by thorn.
|
||||
Fixed bug where an dom exception would be thrown in Gecko when the theme_advanced_path path was set to false under xml application mode.
|
||||
Fixed bug where it was impossible to get out of a link at the end of a block element in Gecko.
|
||||
Fixed bug where the latest WebKit nightly would fail when changing font size and font family.
|
||||
Fixed bug where the latest WebKit nightly would fail when opening dialogs due to changes to the arguments object.
|
||||
Fixed bug where paragraphs wasn't added to elements positioned absolute using classes.
|
||||
Fixed bug where font size values with dot's like 1.4em would produce a class instead of the style value.
|
||||
Fixed bug where IE 8 would return an incorrect position for elements.
|
||||
Fixed bug where IE 8 would render colorpicker/filepicker icons incorrectly.
|
||||
Fixed bug where trailing slashes for directories in URLs would be removed.
|
||||
Fixed bug where autostart and other boolean values in the media dialog wouldn't be stored/parsed correctly.
|
||||
Fixed bug where the repaint call for the media plugin wouldn't be executed due to a typo in the source.
|
||||
Fixed bug where id attribute of object elements wasn't kept intact by the media plugin.
|
||||
Fixed bug where preview of embeded elements when the media_use_script option was used would fail.
|
||||
Fixed bug where inlinepopups could be rendered at an incorrect location on IE 6 while dragging.
|
||||
Fixed bug where the blocker shim could be placed at an incorrect location on IE 6.
|
||||
Fixed bug where the multiple and size attributes of select elements would produce incorrect values while running in IE.
|
||||
Fixed bug where IE would loose the caret position is you selected a color from the color drop down.
|
||||
Fixed bug where remove format wouldn't work on IE since it couldn't remove span elements that had style information.
|
||||
Fixed bug where Opera was removing links when removing formatting from selected contents.
|
||||
Fixed bug where paragraphs could be produced inside non positional elements styled with the CSS position value of static.
|
||||
Fixed bug where removeformat wouldn't work if you selected part of a span in IE.
|
||||
Fixed bug where media plugin didn't retain the style attribute on embed/object elements.
|
||||
Fixed bug where auto focus on empty editor instances could produce strange results if you inserted an image into it.
|
||||
Fixed bug where characters would be removed in FF when inserted with the mceInsertContent or selection.setContent methods.
|
||||
Fixed bug where warning message of missing paste support wasn't displayed on WebKit browsers.
|
||||
Fixed bug where anchor links could include other links. The selected range is now unlinked before adding news links to it.
|
||||
Fixed memory leak when TinyMCE was used with prototype. Patch contributed by James Ots.
|
||||
Fixed so the non documented fullpage_hide_in_source_view option for the fullpage plugin works again in the 3.x branch.
|
||||
Fixed so tables doesn't get inserted into paragraphs by default since it's not W3C valid. Can be disabled by using the fix_table_elements option.
|
||||
Fixed so the source view dialog sets a source_view state to the event object. Enables plugins to intercept the source view mode.
|
||||
Fixed various validation issues with the html dialogs and pages.
|
||||
Removed ask mode option since there is way better ways of doing this now. Use the add/remove control methods instead.
|
||||
Removed logic for compatibility with Safari 2.x, this browser is no longer supported since no one is using it.
|
||||
Removed the auto domain relaxing feature. If loading scripts cross sub domains it's better to specify the document.domain by hand.
|
||||
Version 3.2.1.1 (2008-11-27)
|
||||
Added new theme_advanced_default_background_color/theme_advanced_default_foreground_color options. Patch contributed by David Bildström (ChronoZ).
|
||||
Fixed font style formatting compatibility issue with Adobe Air.
|
||||
Fixed so legacy font elements get converted into spans even if cleanup_on_startup isn't enabled.
|
||||
Fixed bug where pre elements could be incorrectly modified by an IE bug workaround. Patch contributed by hu vime.
|
||||
Fixed bug where input elements inside inlinepopups wasn't editable in Firefox 2.
|
||||
Fixed bug where the xhtmlxtras plugin wasn't replacing attribute values correctly.
|
||||
Fixed bug where menu buttons in skin variants would look strange due to IE 8 fixes.
|
||||
Fixed bug where WebKit browsers would on backspace take you back to the previous page if the editor was empty.
|
||||
Fixed bug where DOMUtils decode method wouldn't handle strings larger than 4096kb due to node chunking.
|
||||
Fixed bug where meta key wasn't handled as ctrl key on Mac OS X for custom keyboard short cuts.
|
||||
Fixed bug where init event would get fired twice on WebKit on Mac OS X.
|
||||
Version 3.2.1 (2008-11-04)
|
||||
Added support for custom icon image for drop menus. Use icon_src to set a custom image directly.
|
||||
Added new media_strict option to media plugin. Enables you to control if the flash embed is strict or not. Enabled by default.
|
||||
Fixed so the editors script files gets dynamically loaded without using XHR or eval.
|
||||
Fixed so the media plugin outputs valid XHTML object elements for Flash movies. Can be disabled with the media_strict option.
|
||||
Fixed so dynamic loading doesn't require eval calls on non IE browsers for better Air support.
|
||||
Fixed bug where the editor wasn't treated as empty if the remaining paragraph had attributes.
|
||||
Fixed bug where id's of elements was removed ones they got wrapped in paragraphs. Patch contributed by ChronoZ.
|
||||
Fixed bug where WebKit browsers where placing list elements inside paragraph elements.
|
||||
Fixed bug where inserting images or links would produce absolute urls on WebKit browsers.
|
||||
Fixed bug where values for checked, readonly, disabled and selected attributes was incorrect on IE.
|
||||
Fixed bug where positive values for checked, readonly, disabled and selected attributes wasn't forced to valid values.
|
||||
Fixed bug where selecting the first option in a native select box would produce an undefined error.
|
||||
Fixed bug where tabindex 32768 could be outputted on IE if element attributes where cloned.
|
||||
Fixed bug where the media dialogs preview window would display incorrect contents due to duplicate clsid prefixes.
|
||||
Fixed bug where non pixel or percent heights for textarea elements would produce errors on IE.
|
||||
Fixed bug where cdata sections in script elements wasn't handled correctly.
|
||||
Fixed bug where nowrap of table cells would produce a 65535 value output.
|
||||
Fixed bug where media plugin would produce an error if you selected the first item in the items list.
|
||||
Fixed bug where media plugin would modify links with the item _value in them.
|
||||
Fixed so table width/height is better forced if inline_styles is enabled. Patch contributed by daKmoR.
|
||||
Fixed css for IE 8 such as opacity and other rendering quirks.
|
||||
Version 3.2.0.2 (2008-10-02)
|
||||
Fixed bug where the SelectBox and NativeSelectBox wasn't updated correctly if undefined was passed to them.
|
||||
Fixed bug where the style dropdown wasn't correctly changed back to it's original state when element had no class.
|
||||
Fixed bug where multiple pending font styles wasn't handled correctly.
|
||||
Fixed so you can disable all auto css loading for dialogs by setting the popups_css option to false.
|
||||
Version 3.2.0.1 (2008-09-17)
|
||||
Fixed bug where font sizes and faces wouldn't be changed correctly when there was a parent with a different style.
|
||||
Fixed bug where adding fonts to the same selection would produce redundant spans.
|
||||
Version 3.2 (2008-09-11)
|
||||
Added new text style support, it will now use span elements internally instead of font elements.
|
||||
Added new improved support for the theme_advanced_font_sizes option, check the Wiki for details.
|
||||
Added new keep_style setting that maintains the text style on return/enter on non IE browsers, enabled by default.
|
||||
Added new onBeforeSetContent/onBeforeGetContent/onSetContent/onGetContent events to the Selection class.
|
||||
Added new selectByIndex method to ListBox class. This enables you to select list items by an index instead of a value.
|
||||
Added new possibility to the select method of the ListBox class. This can now have a selector function as it's value argument.
|
||||
Added new possibility to skip the loading of popups css by setting the feature popup_css to the value false.
|
||||
Added new possibility to skip translation of popups by setting the translate_i18n feature to false.
|
||||
Added new element_format option enables you to produce HTML element endings instead of XHTML. But we are still in the XHTML is better camp.
|
||||
Added missing allowfullscreen and quality options for flash elements, this will now get correctly stored.
|
||||
Fixed bug where table cell dialog didn't close properly unless the accessibility_warnings option was set to false.
|
||||
Fixed bug where the modal dialog blocker element for inlinepopups wasn't placed at a correct location if the page had scroll.
|
||||
Fixed bug where non inline dialogs didn't close correctly if the inlinepopups plugin was used.
|
||||
Fixed bug where non inline dialogs could make the modal dialog blocker to work incorrectly.
|
||||
Fixed bug where style select wasn't populated correctly if you pressed the arrow. Patch by Hari Karam Singh.
|
||||
Fixed bug where toggling the fullscreen mode didn't restore scrollbars on IE when the editor was inside a frame. Patch by Jacob Barrett.
|
||||
Fixed bug where inserting flash contents using the template plugin didn't work correctly.
|
||||
Fixed bug where inserting flash contents using the selection.setContent or mceInsertContent command didn't work correctly.
|
||||
Fixed bug where IE would produce an exception if a comment started with -.
|
||||
Fixed bug where the blockquote button would wrap lists incorrectly on non IE browsers.
|
||||
Fixed bug where Opera would display BR elements in the element path.
|
||||
Fixed bug where xhtmlxtras didn't insert elements correctly on IE.
|
||||
Fixed bug where the buttons wasn't activated correctly in the xhtmlxtras plugin.
|
||||
Fixed bug where adding an object as the style attribute for the dom setAttribs method wouldn't work.
|
||||
Fixed bug where the background color would bleed out to parent container element in Gecko.
|
||||
Fixed bug where the insert column actions for tables would fail if you did it in a thead or tfoot. Patch contributed by T Andersen (tan73).
|
||||
Fixed bug where event blocker element wasn't positioned correctly for the inlinepopups plugin.
|
||||
Fixed bug where pasting from Office 2007 would produce an odd comment in the contents.
|
||||
Fixed bug where the paste as plain text could remove an extra character. Patch contributed by Speednet.
|
||||
Fixed bug where some characters where missing for the paste_replace_list option. Patch contributed by Speednet.
|
||||
Fixed bug where removing non existing editor instances by the mceRemoveControl command would produce an error.
|
||||
Fixed bug where meta elements with the name description would produce errors in IE.
|
||||
Fixed bug where color and background colors wouldn't be updated properly.
|
||||
Fixed bug where the createMenuButton of tinymce.ControlManager didn't implement the last class argument.
|
||||
Fixed bug where the editor_css option was relative from the TinyMCE installation directory not the current page.
|
||||
Fixed bug where elements wouldn't be padded if the element contained bogus br elements. For example TD elements.
|
||||
Fixed bug where parsing of <body > in fullpage plugin would produce an error.
|
||||
Fixed bug where relative urls with just ./ would become an empty string.
|
||||
Fixed bug where outdent button would be disabled if inline_styles where set to false.
|
||||
Fixed bug where replace with an empty search string would produce an error on IE.
|
||||
Fixed bug where restoring the overflow state of the body in fullscreen plugin running on IE would produce vertical scrollbars.
|
||||
Fixed bug where pressing return/enter in list items would sometimes move the caret the to top of the content area in FF.
|
||||
Fixed bug where the style listbox wouldn't be updated correctly if you used the use_native_selects option.
|
||||
Fixed bug where WebKit browsers would produce a div element when ending list elements using return.
|
||||
Fixed so translation of popup contents only occurs if it's needed.
|
||||
Optimized the URI object in regards or converting absolute URIs to relative URIs.
|
||||
Version 3.1.1 (2008-08-18)
|
||||
Added new getSize method to DOMUtils it will return the dimensions only of an element.
|
||||
Added new alert/confirm methods to the tinyMCEPopup class to prevent focus problems and also to shorten method calls.
|
||||
Added new plugin_preview_inline option to preview plugin to enable/disable native/inline dialogs.
|
||||
Added new readonly option. If this is set the editor will only display the contents for the user.
|
||||
Added missing tabindex and accesskey to input elements in the default valid_elements setup.
|
||||
Updated firebug lite to 1.2, to enable it use the tiny_mce_dev.js?debug=1 on the development package.
|
||||
Fixed so the preview dialog in the preview plugin uses inline dialogs/popups.
|
||||
Fixed so CDATA sections remains intact through the serialization process of the DOM tree.
|
||||
Fixed various issues with the getAttrib command. It will now return more correct values.
|
||||
Fixed bug where the embed element wasn't properly parsed in the media plugin it now supports 3 formats.
|
||||
Fixed bug where the noshade attribute was serialized incorrectly on IE.
|
||||
Fixed bug where editing an existing link element didn't force it relative.
|
||||
Fixed bug where image link creation fails on Safari if the image is aligned.
|
||||
Fixed bug where it was possible to scroll the fullscreen mode in Opera 9.50.
|
||||
Fixed bug where removal of center image alignment would fail. Patch contributed by Andrew Ozz.
|
||||
Fixed bug where inlinedialogs didn't work properly if the doctype was incorrect in IE.
|
||||
Fixed bug where cross domain loading didn't work correctly in Opera 9.50.
|
||||
Fixed bug where breaking huge text blocks with return/enter key would scroll to end of block.
|
||||
Fixed bug where replace button kept inserting the replacement text even if there is no more matches.
|
||||
Fixed bug with fullpage plugin where value wasn't set correctly. Patch contributed by Pascal Chantelois.
|
||||
Fixed bug where the dom utils setAttrib method call could produce an exception if the input was null/false.
|
||||
Fixed bug where pressing backspace would sometimes remove one extra character in Gecko browsers.
|
||||
Fixed bug where the native confirm/alert boxes would move focus to parent document if fired in dialogs.
|
||||
Fixed bug where Opera 9.50 was telling you that the selection is collapsed even when it isn't.
|
||||
Fixed bug where mceInsertContent would break up existing elements in Opera and Gecko.
|
||||
Fixed bug where TinyMCE fails to detect some keyboard combos on Mac, contributed by MattyRob.
|
||||
Fixed bug where replace all didn't move the caret to beginning of text before searching.
|
||||
Fixed bug where the oninit callback wasn't executed correctly when the strict_loading_mode option was used, thanks goes to Nicholas Oxhoej.
|
||||
Fixed bug where a access denied exception was thrown if some other script specified document.domain before loading TinyMCE.
|
||||
Fixed so setting language to empty string will skip language loading if translations are made by some backend.
|
||||
Fixed so dialog_type is automatically modal if you use the inlinepopups plugin use dialog_type : "window" to re-enable the old behavior.
|
||||
Version 3.1.0.1 (2008-06-18)
|
||||
Fixed bug where the Opera line break fix didn't work correctly on Mac OS X and Unix.
|
||||
Fixed bug where IE was producing the default value the maxlength attribute of input elements.
|
||||
Version 3.1.0 (2008-06-17)
|
||||
Fixed bug where the paste as text didn't work correctly it encoded produced paragraphs and br elements.
|
||||
Fixed bug where embed element in XHTML style didn't work correctly in the media plugin.
|
||||
Fixed bug where style elements was forced empty in IE. The will now be wrapped in a comment just like script elements.
|
||||
Fixed bug where some script elements wrapped in CDATA could fail to be serialized correctly.
|
||||
Fixed bug where FF 3 produced -moz- internal styles in some style attributes.
|
||||
Fixed bug where query strings and external URLs didn't work correctly in style attributes.
|
||||
Fixed bug where shape attribute of area elements got serialized as rect regardless of it's initial value in IE 6.
|
||||
Fixed bug where selection of elements inside layers would fail in IE since focus was moved to the document body.
|
||||
Fixed bug where pressing enter/return in an editable select box would produce an __mce_add_custom__ class value.
|
||||
Fixed bug where changing font size of text placed inside a colored text chunk would remove the parent node.
|
||||
Fixed bug where Opera 9.5 final produced a strange line break behavior due to a workaround for previous Opera versions.
|
||||
Fixed bug where text/background color would produce a strange focus problem when you tried to click on the body in IE.
|
||||
Fixed issue where selecting the title of an listbox equals the old 2.x behavior of changing the value to an empty string.
|
||||
Fixed issue where it was common for the media plugin to break if the _value attribute wasn't added for the param element.
|
||||
Fixed issue where the wrong parent editor instance might be updated if you use fullscreen mode in an incorrect way.
|
||||
Fixed issue where Safari was producing a warning about the base element not being closed correctly.
|
||||
Removed redundant form element name matching from regexp in the DOMUtils class.
|
||||
Version 3.0.9 (2008-06-02)
|
||||
Added new contextmenu_offset_x/contextmenu_offset_y options for the contextmenu plugin.
|
||||
Added cite attribute to the default rule for the blockquote element.
|
||||
Added support for using arrow keys for selection of items in listboxes.
|
||||
Added support for using arrow keys for selection of items in dropmenus.
|
||||
Fixed bug where blockformat change on elements with BR inside them didn't change correctly on Firefox.
|
||||
Fixed bug where removing table rows inside thead or tfoot would remove the whole table if it was the last one.
|
||||
Fixed bug where XHR synchronous mode didn't execute the callback handlers synchronously.
|
||||
Fixed bug where setting border to 0 didn't add border: 0 to the style attribute when using the advimage dialog.
|
||||
Fixed bug where the selection of images and table cells didn't work correctly when the editor is placed in a frame and running on IE.
|
||||
Fixed bug where the store/restore of a selection didn't work correctly in non IE browsers.
|
||||
Fixed bug where only the first element would be invalid for the invalid_elements option.
|
||||
Fixed bug where paste as plain text didn't encode the characters correctly when they where inserted.
|
||||
Fixed bug where HTML source window couldn't be maximized on Gecko when the maximizable feature was enabled.
|
||||
Fixed bug where color selection using the color picker could produce exception in IE.
|
||||
Fixed bug where font size changes could produce produce extra redundant elements.
|
||||
Fixed bug where IE could produce unknown runtime error if you replaced a image with another image from a separate frame.
|
||||
Fixed bug where the domLoaded state for the Event class wasn't set correctly if the editor was loaded dynamically using the gzip compressor.
|
||||
Fixed bug where handling of the base element for a page would produce incorrect urls. Based on a patch contributed by John LeSueur.
|
||||
Fixed bug where table constraint alert boxes was presented with an empty value and wasn't the skinned inline ones.
|
||||
Fixed bug where the onChange event wasn't fired when the form was submitted. It's now also triggered when the save method is called.
|
||||
Fixed bug where encoding set to xml didn't work as expected. It now encodes the contents into XML entities.
|
||||
Fixed bug where numrows didn't work correctly for the merge cells dialog of the table plugin.
|
||||
Fixed bug where the onGetContent event was fired even when the no_events flag was set.
|
||||
Fixed bug where the preview panels for the advimage and the media plugin could overflow on Safari and FF 3.
|
||||
Fixed bug where the editing and removal of abbr elements using the xhtmlxtras plugin working correctly on IE.
|
||||
Fixed bug where save button in the save plugin didn't work correctly on IE.
|
||||
Fixed bug where dragging layers didn't work as expected since it would snap back to it's original location if you saved.
|
||||
Fixed bug where the description of the template plugin dialog wasn't updated correctly.
|
||||
Fixed bug where the values for frame and rules in the table dialogs where swapped.
|
||||
Fixed bug where the elements like ins, del, cite, acronym and abbr didn't have the default editing style as the old 2.x branch.
|
||||
Fixed bug where ask mode would lock the focused textarea if you pressed cancel in the confirm dialog on FF 3.
|
||||
Fixed bug where ask mode would produce contents for empty textareas if you reloaded the page.
|
||||
Fixed so the onGetContent event gets the full pass through object just like the other events.
|
||||
Fixed so attributes for block elements remains the same when you change format of a element.
|
||||
Version 3.0.8 (2008-04-30)
|
||||
Fixed bug where IE would produce an error if textareas without names where converted.
|
||||
Fixed bug where editor wasn't forced empty when there was only a single br or empty paragraph left.
|
||||
Fixed bug where IE would produce an warning message if object elements where produced in the media plugins preview running on https.
|
||||
Fixed bug where new addVer function didn't handle hash items correctly. Patch contributed by Mirek Burkon.
|
||||
Fixed bug where font_size_style_values option wasn't applied correctly to fonts inside the editor.
|
||||
Fixed bug where image selection could be lost if a image was edited using context menu on IE.
|
||||
Fixed bug where style values wasn't updated properly due to an invalid regexp.
|
||||
Fixed bug where IE 6 where displaying warning message about insecure items when inserting an image while using https. Patch contributed by Norifumi Sunaoka.
|
||||
Fixed bug where IE was producing an auto save message if you selected a color from the color split button.
|
||||
Fixed bug where backspace sometimes would move the caret to the end of the previous block in Gecko.
|
||||
Fixed bug where the rowlayout manager didn't work as described in the documentation.
|
||||
Fixed bug where the default options for the fullpage plugin wasn't applied correctly.
|
||||
Fixed bug where selection would jump one character if you applied a styles to a words in non IE browsers.
|
||||
Fixed bug where undo levels wasn't added correctly if you went back in undo history and added a new event.
|
||||
Fixed bug where font size dropdown didn't mark the selected size in IE.
|
||||
Fixed bug where the size of the editor was determined using clientWidth instead of offsetWidth.
|
||||
Fixed so the onchange event doesn't fire on the initial undo level, it will also fire when the editor is blurred.
|
||||
Fixed so the advhr plugin produces XHTML valid output instead of non standard attributes.
|
||||
Fixed so blockquote gets converted into [quote] in when the bbcode plugin is enabled.
|
||||
Fixed so theme_advanced_font_sizes can be named for example Font 1=1, Font 2=2 etc.
|
||||
Fixed so editor_selector/editor_deselector can be regexps. By default only strings are allowed not part regexps like before.
|
||||
Fixed so that the version suffix is optional. It still requires the build process so you need to export it manually.
|
||||
Fixed so it's possible to tab to table cells in non Gecko browsers and also produce new rows if you tab at the end of a table. Contributed by Josh Peek.
|
||||
Version 3.0.7 (2008-04-14)
|
||||
Added new version suffix to all internal GET requests to make sure that the users cache gets cleared correctly.
|
||||
Fixed issue with isDirty returning true event if it wasn't dirty on IE due to changes in tables during initialization.
|
||||
Fixed memory leak in IE where if a page was unloaded before all images on the page was loaded it would leak.
|
||||
Fixed bug in IE where underline and strikethrough could produce an exception error message.
|
||||
Fixed bug where inserting paragraphs in totally empty table cells would produce odd effects.
|
||||
Fixed bug where layer style data wasn't updated correctly due to some performance enhancements with the DOM serializer.
|
||||
Fixed bug where it would convert the wrong element if there was two elements with the same name and id on the page.
|
||||
Fixed bug where it was possible to add style information to the body element using the style plugin.
|
||||
Fixed bug where Gecko would add an extra undo level some times due to the blur event.
|
||||
Fixed bug where the underline icon would get active if the caret was inside a link element.
|
||||
Fixed bug where merging th cells not working correctly. Patch contributed by André R.
|
||||
Fixed bug where forecolorpicker and backcolorpicker buttons where rendered incorrectly when the o2k7 skin was used.
|
||||
Fixed bug where comment couldn't contain -- since it's invalid markup. It will now at least not break on those invalid comments.
|
||||
Fixed bug where apos wasn't handled correctly in IE. It will now convert apos to ' on IE since that browser doesn't support that entity.
|
||||
Fixed bug where entities wasn't encoded correctly inside pre elements since they where protected from whitespace removal.
|
||||
Fixed bug where color split buttons where rendered incorrectly on IE6 when using the non default theme.
|
||||
Fixed so caret is placed after links ones they are created, to improve usability of the editor.
|
||||
Fixed so you can select tables by clicking on it's borders in non IE browsers to normalize the behavior.
|
||||
Fixed so the menus can be toggled by clicking once more on the icon in listboxes, menubuttons and splitbuttons based on code contributed by Josh Peek.
|
||||
Fixed so buttons can be labeled, currently only works with the default skin, so it's kind of experimental. Patch contributed by Daniel Insley.
|
||||
Fixed so forecolorpicker and backcolorpicker remembers the last selected color. Patch contributed by Shane Tomlinson.
|
||||
Fixed so that you can only execute the mceAddEditor command once for the same instance name.
|
||||
Fixed so command functions added with addCommand can pass though the call to default handles if it returns true.
|
||||
Version 3.0.6.2 (2008-04-07)
|
||||
Fixed bug where empty tables couldn't be edited correctly on non IE browsers if they where loaded into the editor.
|
||||
Fixed bug where it was impossible to resize layers correctly in IE since it thought it was an image.
|
||||
Fixed bug where an editor instance was stealing focus in IE resulting in a scroll to the editor on page reloads.
|
||||
Fixed bug where Safari was crashing on Mac OS X if you closed dialogs using the Esc key.
|
||||
Version 3.0.6.1 (2008-04-04)
|
||||
Added support for the missing mceAddFrameControl command. The input for this command has changed so consult the Wiki.
|
||||
Fixed bug where sub menus for the drop menus would leave an empty element behind.
|
||||
Fixed memory leak in IE if the editor was placed in a frame or iframe.
|
||||
Version 3.0.6 (2008-04-03)
|
||||
Added elements to the default value of valid_elements option. It now contains all XHTML strict elements and a few transitional.
|
||||
Added more accessibility fixes, it's now possible to navigate and close list boxes and split button menus with the keyboard.
|
||||
Added missing getInfo method to the contextmenu and safari plugin, this caused problems for the Drupal module.
|
||||
Added new inlinepopups_zindex option to the inlinepopups plugin so that you can configure the default start z-index.
|
||||
Added new setControlType method to the tinymce.ControlManager class. This method enables you to override the default classes.
|
||||
Added ability to specific an optional control class to use instead of the default one for the ControlManager methods. Based on concept by Josh Peek.
|
||||
Fixed bug where attribute rules for the DOM Serializer couldn't contain - or _ characters in their names.
|
||||
Fixed bug where inlinepopups event blocker and modal dialog blocker elements produced vertical scrollbars.
|
||||
Fixed bug where there was a rendering issue with quirks mode in Safari moving the resize handle to an incorrect position.
|
||||
Fixed bug with forecolor/backcolor controls on IE. Sometimes elements positioned relative will generate display errors.
|
||||
Fixed bug where a p2 was leaking out in the global name space when you selected a color from the forecolor/backcolor controls.
|
||||
Fixed bug where empty paragraphs didn't work as expected in browsers other than IE.
|
||||
Fixed bug where the load method of the tinymce.dom.ScriptLoader didn't check if the file was already loaded.
|
||||
Fixed bug where the load method for the PluginManager and ThemeManager didn't check if a plugin/theme by a specific name was all ready loaded.
|
||||
Fixed bug where the theme_advanced_link_targets option didn't work correctly with the advanced themes link dialog. Patch contributed by Arnold B.
|
||||
Fixed bug where the style command would merge classes into empty span elements.
|
||||
Fixed bug where the style command would remove empty span elements outside the current selection.
|
||||
Fixed bug where the fix for the Safari backspace bug removed all editor contents if it was filled with empty paragraphs.
|
||||
Fixed bug where alert and confirm boxes opened by the inlinepopups plugin would produce an exception if domain relaxing was used.
|
||||
Fixed bug where Safari was adding style attributes to all elements when you paste them into the editor.
|
||||
Fixed bug where the spellchecker menus was visually incorrect since the space for the non existing icon was still there.
|
||||
Fixed bug where remove_linebreaks option didn't remove line breaks inside the text contents of a element.
|
||||
Fixed bug where Safari 3.1 was introducing _mc_tmp into paragraphs due to the new querySelectorAll and a TinyMCE specific workaround.
|
||||
Fixed bug where getParam method in the Editor class was returning incorrect objects and would mess up the font drop down. Patch contributed by speednet.
|
||||
Fixed bug where the table dialog would produce an exception in IE when you edited tables since it tried to place focus in a disabled field.
|
||||
Fixed bug where class attribute on some span elements was removed on cleanup.
|
||||
Fixed bug where resizing the editor in IE could produce an exception if the editor width/height got to be a negative value.
|
||||
Fixed bug where wmv files wouldn't play since the src param was used instead of the url param.
|
||||
Fixed bug where br elements would be added here and there in Gecko. Geckos internal _moz_dirty br elements where serialized as well.
|
||||
Fixed bug where editing named anchors would produce two anchors instead of one updated one.
|
||||
Fixed bug where arrow and function keys didn't work when an noneditable element was focused within the editor.
|
||||
Fixed bug where the dispatcher could produce an exception if the listener list was altered inside an event callback.
|
||||
Fixed bug where it was impossible to totally empty the editor contents on Safari due to an mistreatment of nbsp as whitespace. Patch contributed by Andrew Ozz.
|
||||
Fixed bug where TinyMCE would not convert textareas with the same name attribute value. It will now generate an unique id for those textareas.
|
||||
Fixed bug where backspace/delete key was deleting td elements inside tables while running on Gecko.
|
||||
Fixed bug where Firefox 3.0b4 and Opera 9.26 where scrolling to the top of document when pressing return/enter.
|
||||
Fixed bug where the template plugin wasn't just inserting the mceTmpl tagged element.
|
||||
Fixed bug where the alert method of the default WindowManager implementation didn't translate input language strings like the inlinepopups dialog does.
|
||||
Fixed bugs with the backspace behavior in Gecko. The caret was placed on incorrect locations in the DOM sometimes.
|
||||
Fixed so advimage dialog and table dialogs has support for editable select boxes for the class value.
|
||||
Fixed so the media, pagebreak and spellchecker doesn't load it's default content.css file if the content_css option is set to false.
|
||||
Fixed so the paste_use_dialog option works again it's enabled by default but can be disabled on IE. Patch contributed by Speednet.
|
||||
Fixed so that the fullscreen editor is focused when switching fullscreen editing on.
|
||||
Fixed so it's possible to edit images and links inside tables using the context menu.
|
||||
Fixed so table dialogs and the advanced image dialog doesn't loose selection in IE if the dialogs where navigated/submitted with the keyboard.
|
||||
Fixed so the theme_advanced_blockformats options can have named items for example title 1=h1;title 2=h2.
|
||||
Fixed so it's possible to add a custom editor_css for the simple theme.
|
||||
Fixed quirks with directionality rtl, patch contributed by Andrew Ozz.
|
||||
Fixed so the inlinepopups default start zIndex is 300000.
|
||||
Fixed typo in media plugin Shockware is now replaced with Shockwave.
|
||||
Fixed psuedo memory leak in IE with the replaceChild method inside the DOMUtils.replace method.
|
||||
Fixed so memory is released when an editor instance is removed from page.
|
||||
Optimized the color split button menus so that they use less event handlers.
|
||||
Removed the util/mclayer.js file since it's no longer used by any of the TinyMCE dialogs and is considered deprecated.
|
||||
Version 3.0.5 (2008-03-12)
|
||||
Added new black skin variant to the o2k7 skin contributed by Stefan Moonen.
|
||||
Added new explode method to the tinymce core class. This does a split but removed whitespace it also defaults to a , delimiter.
|
||||
Added new detection logic for IE 8 standards mode into the DOMUtils class strMode can now be checked to see if that mode is on/off.
|
||||
Added new noscale option value for the scale select box for Flash in the media plugin.
|
||||
Fixed bug where the menu for the ColorSplitButton wasn't removed when the editor was removed.
|
||||
Fixed bug where font colors couldn't be edited correctly since the style of the element didn't get updated correctly.
|
||||
Fixed bug where class of elements would get lost when TinyMCE was fixing incorrect HTML markup.
|
||||
Fixed bug where table editing would produce double height values.
|
||||
Fixed bug where width style value wouldn't be removed if you switched width unit from cm/em to pixels or percent.
|
||||
Fixed bug where the search/replace input box wasn't auto focused like the other dialogs.
|
||||
Fixed bug where the old mceAddControl command would use the fullscreen settings next time it created an instance.
|
||||
Fixed bug where multiple lines where added to the target cell if you merged multiple empty cells.
|
||||
Fixed bug where drop down menus would be incorrectly positioned inside scrollable divs.
|
||||
Fixed bug where the separators of the silver skin variant didn't display correctly in IE 6.
|
||||
Fixed bug where createStyleSheet seems to load scripts at opposite order in some IE versions.
|
||||
Fixed bug where directionality could produce odd results for the UI and the dialogs.
|
||||
Fixed bug where the DOM serializer wouldn't serialize custom namespaced attributes in IE 6 using the *[*] valid elements rule.
|
||||
Fixed bug where table caption would be inserted after the thead element if you swapped a tr to be inside the thead.
|
||||
Fixed bug where the youtube detection logic for the media plugin was to generic.
|
||||
Fixed so the deprecated and undocumented theme_advanced_path_location set to none won't hide the whole statusbar.
|
||||
Fixed so most input lists can have whitespace in them they are now split using the new tinymce.explode method.
|
||||
Fixed so the popup_css and popup_css_add URLs are relative to where the current document is located.
|
||||
Fixed various bugs and quirks with the store/restore selection logic.
|
||||
Fixed so the editor starts in IE 8 standards mode but still that browser is very very buggy.
|
||||
Fixed so dialog_type set to modal will block the background and other inline windows and only give access to the front most window.
|
||||
Version 3.0.4.1 (2008-03-08)
|
||||
Fixed critical bug where it was impossible to edit images when inlinepopups where used due to lost selection in IE.
|
||||
Version 3.0.4 (2008-03-07)
|
||||
Added new option constrain_menus, this enables you to force view port constraints on all menus. Contributed by Shane Tomlinson.
|
||||
Fixed bug where table background wasn't visible inside the editor due to a default CSS rule overriding the style attribute.
|
||||
Fixed bug where links would get a null class added if no styles was used in IE.
|
||||
Fixed bug where spellchecker was auto focusing the editor in IE.
|
||||
Fixed bug where document.domain would produce invalid argument if the editor was loaded in IE6 over a network UNC path.
|
||||
Fixed bug where table height attribute was used, this is deprecated in XHTML so it now adds it as an style.
|
||||
Fixed bug where textareas with style values would produce error in IE.
|
||||
Fixed so the first element in each dialog is focused by default to enhance keyboard usage.
|
||||
Fixed so you can add a mceFocus class to elements to make it auto focused.
|
||||
Fixed so you can close dialogs using the esc key.
|
||||
Fixed so you can press return/enter to submit the action of each dialog.
|
||||
Fixed so tabbing inside an inline popups wont focus the resize anchor elements.
|
||||
Fixed so you can press ok in inline alert messages using the return/enter key.
|
||||
Fixed so textareas can be set to non px or % sizes for example em, cm, pt etc.
|
||||
Fixed so non pixel values can be used in width/height properties for tables.
|
||||
Fixed so the custom context menu can be disabled by holding down ctrl key while clicking.
|
||||
Fixed so the layout for the o2k7 skin looks better if you don't have separators before and after list boxes.
|
||||
Fixed so the sub classes get a copy of the super class constructor function to ease up type checking.
|
||||
Fixed so font sizes for the format block previews are normalized according to http://www.w3.org/TR/CSS21/sample.html (it can be overridden).
|
||||
Fixed so font sizes for h1-h6 in the default content.css is normalized according to http://www.w3.org/TR/CSS21/sample.html (it can be overridden).
|
||||
Version 3.0.3 (2008-03-03)
|
||||
Fixed bug where an error about document.domain would be thrown if TinyMCE was loaded using a different port.
|
||||
Fixed bug where mode exact would convert textareas without id or name if the elements option was omitted.
|
||||
Fixed bug where the caret could be placed at an incorrect location when backspace was used in Gecko.
|
||||
Fixed bug where local file:// URLs where converted into absolute domain URLs.
|
||||
Fixed bug where an error was produced if a editor was removed inside an editor command.
|
||||
Fixed bug where force_p_newlines didn't effect the paste plugin correctly.
|
||||
Fixed bug where the paste plugin was producing an exception on IE if you pasted contents with middots.
|
||||
Fixed bug where delete key could produce exceptions in Gecko sometimes due to the fix for the table cell bug.
|
||||
Fixed bug where the layer plugin would produce an visual add class called mceVisualAid this one is now renamed to mceItemVisualAid to mark it internal.
|
||||
Fixed bug where TinyMCE wouldn't initialize properly if ActiveX controls was disabled in IE.
|
||||
Fixed bug where tables and other elements that had visual aids on them would produce an extra space after any custom class names.
|
||||
Fixed bug where search with an empty string would produce some odd "invalid pointer" error in IE.
|
||||
Fixed bug where elements like menus where placed at incorrect positions in Opera 9.26.
|
||||
Fixed bug where IE was loosing focus of the editor when you clicked some dropmenu and if it was placed in a frame or iframe.
|
||||
Fixed bug where focus of images could be lost in IE if you focused the accessibility confirm dialog in the advimage plugin.
|
||||
Fixed bug where nestled font elements would produce odd output like missing font elements.
|
||||
Fixed bug where text colors and styles got removed if invalid_elements included the font element.
|
||||
Fixed bug where text-decoration set to underline or line-through would remove other styles from span elements.
|
||||
Fixed bug where editor contents like \n\n would be incorrectly handled and processed as real line feeds.
|
||||
Fixed bug where incorrectly encoded urls with ampersands in them would be decoded incorrectly.
|
||||
Optimized the DOMUtils decode method to be a lot faster if the string doesn't have any entities to decode.
|
||||
Version 3.0.2.1 (2008-02-26)
|
||||
Fixed alert/confirm dialogs so they display correctly.
|
||||
Version 3.0.2 (2008-02-26)
|
||||
Added new body_id option that enables you to specify the id of the body inside the editor iframe based on ideas by David Bildström (ChronoZ).
|
||||
Added new body_class option that enables you to set the class for the body of the editor iframe based on ideas by David Bildström (ChronoZ).
|
||||
Added new CSS class to the default content.css files mceForceColors that forces white background and black text can be used with the body_class option.
|
||||
Added new type parameter to the Editor.getParam function to reduce redundant logic for parsing hash tables.
|
||||
Added new isDone method to the ScriptLoaded class, this enables you to check if a script has been loaded or not.
|
||||
Added new resizeTo and resizeBy methods for the advanced theme. Can be called using tinyMCE.activeEditor.theme.resizeTo(w, h);
|
||||
Added new skin_variant option this can be used to extend existing skins with slight modifications like color.
|
||||
Added new variant of the o2k7 skin called "silver" based on a contribution made by Stefan Moonen.
|
||||
Fixed bug where the template plugin might produce errors if the template_mdate_classes wasn't configured.
|
||||
Fixed bug where the media plugin didn't convert the URLs for movies once they where inserted.
|
||||
Fixed bug where the style field for the advlink dialog didn't work correctly if you edited an existing link.
|
||||
Fixed bug where alignment of toolbars would fail in editor was uses in a quirks mode on IE, fix contributed by Peter Wood & Art Lawry.
|
||||
Fixed bug where initialization of multiple editors at the same time using the mceAddControl method would produce errors.
|
||||
Fixed bug where initialization of editors using mceAddControl command or new tinymce.Editor calls would fail during page load.
|
||||
Fixed bug where the check for domain relaxing could fail if the document.domain property was changed by another script.
|
||||
Fixed bug where textareas couldn't be named description or any other name that matches the meta elements in IE and Opera.
|
||||
Fixed bug where the element path would fail sometimes in IE due to "unknown runtime error" on innerHTML.
|
||||
Fixed bug where Safari would crash if you was hiding the editor before serializing the contents.
|
||||
Fixed bug where the editor wasn't scaled propertly in fullscreen mode using the old fullscreen_new_window option.
|
||||
Fixed bug where render method didn't load language packs in IE and Opera if you rendered an editor during page load.
|
||||
Fixed bug where resizing the browser window in fullscreen didn't resize the editor.
|
||||
Fixed bug where the blockquote command didn't move the caret inside the new empty blockquote if you used it on an empty document.
|
||||
Fixed bug where auto in a style width/height for the textarea would produce an editor with the size value of 100. Fix contributed by Shane Tomlinson.
|
||||
Fixed bug where restoration of selection at the beginning of an element could fail in Gecko.
|
||||
Fixed bug where caret restoration after a cleanup could place the it at an incorrect location.
|
||||
Fixed bug where delete key inside td elements would delete the cell in Gecko.
|
||||
Fixed so the blockquote button toggles individual lines. This behavior is a bit more like the old indentation behavior in the 2.x branch.
|
||||
Fixed so the dialog language packs only gets loaded the first time you open a dialog.
|
||||
Fixed so all classes in the whole UI is prefixed with "mce" to avoid collisions, use the skin converter to update your existing skins.
|
||||
Fixed so all classes in the inlinepopups logic is prefixed with "mce" to avoid collisions, use the skin converter to update your existing skins.
|
||||
Fixed so that the window in fullscreen mode can be resized when fullscreen_new_window option is enabled.
|
||||
Fixed so blockquote elements are formatted in the source output with an linefeed before and after it.
|
||||
Optimized the editor initialization by reducing the number of calls to getBookmark/moveToBookmark.
|
||||
Version 3.0.1 (2008-02-21)
|
||||
Added spellchecker plugin into the main package, but without any backend can be specified with the spellchecker_rpc_url option.
|
||||
Added src attribute for script elements to the default valid_elements option value.
|
||||
Added extra parameter to the class_filter callback it can now also filter out classes based on the whole CSS rule.
|
||||
Added support for domain relaxing, TinyMCE can now be loaded from an remote domain as long as they are on the same root domain.
|
||||
Added support for custom elements the new custom_elements option enables you to add non HTML elements to the editor.
|
||||
Added support for the W3C Selectors API that was added to latest nightly build of WebKit.
|
||||
Fixed bug where some object param element wasn't stored correctly using the media plugin.
|
||||
Fixed bug where Opera was scrolling to top of page is drop menus on list boxes where displayed.
|
||||
Fixed bug where IE6 was crashing if a format block was used on a container with anchor elements.
|
||||
Fixed bug where spans with font sizes wasn't handled correctly when editor was loading contents.
|
||||
Fixed bug where mode exact couldn't convert editors with name only. Id is no longer required but recommended.
|
||||
Fixed bug where the mceInsertRawHTML command produced an extra undo level.
|
||||
Fixed bug where the specific_textareas mode didn't work correctly this is the same thing as textareas now.
|
||||
Fixed bug where the values of input elements in the HTML page of dialogs pages where changed in IE.
|
||||
Fixed bug where fullscreen and fullpage plugins didn't work well together.
|
||||
Fixed bug where embed elements wasn't handled properly in the media plugin.
|
||||
Fixed bug where style information on span elements gets munged when fonts are converted to spans.
|
||||
Fixed bug where some entities in element attributes where encoded incorrectly in the latest WebKit build.
|
||||
Fixed bug where initialization would fail in IE if there where two input elements with the name submit in the form.
|
||||
Fixed bug where fullscreen mode didn't work correctly in IE when the fullscreen_new_window option was used.
|
||||
Fixed bug where invalid contents like an ul inside a p element would produce odd results in IE.
|
||||
Fixed bug where Opera 9.2x was placing the drop menus at incorrect locations if the editor was placed in a table.
|
||||
Fixed bug where Opera was producing odd results if enter/return was pressed while having forced_root_blocks disabled.
|
||||
Fixed bug where layer plugin was stealing focus in IE on initialization.
|
||||
Fixed bug where body attributes wasn't set properly in the fullpage plugin, fix contributed by Hiroaki Kawai.
|
||||
Fixed bug where insert image and insert link dialogs where producing an extra level in the undo history.
|
||||
Fixed bug where Gecko would produce an error if empty elements like <div></div> where inserted using mceInsertContent.
|
||||
Fixed bug where center alignment of images produced odd results inside table cells.
|
||||
Fixed bug where center alignment of images couldn't be toggled correctly.
|
||||
Fixed bug where alignment of images inside tables would produce double float style items in IE if the fix_table_elements option was enabled.
|
||||
Fixed bug where a variable called 'v' was polluting the global namespace. Objects tinymce and tinyMCE are the only ones allowed to be global.
|
||||
Fixed bug where insert table from context menu couldn't insert new tables inside existing tables.
|
||||
Fixed bug where Safari wouldn't produce br elements on enter when the force_br_newlines option was enabled.
|
||||
Fixed bug where switching cell type in table cell dialog would produce odd attributes in IE.
|
||||
Fixed bug where Gecko was outputting internal attributes if valid_elements where set to "*[*]".
|
||||
Fixed bug where the style plugin would produce non hex colors inside the dialog when running on Gecko.
|
||||
Fixed bug where an empty src value for insert image would remove the currently selected image if it wasn't and image element.
|
||||
Fixed bug where hidden input elements would break the logic for the tab_focus option.
|
||||
Fixed bug where save button wasn't working correctly in fullscreen mode.
|
||||
Fixed bug where the editor was forced to be placed in a form element if the save_onsavecallback option was used.
|
||||
Fixed bug where upper case param attributes wasn't parsed correctly in the media plugin.
|
||||
Fixed bug where render method of tinymce.Editor class would produce an exception if the strict_loading_mode option was omitted.
|
||||
Fixed bug where nodeChanged event could be fired while the editor was loading and there for produce an exception in FF.
|
||||
Fixed bug where no undo levels where added if the user created new table rows using the tab key on Gecko.
|
||||
Fixed bug where tables would be broken if you selected a different block format for contents withing an table cell.
|
||||
Fixed bug where the render method of the tinymce.Editor class didn't setup the tinymce.EditorManager.settings object correctly.
|
||||
Fixed bug where the advanced image dialog would go to the first tab if the alternative image was changed using the file browser link.
|
||||
Fixed bug where the forced_root_block option would produce BR elements inside empty blocks if the block wasn't a paragraph.
|
||||
Fixed bug where the forced_root_block doesn't work correctly on IE if the specified element was something else than paragraphs.
|
||||
Fixed bug where selection of images would get lost if user selected something from the context menu in IE.
|
||||
Fixed bug where the context menu plugin would pollute the global namespace with two variables p1 and p2.
|
||||
Fixed compatibility issue with Mootools, it is destroying document.getElementById on unload in IE. (Mantra: You don't own the internal objects).
|
||||
Fixed bugs where dialogs/tabs and other UI elements where rendered incorrectly in Firefox 3.
|
||||
Fixed so the auto CSS class importer is compatible with 2.x.
|
||||
Fixed so the editor UI and inlinedialogs works correctly with the YUI CSS reset package.
|
||||
Fixed so header and footer elements are forced to lower case when the fullpage plugin is used.
|
||||
Fixed so load prefixes "-" for plugins and themes isn't required if the plugin/theme was loaded by the ThemeManager/PluginManager.
|
||||
Fixed so the JSONRequest uses application/json content type to make Ruby on rails happy.
|
||||
Fixed so the CSS rule is more exact for the body in the default content.css files. Body is now defined as "body.mceContentBody" instead of just "body".
|
||||
Fixed so the tiny_mce_dev.js uses XHR instead of document.write to load scripts to resolve an issue with Opera 9.50.
|
||||
Fixed so language pack loading can be disabled by setting the language option to false. Can be useful for systems with their own language pack management.
|
||||
Version 3.0 (2008-01-30)
|
||||
Added map and area elements to the default valid_elements list and also some indentation rules.
|
||||
Fixed bug where empty paragraphs wasn't padded when loading contents.
|
||||
Fixed bug where the RowLayout manager didn't work at all.
|
||||
Fixed bug where style attribute data would get messed up in advimage dialog.
|
||||
Fixed bug where the table dialogs class select wasn't updated correctly.
|
||||
Fixed bug where elements would get extra whitespace around on insert when body was present in valid_elements.
|
||||
Fixed bug where coords attribute of the area element wasn't handled properly in IE.
|
||||
Fixed bug where Safari didn't produce BR elements on shift+return.
|
||||
Fixed bug where force blocks would cast odd invalid attribute exception in IE.
|
||||
Fixed bug where media plugin would produce extra whitespace before and after objects.
|
||||
Fixed bug where cleanup_callback could break the contents of the editor. But use the new event system instead of this option.
|
||||
Fixed bug where the tab_focus option didn't work between editor instanced. You can now tab between editors.
|
||||
Fixed bug where the load function of the ScriptLoader class didn't load single files without the load que as it was supposed to.
|
||||
Fixed bug where the execcommand_callback parameter order was incorrect. Recommendation use the new addCommand method.
|
||||
Fixed bug where range.select calls sometimes failed on some IE versions.
|
||||
Fixed bug where Safari was scrolling to top of document when enter/returned was pressed.
|
||||
Fixed bug where fullscreen_new_window option didn't work correctly.
|
||||
Fixed bug where the nonbreaking plugin inserted an space instead of an non breaking space the first time.
|
||||
Fixed bug where the visualization of non breaking spaces where visual in element path.
|
||||
Fixed so the focus is restored to the editor after inserting an custom character.
|
||||
Fixed so the isNotDirty state is set to false if a new undo level is added.
|
||||
Fixed so pointless style information for borders gets removed in IE.
|
||||
Fixed so the resize button has a se-resize cursor css value.
|
||||
Version 3.0rc2 (2008-01-18)
|
||||
Added new fix_nesting option to fix bug #1867292, this is disabled by default.
|
||||
Added new indentation option enables you to specify how much each indent/outdent call will add/remove.
|
||||
Added easier support for enabling/disabling icon columns on drop menues.
|
||||
Added new menu button control class. This control is very similar to the splitbutton but without any onclick action.
|
||||
Added support for previous tab focus (shift+tab). The tab_focus setting now takes two items next and previous element.
|
||||
Fixed bug where iframes inside the editor got removed in Firefox on initial load.
|
||||
Fixed bug where the CSS for abbr elements wasn't applied correctly in IE.
|
||||
Fixed bug where mceAddControl on element inside a hidden container produced errors.
|
||||
Fixed bug where closed anchors like <a /> produced strange results.
|
||||
Fixed bug where caret would jump to the top of the editor if enter was pressed a the end of a list.
|
||||
Fixed bug where remove editor failed if the editor wasn't properly initialized.
|
||||
Fixed bug where render call on for a non existing element produced exception.
|
||||
Fixed bug where parent window was hidden when the color picker was used in a non inlinepopups setup.
|
||||
Fixed bug where onchange event wasn't fired correctly on IE when color picker was used in dialogs.
|
||||
Fixed bug where save plugin could not save contents if the converted element wasn't an textarea.
|
||||
Fixed bug where events might be fired even after an editor instance was removed such as blur events.
|
||||
Fixed bug where an exception about undefined undo levels could be throwed sometimes.
|
||||
Fixed bug where the plugin_preview_pageurl option didn't work.
|
||||
Fixed bug where adding/removing an editor instance very fast could produce problems.
|
||||
Fixed bug where the link button was highlighted when an anchor element was selected.
|
||||
Fixed bug where the selected contents where removed if a new anchor element was added.
|
||||
Fixed bug where splitbuttons where rendered one pixel down in the default theme.
|
||||
Fixed bug where some buttons where placed at incorrect positions in the o2k7 theme.
|
||||
Fixed bug that made it impossible to visually disable a custom button that used an image instead of CSS sprites.
|
||||
Fixed bug where it wasn't possible to press delete/backspace if the editor was added+removed and re-added due to a FF bug.
|
||||
Fixed bug where an entities option with only 38,amp,60,lt,62,gt would fail in IE.
|
||||
Fixed bug where innerHTML sometimes generated unknown runtime error on IE.
|
||||
Fixed bug where content_css files wasn't loaded in the template preview iframe.
|
||||
Fixed bug where scroll position was incorrect when toggling fullscreen mode.
|
||||
Fixed bug where restoration of overflow didn't work correctly when disabling fullscreen mode in Opera.
|
||||
Fixed bug where drop menus where places at incorrect locations if the editor was placed in a scrollable container element.
|
||||
Fixed bug where hideMenu didn't hide sub menus correctly. It will now hide all menus recursively.
|
||||
Fixed so theme_advanced_path_location can be used in init options for compatibility reasons.
|
||||
Fixed so the drop menu colors matches the rest of o2k7 theme.
|
||||
Fixed so the preview example.html file is updated to the new 3.x API.
|
||||
Fixed so the margins are the same by default inside the editable area between IE and other browsers.
|
||||
Fixed so editor contents gets stored before it the onSubmit event is fired.
|
||||
Version 3.0rc1 (2008-01-08)
|
||||
Added new classes for toolbar rows in advanced theme mceToolbarRow1..n enabled you to change appearance of individual rows.
|
||||
Added auto detection for the strict_loading_mode option when running in application/xhtml+xml mode on Gecko.
|
||||
Optimized the HTML serializer by bundling some post process methods together.
|
||||
Fixed so that the toolbars have unique IDs, enables you to alter the toolbars using the ControlManager and the DOM.
|
||||
Fixed bug where delta values for dialog sizes in language packs didn't work correctly due to missing string to number casting.
|
||||
Fixed bug where paragraph generation logic didn't handle hr or table elements correctly if they where the only element.
|
||||
Fixed bug where some elements got extra linebreaks added after or before it in HTML output.
|
||||
Fixed bug where it was hard to modify existing style data on table rows and table cells.
|
||||
Fixed bug where the dom.getRect method didn't handle non pixel values correctly.
|
||||
Fixed bug where strikethrough and underline couldn't be toggled on existing span elements.
|
||||
Fixed bug where the postprocessor searched for nsbp instead of nbsp entities.
|
||||
Fixed bug where it was impossible to edit links that had child elements within them.
|
||||
Fixed bug where it was possible to click on the parent item of a submenu.
|
||||
Fixed bug where mouseover/mouseout images couldn't be removed in advimage dialog.
|
||||
Fixed bug where drop menus didn't work when running in application/xhtml+xml mode.
|
||||
Fixed bug where Opera added doctype to output in application/xhtml+xml mode.
|
||||
Fixed bug where some DOM methods didn't work correctly in the application/xhtml+xml mode.
|
||||
Fixed bug where the inlinepopups didn't work correctly in the application/xhtml+xml mode.
|
||||
Fixed bug where the ColorSplitButton didn't display correctly in the application/xhtml+xml mode.
|
||||
Fixed bug where the UI layout was incorrect on Gecko browsers when running in application/xhtml+xml mode.
|
||||
Fixed bug where the word paste plugin produced exception while running in application/xhtml+xml mode.
|
||||
Fixed bug where there wasn't any hidden input element generated for divs while running in application/xhtml+xml mode.
|
||||
Fixed bug where indentation of script/style/pre elements where incorrect.
|
||||
Fixed bug where script element contents was removed in IE.
|
||||
Fixed bug where script element contents got entity encoded.
|
||||
Fixed bug where you couldn't edit existing element styles using the styles plugin.
|
||||
Fixed bug where styles wasn't updated properly sometimes due to an performance enhancement.
|
||||
Fixed bug where font sizes couldn't be changed using the style plugin.
|
||||
Fixed bug where an error was produced in Gecko browsers when switching back from fullscreen mode.
|
||||
Fixed bug where Opera was producing br elements after elements like h3.
|
||||
Fixed bug where TinyMCE couldn't be loaded on a page using - characters in it's URL.
|
||||
Fixed bug where the editor container element was forced to have a specific name.
|
||||
Fixed bug with force_br_newlines option on Firefox, even though it should never be used (Read FAQ).
|
||||
Fixed bug where onclick event had an return true; prefix added when creating an popup.
|
||||
Fixed bug where the theme_advanced_statusbar_location option couldn't handle the value "none".
|
||||
Fixed issue with URLs with multiple at characters for example an Zope URI.
|
||||
Fixed so simple and advanced themes doesn't collide.
|
||||
Fixed so a elements gets removed when the href field is left empty, the href attribute is required in a link after all.
|
||||
Fixed so img elements gets removed when the src field is left empty, the src attribute is required for all images after all.
|
||||
Removed the indent and encode methods from the tinymce.dom.Serializer class due to performance enhancement and reduction of the API size.
|
||||
Version 3.0b3 (2007-12-14)
|
||||
Added new getElement method to Editor class, returns the element that was replaced with the editor instance.
|
||||
Added new unavailable prefix for disabled controls for accessibility reasons.
|
||||
Fixed bug where regexp patterns couldn't be used for the editor_selector/editor_deselector options.
|
||||
Fixed bug where the DOM wasn't properly initialized before the onInit event was executed in popups.
|
||||
Fixed bug where font sizes where reduced by font size actions on previous spans in Safari.
|
||||
Fixed bug where HR elements got places at the wrong location in IE.
|
||||
Fixed bug where align/justify didn't work correctly on multiple paragraphs.
|
||||
Fixed bug with missing translation for cell scope settings.
|
||||
Fixed bug where selection/caret position was lost on some table actions.
|
||||
Fixed bug where editor instances couldn't be added to hidden div elements.
|
||||
Fixed bug where list elements in Safari would get an odd ID attribute.
|
||||
Fixed bug where IE would return <html/> when the editor was completely empty.
|
||||
Fixed bug where accessibility title attribute for access keys wasn't setup properly.
|
||||
Fixed bug where forecolorpicker and backcolorpicker control names wasn't working.
|
||||
Fixed bug where inserting template content didn't work in Safari due to selection exception.
|
||||
Fixed bug where absolute URLs to remote hosts couldn't be used for background images.
|
||||
Fixed bug where mysterious span elements where produced in Safari when injecting HTML contents.
|
||||
Fixed bug where the media plugin didn't work correctly on the latest Opera 9.24.
|
||||
Fixed bug where indentation of HTML output wasn't applied to all block elements.
|
||||
Fixed bug where Safari was production DOM exception if you pressed enter in an empty editor.
|
||||
Fixed bug where media plugin didn't parse script tags correctly patch contributed by Mathieu Campagna.
|
||||
Fixed bug where the drop menus of list boxes like blockformat could produce scrolling of the page.
|
||||
Fixed bug where the drop menus where placed at an incorrect location if TinyMCE was placed in a scrollable div.
|
||||
Fixed bug where submit buttons couldn't be named submit, it's not recommended to name submit buttons submit anyway.
|
||||
Fixed bug where the stylelistbox produced an exception if there was only one class in the list box.
|
||||
Fixed bug where the stylelistbox wasn't updated correctly when the current class was removed.
|
||||
Fixed bug where the formatblock command sometimes removed the body element.
|
||||
Fixed bug where fullscreen switching in IE sometimes produced an exception when the spellchecker plugin was enabled.
|
||||
Fixed issue where FF produced an empty paragraph when the editor was completely empty.
|
||||
Fixed issue with size of image dialog in the advanced theme.
|
||||
Fixed issues with the bbcode plugin it now also handles spans and the [font] rule.
|
||||
Fixed so the style compression feature is a bit smarter to resolve issues with Opera.
|
||||
Reintroduced the remove_linebreaks option, this is enabled by default.
|
||||
Version 3.0b2 (2007-11-29)
|
||||
Added type and compact attributes to the default valid_elements list for the ul and ol elements.
|
||||
Added missing accessibility support to native list boxes in both the toolbar and dialogs.
|
||||
Added missing access key for the element path for accessibility reasons.
|
||||
Fixed support for loading themes from external URLs.
|
||||
Fixed bug where setOuterHTML didn't work correctly when multiple elements where passed to it.
|
||||
Fixed bug with visualchars plugin was moving elements around in the DOM.
|
||||
Fixed bug with DIV elements that got converted into editors on IE.
|
||||
Fixed bug with paste plugin using the old event API.
|
||||
Fixed bug where the spellchecker was removing the word when it was ignored.
|
||||
Fixed bug where fullscreen wasn't working properly.
|
||||
Fixed bug where the base href element and attribute was ignored.
|
||||
Fixed bug where redo function didn't work in IE.
|
||||
Fixed bug where content_css didn't work as previous 2.x branch.
|
||||
Fixed bug where preview dialog was throwing errors if the content_css wasn't defined.
|
||||
Fixed bug where the theme_advanced_path option didn't work like the 2.x branch.
|
||||
Fixed bug where the theme_advanced_statusbar_location was called theme_advanced_status_location.
|
||||
Fixed bug where the strict_loading_mode option didn't work if you created editors dynamically without using the EditorManager.
|
||||
Fixed bug where some language values wasn't translated such as insert and update in dialogs.
|
||||
Fixed bug where some image attributes wasn't stored correctly when inserting an image.
|
||||
Fixed bug where fullscreen mode didn't restore scrollbars when disabled.
|
||||
Fixed bug where there was no visual representation for tab focus in toolbars on IE.
|
||||
Fixed bug where HR elements wasn't treated as block elements so forced_root_block would fail on these.
|
||||
Fixed bug where autosave presented warning message even when the form was submitted normally.
|
||||
Fixed typo of openBrower it's now openBrowser in form_utils.js.
|
||||
Fixed various HTML problems like missing TD elements and duplicated doctypes.
|
||||
Fixed default values for theme_advanced_resize_horizontal, theme_advanced_resizing_use_cookie to be 2.x compatible.
|
||||
Moved spellchecker JS files into the development package.
|
||||
Removed support for theme_advanced_path_location since the theme_advanced_statusbar_location is the correct option name.
|
||||
Version 3.0b1 (2007-11-21)
|
||||
Added new tab_focus option, that enables you to specify a element id or that the next element to be focused on tab key down.
|
||||
Added new addQueryValueHandler method to the tinymce.Editor class.
|
||||
Added new class_filter option, this enables you to specify a function that can filter out CSS classes for the styles list box.
|
||||
Added support form [url=url]title[/url] to the bbcode plugin.
|
||||
Renamed the addCommandQueryState method in the tinymce.Editor class to addQueryStateHandler.
|
||||
Renamed loadQue to loadQueue, to correct spelling.
|
||||
Removed the createDOM method from the window manager and replace it with a createInstance method.
|
||||
Removed the add to beginning of class attribute parameter of the DOMUtils.addClass method.
|
||||
Fixed bug with the forced_root_block option, didn't work correctly with multiple inline elements.
|
||||
Fixed bug where image dialogs replaced the current image element with a new one even when it was updated.
|
||||
Fixed bug where the submit trigger wasn't executed when divs where converted into editor instances.
|
||||
Fixed bug where div elements that got converted into editors didn't get a hidden input element generated for them.
|
||||
Fixed bug where the the media_use_script option for the media plugin wasn't working correctly.
|
||||
Fixed bug where the font size and font family listboxes wasn't updated correctly on Safari.
|
||||
Fixed bug where the height of the fieldset in default image dialog for the advanced theme was to small.
|
||||
Fixed bug where the font sizes behaved incorrectly after a cleanup on Safari.
|
||||
Fixed bug where formatblock didn't work correctly in Safari on some elements.
|
||||
Fixed bug where template plugin didn't insert content correctly unless some options where specified.
|
||||
Fixed bug where charmap on Safari produced scrollbars.
|
||||
Fixed bug where there was white artifacts in some dialogs due to missing background color.
|
||||
Fixed bug where port was added to all external URLs if the editor was loaded from a custom port.
|
||||
Fixed bug where the context menus got duplicated on Safari 3.0.4 on Mac OS X.
|
||||
Fixed bug where dialogs like paste from word was huge on Firefox.
|
||||
Fixed bug with media plugin not working with windows media objects.
|
||||
Fixed bug where a forever loop was created if multiple instances where submitted using form.submit.
|
||||
Fixed bug with editing a table produce error in IE when inlinepopups where used.
|
||||
Fixed bug where the style plugin generated ugly looking style information in IE.
|
||||
Fixed bug where the inline dialogs that got opened while in fullscreen mode wasn't visible.
|
||||
Fixed bug where it was difficult to place the caret inside the word paste dialog.
|
||||
Fixed bug where Opera produced strange border in the word paste dialog.
|
||||
Fixed bug where viewport constraints could move a inlinepopup to a negative x, y position if the viewport was to small.
|
||||
Fixed bug where template plugin was producing an error due to a deprecated API call.
|
||||
Fixed bug where drag drop of images failed in Gecko if a document_base_url was specified.
|
||||
Fixed bug where Firefox 3 failed to apply block formats like H1-H6 it still breaks on DIVs this has been reported to bugzilla.
|
||||
Fixed bug where IE was producing a warning dialog about non secure items when running TinyMCE over HTTPS.
|
||||
Fixed bug where the onbeforeunload event was triggered when menus or dialogs where opened.
|
||||
Fixed bug where the fullscreen mode of the HTML view source box threw an error.
|
||||
Fixed bug where the mceFocus command didn't work correctly.
|
||||
Fixed bug where the selection could get lost in IE using inlinepopups.
|
||||
Fixed so the body of the editor area has the mceContentBody class just like the 2.x branch.
|
||||
Fixed so the media icon gets active when a media element is selected.
|
||||
Version 3.0a3 (2007-11-13)
|
||||
Added new experimental jQuery and Prototype framework adapters to the development package.
|
||||
Added new translation.html file for the development package. Helps with the internationalization of TinyMCE.
|
||||
Added new setup callback option, use this callback to add events to TinyMCE. This method is recommended over the old callbacks.
|
||||
Added new API documetation to all classes, functions, events, properties to the Wiki with examples etc.
|
||||
Added new init method to all plugins and themes, since it's shorter to write and it mimics interface capable languages better.
|
||||
Fixed various CSS issues in the default skin such as alignment of split buttons and separators.
|
||||
Fixed issues with mod_security. It didn't like that a content type of text/javascript was forced in a XHR.
|
||||
Fixed all events so that they now pass the sender object as it's first argument.
|
||||
Fixed some DOM methods so they now can take an array as input.
|
||||
Fixed so addButton and the methods of the ControlManager uses less arguments and it now uses a settings object instead.
|
||||
Fixed various issues with the tinymce.util.URI class.
|
||||
Fixed bug in IE and Safari and the on demand gzip loading feature.
|
||||
Fixed bug with moving inline windows sometimes failed in IE6.
|
||||
Fixed bug where save_callback function wasn't executed at all.
|
||||
Fixed bug where inlinepopups produces scrollbars if windows where moved to the corners of the browser.
|
||||
Fixed bug where view HTML source failed when inserting a embedded media object.
|
||||
Fixed bug where the listbox menus didn't display correctly on IE6.
|
||||
Fixed bug where undo level wasn't added when editor was blurred.
|
||||
Fixed bug where spellchecker wasn't disabled when fullscreen mode was enabled.
|
||||
Fixed bug where Firefox could crash some times when the user switched to fullscreen mode.
|
||||
Fixed bug where tinymce.ui.DropMenu didn't remove all item data when an item was removed from the menu.
|
||||
Fixed bug where anchor list in advlink dialog wasn't populated correctly in Safari.
|
||||
Fixed bug where it wasn't possible to edit tables in IE when inlinepopups was enabled.
|
||||
Fixed bug where it wasn't possible to change the table width of an existing table.
|
||||
Fixed bug where xhtmlxtras like abbr didn't work correctly on IE.
|
||||
Fixed bug where IE6 had some graphics rendering issues with the inlinepopups.
|
||||
Fixed bug where inlinepopup windows where moved incorrectly when they were boundary checked for min width.
|
||||
Fixed bug where textareas without id or name couldn't be converted into editor instances.
|
||||
Fixed bug where TinyMCE was stealing element focus on IE.
|
||||
Fixed bug where the getParam method didn't handle false values correctly.
|
||||
Fixed bug where inlinepopups was clipped by other TinyMCE instances or relative elements in IE.
|
||||
Fixed bug where the contextmenu was clipped by other TinyMCE instances or relative elements in IE.
|
||||
Fixed bug where listbox menus was clipped by other TinyMCE instances or relative elements in IE.
|
||||
Fixed bug where listboxes wasn't updated correctly when the a value wasn't found by select.
|
||||
Fixed various CSS issues that produced odd rendering bugs in IE.
|
||||
Fixed issues with tinymce.ui.DropMenu class, it required some optional settings to be specified.
|
||||
Fixed so multiple blockquotes can be removed with a easier method than before.
|
||||
Optimized some of the core API to boost performance.
|
||||
Removed some functions from the core API that wasn't needed.
|
||||
Version 3.0a2 (2007-11-02)
|
||||
Fixed critical bug where IE generaded an error on a hasAttribute call in the serialization engine.
|
||||
Fixed critical bug where some dialogs didn't open in the non dev package.
|
||||
Fixed bug when using the theme_advanced_styles option. Error was thrown in some dialogs.
|
||||
Fixed bug where the close buttons produced an error when native windows where used.
|
||||
Fixed bug in default skin so that split buttons gets activated correctly.
|
||||
Fixed so plugins can be loaded from external urls outsite the plugins directory.
|
||||
Version 3.0a1 (2007-11-01)
|
||||
Rewrote the core and most of the plugins and themes from scratch.
|
||||
Added new and improved serialization engine, faster and more powerful.
|
||||
Added new internal event system, things like editor.onClick.add(func).
|
||||
Added new inlinepopups plugin, the dialogs are now skinnable and uses clearlooks2 as default.
|
||||
Added new contextmenu plugin, context menus can now have submenus and plugins can add items on the fly.
|
||||
Added new skin support for the simple and advanced themes you can alter the whole UI using CSS.
|
||||
Added new o2k7 skin for the simple and advanced themes.
|
||||
Added new custom list boxes for font size/format/style etc with preview support.
|
||||
Added new UI management, enabled plugins to create controls like splitbuttons or menus easier.
|
||||
Added new JSON parser/serializer and JSON-RPC class to the core API.
|
||||
Added new cookie utility class to the core API.
|
||||
Added new Unit testing class to the core API only available in dev mode.
|
||||
Added new firebug lite integration when loading the dev version of TinyMCE.
|
||||
Added new Safari plugin, fixes lots compatibility of issues with Safari 3.x.
|
||||
Added new URI/URL parsing it now handles the hole RFC and even some exceptions.
|
||||
Added new pagebreak plugin, enables you to insert pagebreak comments like <!-- pagebreak -->
|
||||
Added new on demand loading of plugins and themes. Enables you to load and init TinyMCE at any time.
|
||||
Added new throbber/progress visualization a plugin can show/hide this when it's needed.
|
||||
Added new blockquote button. Enables you to wrap paragraphs in blockquotes.
|
||||
Added new compat2x plugin. Will provide a TinyMCE 2.x API for older plugins.
|
||||
Added new theme_advanced_resizing_min_width, theme_advanced_resizing_min_height options.
|
||||
Added new theme_advanced_resizing_max_height, theme_advanced_resizing_max_height options.
|
||||
Added new use_native_selects option. Enables you to toggle native listboxes on and off.
|
||||
Added new docs_url option enables you to specify where the TinyMCE user documentation is located.
|
||||
Added new frame and rules options for the table dialog.
|
||||
Added new global rule for valid_elements/extended_valid_elements enables you to specify global attributes for all elements.
|
||||
Added new deny attribute rule characher so it's possible to deny global attribute rules on specific elements.
|
||||
Added new unit tests in the dev package of TinyMCE. Runs tests on the core API, commands and settings of the editor.
|
||||
Readded the inline_styles option and enabled it by default so deprecated attributes are no longer used.
|
||||
Removed all button images and replaced them with CSS sprite images. Reduces the number of requests needed.
|
||||
Removed lots of language files and merged them into the base language files. Reduces the number of requests needed.
|
||||
Removed lots of unnecessary files and merged many of them together to reduce requests and improve loading speed.
|
||||
Reduced the over all script size by 33% and the number of files/requests by 75% so it loads a lot faster.
|
||||
Fixed so convert_fonts_to_spans are enabled by default. So no more font tags.
|
||||
Fixed so underline and strikethrough uses spans instread of deprecated U and STRIKE elements.
|
||||
Fixed so indent/outdent adds/removed margin-left instead of blockquotes.
|
||||
Fixed so alignment of paragraphs results in a text-align style value instead of the deprecated align attribute.
|
||||
Fixed so alignment of images uses float or vertical-align style values instead of the deprecated align attribute.
|
||||
Fixed so all classes from @import stylesheets gets imported into the editor.
|
||||
Fixed so the directionality can toggle the dir attribute on and off.
|
||||
Fixed so the fullscreen_settings can be used for all types of fullscreen modes.
|
||||
Fixed so the advanced HR dialog gets displayed when inserting a HR not only on edit.
|
||||
Fixed bug where word wrap didn't work in the source editor on Safari.
|
||||
Fixed so non HTML elements can be used within the editor such as <myns:tag>
|
||||
Fixed various memory leaks in IE and reduced the unload cleanups needed.
|
||||
Fixed so the preformatted option adds an invisible container pre tag inside the editor.
|
||||
Renamed the _template plugin to example and updated it to use the new 3.x API.
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;if(tinyMCE.isIE){return}a.onKeyDown.add(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng().cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();
|
||||
(function(){tinymce.create("tinymce.plugins.AutolinkPlugin",{init:function(a,b){var c=this;a.onKeyDown.addToTop(function(d,f){if(f.keyCode==13){return c.handleEnter(d)}});if(tinyMCE.isIE){return}a.onKeyPress.add(function(d,f){if(f.which==41){return c.handleEclipse(d)}});a.onKeyUp.add(function(d,f){if(f.keyCode==32){return c.handleSpacebar(d)}})},handleEclipse:function(a){this.parseCurrentLine(a,-1,"(",true)},handleSpacebar:function(a){this.parseCurrentLine(a,0,"",true)},handleEnter:function(a){this.parseCurrentLine(a,-1,"",false)},parseCurrentLine:function(i,d,b,g){var a,f,c,n,k,m,h,e,j;a=i.selection.getRng(true).cloneRange();if(a.startOffset<5){e=a.endContainer.previousSibling;if(e==null){if(a.endContainer.firstChild==null||a.endContainer.firstChild.nextSibling==null){return}e=a.endContainer.firstChild.nextSibling}j=e.length;a.setStart(e,j);a.setEnd(e,j);if(a.endOffset<5){return}f=a.endOffset;n=e}else{n=a.endContainer;if(n.nodeType!=3&&n.firstChild){while(n.nodeType!=3&&n.firstChild){n=n.firstChild}a.setStart(n,0);a.setEnd(n,n.nodeValue.length)}if(a.endOffset==1){f=2}else{f=a.endOffset-1-d}}c=f;do{a.setStart(n,f-2);a.setEnd(n,f-1);f-=1}while(a.toString()!=" "&&a.toString()!=""&&a.toString().charCodeAt(0)!=160&&(f-2)>=0&&a.toString()!=b);if(a.toString()==b||a.toString().charCodeAt(0)==160){a.setStart(n,f);a.setEnd(n,c);f+=1}else{if(a.startOffset==0){a.setStart(n,0);a.setEnd(n,c)}else{a.setStart(n,f);a.setEnd(n,c)}}var m=a.toString();if(m.charAt(m.length-1)=="."){a.setEnd(n,c-1)}m=a.toString();h=m.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])){h[1]="mailto:"+h[1]}}k=i.selection.getBookmark();i.selection.setRng(a);tinyMCE.execCommand("createlink",false,h[1]+h[2]);i.selection.moveToBookmark(k);if(tinyMCE.isWebKit){i.selection.collapse(false);var l=Math.min(n.length,c+1);a.setStart(n,l);a.setEnd(n,l);i.selection.setRng(a)}}},getInfo:function(){return{longname:"Autolink",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("autolink",tinymce.plugins.AutolinkPlugin)})();
|
||||
|
|
@ -1,174 +1,180 @@
|
|||
/**
|
||||
* editor_plugin_src.js
|
||||
*
|
||||
* Copyright 2011, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://tinymce.moxiecode.com/license
|
||||
* Contributing: http://tinymce.moxiecode.com/contributing
|
||||
*/
|
||||
|
||||
(function() {
|
||||
tinymce.create('tinymce.plugins.AutolinkPlugin', {
|
||||
/**
|
||||
* Initializes the plugin, this will be executed after the plugin has been created.
|
||||
* This call is done before the editor instance has finished it's initialization so use the onInit event
|
||||
* of the editor instance to intercept that event.
|
||||
*
|
||||
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
|
||||
* @param {string} url Absolute URL to where the plugin is located.
|
||||
*/
|
||||
|
||||
init : function(ed, url) {
|
||||
var t = this;
|
||||
|
||||
// Internet Explorer has built-in automatic linking
|
||||
if (tinyMCE.isIE)
|
||||
return;
|
||||
|
||||
// Add a key down handler
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
if (e.keyCode == 13)
|
||||
return t.handleEnter(ed);
|
||||
});
|
||||
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
if (e.which == 41)
|
||||
return t.handleEclipse(ed);
|
||||
});
|
||||
|
||||
// Add a key up handler
|
||||
ed.onKeyUp.add(function(ed, e) {
|
||||
if (e.keyCode == 32)
|
||||
return t.handleSpacebar(ed);
|
||||
});
|
||||
},
|
||||
|
||||
handleEclipse : function(ed) {
|
||||
this.parseCurrentLine(ed, -1, '(', true);
|
||||
},
|
||||
|
||||
handleSpacebar : function(ed) {
|
||||
this.parseCurrentLine(ed, 0, '', true);
|
||||
},
|
||||
|
||||
handleEnter : function(ed) {
|
||||
this.parseCurrentLine(ed, -1, '', false);
|
||||
},
|
||||
|
||||
parseCurrentLine : function(ed, end_offset, delimiter, goback) {
|
||||
var r, end, start, endContainer, bookmark, text, matches, prev, len;
|
||||
|
||||
// We need at least five characters to form a URL,
|
||||
// hence, at minimum, five characters from the beginning of the line.
|
||||
r = ed.selection.getRng().cloneRange();
|
||||
if (r.startOffset < 5) {
|
||||
// During testing, the caret is placed inbetween two text nodes.
|
||||
// The previous text node contains the URL.
|
||||
prev = r.endContainer.previousSibling;
|
||||
if (prev == null) {
|
||||
if (r.endContainer.firstChild == null || r.endContainer.firstChild.nextSibling == null)
|
||||
return;
|
||||
|
||||
prev = r.endContainer.firstChild.nextSibling;
|
||||
}
|
||||
len = prev.length;
|
||||
r.setStart(prev, len);
|
||||
r.setEnd(prev, len);
|
||||
|
||||
if (r.endOffset < 5)
|
||||
return;
|
||||
|
||||
end = r.endOffset;
|
||||
endContainer = prev;
|
||||
} else {
|
||||
endContainer = r.endContainer;
|
||||
|
||||
// Get a text node
|
||||
if (endContainer.nodeType != 3 && endContainer.firstChild) {
|
||||
while (endContainer.nodeType != 3 && endContainer.firstChild)
|
||||
endContainer = endContainer.firstChild;
|
||||
|
||||
r.setStart(endContainer, 0);
|
||||
r.setEnd(endContainer, endContainer.nodeValue.length);
|
||||
}
|
||||
|
||||
if (r.endOffset == 1)
|
||||
end = 2;
|
||||
else
|
||||
end = r.endOffset - 1 - end_offset;
|
||||
}
|
||||
|
||||
start = end;
|
||||
|
||||
do
|
||||
{
|
||||
// Move the selection one character backwards.
|
||||
r.setStart(endContainer, end - 2);
|
||||
r.setEnd(endContainer, end - 1);
|
||||
end -= 1;
|
||||
|
||||
// Loop until one of the following is found: a blank space, , delimeter, (end-2) >= 0
|
||||
} while (r.toString() != ' ' && r.toString() != '' && r.toString().charCodeAt(0) != 160 && (end -2) >= 0 && r.toString() != delimiter);
|
||||
|
||||
if (r.toString() == delimiter || r.toString().charCodeAt(0) == 160) {
|
||||
r.setStart(endContainer, end);
|
||||
r.setEnd(endContainer, start);
|
||||
end += 1;
|
||||
} else if (r.startOffset == 0) {
|
||||
r.setStart(endContainer, 0);
|
||||
r.setEnd(endContainer, start);
|
||||
}
|
||||
else {
|
||||
r.setStart(endContainer, end);
|
||||
r.setEnd(endContainer, start);
|
||||
}
|
||||
|
||||
text = r.toString();
|
||||
matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);
|
||||
|
||||
if (matches) {
|
||||
if (matches[1] == 'www.') {
|
||||
matches[1] = 'http://www.';
|
||||
} else if (/@$/.test(matches[1])) {
|
||||
matches[1] = 'mailto:' + matches[1];
|
||||
}
|
||||
|
||||
bookmark = ed.selection.getBookmark();
|
||||
|
||||
ed.selection.setRng(r);
|
||||
tinyMCE.execCommand('createlink',false, matches[1] + matches[2]);
|
||||
ed.selection.moveToBookmark(bookmark);
|
||||
|
||||
// TODO: Determine if this is still needed.
|
||||
if (tinyMCE.isWebKit) {
|
||||
// move the caret to its original position
|
||||
ed.selection.collapse(false);
|
||||
var max = Math.min(endContainer.length, start + 1);
|
||||
r.setStart(endContainer, max);
|
||||
r.setEnd(endContainer, max);
|
||||
ed.selection.setRng(r);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns information about the plugin as a name/value array.
|
||||
* The current keys are longname, author, authorurl, infourl and version.
|
||||
*
|
||||
* @return {Object} Name/value array containing information about the plugin.
|
||||
*/
|
||||
getInfo : function() {
|
||||
return {
|
||||
longname : 'Autolink',
|
||||
author : 'Moxiecode Systems AB',
|
||||
authorurl : 'http://tinymce.moxiecode.com',
|
||||
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink',
|
||||
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('autolink', tinymce.plugins.AutolinkPlugin);
|
||||
})();
|
||||
/**
|
||||
* editor_plugin_src.js
|
||||
*
|
||||
* Copyright 2011, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://tinymce.moxiecode.com/license
|
||||
* Contributing: http://tinymce.moxiecode.com/contributing
|
||||
*/
|
||||
|
||||
(function() {
|
||||
tinymce.create('tinymce.plugins.AutolinkPlugin', {
|
||||
/**
|
||||
* Initializes the plugin, this will be executed after the plugin has been created.
|
||||
* This call is done before the editor instance has finished it's initialization so use the onInit event
|
||||
* of the editor instance to intercept that event.
|
||||
*
|
||||
* @param {tinymce.Editor} ed Editor instance that the plugin is initialized in.
|
||||
* @param {string} url Absolute URL to where the plugin is located.
|
||||
*/
|
||||
|
||||
init : function(ed, url) {
|
||||
var t = this;
|
||||
|
||||
// Add a key down handler
|
||||
ed.onKeyDown.addToTop(function(ed, e) {
|
||||
if (e.keyCode == 13)
|
||||
return t.handleEnter(ed);
|
||||
});
|
||||
|
||||
// Internet Explorer has built-in automatic linking for most cases
|
||||
if (tinyMCE.isIE)
|
||||
return;
|
||||
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
if (e.which == 41)
|
||||
return t.handleEclipse(ed);
|
||||
});
|
||||
|
||||
// Add a key up handler
|
||||
ed.onKeyUp.add(function(ed, e) {
|
||||
if (e.keyCode == 32)
|
||||
return t.handleSpacebar(ed);
|
||||
});
|
||||
},
|
||||
|
||||
handleEclipse : function(ed) {
|
||||
this.parseCurrentLine(ed, -1, '(', true);
|
||||
},
|
||||
|
||||
handleSpacebar : function(ed) {
|
||||
this.parseCurrentLine(ed, 0, '', true);
|
||||
},
|
||||
|
||||
handleEnter : function(ed) {
|
||||
this.parseCurrentLine(ed, -1, '', false);
|
||||
},
|
||||
|
||||
parseCurrentLine : function(ed, end_offset, delimiter, goback) {
|
||||
var r, end, start, endContainer, bookmark, text, matches, prev, len;
|
||||
|
||||
// We need at least five characters to form a URL,
|
||||
// hence, at minimum, five characters from the beginning of the line.
|
||||
r = ed.selection.getRng(true).cloneRange();
|
||||
if (r.startOffset < 5) {
|
||||
// During testing, the caret is placed inbetween two text nodes.
|
||||
// The previous text node contains the URL.
|
||||
prev = r.endContainer.previousSibling;
|
||||
if (prev == null) {
|
||||
if (r.endContainer.firstChild == null || r.endContainer.firstChild.nextSibling == null)
|
||||
return;
|
||||
|
||||
prev = r.endContainer.firstChild.nextSibling;
|
||||
}
|
||||
len = prev.length;
|
||||
r.setStart(prev, len);
|
||||
r.setEnd(prev, len);
|
||||
|
||||
if (r.endOffset < 5)
|
||||
return;
|
||||
|
||||
end = r.endOffset;
|
||||
endContainer = prev;
|
||||
} else {
|
||||
endContainer = r.endContainer;
|
||||
|
||||
// Get a text node
|
||||
if (endContainer.nodeType != 3 && endContainer.firstChild) {
|
||||
while (endContainer.nodeType != 3 && endContainer.firstChild)
|
||||
endContainer = endContainer.firstChild;
|
||||
|
||||
r.setStart(endContainer, 0);
|
||||
r.setEnd(endContainer, endContainer.nodeValue.length);
|
||||
}
|
||||
|
||||
if (r.endOffset == 1)
|
||||
end = 2;
|
||||
else
|
||||
end = r.endOffset - 1 - end_offset;
|
||||
}
|
||||
|
||||
start = end;
|
||||
|
||||
do
|
||||
{
|
||||
// Move the selection one character backwards.
|
||||
r.setStart(endContainer, end - 2);
|
||||
r.setEnd(endContainer, end - 1);
|
||||
end -= 1;
|
||||
|
||||
// Loop until one of the following is found: a blank space, , delimeter, (end-2) >= 0
|
||||
} while (r.toString() != ' ' && r.toString() != '' && r.toString().charCodeAt(0) != 160 && (end -2) >= 0 && r.toString() != delimiter);
|
||||
|
||||
if (r.toString() == delimiter || r.toString().charCodeAt(0) == 160) {
|
||||
r.setStart(endContainer, end);
|
||||
r.setEnd(endContainer, start);
|
||||
end += 1;
|
||||
} else if (r.startOffset == 0) {
|
||||
r.setStart(endContainer, 0);
|
||||
r.setEnd(endContainer, start);
|
||||
}
|
||||
else {
|
||||
r.setStart(endContainer, end);
|
||||
r.setEnd(endContainer, start);
|
||||
}
|
||||
|
||||
// Exclude last . from word like "www.site.com."
|
||||
var text = r.toString();
|
||||
if (text.charAt(text.length - 1) == '.') {
|
||||
r.setEnd(endContainer, start - 1);
|
||||
}
|
||||
|
||||
text = r.toString();
|
||||
matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|[A-Z0-9._%+-]+@)(.+)$/i);
|
||||
|
||||
if (matches) {
|
||||
if (matches[1] == 'www.') {
|
||||
matches[1] = 'http://www.';
|
||||
} else if (/@$/.test(matches[1])) {
|
||||
matches[1] = 'mailto:' + matches[1];
|
||||
}
|
||||
|
||||
bookmark = ed.selection.getBookmark();
|
||||
|
||||
ed.selection.setRng(r);
|
||||
tinyMCE.execCommand('createlink',false, matches[1] + matches[2]);
|
||||
ed.selection.moveToBookmark(bookmark);
|
||||
|
||||
// TODO: Determine if this is still needed.
|
||||
if (tinyMCE.isWebKit) {
|
||||
// move the caret to its original position
|
||||
ed.selection.collapse(false);
|
||||
var max = Math.min(endContainer.length, start + 1);
|
||||
r.setStart(endContainer, max);
|
||||
r.setEnd(endContainer, max);
|
||||
ed.selection.setRng(r);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns information about the plugin as a name/value array.
|
||||
* The current keys are longname, author, authorurl, infourl and version.
|
||||
*
|
||||
* @return {Object} Name/value array containing information about the plugin.
|
||||
*/
|
||||
getInfo : function() {
|
||||
return {
|
||||
longname : 'Autolink',
|
||||
author : 'Moxiecode Systems AB',
|
||||
authorurl : 'http://tinymce.moxiecode.com',
|
||||
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autolink',
|
||||
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Register plugin
|
||||
tinymce.PluginManager.add('autolink', tinymce.plugins.AutolinkPlugin);
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
||||
(function(){var a=tinymce.DOM;tinymce.create("tinymce.plugins.FullScreenPlugin",{init:function(d,e){var f=this,g={},c,b;f.editor=d;d.addCommand("mceFullScreen",function(){var i,j=a.doc.documentElement;if(d.getParam("fullscreen_is_enabled")){if(d.getParam("fullscreen_new_window")){closeFullscreen()}else{a.win.setTimeout(function(){tinymce.dom.Event.remove(a.win,"resize",f.resizeFunc);tinyMCE.get(d.getParam("fullscreen_editor_id")).setContent(d.getContent());tinyMCE.remove(d);a.remove("mce_fullscreen_container");j.style.overflow=d.getParam("fullscreen_html_overflow");a.setStyle(a.doc.body,"overflow",d.getParam("fullscreen_overflow"));a.win.scrollTo(d.getParam("fullscreen_scrollx"),d.getParam("fullscreen_scrolly"));tinyMCE.settings=tinyMCE.oldSettings},10)}return}if(d.getParam("fullscreen_new_window")){i=a.win.open(e+"/fullscreen.htm","mceFullScreenPopup","fullscreen=yes,menubar=no,toolbar=no,scrollbars=no,resizable=yes,left=0,top=0,width="+screen.availWidth+",height="+screen.availHeight);try{i.resizeTo(screen.availWidth,screen.availHeight)}catch(h){}}else{tinyMCE.oldSettings=tinyMCE.settings;g.fullscreen_overflow=a.getStyle(a.doc.body,"overflow",1)||"auto";g.fullscreen_html_overflow=a.getStyle(j,"overflow",1);c=a.getViewPort();g.fullscreen_scrollx=c.x;g.fullscreen_scrolly=c.y;if(tinymce.isOpera&&g.fullscreen_overflow=="visible"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&g.fullscreen_overflow=="scroll"){g.fullscreen_overflow="auto"}if(tinymce.isIE&&(g.fullscreen_html_overflow=="visible"||g.fullscreen_html_overflow=="scroll")){g.fullscreen_html_overflow="auto"}if(g.fullscreen_overflow=="0px"){g.fullscreen_overflow=""}a.setStyle(a.doc.body,"overflow","hidden");j.style.overflow="hidden";c=a.getViewPort();a.win.scrollTo(0,0);if(tinymce.isIE){c.h-=1}if(tinymce.isIE6||document.compatMode=="BackCompat"){b="absolute;top:"+c.y}else{b="fixed;top:0"}n=a.add(a.doc.body,"div",{id:"mce_fullscreen_container",style:"position:"+b+";left:0;width:"+c.w+"px;height:"+c.h+"px;z-index:200000;"});a.add(n,"div",{id:"mce_fullscreen"});tinymce.each(d.settings,function(k,l){g[l]=k});g.id="mce_fullscreen";g.width=n.clientWidth;g.height=n.clientHeight-15;g.fullscreen_is_enabled=true;g.fullscreen_editor_id=d.id;g.theme_advanced_resizing=false;g.save_onsavecallback=function(){d.setContent(tinyMCE.get(g.id).getContent());d.execCommand("mceSave")};tinymce.each(d.getParam("fullscreen_settings"),function(m,l){g[l]=m});if(g.theme_advanced_toolbar_location==="external"){g.theme_advanced_toolbar_location="top"}f.fullscreenEditor=new tinymce.Editor("mce_fullscreen",g);f.fullscreenEditor.onInit.add(function(){f.fullscreenEditor.setContent(d.getContent());f.fullscreenEditor.focus()});f.fullscreenEditor.render();f.fullscreenElement=new tinymce.dom.Element("mce_fullscreen_container");f.fullscreenElement.update();f.resizeFunc=tinymce.dom.Event.add(a.win,"resize",function(){var o=tinymce.DOM.getViewPort(),l=f.fullscreenEditor,k,m;k=l.dom.getSize(l.getContainer().firstChild);m=l.dom.getSize(l.getContainer().getElementsByTagName("iframe")[0]);l.theme.resizeTo(o.w-k.w+m.w,o.h-k.h+m.h)})}});d.addButton("fullscreen",{title:"fullscreen.desc",cmd:"mceFullScreen"});d.onNodeChange.add(function(i,h){h.setActive("fullscreen",i.getParam("fullscreen_is_enabled"))})},getInfo:function(){return{longname:"Fullscreen",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/fullscreen",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("fullscreen",tinymce.plugins.FullScreenPlugin)})();
|
||||
|
|
@ -79,7 +79,7 @@
|
|||
vp.h -= 1;
|
||||
|
||||
// Use fixed position if it exists
|
||||
if (tinymce.isIE6)
|
||||
if (tinymce.isIE6 || document.compatMode == 'BackCompat')
|
||||
posCss = 'absolute;top:' + vp.y;
|
||||
else
|
||||
posCss = 'fixed;top:0';
|
||||
|
|
|
|||
|
|
@ -1,951 +1,951 @@
|
|||
/**
|
||||
* editor_plugin_src.js
|
||||
*
|
||||
* Copyright 2011, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://tinymce.moxiecode.com/license
|
||||
* Contributing: http://tinymce.moxiecode.com/contributing
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var each = tinymce.each, Event = tinymce.dom.Event, bookmark;
|
||||
|
||||
// Skips text nodes that only contain whitespace since they aren't semantically important.
|
||||
function skipWhitespaceNodes(e, next) {
|
||||
while (e && (e.nodeType === 8 || (e.nodeType === 3 && /^[ \t\n\r]*$/.test(e.nodeValue)))) {
|
||||
e = next(e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
function skipWhitespaceNodesBackwards(e) {
|
||||
return skipWhitespaceNodes(e, function(e) {
|
||||
return e.previousSibling;
|
||||
});
|
||||
}
|
||||
|
||||
function skipWhitespaceNodesForwards(e) {
|
||||
return skipWhitespaceNodes(e, function(e) {
|
||||
return e.nextSibling;
|
||||
});
|
||||
}
|
||||
|
||||
function hasParentInList(ed, e, list) {
|
||||
return ed.dom.getParent(e, function(p) {
|
||||
return tinymce.inArray(list, p) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
function isList(e) {
|
||||
return e && (e.tagName === 'OL' || e.tagName === 'UL');
|
||||
}
|
||||
|
||||
function splitNestedLists(element, dom) {
|
||||
var tmp, nested, wrapItem;
|
||||
tmp = skipWhitespaceNodesBackwards(element.lastChild);
|
||||
while (isList(tmp)) {
|
||||
nested = tmp;
|
||||
tmp = skipWhitespaceNodesBackwards(nested.previousSibling);
|
||||
}
|
||||
if (nested) {
|
||||
wrapItem = dom.create('li', { style: 'list-style-type: none;'});
|
||||
dom.split(element, nested);
|
||||
dom.insertAfter(wrapItem, nested);
|
||||
wrapItem.appendChild(nested);
|
||||
wrapItem.appendChild(nested);
|
||||
element = wrapItem.previousSibling;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
function attemptMergeWithAdjacent(e, allowDifferentListStyles, mergeParagraphs) {
|
||||
e = attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs);
|
||||
return attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs);
|
||||
}
|
||||
|
||||
function attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs) {
|
||||
var prev = skipWhitespaceNodesBackwards(e.previousSibling);
|
||||
if (prev) {
|
||||
return attemptMerge(prev, e, allowDifferentListStyles ? prev : false, mergeParagraphs);
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
function attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs) {
|
||||
var next = skipWhitespaceNodesForwards(e.nextSibling);
|
||||
if (next) {
|
||||
return attemptMerge(e, next, allowDifferentListStyles ? next : false, mergeParagraphs);
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
function attemptMerge(e1, e2, differentStylesMasterElement, mergeParagraphs) {
|
||||
if (canMerge(e1, e2, !!differentStylesMasterElement, mergeParagraphs)) {
|
||||
return merge(e1, e2, differentStylesMasterElement);
|
||||
} else if (e1 && e1.tagName === 'LI' && isList(e2)) {
|
||||
// Fix invalidly nested lists.
|
||||
e1.appendChild(e2);
|
||||
}
|
||||
return e2;
|
||||
}
|
||||
|
||||
function canMerge(e1, e2, allowDifferentListStyles, mergeParagraphs) {
|
||||
if (!e1 || !e2) {
|
||||
return false;
|
||||
} else if (e1.tagName === 'LI' && e2.tagName === 'LI') {
|
||||
return e2.style.listStyleType === 'none' || containsOnlyAList(e2);
|
||||
} else if (isList(e1)) {
|
||||
return (e1.tagName === e2.tagName && (allowDifferentListStyles || e1.style.listStyleType === e2.style.listStyleType)) || isListForIndent(e2);
|
||||
} else return mergeParagraphs && e1.tagName === 'P' && e2.tagName === 'P';
|
||||
}
|
||||
|
||||
function isListForIndent(e) {
|
||||
var firstLI = skipWhitespaceNodesForwards(e.firstChild), lastLI = skipWhitespaceNodesBackwards(e.lastChild);
|
||||
return firstLI && lastLI && isList(e) && firstLI === lastLI && (isList(firstLI) || firstLI.style.listStyleType === 'none' || containsOnlyAList(firstLI));
|
||||
}
|
||||
|
||||
function containsOnlyAList(e) {
|
||||
var firstChild = skipWhitespaceNodesForwards(e.firstChild), lastChild = skipWhitespaceNodesBackwards(e.lastChild);
|
||||
return firstChild && lastChild && firstChild === lastChild && isList(firstChild);
|
||||
}
|
||||
|
||||
function merge(e1, e2, masterElement) {
|
||||
var lastOriginal = skipWhitespaceNodesBackwards(e1.lastChild), firstNew = skipWhitespaceNodesForwards(e2.firstChild);
|
||||
if (e1.tagName === 'P') {
|
||||
e1.appendChild(e1.ownerDocument.createElement('br'));
|
||||
}
|
||||
while (e2.firstChild) {
|
||||
e1.appendChild(e2.firstChild);
|
||||
}
|
||||
if (masterElement) {
|
||||
e1.style.listStyleType = masterElement.style.listStyleType;
|
||||
}
|
||||
e2.parentNode.removeChild(e2);
|
||||
attemptMerge(lastOriginal, firstNew, false);
|
||||
return e1;
|
||||
}
|
||||
|
||||
function findItemToOperateOn(e, dom) {
|
||||
var item;
|
||||
if (!dom.is(e, 'li,ol,ul')) {
|
||||
item = dom.getParent(e, 'li');
|
||||
if (item) {
|
||||
e = item;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
tinymce.create('tinymce.plugins.Lists', {
|
||||
init: function(ed) {
|
||||
var LIST_TABBING = 'TABBING';
|
||||
var LIST_EMPTY_ITEM = 'EMPTY';
|
||||
var LIST_ESCAPE = 'ESCAPE';
|
||||
var LIST_PARAGRAPH = 'PARAGRAPH';
|
||||
var LIST_UNKNOWN = 'UNKNOWN';
|
||||
var state = LIST_UNKNOWN;
|
||||
|
||||
function isTabInList(e) {
|
||||
// Don't indent on Ctrl+Tab or Alt+Tab
|
||||
return e.keyCode === tinymce.VK.TAB && !(e.altKey || e.ctrlKey) &&
|
||||
(ed.queryCommandState('InsertUnorderedList') || ed.queryCommandState('InsertOrderedList'));
|
||||
}
|
||||
|
||||
function isOnLastListItem() {
|
||||
var li = getLi();
|
||||
var grandParent = li.parentNode.parentNode;
|
||||
var isLastItem = li.parentNode.lastChild === li;
|
||||
return isLastItem && !isNestedList(grandParent) && isEmptyListItem(li);
|
||||
}
|
||||
|
||||
function isNestedList(grandParent) {
|
||||
if (isList(grandParent)) {
|
||||
return grandParent.parentNode && grandParent.parentNode.tagName === 'LI';
|
||||
} else {
|
||||
return grandParent.tagName === 'LI';
|
||||
}
|
||||
}
|
||||
|
||||
function isInEmptyListItem() {
|
||||
return ed.selection.isCollapsed() && isEmptyListItem(getLi());
|
||||
}
|
||||
|
||||
function getLi() {
|
||||
var n = ed.selection.getStart();
|
||||
// Get start will return BR if the LI only contains a BR or an empty element as we use these to fix caret position
|
||||
return ((n.tagName == 'BR' || n.tagName == '') && n.parentNode.tagName == 'LI') ? n.parentNode : n;
|
||||
}
|
||||
|
||||
function isEmptyListItem(li) {
|
||||
var numChildren = li.childNodes.length;
|
||||
if (li.tagName === 'LI') {
|
||||
return numChildren == 0 ? true : numChildren == 1 && (li.firstChild.tagName == '' || li.firstChild.tagName == 'BR' || isEmptyIE9Li(li));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isEmptyIE9Li(li) {
|
||||
// only consider this to be last item if there is no list item content or that content is nbsp or space since IE9 creates these
|
||||
var lis = tinymce.grep(li.parentNode.childNodes, function(n) {return n.tagName == 'LI'});
|
||||
var isLastLi = li == lis[lis.length - 1];
|
||||
var child = li.firstChild;
|
||||
return tinymce.isIE9 && isLastLi && (child.nodeValue == String.fromCharCode(160) || child.nodeValue == String.fromCharCode(32));
|
||||
}
|
||||
|
||||
function isEnter(e) {
|
||||
return e.keyCode === tinymce.VK.ENTER;
|
||||
}
|
||||
|
||||
function isEnterWithoutShift(e) {
|
||||
return isEnter(e) && !e.shiftKey;
|
||||
}
|
||||
|
||||
function getListKeyState(e) {
|
||||
if (isTabInList(e)) {
|
||||
return LIST_TABBING;
|
||||
} else if (isEnterWithoutShift(e) && isOnLastListItem()) {
|
||||
// Returns LIST_UNKNOWN since breaking out of lists is handled by the EnterKey.js logic now
|
||||
//return LIST_ESCAPE;
|
||||
return LIST_UNKNOWN;
|
||||
} else if (isEnterWithoutShift(e) && isInEmptyListItem()) {
|
||||
return LIST_EMPTY_ITEM;
|
||||
} else {
|
||||
return LIST_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelDefaultEvents(ed, e) {
|
||||
// list escape is done manually using outdent as it does not create paragraphs correctly in td's
|
||||
if (state == LIST_TABBING || state == LIST_EMPTY_ITEM || tinymce.isGecko && state == LIST_ESCAPE) {
|
||||
Event.cancel(e);
|
||||
}
|
||||
}
|
||||
|
||||
function isCursorAtEndOfContainer() {
|
||||
var range = ed.selection.getRng(true);
|
||||
var startContainer = range.startContainer;
|
||||
if (startContainer.nodeType == 3) {
|
||||
var value = startContainer.nodeValue;
|
||||
if (tinymce.isIE9 && value.length > 1 && value.charCodeAt(value.length-1) == 32) {
|
||||
// IE9 places a space on the end of the text in some cases so ignore last char
|
||||
return (range.endOffset == value.length-1);
|
||||
} else {
|
||||
return (range.endOffset == value.length);
|
||||
}
|
||||
} else if (startContainer.nodeType == 1) {
|
||||
return range.endOffset == startContainer.childNodes.length;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
If we are at the end of a list item surrounded with an element, pressing enter should create a
|
||||
new list item instead without splitting the element e.g. don't want to create new P or H1 tag
|
||||
*/
|
||||
function isEndOfListItem() {
|
||||
var node = ed.selection.getNode();
|
||||
var validElements = 'h1,h2,h3,h4,h5,h6,p,div';
|
||||
var isLastParagraphOfLi = ed.dom.is(node, validElements) && node.parentNode.tagName === 'LI' && node.parentNode.lastChild === node;
|
||||
return ed.selection.isCollapsed() && isLastParagraphOfLi && isCursorAtEndOfContainer();
|
||||
}
|
||||
|
||||
// Creates a new list item after the current selection's list item parent
|
||||
function createNewLi(ed, e) {
|
||||
if (isEnterWithoutShift(e) && isEndOfListItem()) {
|
||||
var node = ed.selection.getNode();
|
||||
var li = ed.dom.create("li");
|
||||
var parentLi = ed.dom.getParent(node, 'li');
|
||||
ed.dom.insertAfter(li, parentLi);
|
||||
|
||||
// Move caret to new list element.
|
||||
if (tinymce.isIE6 || tinymce.isIE7 || tinyMCE.isIE8) {
|
||||
// Removed this line since it would create an odd < > tag and placing the caret inside an empty LI is handled and should be handled by the selection logic
|
||||
//li.appendChild(ed.dom.create(" ")); // IE needs an element within the bullet point
|
||||
ed.selection.setCursorLocation(li, 1);
|
||||
} else {
|
||||
ed.selection.setCursorLocation(li, 0);
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function imageJoiningListItem(ed, e) {
|
||||
var prevSibling;
|
||||
|
||||
if (!tinymce.isGecko)
|
||||
return;
|
||||
|
||||
var n = ed.selection.getStart();
|
||||
if (e.keyCode != tinymce.VK.BACKSPACE || n.tagName !== 'IMG')
|
||||
return;
|
||||
|
||||
function lastLI(node) {
|
||||
var child = node.firstChild;
|
||||
var li = null;
|
||||
do {
|
||||
if (!child)
|
||||
break;
|
||||
|
||||
if (child.tagName === 'LI')
|
||||
li = child;
|
||||
} while (child = child.nextSibling);
|
||||
|
||||
return li;
|
||||
}
|
||||
|
||||
function addChildren(parentNode, destination) {
|
||||
while (parentNode.childNodes.length > 0)
|
||||
destination.appendChild(parentNode.childNodes[0]);
|
||||
}
|
||||
|
||||
// Check if there is a previous sibling
|
||||
prevSibling = n.parentNode.previousSibling;
|
||||
if (!prevSibling)
|
||||
return;
|
||||
|
||||
var ul;
|
||||
if (prevSibling.tagName === 'UL' || prevSibling.tagName === 'OL')
|
||||
ul = prevSibling;
|
||||
else if (prevSibling.previousSibling && (prevSibling.previousSibling.tagName === 'UL' || prevSibling.previousSibling.tagName === 'OL'))
|
||||
ul = prevSibling.previousSibling;
|
||||
else
|
||||
return;
|
||||
|
||||
var li = lastLI(ul);
|
||||
|
||||
// move the caret to the end of the list item
|
||||
var rng = ed.dom.createRng();
|
||||
rng.setStart(li, 1);
|
||||
rng.setEnd(li, 1);
|
||||
ed.selection.setRng(rng);
|
||||
ed.selection.collapse(true);
|
||||
|
||||
// save a bookmark at the end of the list item
|
||||
var bookmark = ed.selection.getBookmark();
|
||||
|
||||
// copy the image an its text to the list item
|
||||
var clone = n.parentNode.cloneNode(true);
|
||||
if (clone.tagName === 'P' || clone.tagName === 'DIV')
|
||||
addChildren(clone, li);
|
||||
else
|
||||
li.appendChild(clone);
|
||||
|
||||
// remove the old copy of the image
|
||||
n.parentNode.parentNode.removeChild(n.parentNode);
|
||||
|
||||
// move the caret where we saved the bookmark
|
||||
ed.selection.moveToBookmark(bookmark);
|
||||
}
|
||||
|
||||
// fix the cursor position to ensure it is correct in IE
|
||||
function setCursorPositionToOriginalLi(li) {
|
||||
var list = ed.dom.getParent(li, 'ol,ul');
|
||||
if (list != null) {
|
||||
var lastLi = list.lastChild;
|
||||
// Removed this line since IE9 would report an DOM character error and placing the caret inside an empty LI is handled and should be handled by the selection logic
|
||||
//lastLi.appendChild(ed.getDoc().createElement(''));
|
||||
ed.selection.setCursorLocation(lastLi, 0);
|
||||
}
|
||||
}
|
||||
|
||||
this.ed = ed;
|
||||
ed.addCommand('Indent', this.indent, this);
|
||||
ed.addCommand('Outdent', this.outdent, this);
|
||||
ed.addCommand('InsertUnorderedList', function() {
|
||||
this.applyList('UL', 'OL');
|
||||
}, this);
|
||||
ed.addCommand('InsertOrderedList', function() {
|
||||
this.applyList('OL', 'UL');
|
||||
}, this);
|
||||
|
||||
ed.onInit.add(function() {
|
||||
ed.editorCommands.addCommands({
|
||||
'outdent': function() {
|
||||
var sel = ed.selection, dom = ed.dom;
|
||||
|
||||
function hasStyleIndent(n) {
|
||||
n = dom.getParent(n, dom.isBlock);
|
||||
return n && (parseInt(ed.dom.getStyle(n, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(n, 'padding-left') || 0, 10)) > 0;
|
||||
}
|
||||
|
||||
return hasStyleIndent(sel.getStart()) || hasStyleIndent(sel.getEnd()) || ed.queryCommandState('InsertOrderedList') || ed.queryCommandState('InsertUnorderedList');
|
||||
}
|
||||
}, 'state');
|
||||
});
|
||||
|
||||
ed.onKeyUp.add(function(ed, e) {
|
||||
if (state == LIST_TABBING) {
|
||||
ed.execCommand(e.shiftKey ? 'Outdent' : 'Indent', true, null);
|
||||
state = LIST_UNKNOWN;
|
||||
return Event.cancel(e);
|
||||
} else if (state == LIST_EMPTY_ITEM) {
|
||||
var li = getLi();
|
||||
var shouldOutdent = ed.settings.list_outdent_on_enter === true || e.shiftKey;
|
||||
ed.execCommand(shouldOutdent ? 'Outdent' : 'Indent', true, null);
|
||||
if (tinymce.isIE) {
|
||||
setCursorPositionToOriginalLi(li);
|
||||
}
|
||||
|
||||
return Event.cancel(e);
|
||||
} else if (state == LIST_ESCAPE) {
|
||||
if (tinymce.isIE6 || tinymce.isIE7 || tinymce.isIE8) {
|
||||
// append a zero sized nbsp so that caret is positioned correctly in IE after escaping and applying formatting.
|
||||
// if there is no text then applying formatting for e.g a H1 to the P tag immediately following list after
|
||||
// escaping from it will cause the caret to be positioned on the last li instead of staying the in P tag.
|
||||
var n = ed.getDoc().createTextNode('\uFEFF');
|
||||
ed.selection.getNode().appendChild(n);
|
||||
} else if (tinymce.isIE9 || tinymce.isGecko) {
|
||||
// IE9 does not escape the list so we use outdent to do this and cancel the default behaviour
|
||||
// Gecko does not create a paragraph outdenting inside a TD so default behaviour is cancelled and we outdent ourselves
|
||||
ed.execCommand('Outdent');
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function fixListItem(parent, reference) {
|
||||
// a zero-sized non-breaking space is placed in the empty list item so that the nested list is
|
||||
// displayed on the below line instead of next to it
|
||||
var n = ed.getDoc().createTextNode('\uFEFF');
|
||||
parent.insertBefore(n, reference);
|
||||
ed.selection.setCursorLocation(n, 0);
|
||||
// repaint to remove rendering artifact. only visible when creating new list
|
||||
ed.execCommand('mceRepaint');
|
||||
}
|
||||
|
||||
function fixIndentedListItemForGecko(ed, e) {
|
||||
if (isEnter(e)) {
|
||||
var li = getLi();
|
||||
if (li) {
|
||||
var parent = li.parentNode;
|
||||
var grandParent = parent && parent.parentNode;
|
||||
if (grandParent && grandParent.nodeName == 'LI' && grandParent.firstChild == parent && li == parent.firstChild) {
|
||||
fixListItem(grandParent, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixIndentedListItemForIE8(ed, e) {
|
||||
if (isEnter(e)) {
|
||||
var li = getLi();
|
||||
if (ed.dom.select('ul li', li).length === 1) {
|
||||
var list = li.firstChild;
|
||||
fixListItem(li, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixDeletingFirstCharOfList(ed, e) {
|
||||
function listElements(list, li) {
|
||||
var elements = [];
|
||||
var walker = new tinymce.dom.TreeWalker(li, list);
|
||||
for (var node = walker.current(); node; node = walker.next()) {
|
||||
if (ed.dom.is(node, 'ol,ul,li')) {
|
||||
elements.push(node);
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
if (e.keyCode == tinymce.VK.BACKSPACE) {
|
||||
var li = getLi();
|
||||
if (li) {
|
||||
var list = ed.dom.getParent(li, 'ol,ul');
|
||||
if (list && list.firstChild === li) {
|
||||
var elements = listElements(list, li);
|
||||
ed.execCommand("Outdent", false, elements);
|
||||
ed.undoManager.add();
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixDeletingEmptyLiInWebkit(ed, e) {
|
||||
var li = getLi();
|
||||
if (e.keyCode === tinymce.VK.BACKSPACE && ed.dom.is(li, 'li') && li.parentNode.firstChild!==li) {
|
||||
if (ed.dom.select('ul,ol', li).length === 1) {
|
||||
var prevLi = li.previousSibling;
|
||||
ed.dom.remove(ed.dom.select('br', li));
|
||||
ed.dom.remove(li, true);
|
||||
var textNodes = tinymce.grep(prevLi.childNodes, function(n){ return n.nodeType === 3 });
|
||||
if (textNodes.length === 1) {
|
||||
var textNode = textNodes[0]
|
||||
ed.selection.setCursorLocation(textNode, textNode.length);
|
||||
}
|
||||
ed.undoManager.add();
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ed.onKeyDown.add(function(_, e) { state = getListKeyState(e); });
|
||||
ed.onKeyDown.add(cancelDefaultEvents);
|
||||
ed.onKeyDown.add(imageJoiningListItem);
|
||||
ed.onKeyDown.add(createNewLi);
|
||||
|
||||
if (tinymce.isGecko) {
|
||||
ed.onKeyUp.add(fixIndentedListItemForGecko);
|
||||
}
|
||||
if (tinymce.isIE8) {
|
||||
ed.onKeyUp.add(fixIndentedListItemForIE8);
|
||||
}
|
||||
if (tinymce.isGecko || tinymce.isWebKit) {
|
||||
ed.onKeyDown.add(fixDeletingFirstCharOfList);
|
||||
}
|
||||
if (tinymce.isWebKit) {
|
||||
ed.onKeyDown.add(fixDeletingEmptyLiInWebkit);
|
||||
}
|
||||
},
|
||||
|
||||
applyList: function(targetListType, oppositeListType) {
|
||||
var t = this, ed = t.ed, dom = ed.dom, applied = [], hasSameType = false, hasOppositeType = false, hasNonList = false, actions,
|
||||
selectedBlocks = ed.selection.getSelectedBlocks();
|
||||
|
||||
function cleanupBr(e) {
|
||||
if (e && e.tagName === 'BR') {
|
||||
dom.remove(e);
|
||||
}
|
||||
}
|
||||
|
||||
function makeList(element) {
|
||||
var list = dom.create(targetListType), li;
|
||||
|
||||
function adjustIndentForNewList(element) {
|
||||
// If there's a margin-left, outdent one level to account for the extra list margin.
|
||||
if (element.style.marginLeft || element.style.paddingLeft) {
|
||||
t.adjustPaddingFunction(false)(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (element.tagName === 'LI') {
|
||||
// No change required.
|
||||
} else if (element.tagName === 'P' || element.tagName === 'DIV' || element.tagName === 'BODY') {
|
||||
processBrs(element, function(startSection, br) {
|
||||
doWrapList(startSection, br, element.tagName === 'BODY' ? null : startSection.parentNode);
|
||||
li = startSection.parentNode;
|
||||
adjustIndentForNewList(li);
|
||||
cleanupBr(br);
|
||||
});
|
||||
if (li) {
|
||||
if (li.tagName === 'LI' && (element.tagName === 'P' || selectedBlocks.length > 1)) {
|
||||
dom.split(li.parentNode.parentNode, li.parentNode);
|
||||
}
|
||||
attemptMergeWithAdjacent(li.parentNode, true);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Put the list around the element.
|
||||
li = dom.create('li');
|
||||
dom.insertAfter(li, element);
|
||||
li.appendChild(element);
|
||||
adjustIndentForNewList(element);
|
||||
element = li;
|
||||
}
|
||||
dom.insertAfter(list, element);
|
||||
list.appendChild(element);
|
||||
attemptMergeWithAdjacent(list, true);
|
||||
applied.push(element);
|
||||
}
|
||||
|
||||
function doWrapList(start, end, template) {
|
||||
var li, n = start, tmp;
|
||||
while (!dom.isBlock(start.parentNode) && start.parentNode !== dom.getRoot()) {
|
||||
start = dom.split(start.parentNode, start.previousSibling);
|
||||
start = start.nextSibling;
|
||||
n = start;
|
||||
}
|
||||
if (template) {
|
||||
li = template.cloneNode(true);
|
||||
start.parentNode.insertBefore(li, start);
|
||||
while (li.firstChild) dom.remove(li.firstChild);
|
||||
li = dom.rename(li, 'li');
|
||||
} else {
|
||||
li = dom.create('li');
|
||||
start.parentNode.insertBefore(li, start);
|
||||
}
|
||||
while (n && n != end) {
|
||||
tmp = n.nextSibling;
|
||||
li.appendChild(n);
|
||||
n = tmp;
|
||||
}
|
||||
if (li.childNodes.length === 0) {
|
||||
li.innerHTML = '<br _mce_bogus="1" />';
|
||||
}
|
||||
makeList(li);
|
||||
}
|
||||
|
||||
function processBrs(element, callback) {
|
||||
var startSection, previousBR, END_TO_START = 3, START_TO_END = 1,
|
||||
breakElements = 'br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl';
|
||||
|
||||
function isAnyPartSelected(start, end) {
|
||||
var r = dom.createRng(), sel;
|
||||
bookmark.keep = true;
|
||||
ed.selection.moveToBookmark(bookmark);
|
||||
bookmark.keep = false;
|
||||
sel = ed.selection.getRng(true);
|
||||
if (!end) {
|
||||
end = start.parentNode.lastChild;
|
||||
}
|
||||
r.setStartBefore(start);
|
||||
r.setEndAfter(end);
|
||||
return !(r.compareBoundaryPoints(END_TO_START, sel) > 0 || r.compareBoundaryPoints(START_TO_END, sel) <= 0);
|
||||
}
|
||||
|
||||
function nextLeaf(br) {
|
||||
if (br.nextSibling)
|
||||
return br.nextSibling;
|
||||
if (!dom.isBlock(br.parentNode) && br.parentNode !== dom.getRoot())
|
||||
return nextLeaf(br.parentNode);
|
||||
}
|
||||
|
||||
// Split on BRs within the range and process those.
|
||||
startSection = element.firstChild;
|
||||
// First mark the BRs that have any part of the previous section selected.
|
||||
var trailingContentSelected = false;
|
||||
each(dom.select(breakElements, element), function(br) {
|
||||
if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
|
||||
return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
|
||||
}
|
||||
if (isAnyPartSelected(startSection, br)) {
|
||||
dom.addClass(br, '_mce_tagged_br');
|
||||
startSection = nextLeaf(br);
|
||||
}
|
||||
});
|
||||
trailingContentSelected = (startSection && isAnyPartSelected(startSection, undefined));
|
||||
startSection = element.firstChild;
|
||||
each(dom.select(breakElements, element), function(br) {
|
||||
// Got a section from start to br.
|
||||
var tmp = nextLeaf(br);
|
||||
if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
|
||||
return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
|
||||
}
|
||||
if (dom.hasClass(br, '_mce_tagged_br')) {
|
||||
callback(startSection, br, previousBR);
|
||||
previousBR = null;
|
||||
} else {
|
||||
previousBR = br;
|
||||
}
|
||||
startSection = tmp;
|
||||
});
|
||||
if (trailingContentSelected) {
|
||||
callback(startSection, undefined, previousBR);
|
||||
}
|
||||
}
|
||||
|
||||
function wrapList(element) {
|
||||
processBrs(element, function(startSection, br, previousBR) {
|
||||
// Need to indent this part
|
||||
doWrapList(startSection, br);
|
||||
cleanupBr(br);
|
||||
cleanupBr(previousBR);
|
||||
});
|
||||
}
|
||||
|
||||
function changeList(element) {
|
||||
if (tinymce.inArray(applied, element) !== -1) {
|
||||
return;
|
||||
}
|
||||
if (element.parentNode.tagName === oppositeListType) {
|
||||
dom.split(element.parentNode, element);
|
||||
makeList(element);
|
||||
attemptMergeWithNext(element.parentNode, false);
|
||||
}
|
||||
applied.push(element);
|
||||
}
|
||||
|
||||
function convertListItemToParagraph(element) {
|
||||
var child, nextChild, mergedElement, splitLast;
|
||||
if (tinymce.inArray(applied, element) !== -1) {
|
||||
return;
|
||||
}
|
||||
element = splitNestedLists(element, dom);
|
||||
while (dom.is(element.parentNode, 'ol,ul,li')) {
|
||||
dom.split(element.parentNode, element);
|
||||
}
|
||||
// Push the original element we have from the selection, not the renamed one.
|
||||
applied.push(element);
|
||||
element = dom.rename(element, 'p');
|
||||
mergedElement = attemptMergeWithAdjacent(element, false, ed.settings.force_br_newlines);
|
||||
if (mergedElement === element) {
|
||||
// Now split out any block elements that can't be contained within a P.
|
||||
// Manually iterate to ensure we handle modifications correctly (doesn't work with tinymce.each)
|
||||
child = element.firstChild;
|
||||
while (child) {
|
||||
if (dom.isBlock(child)) {
|
||||
child = dom.split(child.parentNode, child);
|
||||
splitLast = true;
|
||||
nextChild = child.nextSibling && child.nextSibling.firstChild;
|
||||
} else {
|
||||
nextChild = child.nextSibling;
|
||||
if (splitLast && child.tagName === 'BR') {
|
||||
dom.remove(child);
|
||||
}
|
||||
splitLast = false;
|
||||
}
|
||||
child = nextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
each(selectedBlocks, function(e) {
|
||||
e = findItemToOperateOn(e, dom);
|
||||
if (e.tagName === oppositeListType || (e.tagName === 'LI' && e.parentNode.tagName === oppositeListType)) {
|
||||
hasOppositeType = true;
|
||||
} else if (e.tagName === targetListType || (e.tagName === 'LI' && e.parentNode.tagName === targetListType)) {
|
||||
hasSameType = true;
|
||||
} else {
|
||||
hasNonList = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasNonList &&!hasSameType || hasOppositeType || selectedBlocks.length === 0) {
|
||||
actions = {
|
||||
'LI': changeList,
|
||||
'H1': makeList,
|
||||
'H2': makeList,
|
||||
'H3': makeList,
|
||||
'H4': makeList,
|
||||
'H5': makeList,
|
||||
'H6': makeList,
|
||||
'P': makeList,
|
||||
'BODY': makeList,
|
||||
'DIV': selectedBlocks.length > 1 ? makeList : wrapList,
|
||||
defaultAction: wrapList,
|
||||
elements: this.selectedBlocks()
|
||||
};
|
||||
} else {
|
||||
actions = {
|
||||
defaultAction: convertListItemToParagraph,
|
||||
elements: this.selectedBlocks()
|
||||
};
|
||||
}
|
||||
this.process(actions);
|
||||
},
|
||||
|
||||
indent: function() {
|
||||
var ed = this.ed, dom = ed.dom, indented = [];
|
||||
|
||||
function createWrapItem(element) {
|
||||
var wrapItem = dom.create('li', { style: 'list-style-type: none;'});
|
||||
dom.insertAfter(wrapItem, element);
|
||||
return wrapItem;
|
||||
}
|
||||
|
||||
function createWrapList(element) {
|
||||
var wrapItem = createWrapItem(element),
|
||||
list = dom.getParent(element, 'ol,ul'),
|
||||
listType = list.tagName,
|
||||
listStyle = dom.getStyle(list, 'list-style-type'),
|
||||
attrs = {},
|
||||
wrapList;
|
||||
if (listStyle !== '') {
|
||||
attrs.style = 'list-style-type: ' + listStyle + ';';
|
||||
}
|
||||
wrapList = dom.create(listType, attrs);
|
||||
wrapItem.appendChild(wrapList);
|
||||
return wrapList;
|
||||
}
|
||||
|
||||
function indentLI(element) {
|
||||
if (!hasParentInList(ed, element, indented)) {
|
||||
element = splitNestedLists(element, dom);
|
||||
var wrapList = createWrapList(element);
|
||||
wrapList.appendChild(element);
|
||||
attemptMergeWithAdjacent(wrapList.parentNode, false);
|
||||
attemptMergeWithAdjacent(wrapList, false);
|
||||
indented.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
this.process({
|
||||
'LI': indentLI,
|
||||
defaultAction: this.adjustPaddingFunction(true),
|
||||
elements: this.selectedBlocks()
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
outdent: function(ui, elements) {
|
||||
var t = this, ed = t.ed, dom = ed.dom, outdented = [];
|
||||
|
||||
function outdentLI(element) {
|
||||
var listElement, targetParent, align;
|
||||
if (!hasParentInList(ed, element, outdented)) {
|
||||
if (dom.getStyle(element, 'margin-left') !== '' || dom.getStyle(element, 'padding-left') !== '') {
|
||||
return t.adjustPaddingFunction(false)(element);
|
||||
}
|
||||
align = dom.getStyle(element, 'text-align', true);
|
||||
if (align === 'center' || align === 'right') {
|
||||
dom.setStyle(element, 'text-align', 'left');
|
||||
return;
|
||||
}
|
||||
element = splitNestedLists(element, dom);
|
||||
listElement = element.parentNode;
|
||||
targetParent = element.parentNode.parentNode;
|
||||
if (targetParent.tagName === 'P') {
|
||||
dom.split(targetParent, element.parentNode);
|
||||
} else {
|
||||
dom.split(listElement, element);
|
||||
if (targetParent.tagName === 'LI') {
|
||||
// Nested list, need to split the LI and go back out to the OL/UL element.
|
||||
dom.split(targetParent, element);
|
||||
} else if (!dom.is(targetParent, 'ol,ul')) {
|
||||
dom.rename(element, 'p');
|
||||
}
|
||||
}
|
||||
outdented.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
var listElements = elements && tinymce.is(elements, 'array') ? elements : this.selectedBlocks();
|
||||
this.process({
|
||||
'LI': outdentLI,
|
||||
defaultAction: this.adjustPaddingFunction(false),
|
||||
elements: listElements
|
||||
});
|
||||
|
||||
each(outdented, attemptMergeWithAdjacent);
|
||||
},
|
||||
|
||||
process: function(actions) {
|
||||
var t = this, sel = t.ed.selection, dom = t.ed.dom, selectedBlocks, r;
|
||||
|
||||
function isEmptyElement(element) {
|
||||
var excludeBrsAndBookmarks = tinymce.grep(element.childNodes, function(n) {
|
||||
return !(n.nodeName === 'BR' || n.nodeName === 'SPAN' && dom.getAttrib(n, 'data-mce-type') == 'bookmark'
|
||||
|| n.nodeType == 3 && (n.nodeValue == String.fromCharCode(160) || n.nodeValue == ''));
|
||||
});
|
||||
return excludeBrsAndBookmarks.length === 0;
|
||||
}
|
||||
|
||||
function processElement(element) {
|
||||
dom.removeClass(element, '_mce_act_on');
|
||||
if (!element || element.nodeType !== 1 || selectedBlocks.length > 1 && isEmptyElement(element)) {
|
||||
return;
|
||||
}
|
||||
element = findItemToOperateOn(element, dom);
|
||||
var action = actions[element.tagName];
|
||||
if (!action) {
|
||||
action = actions.defaultAction;
|
||||
}
|
||||
action(element);
|
||||
}
|
||||
|
||||
function recurse(element) {
|
||||
t.splitSafeEach(element.childNodes, processElement);
|
||||
}
|
||||
|
||||
function brAtEdgeOfSelection(container, offset) {
|
||||
return offset >= 0 && container.hasChildNodes() && offset < container.childNodes.length &&
|
||||
container.childNodes[offset].tagName === 'BR';
|
||||
}
|
||||
|
||||
function isInTable() {
|
||||
var n = sel.getNode();
|
||||
var p = dom.getParent(n, 'td');
|
||||
return p !== null;
|
||||
}
|
||||
|
||||
selectedBlocks = actions.elements;
|
||||
|
||||
r = sel.getRng(true);
|
||||
if (!r.collapsed) {
|
||||
if (brAtEdgeOfSelection(r.endContainer, r.endOffset - 1)) {
|
||||
r.setEnd(r.endContainer, r.endOffset - 1);
|
||||
sel.setRng(r);
|
||||
}
|
||||
if (brAtEdgeOfSelection(r.startContainer, r.startOffset)) {
|
||||
r.setStart(r.startContainer, r.startOffset + 1);
|
||||
sel.setRng(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tinymce.isIE8) {
|
||||
// append a zero sized nbsp so that caret is restored correctly using bookmark
|
||||
var s = t.ed.selection.getNode();
|
||||
if (s.tagName === 'LI' && !(s.parentNode.lastChild === s)) {
|
||||
var i = t.ed.getDoc().createTextNode('\uFEFF');
|
||||
s.appendChild(i);
|
||||
}
|
||||
}
|
||||
|
||||
bookmark = sel.getBookmark();
|
||||
actions.OL = actions.UL = recurse;
|
||||
t.splitSafeEach(selectedBlocks, processElement);
|
||||
sel.moveToBookmark(bookmark);
|
||||
bookmark = null;
|
||||
|
||||
// we avoid doing repaint in a table as this will move the caret out of the table in Firefox 3.6
|
||||
if (!isInTable()) {
|
||||
// Avoids table or image handles being left behind in Firefox.
|
||||
t.ed.execCommand('mceRepaint');
|
||||
}
|
||||
},
|
||||
|
||||
splitSafeEach: function(elements, f) {
|
||||
if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) ||
|
||||
/Firefox\/3\.[0-4]/.test(navigator.userAgent))) {
|
||||
this.classBasedEach(elements, f);
|
||||
} else {
|
||||
each(elements, f);
|
||||
}
|
||||
},
|
||||
|
||||
classBasedEach: function(elements, f) {
|
||||
var dom = this.ed.dom, nodes, element;
|
||||
// Mark nodes
|
||||
each(elements, function(element) {
|
||||
dom.addClass(element, '_mce_act_on');
|
||||
});
|
||||
nodes = dom.select('._mce_act_on');
|
||||
while (nodes.length > 0) {
|
||||
element = nodes.shift();
|
||||
dom.removeClass(element, '_mce_act_on');
|
||||
f(element);
|
||||
nodes = dom.select('._mce_act_on');
|
||||
}
|
||||
},
|
||||
|
||||
adjustPaddingFunction: function(isIndent) {
|
||||
var indentAmount, indentUnits, ed = this.ed;
|
||||
indentAmount = ed.settings.indentation;
|
||||
indentUnits = /[a-z%]+/i.exec(indentAmount);
|
||||
indentAmount = parseInt(indentAmount, 10);
|
||||
return function(element) {
|
||||
var currentIndent, newIndentAmount;
|
||||
currentIndent = parseInt(ed.dom.getStyle(element, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(element, 'padding-left') || 0, 10);
|
||||
if (isIndent) {
|
||||
newIndentAmount = currentIndent + indentAmount;
|
||||
} else {
|
||||
newIndentAmount = currentIndent - indentAmount;
|
||||
}
|
||||
ed.dom.setStyle(element, 'padding-left', '');
|
||||
ed.dom.setStyle(element, 'margin-left', newIndentAmount > 0 ? newIndentAmount + indentUnits : '');
|
||||
};
|
||||
},
|
||||
|
||||
selectedBlocks: function() {
|
||||
var ed = this.ed
|
||||
var selectedBlocks = ed.selection.getSelectedBlocks();
|
||||
return selectedBlocks.length == 0 ? [ ed.dom.getRoot() ] : selectedBlocks;
|
||||
},
|
||||
|
||||
getInfo: function() {
|
||||
return {
|
||||
longname : 'Lists',
|
||||
author : 'Moxiecode Systems AB',
|
||||
authorurl : 'http://tinymce.moxiecode.com',
|
||||
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists',
|
||||
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
||||
};
|
||||
}
|
||||
});
|
||||
tinymce.PluginManager.add("lists", tinymce.plugins.Lists);
|
||||
}());
|
||||
/**
|
||||
* editor_plugin_src.js
|
||||
*
|
||||
* Copyright 2011, Moxiecode Systems AB
|
||||
* Released under LGPL License.
|
||||
*
|
||||
* License: http://tinymce.moxiecode.com/license
|
||||
* Contributing: http://tinymce.moxiecode.com/contributing
|
||||
*/
|
||||
|
||||
(function() {
|
||||
var each = tinymce.each, Event = tinymce.dom.Event, bookmark;
|
||||
|
||||
// Skips text nodes that only contain whitespace since they aren't semantically important.
|
||||
function skipWhitespaceNodes(e, next) {
|
||||
while (e && (e.nodeType === 8 || (e.nodeType === 3 && /^[ \t\n\r]*$/.test(e.nodeValue)))) {
|
||||
e = next(e);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
function skipWhitespaceNodesBackwards(e) {
|
||||
return skipWhitespaceNodes(e, function(e) {
|
||||
return e.previousSibling;
|
||||
});
|
||||
}
|
||||
|
||||
function skipWhitespaceNodesForwards(e) {
|
||||
return skipWhitespaceNodes(e, function(e) {
|
||||
return e.nextSibling;
|
||||
});
|
||||
}
|
||||
|
||||
function hasParentInList(ed, e, list) {
|
||||
return ed.dom.getParent(e, function(p) {
|
||||
return tinymce.inArray(list, p) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
function isList(e) {
|
||||
return e && (e.tagName === 'OL' || e.tagName === 'UL');
|
||||
}
|
||||
|
||||
function splitNestedLists(element, dom) {
|
||||
var tmp, nested, wrapItem;
|
||||
tmp = skipWhitespaceNodesBackwards(element.lastChild);
|
||||
while (isList(tmp)) {
|
||||
nested = tmp;
|
||||
tmp = skipWhitespaceNodesBackwards(nested.previousSibling);
|
||||
}
|
||||
if (nested) {
|
||||
wrapItem = dom.create('li', { style: 'list-style-type: none;'});
|
||||
dom.split(element, nested);
|
||||
dom.insertAfter(wrapItem, nested);
|
||||
wrapItem.appendChild(nested);
|
||||
wrapItem.appendChild(nested);
|
||||
element = wrapItem.previousSibling;
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
function attemptMergeWithAdjacent(e, allowDifferentListStyles, mergeParagraphs) {
|
||||
e = attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs);
|
||||
return attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs);
|
||||
}
|
||||
|
||||
function attemptMergeWithPrevious(e, allowDifferentListStyles, mergeParagraphs) {
|
||||
var prev = skipWhitespaceNodesBackwards(e.previousSibling);
|
||||
if (prev) {
|
||||
return attemptMerge(prev, e, allowDifferentListStyles ? prev : false, mergeParagraphs);
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
function attemptMergeWithNext(e, allowDifferentListStyles, mergeParagraphs) {
|
||||
var next = skipWhitespaceNodesForwards(e.nextSibling);
|
||||
if (next) {
|
||||
return attemptMerge(e, next, allowDifferentListStyles ? next : false, mergeParagraphs);
|
||||
} else {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
function attemptMerge(e1, e2, differentStylesMasterElement, mergeParagraphs) {
|
||||
if (canMerge(e1, e2, !!differentStylesMasterElement, mergeParagraphs)) {
|
||||
return merge(e1, e2, differentStylesMasterElement);
|
||||
} else if (e1 && e1.tagName === 'LI' && isList(e2)) {
|
||||
// Fix invalidly nested lists.
|
||||
e1.appendChild(e2);
|
||||
}
|
||||
return e2;
|
||||
}
|
||||
|
||||
function canMerge(e1, e2, allowDifferentListStyles, mergeParagraphs) {
|
||||
if (!e1 || !e2) {
|
||||
return false;
|
||||
} else if (e1.tagName === 'LI' && e2.tagName === 'LI') {
|
||||
return e2.style.listStyleType === 'none' || containsOnlyAList(e2);
|
||||
} else if (isList(e1)) {
|
||||
return (e1.tagName === e2.tagName && (allowDifferentListStyles || e1.style.listStyleType === e2.style.listStyleType)) || isListForIndent(e2);
|
||||
} else return mergeParagraphs && e1.tagName === 'P' && e2.tagName === 'P';
|
||||
}
|
||||
|
||||
function isListForIndent(e) {
|
||||
var firstLI = skipWhitespaceNodesForwards(e.firstChild), lastLI = skipWhitespaceNodesBackwards(e.lastChild);
|
||||
return firstLI && lastLI && isList(e) && firstLI === lastLI && (isList(firstLI) || firstLI.style.listStyleType === 'none' || containsOnlyAList(firstLI));
|
||||
}
|
||||
|
||||
function containsOnlyAList(e) {
|
||||
var firstChild = skipWhitespaceNodesForwards(e.firstChild), lastChild = skipWhitespaceNodesBackwards(e.lastChild);
|
||||
return firstChild && lastChild && firstChild === lastChild && isList(firstChild);
|
||||
}
|
||||
|
||||
function merge(e1, e2, masterElement) {
|
||||
var lastOriginal = skipWhitespaceNodesBackwards(e1.lastChild), firstNew = skipWhitespaceNodesForwards(e2.firstChild);
|
||||
if (e1.tagName === 'P') {
|
||||
e1.appendChild(e1.ownerDocument.createElement('br'));
|
||||
}
|
||||
while (e2.firstChild) {
|
||||
e1.appendChild(e2.firstChild);
|
||||
}
|
||||
if (masterElement) {
|
||||
e1.style.listStyleType = masterElement.style.listStyleType;
|
||||
}
|
||||
e2.parentNode.removeChild(e2);
|
||||
attemptMerge(lastOriginal, firstNew, false);
|
||||
return e1;
|
||||
}
|
||||
|
||||
function findItemToOperateOn(e, dom) {
|
||||
var item;
|
||||
if (!dom.is(e, 'li,ol,ul')) {
|
||||
item = dom.getParent(e, 'li');
|
||||
if (item) {
|
||||
e = item;
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
tinymce.create('tinymce.plugins.Lists', {
|
||||
init: function(ed) {
|
||||
var LIST_TABBING = 'TABBING';
|
||||
var LIST_EMPTY_ITEM = 'EMPTY';
|
||||
var LIST_ESCAPE = 'ESCAPE';
|
||||
var LIST_PARAGRAPH = 'PARAGRAPH';
|
||||
var LIST_UNKNOWN = 'UNKNOWN';
|
||||
var state = LIST_UNKNOWN;
|
||||
|
||||
function isTabInList(e) {
|
||||
// Don't indent on Ctrl+Tab or Alt+Tab
|
||||
return e.keyCode === tinymce.VK.TAB && !(e.altKey || e.ctrlKey) &&
|
||||
(ed.queryCommandState('InsertUnorderedList') || ed.queryCommandState('InsertOrderedList'));
|
||||
}
|
||||
|
||||
function isOnLastListItem() {
|
||||
var li = getLi();
|
||||
var grandParent = li.parentNode.parentNode;
|
||||
var isLastItem = li.parentNode.lastChild === li;
|
||||
return isLastItem && !isNestedList(grandParent) && isEmptyListItem(li);
|
||||
}
|
||||
|
||||
function isNestedList(grandParent) {
|
||||
if (isList(grandParent)) {
|
||||
return grandParent.parentNode && grandParent.parentNode.tagName === 'LI';
|
||||
} else {
|
||||
return grandParent.tagName === 'LI';
|
||||
}
|
||||
}
|
||||
|
||||
function isInEmptyListItem() {
|
||||
return ed.selection.isCollapsed() && isEmptyListItem(getLi());
|
||||
}
|
||||
|
||||
function getLi() {
|
||||
var n = ed.selection.getStart();
|
||||
// Get start will return BR if the LI only contains a BR or an empty element as we use these to fix caret position
|
||||
return ((n.tagName == 'BR' || n.tagName == '') && n.parentNode.tagName == 'LI') ? n.parentNode : n;
|
||||
}
|
||||
|
||||
function isEmptyListItem(li) {
|
||||
var numChildren = li.childNodes.length;
|
||||
if (li.tagName === 'LI') {
|
||||
return numChildren == 0 ? true : numChildren == 1 && (li.firstChild.tagName == '' || li.firstChild.tagName == 'BR' || isEmptyIE9Li(li));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isEmptyIE9Li(li) {
|
||||
// only consider this to be last item if there is no list item content or that content is nbsp or space since IE9 creates these
|
||||
var lis = tinymce.grep(li.parentNode.childNodes, function(n) {return n.tagName == 'LI'});
|
||||
var isLastLi = li == lis[lis.length - 1];
|
||||
var child = li.firstChild;
|
||||
return tinymce.isIE9 && isLastLi && (child.nodeValue == String.fromCharCode(160) || child.nodeValue == String.fromCharCode(32));
|
||||
}
|
||||
|
||||
function isEnter(e) {
|
||||
return e.keyCode === tinymce.VK.ENTER;
|
||||
}
|
||||
|
||||
function isEnterWithoutShift(e) {
|
||||
return isEnter(e) && !e.shiftKey;
|
||||
}
|
||||
|
||||
function getListKeyState(e) {
|
||||
if (isTabInList(e)) {
|
||||
return LIST_TABBING;
|
||||
} else if (isEnterWithoutShift(e) && isOnLastListItem()) {
|
||||
// Returns LIST_UNKNOWN since breaking out of lists is handled by the EnterKey.js logic now
|
||||
//return LIST_ESCAPE;
|
||||
return LIST_UNKNOWN;
|
||||
} else if (isEnterWithoutShift(e) && isInEmptyListItem()) {
|
||||
return LIST_EMPTY_ITEM;
|
||||
} else {
|
||||
return LIST_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
function cancelDefaultEvents(ed, e) {
|
||||
// list escape is done manually using outdent as it does not create paragraphs correctly in td's
|
||||
if (state == LIST_TABBING || state == LIST_EMPTY_ITEM || tinymce.isGecko && state == LIST_ESCAPE) {
|
||||
Event.cancel(e);
|
||||
}
|
||||
}
|
||||
|
||||
function isCursorAtEndOfContainer() {
|
||||
var range = ed.selection.getRng(true);
|
||||
var startContainer = range.startContainer;
|
||||
if (startContainer.nodeType == 3) {
|
||||
var value = startContainer.nodeValue;
|
||||
if (tinymce.isIE9 && value.length > 1 && value.charCodeAt(value.length-1) == 32) {
|
||||
// IE9 places a space on the end of the text in some cases so ignore last char
|
||||
return (range.endOffset == value.length-1);
|
||||
} else {
|
||||
return (range.endOffset == value.length);
|
||||
}
|
||||
} else if (startContainer.nodeType == 1) {
|
||||
return range.endOffset == startContainer.childNodes.length;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
If we are at the end of a list item surrounded with an element, pressing enter should create a
|
||||
new list item instead without splitting the element e.g. don't want to create new P or H1 tag
|
||||
*/
|
||||
function isEndOfListItem() {
|
||||
var node = ed.selection.getNode();
|
||||
var validElements = 'h1,h2,h3,h4,h5,h6,p,div';
|
||||
var isLastParagraphOfLi = ed.dom.is(node, validElements) && node.parentNode.tagName === 'LI' && node.parentNode.lastChild === node;
|
||||
return ed.selection.isCollapsed() && isLastParagraphOfLi && isCursorAtEndOfContainer();
|
||||
}
|
||||
|
||||
// Creates a new list item after the current selection's list item parent
|
||||
function createNewLi(ed, e) {
|
||||
if (isEnterWithoutShift(e) && isEndOfListItem()) {
|
||||
var node = ed.selection.getNode();
|
||||
var li = ed.dom.create("li");
|
||||
var parentLi = ed.dom.getParent(node, 'li');
|
||||
ed.dom.insertAfter(li, parentLi);
|
||||
|
||||
// Move caret to new list element.
|
||||
if (tinymce.isIE6 || tinymce.isIE7 || tinyMCE.isIE8) {
|
||||
// Removed this line since it would create an odd < > tag and placing the caret inside an empty LI is handled and should be handled by the selection logic
|
||||
//li.appendChild(ed.dom.create(" ")); // IE needs an element within the bullet point
|
||||
ed.selection.setCursorLocation(li, 1);
|
||||
} else {
|
||||
ed.selection.setCursorLocation(li, 0);
|
||||
}
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function imageJoiningListItem(ed, e) {
|
||||
var prevSibling;
|
||||
|
||||
if (!tinymce.isGecko)
|
||||
return;
|
||||
|
||||
var n = ed.selection.getStart();
|
||||
if (e.keyCode != tinymce.VK.BACKSPACE || n.tagName !== 'IMG')
|
||||
return;
|
||||
|
||||
function lastLI(node) {
|
||||
var child = node.firstChild;
|
||||
var li = null;
|
||||
do {
|
||||
if (!child)
|
||||
break;
|
||||
|
||||
if (child.tagName === 'LI')
|
||||
li = child;
|
||||
} while (child = child.nextSibling);
|
||||
|
||||
return li;
|
||||
}
|
||||
|
||||
function addChildren(parentNode, destination) {
|
||||
while (parentNode.childNodes.length > 0)
|
||||
destination.appendChild(parentNode.childNodes[0]);
|
||||
}
|
||||
|
||||
// Check if there is a previous sibling
|
||||
prevSibling = n.parentNode.previousSibling;
|
||||
if (!prevSibling)
|
||||
return;
|
||||
|
||||
var ul;
|
||||
if (prevSibling.tagName === 'UL' || prevSibling.tagName === 'OL')
|
||||
ul = prevSibling;
|
||||
else if (prevSibling.previousSibling && (prevSibling.previousSibling.tagName === 'UL' || prevSibling.previousSibling.tagName === 'OL'))
|
||||
ul = prevSibling.previousSibling;
|
||||
else
|
||||
return;
|
||||
|
||||
var li = lastLI(ul);
|
||||
|
||||
// move the caret to the end of the list item
|
||||
var rng = ed.dom.createRng();
|
||||
rng.setStart(li, 1);
|
||||
rng.setEnd(li, 1);
|
||||
ed.selection.setRng(rng);
|
||||
ed.selection.collapse(true);
|
||||
|
||||
// save a bookmark at the end of the list item
|
||||
var bookmark = ed.selection.getBookmark();
|
||||
|
||||
// copy the image an its text to the list item
|
||||
var clone = n.parentNode.cloneNode(true);
|
||||
if (clone.tagName === 'P' || clone.tagName === 'DIV')
|
||||
addChildren(clone, li);
|
||||
else
|
||||
li.appendChild(clone);
|
||||
|
||||
// remove the old copy of the image
|
||||
n.parentNode.parentNode.removeChild(n.parentNode);
|
||||
|
||||
// move the caret where we saved the bookmark
|
||||
ed.selection.moveToBookmark(bookmark);
|
||||
}
|
||||
|
||||
// fix the cursor position to ensure it is correct in IE
|
||||
function setCursorPositionToOriginalLi(li) {
|
||||
var list = ed.dom.getParent(li, 'ol,ul');
|
||||
if (list != null) {
|
||||
var lastLi = list.lastChild;
|
||||
// Removed this line since IE9 would report an DOM character error and placing the caret inside an empty LI is handled and should be handled by the selection logic
|
||||
//lastLi.appendChild(ed.getDoc().createElement(''));
|
||||
ed.selection.setCursorLocation(lastLi, 0);
|
||||
}
|
||||
}
|
||||
|
||||
this.ed = ed;
|
||||
ed.addCommand('Indent', this.indent, this);
|
||||
ed.addCommand('Outdent', this.outdent, this);
|
||||
ed.addCommand('InsertUnorderedList', function() {
|
||||
this.applyList('UL', 'OL');
|
||||
}, this);
|
||||
ed.addCommand('InsertOrderedList', function() {
|
||||
this.applyList('OL', 'UL');
|
||||
}, this);
|
||||
|
||||
ed.onInit.add(function() {
|
||||
ed.editorCommands.addCommands({
|
||||
'outdent': function() {
|
||||
var sel = ed.selection, dom = ed.dom;
|
||||
|
||||
function hasStyleIndent(n) {
|
||||
n = dom.getParent(n, dom.isBlock);
|
||||
return n && (parseInt(ed.dom.getStyle(n, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(n, 'padding-left') || 0, 10)) > 0;
|
||||
}
|
||||
|
||||
return hasStyleIndent(sel.getStart()) || hasStyleIndent(sel.getEnd()) || ed.queryCommandState('InsertOrderedList') || ed.queryCommandState('InsertUnorderedList');
|
||||
}
|
||||
}, 'state');
|
||||
});
|
||||
|
||||
ed.onKeyUp.add(function(ed, e) {
|
||||
if (state == LIST_TABBING) {
|
||||
ed.execCommand(e.shiftKey ? 'Outdent' : 'Indent', true, null);
|
||||
state = LIST_UNKNOWN;
|
||||
return Event.cancel(e);
|
||||
} else if (state == LIST_EMPTY_ITEM) {
|
||||
var li = getLi();
|
||||
var shouldOutdent = ed.settings.list_outdent_on_enter === true || e.shiftKey;
|
||||
ed.execCommand(shouldOutdent ? 'Outdent' : 'Indent', true, null);
|
||||
if (tinymce.isIE) {
|
||||
setCursorPositionToOriginalLi(li);
|
||||
}
|
||||
|
||||
return Event.cancel(e);
|
||||
} else if (state == LIST_ESCAPE) {
|
||||
if (tinymce.isIE6 || tinymce.isIE7 || tinymce.isIE8) {
|
||||
// append a zero sized nbsp so that caret is positioned correctly in IE after escaping and applying formatting.
|
||||
// if there is no text then applying formatting for e.g a H1 to the P tag immediately following list after
|
||||
// escaping from it will cause the caret to be positioned on the last li instead of staying the in P tag.
|
||||
var n = ed.getDoc().createTextNode('\uFEFF');
|
||||
ed.selection.getNode().appendChild(n);
|
||||
} else if (tinymce.isIE9 || tinymce.isGecko) {
|
||||
// IE9 does not escape the list so we use outdent to do this and cancel the default behaviour
|
||||
// Gecko does not create a paragraph outdenting inside a TD so default behaviour is cancelled and we outdent ourselves
|
||||
ed.execCommand('Outdent');
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function fixListItem(parent, reference) {
|
||||
// a zero-sized non-breaking space is placed in the empty list item so that the nested list is
|
||||
// displayed on the below line instead of next to it
|
||||
var n = ed.getDoc().createTextNode('\uFEFF');
|
||||
parent.insertBefore(n, reference);
|
||||
ed.selection.setCursorLocation(n, 0);
|
||||
// repaint to remove rendering artifact. only visible when creating new list
|
||||
ed.execCommand('mceRepaint');
|
||||
}
|
||||
|
||||
function fixIndentedListItemForGecko(ed, e) {
|
||||
if (isEnter(e)) {
|
||||
var li = getLi();
|
||||
if (li) {
|
||||
var parent = li.parentNode;
|
||||
var grandParent = parent && parent.parentNode;
|
||||
if (grandParent && grandParent.nodeName == 'LI' && grandParent.firstChild == parent && li == parent.firstChild) {
|
||||
fixListItem(grandParent, parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixIndentedListItemForIE8(ed, e) {
|
||||
if (isEnter(e)) {
|
||||
var li = getLi();
|
||||
if (ed.dom.select('ul li', li).length === 1) {
|
||||
var list = li.firstChild;
|
||||
fixListItem(li, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixDeletingFirstCharOfList(ed, e) {
|
||||
function listElements(list, li) {
|
||||
var elements = [];
|
||||
var walker = new tinymce.dom.TreeWalker(li, list);
|
||||
for (var node = walker.current(); node; node = walker.next()) {
|
||||
if (ed.dom.is(node, 'ol,ul,li')) {
|
||||
elements.push(node);
|
||||
}
|
||||
}
|
||||
return elements;
|
||||
}
|
||||
|
||||
if (e.keyCode == tinymce.VK.BACKSPACE) {
|
||||
var li = getLi();
|
||||
if (li) {
|
||||
var list = ed.dom.getParent(li, 'ol,ul');
|
||||
if (list && list.firstChild === li) {
|
||||
var elements = listElements(list, li);
|
||||
ed.execCommand("Outdent", false, elements);
|
||||
ed.undoManager.add();
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fixDeletingEmptyLiInWebkit(ed, e) {
|
||||
var li = getLi();
|
||||
if (e.keyCode === tinymce.VK.BACKSPACE && ed.dom.is(li, 'li') && li.parentNode.firstChild!==li) {
|
||||
if (ed.dom.select('ul,ol', li).length === 1) {
|
||||
var prevLi = li.previousSibling;
|
||||
ed.dom.remove(ed.dom.select('br', li));
|
||||
ed.dom.remove(li, true);
|
||||
var textNodes = tinymce.grep(prevLi.childNodes, function(n){ return n.nodeType === 3 });
|
||||
if (textNodes.length === 1) {
|
||||
var textNode = textNodes[0]
|
||||
ed.selection.setCursorLocation(textNode, textNode.length);
|
||||
}
|
||||
ed.undoManager.add();
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ed.onKeyDown.add(function(_, e) { state = getListKeyState(e); });
|
||||
ed.onKeyDown.add(cancelDefaultEvents);
|
||||
ed.onKeyDown.add(imageJoiningListItem);
|
||||
ed.onKeyDown.add(createNewLi);
|
||||
|
||||
if (tinymce.isGecko) {
|
||||
ed.onKeyUp.add(fixIndentedListItemForGecko);
|
||||
}
|
||||
if (tinymce.isIE8) {
|
||||
ed.onKeyUp.add(fixIndentedListItemForIE8);
|
||||
}
|
||||
if (tinymce.isGecko || tinymce.isWebKit) {
|
||||
ed.onKeyDown.add(fixDeletingFirstCharOfList);
|
||||
}
|
||||
if (tinymce.isWebKit) {
|
||||
ed.onKeyDown.add(fixDeletingEmptyLiInWebkit);
|
||||
}
|
||||
},
|
||||
|
||||
applyList: function(targetListType, oppositeListType) {
|
||||
var t = this, ed = t.ed, dom = ed.dom, applied = [], hasSameType = false, hasOppositeType = false, hasNonList = false, actions,
|
||||
selectedBlocks = ed.selection.getSelectedBlocks();
|
||||
|
||||
function cleanupBr(e) {
|
||||
if (e && e.tagName === 'BR') {
|
||||
dom.remove(e);
|
||||
}
|
||||
}
|
||||
|
||||
function makeList(element) {
|
||||
var list = dom.create(targetListType), li;
|
||||
|
||||
function adjustIndentForNewList(element) {
|
||||
// If there's a margin-left, outdent one level to account for the extra list margin.
|
||||
if (element.style.marginLeft || element.style.paddingLeft) {
|
||||
t.adjustPaddingFunction(false)(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (element.tagName === 'LI') {
|
||||
// No change required.
|
||||
} else if (element.tagName === 'P' || element.tagName === 'DIV' || element.tagName === 'BODY') {
|
||||
processBrs(element, function(startSection, br) {
|
||||
doWrapList(startSection, br, element.tagName === 'BODY' ? null : startSection.parentNode);
|
||||
li = startSection.parentNode;
|
||||
adjustIndentForNewList(li);
|
||||
cleanupBr(br);
|
||||
});
|
||||
if (li) {
|
||||
if (li.tagName === 'LI' && (element.tagName === 'P' || selectedBlocks.length > 1)) {
|
||||
dom.split(li.parentNode.parentNode, li.parentNode);
|
||||
}
|
||||
attemptMergeWithAdjacent(li.parentNode, true);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Put the list around the element.
|
||||
li = dom.create('li');
|
||||
dom.insertAfter(li, element);
|
||||
li.appendChild(element);
|
||||
adjustIndentForNewList(element);
|
||||
element = li;
|
||||
}
|
||||
dom.insertAfter(list, element);
|
||||
list.appendChild(element);
|
||||
attemptMergeWithAdjacent(list, true);
|
||||
applied.push(element);
|
||||
}
|
||||
|
||||
function doWrapList(start, end, template) {
|
||||
var li, n = start, tmp;
|
||||
while (!dom.isBlock(start.parentNode) && start.parentNode !== dom.getRoot()) {
|
||||
start = dom.split(start.parentNode, start.previousSibling);
|
||||
start = start.nextSibling;
|
||||
n = start;
|
||||
}
|
||||
if (template) {
|
||||
li = template.cloneNode(true);
|
||||
start.parentNode.insertBefore(li, start);
|
||||
while (li.firstChild) dom.remove(li.firstChild);
|
||||
li = dom.rename(li, 'li');
|
||||
} else {
|
||||
li = dom.create('li');
|
||||
start.parentNode.insertBefore(li, start);
|
||||
}
|
||||
while (n && n != end) {
|
||||
tmp = n.nextSibling;
|
||||
li.appendChild(n);
|
||||
n = tmp;
|
||||
}
|
||||
if (li.childNodes.length === 0) {
|
||||
li.innerHTML = '<br _mce_bogus="1" />';
|
||||
}
|
||||
makeList(li);
|
||||
}
|
||||
|
||||
function processBrs(element, callback) {
|
||||
var startSection, previousBR, END_TO_START = 3, START_TO_END = 1,
|
||||
breakElements = 'br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl';
|
||||
|
||||
function isAnyPartSelected(start, end) {
|
||||
var r = dom.createRng(), sel;
|
||||
bookmark.keep = true;
|
||||
ed.selection.moveToBookmark(bookmark);
|
||||
bookmark.keep = false;
|
||||
sel = ed.selection.getRng(true);
|
||||
if (!end) {
|
||||
end = start.parentNode.lastChild;
|
||||
}
|
||||
r.setStartBefore(start);
|
||||
r.setEndAfter(end);
|
||||
return !(r.compareBoundaryPoints(END_TO_START, sel) > 0 || r.compareBoundaryPoints(START_TO_END, sel) <= 0);
|
||||
}
|
||||
|
||||
function nextLeaf(br) {
|
||||
if (br.nextSibling)
|
||||
return br.nextSibling;
|
||||
if (!dom.isBlock(br.parentNode) && br.parentNode !== dom.getRoot())
|
||||
return nextLeaf(br.parentNode);
|
||||
}
|
||||
|
||||
// Split on BRs within the range and process those.
|
||||
startSection = element.firstChild;
|
||||
// First mark the BRs that have any part of the previous section selected.
|
||||
var trailingContentSelected = false;
|
||||
each(dom.select(breakElements, element), function(br) {
|
||||
if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
|
||||
return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
|
||||
}
|
||||
if (isAnyPartSelected(startSection, br)) {
|
||||
dom.addClass(br, '_mce_tagged_br');
|
||||
startSection = nextLeaf(br);
|
||||
}
|
||||
});
|
||||
trailingContentSelected = (startSection && isAnyPartSelected(startSection, undefined));
|
||||
startSection = element.firstChild;
|
||||
each(dom.select(breakElements, element), function(br) {
|
||||
// Got a section from start to br.
|
||||
var tmp = nextLeaf(br);
|
||||
if (br.hasAttribute && br.hasAttribute('_mce_bogus')) {
|
||||
return true; // Skip the bogus Brs that are put in to appease Firefox and Safari.
|
||||
}
|
||||
if (dom.hasClass(br, '_mce_tagged_br')) {
|
||||
callback(startSection, br, previousBR);
|
||||
previousBR = null;
|
||||
} else {
|
||||
previousBR = br;
|
||||
}
|
||||
startSection = tmp;
|
||||
});
|
||||
if (trailingContentSelected) {
|
||||
callback(startSection, undefined, previousBR);
|
||||
}
|
||||
}
|
||||
|
||||
function wrapList(element) {
|
||||
processBrs(element, function(startSection, br, previousBR) {
|
||||
// Need to indent this part
|
||||
doWrapList(startSection, br);
|
||||
cleanupBr(br);
|
||||
cleanupBr(previousBR);
|
||||
});
|
||||
}
|
||||
|
||||
function changeList(element) {
|
||||
if (tinymce.inArray(applied, element) !== -1) {
|
||||
return;
|
||||
}
|
||||
if (element.parentNode.tagName === oppositeListType) {
|
||||
dom.split(element.parentNode, element);
|
||||
makeList(element);
|
||||
attemptMergeWithNext(element.parentNode, false);
|
||||
}
|
||||
applied.push(element);
|
||||
}
|
||||
|
||||
function convertListItemToParagraph(element) {
|
||||
var child, nextChild, mergedElement, splitLast;
|
||||
if (tinymce.inArray(applied, element) !== -1) {
|
||||
return;
|
||||
}
|
||||
element = splitNestedLists(element, dom);
|
||||
while (dom.is(element.parentNode, 'ol,ul,li')) {
|
||||
dom.split(element.parentNode, element);
|
||||
}
|
||||
// Push the original element we have from the selection, not the renamed one.
|
||||
applied.push(element);
|
||||
element = dom.rename(element, 'p');
|
||||
mergedElement = attemptMergeWithAdjacent(element, false, ed.settings.force_br_newlines);
|
||||
if (mergedElement === element) {
|
||||
// Now split out any block elements that can't be contained within a P.
|
||||
// Manually iterate to ensure we handle modifications correctly (doesn't work with tinymce.each)
|
||||
child = element.firstChild;
|
||||
while (child) {
|
||||
if (dom.isBlock(child)) {
|
||||
child = dom.split(child.parentNode, child);
|
||||
splitLast = true;
|
||||
nextChild = child.nextSibling && child.nextSibling.firstChild;
|
||||
} else {
|
||||
nextChild = child.nextSibling;
|
||||
if (splitLast && child.tagName === 'BR') {
|
||||
dom.remove(child);
|
||||
}
|
||||
splitLast = false;
|
||||
}
|
||||
child = nextChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
each(selectedBlocks, function(e) {
|
||||
e = findItemToOperateOn(e, dom);
|
||||
if (e.tagName === oppositeListType || (e.tagName === 'LI' && e.parentNode.tagName === oppositeListType)) {
|
||||
hasOppositeType = true;
|
||||
} else if (e.tagName === targetListType || (e.tagName === 'LI' && e.parentNode.tagName === targetListType)) {
|
||||
hasSameType = true;
|
||||
} else {
|
||||
hasNonList = true;
|
||||
}
|
||||
});
|
||||
|
||||
if (hasNonList &&!hasSameType || hasOppositeType || selectedBlocks.length === 0) {
|
||||
actions = {
|
||||
'LI': changeList,
|
||||
'H1': makeList,
|
||||
'H2': makeList,
|
||||
'H3': makeList,
|
||||
'H4': makeList,
|
||||
'H5': makeList,
|
||||
'H6': makeList,
|
||||
'P': makeList,
|
||||
'BODY': makeList,
|
||||
'DIV': selectedBlocks.length > 1 ? makeList : wrapList,
|
||||
defaultAction: wrapList,
|
||||
elements: this.selectedBlocks()
|
||||
};
|
||||
} else {
|
||||
actions = {
|
||||
defaultAction: convertListItemToParagraph,
|
||||
elements: this.selectedBlocks()
|
||||
};
|
||||
}
|
||||
this.process(actions);
|
||||
},
|
||||
|
||||
indent: function() {
|
||||
var ed = this.ed, dom = ed.dom, indented = [];
|
||||
|
||||
function createWrapItem(element) {
|
||||
var wrapItem = dom.create('li', { style: 'list-style-type: none;'});
|
||||
dom.insertAfter(wrapItem, element);
|
||||
return wrapItem;
|
||||
}
|
||||
|
||||
function createWrapList(element) {
|
||||
var wrapItem = createWrapItem(element),
|
||||
list = dom.getParent(element, 'ol,ul'),
|
||||
listType = list.tagName,
|
||||
listStyle = dom.getStyle(list, 'list-style-type'),
|
||||
attrs = {},
|
||||
wrapList;
|
||||
if (listStyle !== '') {
|
||||
attrs.style = 'list-style-type: ' + listStyle + ';';
|
||||
}
|
||||
wrapList = dom.create(listType, attrs);
|
||||
wrapItem.appendChild(wrapList);
|
||||
return wrapList;
|
||||
}
|
||||
|
||||
function indentLI(element) {
|
||||
if (!hasParentInList(ed, element, indented)) {
|
||||
element = splitNestedLists(element, dom);
|
||||
var wrapList = createWrapList(element);
|
||||
wrapList.appendChild(element);
|
||||
attemptMergeWithAdjacent(wrapList.parentNode, false);
|
||||
attemptMergeWithAdjacent(wrapList, false);
|
||||
indented.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
this.process({
|
||||
'LI': indentLI,
|
||||
defaultAction: this.adjustPaddingFunction(true),
|
||||
elements: this.selectedBlocks()
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
outdent: function(ui, elements) {
|
||||
var t = this, ed = t.ed, dom = ed.dom, outdented = [];
|
||||
|
||||
function outdentLI(element) {
|
||||
var listElement, targetParent, align;
|
||||
if (!hasParentInList(ed, element, outdented)) {
|
||||
if (dom.getStyle(element, 'margin-left') !== '' || dom.getStyle(element, 'padding-left') !== '') {
|
||||
return t.adjustPaddingFunction(false)(element);
|
||||
}
|
||||
align = dom.getStyle(element, 'text-align', true);
|
||||
if (align === 'center' || align === 'right') {
|
||||
dom.setStyle(element, 'text-align', 'left');
|
||||
return;
|
||||
}
|
||||
element = splitNestedLists(element, dom);
|
||||
listElement = element.parentNode;
|
||||
targetParent = element.parentNode.parentNode;
|
||||
if (targetParent.tagName === 'P') {
|
||||
dom.split(targetParent, element.parentNode);
|
||||
} else {
|
||||
dom.split(listElement, element);
|
||||
if (targetParent.tagName === 'LI') {
|
||||
// Nested list, need to split the LI and go back out to the OL/UL element.
|
||||
dom.split(targetParent, element);
|
||||
} else if (!dom.is(targetParent, 'ol,ul')) {
|
||||
dom.rename(element, 'p');
|
||||
}
|
||||
}
|
||||
outdented.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
var listElements = elements && tinymce.is(elements, 'array') ? elements : this.selectedBlocks();
|
||||
this.process({
|
||||
'LI': outdentLI,
|
||||
defaultAction: this.adjustPaddingFunction(false),
|
||||
elements: listElements
|
||||
});
|
||||
|
||||
each(outdented, attemptMergeWithAdjacent);
|
||||
},
|
||||
|
||||
process: function(actions) {
|
||||
var t = this, sel = t.ed.selection, dom = t.ed.dom, selectedBlocks, r;
|
||||
|
||||
function isEmptyElement(element) {
|
||||
var excludeBrsAndBookmarks = tinymce.grep(element.childNodes, function(n) {
|
||||
return !(n.nodeName === 'BR' || n.nodeName === 'SPAN' && dom.getAttrib(n, 'data-mce-type') == 'bookmark'
|
||||
|| n.nodeType == 3 && (n.nodeValue == String.fromCharCode(160) || n.nodeValue == ''));
|
||||
});
|
||||
return excludeBrsAndBookmarks.length === 0;
|
||||
}
|
||||
|
||||
function processElement(element) {
|
||||
dom.removeClass(element, '_mce_act_on');
|
||||
if (!element || element.nodeType !== 1 || selectedBlocks.length > 1 && isEmptyElement(element)) {
|
||||
return;
|
||||
}
|
||||
element = findItemToOperateOn(element, dom);
|
||||
var action = actions[element.tagName];
|
||||
if (!action) {
|
||||
action = actions.defaultAction;
|
||||
}
|
||||
action(element);
|
||||
}
|
||||
|
||||
function recurse(element) {
|
||||
t.splitSafeEach(element.childNodes, processElement);
|
||||
}
|
||||
|
||||
function brAtEdgeOfSelection(container, offset) {
|
||||
return offset >= 0 && container.hasChildNodes() && offset < container.childNodes.length &&
|
||||
container.childNodes[offset].tagName === 'BR';
|
||||
}
|
||||
|
||||
function isInTable() {
|
||||
var n = sel.getNode();
|
||||
var p = dom.getParent(n, 'td');
|
||||
return p !== null;
|
||||
}
|
||||
|
||||
selectedBlocks = actions.elements;
|
||||
|
||||
r = sel.getRng(true);
|
||||
if (!r.collapsed) {
|
||||
if (brAtEdgeOfSelection(r.endContainer, r.endOffset - 1)) {
|
||||
r.setEnd(r.endContainer, r.endOffset - 1);
|
||||
sel.setRng(r);
|
||||
}
|
||||
if (brAtEdgeOfSelection(r.startContainer, r.startOffset)) {
|
||||
r.setStart(r.startContainer, r.startOffset + 1);
|
||||
sel.setRng(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tinymce.isIE8) {
|
||||
// append a zero sized nbsp so that caret is restored correctly using bookmark
|
||||
var s = t.ed.selection.getNode();
|
||||
if (s.tagName === 'LI' && !(s.parentNode.lastChild === s)) {
|
||||
var i = t.ed.getDoc().createTextNode('\uFEFF');
|
||||
s.appendChild(i);
|
||||
}
|
||||
}
|
||||
|
||||
bookmark = sel.getBookmark();
|
||||
actions.OL = actions.UL = recurse;
|
||||
t.splitSafeEach(selectedBlocks, processElement);
|
||||
sel.moveToBookmark(bookmark);
|
||||
bookmark = null;
|
||||
|
||||
// we avoid doing repaint in a table as this will move the caret out of the table in Firefox 3.6
|
||||
if (!isInTable()) {
|
||||
// Avoids table or image handles being left behind in Firefox.
|
||||
t.ed.execCommand('mceRepaint');
|
||||
}
|
||||
},
|
||||
|
||||
splitSafeEach: function(elements, f) {
|
||||
if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) ||
|
||||
/Firefox\/3\.[0-4]/.test(navigator.userAgent))) {
|
||||
this.classBasedEach(elements, f);
|
||||
} else {
|
||||
each(elements, f);
|
||||
}
|
||||
},
|
||||
|
||||
classBasedEach: function(elements, f) {
|
||||
var dom = this.ed.dom, nodes, element;
|
||||
// Mark nodes
|
||||
each(elements, function(element) {
|
||||
dom.addClass(element, '_mce_act_on');
|
||||
});
|
||||
nodes = dom.select('._mce_act_on');
|
||||
while (nodes.length > 0) {
|
||||
element = nodes.shift();
|
||||
dom.removeClass(element, '_mce_act_on');
|
||||
f(element);
|
||||
nodes = dom.select('._mce_act_on');
|
||||
}
|
||||
},
|
||||
|
||||
adjustPaddingFunction: function(isIndent) {
|
||||
var indentAmount, indentUnits, ed = this.ed;
|
||||
indentAmount = ed.settings.indentation;
|
||||
indentUnits = /[a-z%]+/i.exec(indentAmount);
|
||||
indentAmount = parseInt(indentAmount, 10);
|
||||
return function(element) {
|
||||
var currentIndent, newIndentAmount;
|
||||
currentIndent = parseInt(ed.dom.getStyle(element, 'margin-left') || 0, 10) + parseInt(ed.dom.getStyle(element, 'padding-left') || 0, 10);
|
||||
if (isIndent) {
|
||||
newIndentAmount = currentIndent + indentAmount;
|
||||
} else {
|
||||
newIndentAmount = currentIndent - indentAmount;
|
||||
}
|
||||
ed.dom.setStyle(element, 'padding-left', '');
|
||||
ed.dom.setStyle(element, 'margin-left', newIndentAmount > 0 ? newIndentAmount + indentUnits : '');
|
||||
};
|
||||
},
|
||||
|
||||
selectedBlocks: function() {
|
||||
var ed = this.ed
|
||||
var selectedBlocks = ed.selection.getSelectedBlocks();
|
||||
return selectedBlocks.length == 0 ? [ ed.dom.getRoot() ] : selectedBlocks;
|
||||
},
|
||||
|
||||
getInfo: function() {
|
||||
return {
|
||||
longname : 'Lists',
|
||||
author : 'Moxiecode Systems AB',
|
||||
authorurl : 'http://tinymce.moxiecode.com',
|
||||
infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/lists',
|
||||
version : tinymce.majorVersion + "." + tinymce.minorVersion
|
||||
};
|
||||
}
|
||||
});
|
||||
tinymce.PluginManager.add("lists", tinymce.plugins.Lists);
|
||||
}());
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -261,12 +261,96 @@
|
|||
selection.collapse(start);
|
||||
}
|
||||
|
||||
function canDelete(backspace) {
|
||||
var rng, container, offset, nonEditableParent;
|
||||
|
||||
function removeNodeIfNotParent(node) {
|
||||
var parent = container;
|
||||
|
||||
while (parent) {
|
||||
if (parent === node) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
dom.remove(node);
|
||||
moveSelection();
|
||||
}
|
||||
|
||||
function isNextPrevTreeNodeNonEditable() {
|
||||
var node, walker, nonEmptyElements = ed.schema.getNonEmptyElements();
|
||||
|
||||
walker = new tinymce.dom.TreeWalker(container, ed.getBody());
|
||||
while (node = (backspace ? walker.prev() : walker.next())) {
|
||||
// Found IMG/INPUT etc
|
||||
if (nonEmptyElements[node.nodeName.toLowerCase()]) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found text node with contents
|
||||
if (node.nodeType === 3 && tinymce.trim(node.nodeValue).length > 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Found non editable node
|
||||
if (getContentEditable(node) === "false") {
|
||||
removeNodeIfNotParent(node);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the content node is within a non editable parent
|
||||
if (getNonEditableParent(node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selection.isCollapsed()) {
|
||||
rng = selection.getRng(true);
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
container = getParentCaretContainer(container) || container;
|
||||
|
||||
// Is in noneditable parent
|
||||
if (nonEditableParent = getNonEditableParent(container)) {
|
||||
removeNodeIfNotParent(nonEditableParent);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the caret is in the middle of a text node
|
||||
if (container.nodeType == 3 && (backspace ? offset > 0 : offset < container.nodeValue.length)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Resolve container index
|
||||
if (container.nodeType == 1) {
|
||||
container = container.childNodes[offset] || container;
|
||||
}
|
||||
|
||||
// Check if previous or next tree node is non editable then block the event
|
||||
if (isNextPrevTreeNodeNonEditable()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
startElement = selection.getStart()
|
||||
endElement = selection.getEnd();
|
||||
|
||||
// Disable all key presses in contentEditable=false except delete or backspace
|
||||
nonEditableParent = getNonEditableParent(startElement) || getNonEditableParent(endElement);
|
||||
if (nonEditableParent && (keyCode < 112 || keyCode > 124) && keyCode != VK.DELETE && keyCode != VK.BACKSPACE) {
|
||||
// Is Ctrl+c, Ctrl+v or Ctrl+x then use default browser behavior
|
||||
if ((tinymce.isMac ? e.metaKey : e.ctrlKey) && (keyCode == 67 || keyCode == 88 || keyCode == 86)) {
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
// Arrow left/right select the element and collapse left/right
|
||||
|
|
@ -298,6 +382,7 @@
|
|||
positionCaretOnElement(nonEditableParent, true);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
|
|
@ -315,23 +400,31 @@
|
|||
positionCaretOnElement(nonEditableParent, false);
|
||||
} else {
|
||||
dom.remove(nonEditableParent);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
removeCaretContainer(caretContainer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((keyCode == VK.BACKSPACE || keyCode == VK.DELETE) && !canDelete(keyCode == VK.BACKSPACE)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ed.onMouseDown.addToTop(function(ed, e){
|
||||
// prevent collapsing selection to caret when clicking in a non-editable section
|
||||
ed.onMouseDown.addToTop(function(ed, e) {
|
||||
var node = ed.selection.getNode();
|
||||
|
||||
if (getContentEditable(node) === "false" && node == e.target) {
|
||||
e.preventDefault();
|
||||
// Expand selection on mouse down we can't block the default event since it's used for drag/drop
|
||||
moveSelection();
|
||||
}
|
||||
});
|
||||
|
||||
ed.onMouseUp.addToTop(moveSelection);
|
||||
ed.onKeyDown.addToTop(handleKey);
|
||||
ed.onKeyUp.addToTop(moveSelection);
|
||||
|
|
@ -341,6 +434,31 @@
|
|||
init : function(ed, url) {
|
||||
var editClass, nonEditClass, nonEditableRegExps;
|
||||
|
||||
// Converts configured regexps to noneditable span items
|
||||
function convertRegExpsToNonEditable(ed, args) {
|
||||
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (args.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], function(match) {
|
||||
var args = arguments, index = args[args.length - 2];
|
||||
|
||||
// Is value inside an attribute then don't replace
|
||||
if (index > 0 && content.charAt(index - 1) == '"') {
|
||||
return match;
|
||||
}
|
||||
|
||||
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
args.content = content;
|
||||
};
|
||||
|
||||
editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " ";
|
||||
nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " ";
|
||||
|
||||
|
|
@ -354,26 +472,10 @@
|
|||
handleContentEditableSelection(ed);
|
||||
|
||||
if (nonEditableRegExps) {
|
||||
ed.onBeforeSetContent.add(function(ed, args) {
|
||||
var i = nonEditableRegExps.length, content = args.content, cls = tinymce.trim(nonEditClass);
|
||||
|
||||
// Don't replace the variables when raw is used for example on undo/redo
|
||||
if (args.format == "raw") {
|
||||
return;
|
||||
}
|
||||
|
||||
while (i--) {
|
||||
content = content.replace(nonEditableRegExps[i], function() {
|
||||
var args = arguments;
|
||||
|
||||
return '<span class="' + cls + '" data-mce-content="' + ed.dom.encode(args[0]) + '">' + ed.dom.encode(typeof(args[1]) === "string" ? args[1] : args[0]) + '</span>';
|
||||
});
|
||||
}
|
||||
|
||||
args.content = content;
|
||||
});
|
||||
ed.selection.onBeforeSetContent.add(convertRegExpsToNonEditable);
|
||||
ed.onBeforeSetContent.add(convertRegExpsToNonEditable);
|
||||
}
|
||||
|
||||
|
||||
// Apply contentEditable true/false on elements with the noneditable/editable classes
|
||||
ed.parser.addAttributeFilter('class', function(nodes) {
|
||||
var i = nodes.length, className, node;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -359,7 +359,7 @@
|
|||
}
|
||||
|
||||
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
|
||||
if (tinymce.isIE && document.documentMode >= 9) {
|
||||
if (tinymce.isIE && document.documentMode >= 9 && /<(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)/.test(o.content)) {
|
||||
// IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser
|
||||
process([[/(?:<br> [\s\r\n]+|<br>)*(<\/?(h[1-6r]|p|div|address|pre|form|table|tbody|thead|tfoot|th|tr|td|li|ol|ul|caption|blockquote|center|dl|dt|dd|dir|fieldset)[^>]*>)(?:<br> [\s\r\n]+|<br>)*/g, '$1']]);
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();
|
||||
(function(){var c=tinymce.DOM,a=tinymce.dom.Event,d=tinymce.each,b=tinymce.explode;tinymce.create("tinymce.plugins.TabFocusPlugin",{init:function(f,g){function e(i,j){if(j.keyCode===9){return a.cancel(j)}}function h(l,p){var j,m,o,n,k;function q(t){n=c.select(":input:enabled,*[tabindex]:not(iframe)");function s(v){return v.nodeName==="BODY"||(v.type!="hidden"&&!(v.style.display=="none")&&!(v.style.visibility=="hidden")&&s(v.parentNode))}function i(v){return v.attributes.tabIndex.specified||v.nodeName=="INPUT"||v.nodeName=="TEXTAREA"}function u(){return tinymce.isIE6||tinymce.isIE7}function r(v){return((!u()||i(v)))&&v.getAttribute("tabindex")!="-1"&&s(v)}d(n,function(w,v){if(w.id==l.id){j=v;return false}});if(t>0){for(m=j+1;m<n.length;m++){if(r(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(r(n[m])){return n[m]}}}return null}if(p.keyCode===9){k=b(l.getParam("tab_focus",l.getParam("tabfocus_elements",":prev,:next")));if(k.length==1){k[1]=k[0];k[0]=":prev"}if(p.shiftKey){if(k[0]==":prev"){n=q(-1)}else{n=c.get(k[0])}}else{if(k[1]==":next"){n=q(1)}else{n=c.get(k[1])}}if(n){if(n.id&&(l=tinymce.get(n.id||n.name))){l.focus()}else{window.setTimeout(function(){if(!tinymce.isWebKit){window.focus()}n.focus()},10)}return a.cancel(p)}}}f.onKeyUp.add(e);if(tinymce.isGecko){f.onKeyPress.add(h);f.onKeyDown.add(e)}else{f.onKeyDown.add(h)}},getInfo:function(){return{longname:"Tabfocus",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/tabfocus",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("tabfocus",tinymce.plugins.TabFocusPlugin)})();
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
var x, i, f, el, v;
|
||||
|
||||
function find(d) {
|
||||
el = DOM.select(':input:enabled,*[tabindex]');
|
||||
el = DOM.select(':input:enabled,*[tabindex]:not(iframe)');
|
||||
|
||||
function canSelectRecursive(e) {
|
||||
return e.nodeName==="BODY" || (e.type != 'hidden' &&
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ function updateAction() {
|
|||
do {
|
||||
if (cell == tdElm)
|
||||
break;
|
||||
col += cell.getAttribute("colspan");
|
||||
col += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
|
||||
} while ((cell = nextCell(cell)) != null);
|
||||
|
||||
for (var i=0; i<rows.length; i++) {
|
||||
|
|
@ -152,7 +152,7 @@ function updateAction() {
|
|||
cell = updateCell(cell, true);
|
||||
break;
|
||||
}
|
||||
curr += cell.getAttribute("colspan");
|
||||
curr += cell.getAttribute("colspan")?cell.getAttribute("colspan"):1;
|
||||
} while ((cell = nextCell(cell)) != null);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre {margin-left: 3px}
|
||||
section, article, address, hgroup, aside {margin: 1em 0 0 3px}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, blockquote, address, pre, figure {display: block; padding-top: 10px; border: 1px dashed #BBB; background: transparent no-repeat}
|
||||
p, h1, h2, h3, h4, h5, h6, hgroup, aside, div, section, article, address, pre, figure {margin-left: 3px}
|
||||
section, article, address, hgroup, aside, figure {margin: 0 0 1em 3px}
|
||||
|
||||
p {background-image: url(data:image/gif;base64,R0lGODlhCQAJAJEAAAAAAP///7u7u////yH5BAEAAAMALAAAAAAJAAkAAAIQnG+CqCN/mlyvsRUpThG6AgA7)}
|
||||
h1 {background-image: url(data:image/gif;base64,R0lGODlhDQAKAIABALu7u////yH5BAEAAAEALAAAAAANAAoAAAIXjI8GybGu1JuxHoAfRNRW3TWXyF2YiRUAOw==)}
|
||||
|
|
@ -17,3 +17,5 @@ address {background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH
|
|||
pre {background-image: url(data:image/gif;base64,R0lGODlhFQAKAIABALu7uwAAACH5BAEAAAEALAAAAAAVAAoAAAIjjI+ZoN0cgDwSmnpz1NCueYERhnibZVKLNnbOq8IvKpJtVQAAOw==)}
|
||||
hgroup {background-image: url(data:image/gif;base64,R0lGODlhJwAKAIABALu7uwAAACH5BAEAAAEALAAAAAAnAAoAAAI3jI+pywYNI3uB0gpsRtt5fFnfNZaVSYJil4Wo03Hv6Z62uOCgiXH1kZIIJ8NiIxRrAZNMZAtQAAA7)}
|
||||
aside {background-image: url(data:image/gif;base64,R0lGODlhHgAKAIABAKqqqv///yH5BAEAAAEALAAAAAAeAAoAAAItjI+pG8APjZOTzgtqy7I3f1yehmQcFY4WKZbqByutmW4aHUd6vfcVbgudgpYCADs=)}
|
||||
figure {background-image: url(data:image/gif;base64,R0lGODlhJAAKAIAAALu7u////yH5BAEAAAEALAAAAAAkAAoAAAI0jI+py+2fwAHUSFvD3RlvG4HIp4nX5JFSpnZUJ6LlrM52OE7uSWosBHScgkSZj7dDKnWAAgA7)}
|
||||
figcaption {border: 1px dashed #BBB}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks")}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();
|
||||
(function(){tinymce.create("tinymce.plugins.VisualBlocks",{init:function(a,b){var c;if(!window.NodeList){return}a.addCommand("mceVisualBlocks",function(){var e=a.dom,d;if(!c){c=e.uniqueId();d=e.create("link",{id:c,rel:"stylesheet",href:b+"/css/visualblocks.css"});a.getDoc().getElementsByTagName("head")[0].appendChild(d)}else{d=e.get(c);d.disabled=!d.disabled}a.controlManager.setActive("visualblocks",!d.disabled)});a.addButton("visualblocks",{title:"visualblocks.desc",cmd:"mceVisualBlocks"});a.onInit.add(function(){if(a.settings.visualblocks_default_state){a.execCommand("mceVisualBlocks",false,null,{skip_focus:true})}})},getInfo:function(){return{longname:"Visual blocks",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualblocks",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("visualblocks",tinymce.plugins.VisualBlocks)})();
|
||||
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
ed.onInit.add(function() {
|
||||
if (ed.settings.visualblocks_default_state) {
|
||||
ed.execCommand('mceVisualBlocks');
|
||||
ed.execCommand('mceVisualBlocks', false, null, {skip_focus : true});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -62,12 +62,8 @@
|
|||
|
||||
<div class="mceActionPanel">
|
||||
<input type="submit" id="insert" name="insert" value="{#apply}" />
|
||||
|
||||
<div id="preview"></div>
|
||||
|
||||
<div id="previewblock">
|
||||
<label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" />
|
||||
</div>
|
||||
<input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();"/>
|
||||
<div id="preview_wrapper"><div id="previewblock"><label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" /></div><span id="preview"></span></div>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -69,6 +69,16 @@
|
|||
each(previewStyles.split(' '), function(name) {
|
||||
var value = dom.getStyle(previewElm, name, true);
|
||||
|
||||
// If background is transparent then check if the body has a background color we can use
|
||||
if (name == 'background-color' && /transparent|rgba\s*\([^)]+,\s*0\)/.test(value)) {
|
||||
value = dom.getStyle(ed.getBody(), name, true);
|
||||
|
||||
// Ignore white since it's the default color, not the nicest fix
|
||||
if (dom.toHex(value).toLowerCase() == '#ffffff') {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Old IE won't calculate the font size so we need to do that manually
|
||||
if (name == 'font-size') {
|
||||
if (/em|%$/.test(value)) {
|
||||
|
|
@ -608,7 +618,7 @@
|
|||
|
||||
// TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.
|
||||
// Maybe actually inherit it from the original textara?
|
||||
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')});
|
||||
n = p = DOM.create('span', {role : 'application', 'aria-labelledby' : ed.id + '_voice', id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '') + (ed.settings.directionality == "rtl" ? ' mceRtl' : '')});
|
||||
DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);
|
||||
|
||||
if (!DOM.boxModel)
|
||||
|
|
@ -925,7 +935,7 @@
|
|||
},
|
||||
|
||||
_addToolbars : function(c, o) {
|
||||
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup;
|
||||
var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup, toolbarsExist = false;
|
||||
|
||||
toolbarGroup = cf.createToolbarGroup('toolbargroup', {
|
||||
'name': ed.getLang('advanced.toolbar'),
|
||||
|
|
@ -941,6 +951,7 @@
|
|||
|
||||
// Create toolbar and add the controls
|
||||
for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {
|
||||
toolbarsExist = true;
|
||||
tb = cf.createToolbar("toolbar" + i, {'class' : 'mceToolbarRow' + i});
|
||||
|
||||
if (s['theme_advanced_buttons' + i + '_add'])
|
||||
|
|
@ -954,6 +965,9 @@
|
|||
|
||||
o.deltaHeight -= s.theme_advanced_row_height;
|
||||
}
|
||||
// Handle case when there are no toolbar buttons and ensure editor height is adjusted accordingly
|
||||
if (!toolbarsExist)
|
||||
o.deltaHeight -= s.theme_advanced_row_height;
|
||||
h.push(toolbarGroup.renderHTML());
|
||||
h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));
|
||||
DOM.setHTML(n, h.join(''));
|
||||
|
|
@ -1112,7 +1126,7 @@
|
|||
}
|
||||
|
||||
if (c = cm.get('formatselect')) {
|
||||
p = getParent(DOM.isBlock);
|
||||
p = getParent(ed.dom.isBlock);
|
||||
|
||||
if (p)
|
||||
c.select(p.nodeName.toLowerCase());
|
||||
|
|
@ -1210,7 +1224,7 @@
|
|||
return;
|
||||
|
||||
// Handle prefix
|
||||
if (tinymce.isIE && n.scopeName !== 'HTML')
|
||||
if (tinymce.isIE && n.scopeName !== 'HTML' && n.scopeName)
|
||||
na = n.scopeName + ':' + na;
|
||||
|
||||
// Remove internal prefix
|
||||
|
|
@ -1271,7 +1285,7 @@
|
|||
if (v) {
|
||||
ti += 'class: ' + v + ' ';
|
||||
|
||||
if (DOM.isBlock(n) || na == 'img' || na == 'span')
|
||||
if (ed.dom.isBlock(n) || na == 'img' || na == 'span')
|
||||
na += '.' + v;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -104,10 +104,12 @@ var ImageDialog = {
|
|||
},
|
||||
|
||||
updateStyle : function() {
|
||||
var dom = tinyMCEPopup.dom, st, v, f = document.forms[0];
|
||||
var dom = tinyMCEPopup.dom, st = {}, v, f = document.forms[0];
|
||||
|
||||
if (tinyMCEPopup.editor.settings.inline_styles) {
|
||||
st = tinyMCEPopup.dom.parseStyle(this.styleVal);
|
||||
tinymce.each(tinyMCEPopup.dom.parseStyle(this.styleVal), function(value, key) {
|
||||
st[key] = value;
|
||||
});
|
||||
|
||||
// Handle align
|
||||
v = getSelectValue(f, 'align');
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* Generic */
|
||||
body {
|
||||
font-family:Verdana, Arial, Helvetica, sans-serif; font-size:11px;
|
||||
background:#F0F0EE;
|
||||
background:#F0F0EE;
|
||||
color: black;
|
||||
padding:0;
|
||||
margin:8px 8px 0 8px;
|
||||
|
|
@ -94,11 +94,12 @@ h3 {font-size:14px;}
|
|||
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
|
||||
#plugintable {width:96%; margin-top:10px;}
|
||||
#pluginscontainer {height:290px; overflow:auto;}
|
||||
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}
|
||||
#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
|
||||
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
|
||||
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
|
||||
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
|
||||
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
|
||||
#colorpicker #light div {overflow:hidden;}
|
||||
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
|
||||
#colorpicker .panel_wrapper div.current {height:175px;}
|
||||
#colorpicker #namedcolors {width:150px;}
|
||||
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
/* Menu */
|
||||
.highcontrastSkin .mceNoIcons span.mceIcon {width:0;}
|
||||
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; }
|
||||
.highcontrastSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid; direction:ltr}
|
||||
.highcontrastSkin .mceMenu table {background:white; color: black}
|
||||
.highcontrastSkin .mceNoIcons a .mceText {padding-left:10px}
|
||||
.highcontrastSkin .mceMenu a, .highcontrastSkin .mceMenu span, .highcontrastSkin .mceMenu {display:block;background:white; color: black}
|
||||
|
|
@ -90,6 +90,10 @@
|
|||
.highcontrastSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
|
||||
.highcontrastSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
|
||||
|
||||
/* Rtl */
|
||||
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
|
||||
.mceRtl .mceMenuItem .mceText {text-align: right}
|
||||
|
||||
/* Formats */
|
||||
.highcontrastSkin .mce_p span.mceText {}
|
||||
.highcontrastSkin .mce_address span.mceText {font-style:italic}
|
||||
|
|
|
|||
|
|
@ -105,11 +105,12 @@ h3 {font-size:14px;}
|
|||
#plugintable, #about #plugintable td {border:1px solid #919B9C;}
|
||||
#plugintable {width:96%; margin-top:10px;}
|
||||
#pluginscontainer {height:290px; overflow:auto;}
|
||||
#colorpicker #preview {float:right; width:50px; height:14px;line-height:1px; border:1px solid black; margin-left:5px;}
|
||||
#colorpicker #preview {display:inline-block; padding-left:40px; height:14px; border:1px solid black; margin-left:5px; margin-right: 5px}
|
||||
#colorpicker #previewblock {position: relative; top: -3px; padding-left:5px; padding-top: 0px; display:inline}
|
||||
#colorpicker #preview_wrapper { text-align:center; padding-top:4px; white-space: nowrap}
|
||||
#colorpicker #colors {float:left; border:1px solid gray; cursor:crosshair;}
|
||||
#colorpicker #light {border:1px solid gray; margin-left:5px; float:left;width:15px; height:150px; cursor:crosshair;}
|
||||
#colorpicker #light div {overflow:hidden;}
|
||||
#colorpicker #previewblock {float:right; padding-left:10px; height:20px;}
|
||||
#colorpicker .panel_wrapper div.current {height:175px;}
|
||||
#colorpicker #namedcolors {width:150px;}
|
||||
#colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@
|
|||
.o2k7Skin .mce_forecolor span.mceAction, .o2k7Skin .mce_backcolor span.mceAction {height:15px;overflow:hidden}
|
||||
|
||||
/* Menu */
|
||||
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD}
|
||||
.o2k7Skin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #ABC6DD; direction:ltr}
|
||||
.o2k7Skin .mceNoIcons span.mceIcon {width:0;}
|
||||
.o2k7Skin .mceNoIcons a .mceText {padding-left:10px}
|
||||
.o2k7Skin .mceMenu table {background:#FFF}
|
||||
|
|
@ -112,6 +112,10 @@
|
|||
.o2k7Skin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=30)'; filter:alpha(opacity=50); background:#FFF}
|
||||
.o2k7Skin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(../default/img/progress.gif) no-repeat; width:32px; height:32px; margin:-16px 0 0 -16px}
|
||||
|
||||
/* Rtl */
|
||||
.mceRtl .mceListBox .mceText {text-align: right; padding: 0 4px 0 0}
|
||||
.mceRtl .mceMenuItem .mceText {text-align: right}
|
||||
|
||||
/* Formats */
|
||||
.o2k7Skin .mce_formatPreview a {font-size:10px}
|
||||
.o2k7Skin .mce_p span.mceText {}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
5107
library/tinymce/jscripts/tiny_mce/tiny_mce_src.js
vendored
5107
library/tinymce/jscripts/tiny_mce/tiny_mce_src.js
vendored
|
|
@ -1,13 +1,14 @@
|
|||
// FILE IS GENERATED BY COMBINING THE SOURCES IN THE "classes" DIRECTORY SO DON'T MODIFY THIS FILE DIRECTLY
|
||||
(function(win) {
|
||||
var whiteSpaceRe = /^\s*|\s*$/g,
|
||||
undefined, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
|
||||
undef, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';
|
||||
|
||||
var tinymce = {
|
||||
majorVersion : '3',
|
||||
|
||||
minorVersion : '5b2',
|
||||
minorVersion : '5.0.1',
|
||||
|
||||
releaseDate : '2012-03-15',
|
||||
releaseDate : '2012-05-10',
|
||||
|
||||
_init : function() {
|
||||
var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;
|
||||
|
|
@ -50,7 +51,8 @@
|
|||
// If base element found, add that infront of baseURL
|
||||
nl = d.getElementsByTagName('base');
|
||||
for (i=0; i<nl.length; i++) {
|
||||
if (v = nl[i].href) {
|
||||
v = nl[i].href;
|
||||
if (v) {
|
||||
// Host only value like http://site.com or http://site.com:8008
|
||||
if (/^https?:\/\/[^\/]+$/.test(v))
|
||||
v += '/';
|
||||
|
|
@ -103,7 +105,7 @@
|
|||
|
||||
is : function(o, t) {
|
||||
if (!t)
|
||||
return o !== undefined;
|
||||
return o !== undef;
|
||||
|
||||
if (t == 'array' && (o.hasOwnProperty && o instanceof Array))
|
||||
return true;
|
||||
|
|
@ -137,7 +139,7 @@
|
|||
|
||||
s = s || o;
|
||||
|
||||
if (o.length !== undefined) {
|
||||
if (o.length !== undef) {
|
||||
// Indexed arrays, needed for Safari
|
||||
for (n=0, l = o.length; n < l; n++) {
|
||||
if (cb.call(s, o[n], n, o) === false)
|
||||
|
|
@ -191,19 +193,23 @@
|
|||
return -1;
|
||||
},
|
||||
|
||||
extend : function(o, e) {
|
||||
var i, l, a = arguments;
|
||||
extend : function(obj, ext) {
|
||||
var i, l, name, args = arguments, value;
|
||||
|
||||
for (i = 1, l = a.length; i < l; i++) {
|
||||
e = a[i];
|
||||
for (i = 1, l = args.length; i < l; i++) {
|
||||
ext = args[i];
|
||||
for (name in ext) {
|
||||
if (ext.hasOwnProperty(name)) {
|
||||
value = ext[name];
|
||||
|
||||
tinymce.each(e, function(v, n) {
|
||||
if (v !== undefined)
|
||||
o[n] = v;
|
||||
});
|
||||
if (value !== undef) {
|
||||
obj[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
return obj;
|
||||
},
|
||||
|
||||
|
||||
|
|
@ -346,69 +352,69 @@
|
|||
},
|
||||
|
||||
addUnload : function(f, s) {
|
||||
var t = this;
|
||||
var t = this, unload;
|
||||
|
||||
unload = function() {
|
||||
var li = t.unloads, o, n;
|
||||
|
||||
if (li) {
|
||||
// Call unload handlers
|
||||
for (n in li) {
|
||||
o = li[n];
|
||||
|
||||
if (o && o.func)
|
||||
o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy
|
||||
}
|
||||
|
||||
// Detach unload function
|
||||
if (win.detachEvent) {
|
||||
win.detachEvent('onbeforeunload', fakeUnload);
|
||||
win.detachEvent('onunload', unload);
|
||||
} else if (win.removeEventListener)
|
||||
win.removeEventListener('unload', unload, false);
|
||||
|
||||
// Destroy references
|
||||
t.unloads = o = li = w = unload = 0;
|
||||
|
||||
// Run garbarge collector on IE
|
||||
if (win.CollectGarbage)
|
||||
CollectGarbage();
|
||||
}
|
||||
};
|
||||
|
||||
function fakeUnload() {
|
||||
var d = document;
|
||||
|
||||
function stop() {
|
||||
// Prevent memory leak
|
||||
d.detachEvent('onstop', stop);
|
||||
|
||||
// Call unload handler
|
||||
if (unload)
|
||||
unload();
|
||||
|
||||
d = 0;
|
||||
};
|
||||
|
||||
// Is there things still loading, then do some magic
|
||||
if (d.readyState == 'interactive') {
|
||||
// Fire unload when the currently loading page is stopped
|
||||
if (d)
|
||||
d.attachEvent('onstop', stop);
|
||||
|
||||
// Remove onstop listener after a while to prevent the unload function
|
||||
// to execute if the user presses cancel in an onbeforeunload
|
||||
// confirm dialog and then presses the browser stop button
|
||||
win.setTimeout(function() {
|
||||
if (d)
|
||||
d.detachEvent('onstop', stop);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
f = {func : f, scope : s || this};
|
||||
|
||||
if (!t.unloads) {
|
||||
function unload() {
|
||||
var li = t.unloads, o, n;
|
||||
|
||||
if (li) {
|
||||
// Call unload handlers
|
||||
for (n in li) {
|
||||
o = li[n];
|
||||
|
||||
if (o && o.func)
|
||||
o.func.call(o.scope, 1); // Send in one arg to distinct unload and user destroy
|
||||
}
|
||||
|
||||
// Detach unload function
|
||||
if (win.detachEvent) {
|
||||
win.detachEvent('onbeforeunload', fakeUnload);
|
||||
win.detachEvent('onunload', unload);
|
||||
} else if (win.removeEventListener)
|
||||
win.removeEventListener('unload', unload, false);
|
||||
|
||||
// Destroy references
|
||||
t.unloads = o = li = w = unload = 0;
|
||||
|
||||
// Run garbarge collector on IE
|
||||
if (win.CollectGarbage)
|
||||
CollectGarbage();
|
||||
}
|
||||
};
|
||||
|
||||
function fakeUnload() {
|
||||
var d = document;
|
||||
|
||||
// Is there things still loading, then do some magic
|
||||
if (d.readyState == 'interactive') {
|
||||
function stop() {
|
||||
// Prevent memory leak
|
||||
d.detachEvent('onstop', stop);
|
||||
|
||||
// Call unload handler
|
||||
if (unload)
|
||||
unload();
|
||||
|
||||
d = 0;
|
||||
};
|
||||
|
||||
// Fire unload when the currently loading page is stopped
|
||||
if (d)
|
||||
d.attachEvent('onstop', stop);
|
||||
|
||||
// Remove onstop listener after a while to prevent the unload function
|
||||
// to execute if the user presses cancel in an onbeforeunload
|
||||
// confirm dialog and then presses the browser stop button
|
||||
win.setTimeout(function() {
|
||||
if (d)
|
||||
d.detachEvent('onstop', stop);
|
||||
}, 0);
|
||||
}
|
||||
};
|
||||
|
||||
// Attach unload handler
|
||||
if (win.attachEvent) {
|
||||
win.attachEvent('onunload', unload);
|
||||
|
|
@ -439,7 +445,11 @@
|
|||
},
|
||||
|
||||
explode : function(s, d) {
|
||||
return s ? tinymce.map(s.split(d || ','), tinymce.trim) : s;
|
||||
if (!s || tinymce.is(s, 'array')) {
|
||||
return s;
|
||||
}
|
||||
|
||||
return tinymce.map(s.split(d || ','), tinymce.trim);
|
||||
},
|
||||
|
||||
_addVer : function(u) {
|
||||
|
|
@ -465,7 +475,7 @@
|
|||
var val = replace, args = arguments, i;
|
||||
|
||||
for (i = 0; i < args.length - 2; i++) {
|
||||
if (args[i] === undefined) {
|
||||
if (args[i] === undef) {
|
||||
val = val.replace(new RegExp('\\$' + i, 'g'), '');
|
||||
} else {
|
||||
val = val.replace(new RegExp('\\$' + i, 'g'), args[i]);
|
||||
|
|
@ -496,52 +506,64 @@
|
|||
tinymce.create('tinymce.util.Dispatcher', {
|
||||
scope : null,
|
||||
listeners : null,
|
||||
inDispatch: false,
|
||||
|
||||
Dispatcher : function(s) {
|
||||
this.scope = s || this;
|
||||
Dispatcher : function(scope) {
|
||||
this.scope = scope || this;
|
||||
this.listeners = [];
|
||||
},
|
||||
|
||||
add : function(cb, s) {
|
||||
this.listeners.push({cb : cb, scope : s || this.scope});
|
||||
add : function(callback, scope) {
|
||||
this.listeners.push({cb : callback, scope : scope || this.scope});
|
||||
|
||||
return cb;
|
||||
return callback;
|
||||
},
|
||||
|
||||
addToTop : function(cb, s) {
|
||||
this.listeners.unshift({cb : cb, scope : s || this.scope});
|
||||
addToTop : function(callback, scope) {
|
||||
var self = this, listener = {cb : callback, scope : scope || self.scope};
|
||||
|
||||
return cb;
|
||||
// Create new listeners if addToTop is executed in a dispatch loop
|
||||
if (self.inDispatch) {
|
||||
self.listeners = [listener].concat(self.listeners);
|
||||
} else {
|
||||
self.listeners.unshift(listener);
|
||||
}
|
||||
|
||||
return callback;
|
||||
},
|
||||
|
||||
remove : function(cb) {
|
||||
var l = this.listeners, o = null;
|
||||
remove : function(callback) {
|
||||
var listeners = this.listeners, output = null;
|
||||
|
||||
tinymce.each(l, function(c, i) {
|
||||
if (cb == c.cb) {
|
||||
o = cb;
|
||||
l.splice(i, 1);
|
||||
tinymce.each(listeners, function(listener, i) {
|
||||
if (callback == listener.cb) {
|
||||
output = listener;
|
||||
listeners.splice(i, 1);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return o;
|
||||
return output;
|
||||
},
|
||||
|
||||
dispatch : function() {
|
||||
var s, a = arguments, i, li = this.listeners, c;
|
||||
var self = this, returnValue, args = arguments, i, listeners = self.listeners, listener;
|
||||
|
||||
self.inDispatch = true;
|
||||
|
||||
// Needs to be a real loop since the listener count might change while looping
|
||||
// And this is also more efficient
|
||||
for (i = 0; i<li.length; i++) {
|
||||
c = li[i];
|
||||
s = c.cb.apply(c.scope, a.length > 0 ? a : [c.scope]);
|
||||
for (i = 0; i < listeners.length; i++) {
|
||||
listener = listeners[i];
|
||||
returnValue = listener.cb.apply(listener.scope, args.length > 0 ? args : [listener.scope]);
|
||||
|
||||
if (s === false)
|
||||
if (returnValue === false)
|
||||
break;
|
||||
}
|
||||
|
||||
return s;
|
||||
self.inDispatch = false;
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -571,7 +593,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
u = (s.base_uri ? s.base_uri.protocol || 'http' : 'http') + '://mce_host' + u;
|
||||
|
||||
// Relative path http:// or protocol relative //path
|
||||
if (!/^[\w-]*:?\/\//.test(u)) {
|
||||
if (!/^[\w\-]*:?\/\//.test(u)) {
|
||||
base_url = s.base_uri ? s.base_uri.path : new tinymce.util.URI(location.href).directory;
|
||||
u = ((s.base_uri && s.base_uri.protocol) || 'http') + '://mce_host' + t.toAbsPath(base_url, u);
|
||||
}
|
||||
|
|
@ -589,17 +611,18 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
t[v] = s;
|
||||
});
|
||||
|
||||
if (b = s.base_uri) {
|
||||
b = s.base_uri;
|
||||
if (b) {
|
||||
if (!t.protocol)
|
||||
t.protocol = b.protocol;
|
||||
|
||||
if (!t.userInfo)
|
||||
t.userInfo = b.userInfo;
|
||||
|
||||
if (!t.port && t.host == 'mce_host')
|
||||
if (!t.port && t.host === 'mce_host')
|
||||
t.port = b.port;
|
||||
|
||||
if (!t.host || t.host == 'mce_host')
|
||||
if (!t.host || t.host === 'mce_host')
|
||||
t.host = b.host;
|
||||
|
||||
t.source = '';
|
||||
|
|
@ -635,6 +658,12 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
if ((u.host != 'mce_host' && t.host != u.host && u.host) || t.port != u.port || t.protocol != u.protocol)
|
||||
return u.getURI();
|
||||
|
||||
var tu = t.getURI(), uu = u.getURI();
|
||||
|
||||
// Allow usage of the base_uri when relative_urls = true
|
||||
if(tu == uu || (tu.charAt(tu.length - 1) == "/" && tu.substr(0, tu.length - 1) == uu))
|
||||
return tu;
|
||||
|
||||
o = t.toRelPath(t.path, u.path);
|
||||
|
||||
// Add query
|
||||
|
|
@ -649,7 +678,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
},
|
||||
|
||||
toAbsolute : function(u, nh) {
|
||||
var u = new tinymce.util.URI(u, {base_uri : this});
|
||||
u = new tinymce.util.URI(u, {base_uri : this});
|
||||
|
||||
return u.getURI(this.host == u.host && this.protocol == u.protocol ? nh : 0);
|
||||
},
|
||||
|
|
@ -680,7 +709,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
}
|
||||
}
|
||||
|
||||
if (bp == 1)
|
||||
if (bp === 1)
|
||||
return path;
|
||||
|
||||
for (i = 0, l = base.length - (bp - 1); i < l; i++)
|
||||
|
|
@ -715,11 +744,11 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
// Merge relURLParts chunks
|
||||
for (i = path.length - 1, o = []; i >= 0; i--) {
|
||||
// Ignore empty or .
|
||||
if (path[i].length == 0 || path[i] == ".")
|
||||
if (path[i].length === 0 || path[i] === ".")
|
||||
continue;
|
||||
|
||||
// Is parent
|
||||
if (path[i] == '..') {
|
||||
if (path[i] === '..') {
|
||||
nb++;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -830,7 +859,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
if (b == -1) {
|
||||
b = c.indexOf(p);
|
||||
|
||||
if (b != 0)
|
||||
if (b !== 0)
|
||||
return null;
|
||||
} else
|
||||
b += 2;
|
||||
|
|
@ -863,7 +892,7 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
|
||||
(function() {
|
||||
function serialize(o, quote) {
|
||||
var i, v, t;
|
||||
var i, v, t, name;
|
||||
|
||||
quote = quote || '"';
|
||||
|
||||
|
|
@ -901,9 +930,9 @@ tinymce.create('tinymce.util.Dispatcher', {
|
|||
|
||||
v = '{';
|
||||
|
||||
for (i in o) {
|
||||
if (o.hasOwnProperty(i)) {
|
||||
v += typeof o[i] != 'function' ? (v.length > 1 ? ',' + quote : quote) + i + quote +':' + serialize(o[i], quote) : '';
|
||||
for (name in o) {
|
||||
if (o.hasOwnProperty(name)) {
|
||||
v += typeof o[name] != 'function' ? (v.length > 1 ? ',' + quote : quote) + name + quote +':' + serialize(o[name], quote) : '';
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -931,6 +960,18 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
send : function(o) {
|
||||
var x, t, w = window, c = 0;
|
||||
|
||||
function ready() {
|
||||
if (!o.async || x.readyState == 4 || c++ > 10000) {
|
||||
if (o.success && c < 10000 && x.status == 200)
|
||||
o.success.call(o.success_scope, '' + x.responseText, x, o);
|
||||
else if (o.error)
|
||||
o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
|
||||
|
||||
x = null;
|
||||
} else
|
||||
w.setTimeout(ready, 10);
|
||||
};
|
||||
|
||||
// Default settings
|
||||
o.scope = o.scope || this;
|
||||
o.success_scope = o.success_scope || o.scope;
|
||||
|
|
@ -964,18 +1005,6 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
|
||||
x.send(o.data);
|
||||
|
||||
function ready() {
|
||||
if (!o.async || x.readyState == 4 || c++ > 10000) {
|
||||
if (o.success && c < 10000 && x.status == 200)
|
||||
o.success.call(o.success_scope, '' + x.responseText, x, o);
|
||||
else if (o.error)
|
||||
o.error.call(o.error_scope, c > 10000 ? 'TIMED_OUT' : 'GENERAL', x, o);
|
||||
|
||||
x = null;
|
||||
} else
|
||||
w.setTimeout(ready, 10);
|
||||
};
|
||||
|
||||
// Syncronous request
|
||||
if (!o.async)
|
||||
return ready();
|
||||
|
|
@ -1055,13 +1084,13 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
modifierPressed: function (e) {
|
||||
return e.shiftKey || e.ctrlKey || e.altKey;
|
||||
}
|
||||
}
|
||||
};
|
||||
})(tinymce);
|
||||
|
||||
(function(tinymce) {
|
||||
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE;
|
||||
tinymce.util.Quirks = function(editor) {
|
||||
var VK = tinymce.VK, BACKSPACE = VK.BACKSPACE, DELETE = VK.DELETE, dom = editor.dom, selection = editor.selection, settings = editor.settings;
|
||||
|
||||
function setEditorCommandState(editor, cmd, state) {
|
||||
function setEditorCommandState(cmd, state) {
|
||||
try {
|
||||
editor.getDoc().execCommand(cmd, false, state);
|
||||
} catch (ex) {
|
||||
|
|
@ -1069,107 +1098,163 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
}
|
||||
}
|
||||
|
||||
function cleanupStylesWhenDeleting(ed) {
|
||||
var dom = ed.dom, selection = ed.selection;
|
||||
function cleanupStylesWhenDeleting() {
|
||||
function removeMergedFormatSpans(isDelete) {
|
||||
var rng, blockElm, node, clonedSpan;
|
||||
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
var rng, blockElm, node, clonedSpan, isDelete;
|
||||
rng = selection.getRng();
|
||||
|
||||
if (e.isDefaultPrevented()) {
|
||||
return;
|
||||
// Find root block
|
||||
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
|
||||
|
||||
// On delete clone the root span of the next block element
|
||||
if (isDelete)
|
||||
blockElm = dom.getNext(blockElm, dom.isBlock);
|
||||
|
||||
// Locate root span element and clone it since it would otherwise get merged by the "apple-style-span" on delete/backspace
|
||||
if (blockElm) {
|
||||
node = blockElm.firstChild;
|
||||
|
||||
// Ignore empty text nodes
|
||||
while (node && node.nodeType == 3 && node.nodeValue.length === 0)
|
||||
node = node.nextSibling;
|
||||
|
||||
if (node && node.nodeName === 'SPAN') {
|
||||
clonedSpan = node.cloneNode(false);
|
||||
}
|
||||
}
|
||||
|
||||
isDelete = e.keyCode == DELETE;
|
||||
if ((isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
|
||||
e.preventDefault();
|
||||
rng = selection.getRng();
|
||||
// Do the backspace/delete action
|
||||
editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
|
||||
|
||||
// Find root block
|
||||
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
|
||||
// Find all odd apple-style-spans
|
||||
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
|
||||
tinymce.each(dom.select('span.Apple-style-span,font.Apple-style-span', blockElm), function(span) {
|
||||
var bm = selection.getBookmark();
|
||||
|
||||
// On delete clone the root span of the next block element
|
||||
if (isDelete)
|
||||
blockElm = dom.getNext(blockElm, dom.isBlock);
|
||||
|
||||
// Locate root span element and clone it since it would otherwise get merged by the "apple-style-span" on delete/backspace
|
||||
if (blockElm) {
|
||||
node = blockElm.firstChild;
|
||||
|
||||
// Ignore empty text nodes
|
||||
while (node && node.nodeType == 3 && node.nodeValue.length == 0)
|
||||
node = node.nextSibling;
|
||||
|
||||
if (node && node.nodeName === 'SPAN') {
|
||||
clonedSpan = node.cloneNode(false);
|
||||
}
|
||||
if (clonedSpan) {
|
||||
dom.replace(clonedSpan.cloneNode(false), span, true);
|
||||
} else {
|
||||
dom.remove(span, true);
|
||||
}
|
||||
|
||||
// Do the backspace/delete action
|
||||
ed.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
|
||||
// Restore the selection
|
||||
selection.moveToBookmark(bm);
|
||||
});
|
||||
};
|
||||
|
||||
// Find all odd apple-style-spans
|
||||
blockElm = dom.getParent(rng.startContainer, dom.isBlock);
|
||||
tinymce.each(dom.select('span.Apple-style-span,font.Apple-style-span', blockElm), function(span) {
|
||||
var bm = selection.getBookmark();
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
var isDelete;
|
||||
|
||||
if (clonedSpan) {
|
||||
dom.replace(clonedSpan.cloneNode(false), span, true);
|
||||
} else {
|
||||
dom.remove(span, true);
|
||||
}
|
||||
|
||||
// Restore the selection
|
||||
selection.moveToBookmark(bm);
|
||||
});
|
||||
isDelete = e.keyCode == DELETE;
|
||||
if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
|
||||
e.preventDefault();
|
||||
removeMergedFormatSpans(isDelete);
|
||||
}
|
||||
});
|
||||
|
||||
editor.addCommand('Delete', function() {removeMergedFormatSpans();});
|
||||
};
|
||||
|
||||
function emptyEditorWhenDeleting() {
|
||||
function getEndPointNode(rng, start) {
|
||||
var container, offset, prefix = start ? 'start' : 'end';
|
||||
|
||||
function emptyEditorWhenDeleting(ed) {
|
||||
function serializeRng(rng) {
|
||||
var body = ed.dom.create("body");
|
||||
var contents = rng.cloneContents();
|
||||
body.appendChild(contents);
|
||||
return ed.selection.serializer.serialize(body, {format: 'html'});
|
||||
}
|
||||
container = rng[prefix + 'Container'];
|
||||
offset = rng[prefix + 'Offset'];
|
||||
|
||||
function allContentsSelected(rng) {
|
||||
var selection = serializeRng(rng);
|
||||
// Resolve indexed container
|
||||
if (container.nodeType == 1 && container.hasChildNodes()) {
|
||||
container = container.childNodes[Math.min(start ? offset : (offset > 0 ? offset - 1 : 0), container.childNodes.length - 1)]
|
||||
}
|
||||
|
||||
var allRng = ed.dom.createRng();
|
||||
allRng.selectNode(ed.getBody());
|
||||
return container;
|
||||
};
|
||||
|
||||
var allSelection = serializeRng(allRng);
|
||||
return selection === allSelection;
|
||||
}
|
||||
function isAtStartEndOfBody(rng, start) {
|
||||
var container, offset, root, childNode, prefix = start ? 'start' : 'end', isAfter;
|
||||
|
||||
ed.onKeyDown.addToTop(function(ed, e) {
|
||||
var keyCode = e.keyCode;
|
||||
if (keyCode == DELETE || keyCode == BACKSPACE) {
|
||||
var rng = ed.selection.getRng(true);
|
||||
if (!rng.collapsed && allContentsSelected(rng)) {
|
||||
ed.setContent('', {format : 'raw'});
|
||||
ed.nodeChanged();
|
||||
container = rng[prefix + 'Container'];
|
||||
offset = rng[prefix + 'Offset'];
|
||||
root = dom.getRoot();
|
||||
|
||||
// Resolve indexed container
|
||||
if (container.nodeType == 1) {
|
||||
isAfter = offset >= container.childNodes.length;
|
||||
container = getEndPointNode(rng, start);
|
||||
|
||||
if (container.nodeType == 3) {
|
||||
offset = start && !isAfter ? 0 : container.nodeValue.length;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if start/end is in the middle of text
|
||||
if (container.nodeType == 3 && ((start && offset > 0) || (!start && offset < container.nodeValue.length))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Walk up the DOM tree to see if the endpoint is at the beginning/end of body
|
||||
while (container !== root) {
|
||||
childNode = container.parentNode[start ? 'firstChild' : 'lastChild'];
|
||||
|
||||
// If first/last element is a BR then jump to it's sibling in case: <p>x<br></p>
|
||||
if (childNode.nodeName == "BR") {
|
||||
childNode = childNode[start ? 'nextSibling' : 'previousSibling'] || childNode;
|
||||
}
|
||||
|
||||
// If the childNode isn't the container node then break in case <p><span>A</span>[X]</p>
|
||||
if (childNode !== container) {
|
||||
return false;
|
||||
}
|
||||
|
||||
container = container.parentNode;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
editor.onKeyDown.addToTop(function(editor, e) {
|
||||
var rng, keyCode = e.keyCode;
|
||||
|
||||
if (!e.isDefaultPrevented() && (keyCode == DELETE || keyCode == BACKSPACE)) {
|
||||
rng = selection.getRng(true);
|
||||
|
||||
if (isAtStartEndOfBody(rng, true) && isAtStartEndOfBody(rng, false) &&
|
||||
(rng.collapsed || dom.findCommonAncestor(getEndPointNode(rng, true), getEndPointNode(rng)) === dom.getRoot())) {
|
||||
editor.setContent('');
|
||||
editor.nodeChanged();
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function inputMethodFocus(ed) {
|
||||
ed.dom.bind(ed.getDoc(), 'focusin', function() {
|
||||
ed.selection.setRng(ed.selection.getRng());
|
||||
});
|
||||
function inputMethodFocus() {
|
||||
if (!editor.settings.content_editable) {
|
||||
// Case 1 IME doesn't initialize if you focus the document
|
||||
dom.bind(editor.getDoc(), 'focusin', function(e) {
|
||||
selection.setRng(selection.getRng());
|
||||
});
|
||||
|
||||
// Case 2 IME doesn't initialize if you click the documentElement it also doesn't properly fire the focusin event
|
||||
dom.bind(editor.getDoc(), 'mousedown', function(e) {
|
||||
if (e.target == editor.getDoc().documentElement) {
|
||||
editor.getWin().focus();
|
||||
selection.setRng(selection.getRng());
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function removeHrOnBackspace(ed) {
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
if (e.keyCode === BACKSPACE) {
|
||||
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) {
|
||||
var node = ed.selection.getNode();
|
||||
function removeHrOnBackspace() {
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
|
||||
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
|
||||
var node = selection.getNode();
|
||||
var previousSibling = node.previousSibling;
|
||||
|
||||
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "hr") {
|
||||
ed.dom.remove(previousSibling);
|
||||
dom.remove(previousSibling);
|
||||
tinymce.dom.Event.cancel(e);
|
||||
}
|
||||
}
|
||||
|
|
@ -1177,13 +1262,13 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
})
|
||||
}
|
||||
|
||||
function focusBody(ed) {
|
||||
function focusBody() {
|
||||
// Fix for a focus bug in FF 3.x where the body element
|
||||
// wouldn't get proper focus if the user clicked on the HTML element
|
||||
if (!Range.prototype.getClientRects) { // Detect getClientRects got introduced in FF 4
|
||||
ed.onMouseDown.add(function(ed, e) {
|
||||
editor.onMouseDown.add(function(editor, e) {
|
||||
if (e.target.nodeName === "HTML") {
|
||||
var body = ed.getBody();
|
||||
var body = editor.getBody();
|
||||
|
||||
// Blur the body it's focused but not correctly focused
|
||||
body.blur();
|
||||
|
|
@ -1197,38 +1282,38 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
}
|
||||
};
|
||||
|
||||
function selectControlElements(ed) {
|
||||
ed.onClick.add(function(ed, e) {
|
||||
function selectControlElements() {
|
||||
editor.onClick.add(function(editor, e) {
|
||||
e = e.target;
|
||||
|
||||
// Workaround for bug, http://bugs.webkit.org/show_bug.cgi?id=12250
|
||||
// WebKit can't even do simple things like selecting an image
|
||||
// Needs tobe the setBaseAndExtend or it will fail to select floated images
|
||||
if (/^(IMG|HR)$/.test(e.nodeName))
|
||||
ed.selection.getSel().setBaseAndExtent(e, 0, e, 1);
|
||||
if (/^(IMG|HR)$/.test(e.nodeName)) {
|
||||
selection.getSel().setBaseAndExtent(e, 0, e, 1);
|
||||
}
|
||||
|
||||
if (e.nodeName == 'A' && ed.dom.hasClass(e, 'mceItemAnchor'))
|
||||
ed.selection.select(e);
|
||||
if (e.nodeName == 'A' && dom.hasClass(e, 'mceItemAnchor')) {
|
||||
selection.select(e);
|
||||
}
|
||||
|
||||
ed.nodeChanged();
|
||||
editor.nodeChanged();
|
||||
});
|
||||
};
|
||||
|
||||
function removeStylesWhenDeletingAccrossBlockElements(ed) {
|
||||
var selection = ed.selection, dom = ed.dom;
|
||||
|
||||
function removeStylesWhenDeletingAccrossBlockElements() {
|
||||
function getAttributeApplyFunction() {
|
||||
var template = dom.getAttribs(selection.getStart().cloneNode(false));
|
||||
|
||||
return function() {
|
||||
var target = selection.getStart();
|
||||
|
||||
if (target !== ed.getBody()) {
|
||||
if (target !== editor.getBody()) {
|
||||
dom.setAttrib(target, "style", null);
|
||||
|
||||
tinymce.each(template, function(attr) {
|
||||
target.setAttributeNode(attr.cloneNode(true));
|
||||
});
|
||||
tinymce.each(template, function(attr) {
|
||||
target.setAttributeNode(attr.cloneNode(true));
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -1237,91 +1322,68 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
return !selection.isCollapsed() && selection.getStart() != selection.getEnd();
|
||||
}
|
||||
|
||||
function blockEvent(ed, e) {
|
||||
function blockEvent(editor, e) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
ed.onKeyPress.add(function(ed, e) {
|
||||
editor.onKeyPress.add(function(editor, e) {
|
||||
var applyAttributes;
|
||||
|
||||
if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {
|
||||
applyAttributes = getAttributeApplyFunction();
|
||||
ed.getDoc().execCommand('delete', false, null);
|
||||
editor.getDoc().execCommand('delete', false, null);
|
||||
applyAttributes();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
dom.bind(ed.getDoc(), 'cut', function(e) {
|
||||
dom.bind(editor.getDoc(), 'cut', function(e) {
|
||||
var applyAttributes;
|
||||
|
||||
if (isSelectionAcrossElements()) {
|
||||
applyAttributes = getAttributeApplyFunction();
|
||||
ed.onKeyUp.addToTop(blockEvent);
|
||||
editor.onKeyUp.addToTop(blockEvent);
|
||||
|
||||
setTimeout(function() {
|
||||
applyAttributes();
|
||||
ed.onKeyUp.remove(blockEvent);
|
||||
editor.onKeyUp.remove(blockEvent);
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
function removeStylesOnPTagsInheritedFromHeadingTag(ed) {
|
||||
ed.onKeyDown.add(function(ed, event) {
|
||||
function checkInHeadingTag(ed) {
|
||||
var currentNode = ed.selection.getNode();
|
||||
var headingTags = 'h1,h2,h3,h4,h5,h6';
|
||||
return ed.dom.is(currentNode, headingTags) || ed.dom.getParent(currentNode, headingTags) !== null;
|
||||
}
|
||||
|
||||
if (event.keyCode === VK.ENTER && !VK.modifierPressed(event) && checkInHeadingTag(ed)) {
|
||||
setTimeout(function() {
|
||||
var currentNode = ed.selection.getNode();
|
||||
if (ed.dom.is(currentNode, 'p')) {
|
||||
ed.dom.setAttrib(currentNode, 'style', null);
|
||||
// While tiny's content is correct after this method call, the content shown is not representative of it and needs to be 'repainted'
|
||||
ed.execCommand('mceCleanup');
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
function selectionChangeNodeChanged(ed) {
|
||||
function selectionChangeNodeChanged() {
|
||||
var lastRng, selectionTimer;
|
||||
|
||||
ed.dom.bind(ed.getDoc(), 'selectionchange', function() {
|
||||
dom.bind(editor.getDoc(), 'selectionchange', function() {
|
||||
if (selectionTimer) {
|
||||
clearTimeout(selectionTimer);
|
||||
selectionTimer = 0;
|
||||
}
|
||||
|
||||
selectionTimer = window.setTimeout(function() {
|
||||
var rng = ed.selection.getRng();
|
||||
var rng = selection.getRng();
|
||||
|
||||
// Compare the ranges to see if it was a real change or not
|
||||
if (!lastRng || !tinymce.dom.RangeUtils.compareRanges(rng, lastRng)) {
|
||||
ed.nodeChanged();
|
||||
editor.nodeChanged();
|
||||
lastRng = rng;
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
}
|
||||
|
||||
function ensureBodyHasRoleApplication(ed) {
|
||||
function ensureBodyHasRoleApplication() {
|
||||
document.body.setAttribute("role", "application");
|
||||
}
|
||||
|
||||
function disableBackspaceIntoATable(ed) {
|
||||
ed.onKeyDown.add(function(ed, e) {
|
||||
if (e.keyCode === BACKSPACE) {
|
||||
if (ed.selection.isCollapsed() && ed.selection.getRng(true).startOffset === 0) {
|
||||
var previousSibling = ed.selection.getNode().previousSibling;
|
||||
|
||||
function disableBackspaceIntoATable() {
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
if (!e.isDefaultPrevented() && e.keyCode === BACKSPACE) {
|
||||
if (selection.isCollapsed() && selection.getRng(true).startOffset === 0) {
|
||||
var previousSibling = selection.getNode().previousSibling;
|
||||
if (previousSibling && previousSibling.nodeName && previousSibling.nodeName.toLowerCase() === "table") {
|
||||
return tinymce.dom.Event.cancel(e);
|
||||
}
|
||||
|
|
@ -1330,7 +1392,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
})
|
||||
}
|
||||
|
||||
function addNewLinesBeforeBrInPre(editor) {
|
||||
function addNewLinesBeforeBrInPre() {
|
||||
var documentMode = editor.getDoc().documentMode;
|
||||
|
||||
// IE8+ rendering mode does the right thing with BR in PRE
|
||||
|
|
@ -1340,8 +1402,8 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
|
||||
// Enable display: none in area and add a specific class that hides all BR elements in PRE to
|
||||
// avoid the caret from getting stuck at the BR elements while pressing the right arrow key
|
||||
setEditorCommandState(editor, 'RespectVisibilityInDesign', true);
|
||||
editor.dom.addClass(editor.getBody(), 'mceHideBrInPre');
|
||||
setEditorCommandState('RespectVisibilityInDesign', true);
|
||||
dom.addClass(editor.getBody(), 'mceHideBrInPre');
|
||||
|
||||
// Adds a \n before all BR elements in PRE to get them visual
|
||||
editor.parser.addNodeFilter('pre', function(nodes, name) {
|
||||
|
|
@ -1382,43 +1444,210 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
});
|
||||
}
|
||||
|
||||
tinymce.create('tinymce.util.Quirks', {
|
||||
Quirks: function(ed) {
|
||||
// All browsers
|
||||
disableBackspaceIntoATable(ed);
|
||||
function removePreSerializedStylesWhenSelectingControls() {
|
||||
dom.bind(editor.getBody(), 'mouseup', function(e) {
|
||||
var value, node = selection.getNode();
|
||||
|
||||
// WebKit
|
||||
if (tinymce.isWebKit) {
|
||||
cleanupStylesWhenDeleting(ed);
|
||||
emptyEditorWhenDeleting(ed);
|
||||
inputMethodFocus(ed);
|
||||
selectControlElements(ed);
|
||||
// Moved styles to attributes on IMG eements
|
||||
if (node.nodeName == 'IMG') {
|
||||
// Convert style width to width attribute
|
||||
if (value = dom.getStyle(node, 'width')) {
|
||||
dom.setAttrib(node, 'width', value.replace(/[^0-9%]+/g, ''));
|
||||
dom.setStyle(node, 'width', '');
|
||||
}
|
||||
|
||||
// iOS
|
||||
if (tinymce.isIDevice) {
|
||||
selectionChangeNodeChanged(ed);
|
||||
// Convert style height to height attribute
|
||||
if (value = dom.getStyle(node, 'height')) {
|
||||
dom.setAttrib(node, 'height', value.replace(/[^0-9%]+/g, ''));
|
||||
dom.setStyle(node, 'height', '');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// IE
|
||||
if (tinymce.isIE) {
|
||||
removeHrOnBackspace(ed);
|
||||
emptyEditorWhenDeleting(ed);
|
||||
ensureBodyHasRoleApplication(ed);
|
||||
//removeStylesOnPTagsInheritedFromHeadingTag(ed)
|
||||
addNewLinesBeforeBrInPre(ed);
|
||||
function keepInlineElementOnDeleteBackspace() {
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
var isDelete, rng, container, offset, brElm, sibling, collapsed;
|
||||
|
||||
isDelete = e.keyCode == DELETE;
|
||||
if (!e.isDefaultPrevented() && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) {
|
||||
rng = selection.getRng();
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
collapsed = rng.collapsed;
|
||||
|
||||
// Override delete if the start container is a text node and is at the beginning of text or
|
||||
// just before/after the last character to be deleted in collapsed mode
|
||||
if (container.nodeType == 3 && container.nodeValue.length > 0 && ((offset === 0 && !collapsed) || (collapsed && offset === (isDelete ? 0 : 1)))) {
|
||||
nonEmptyElements = editor.schema.getNonEmptyElements();
|
||||
|
||||
// Prevent default logic since it's broken
|
||||
e.preventDefault();
|
||||
|
||||
// Insert a BR before the text node this will prevent the containing element from being deleted/converted
|
||||
brElm = dom.create('br', {id: '__tmp'});
|
||||
container.parentNode.insertBefore(brElm, container);
|
||||
|
||||
// Do the browser delete
|
||||
editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null);
|
||||
|
||||
// Check if the previous sibling is empty after deleting for example: <p><b></b>|</p>
|
||||
container = selection.getRng().startContainer;
|
||||
sibling = container.previousSibling;
|
||||
if (sibling && sibling.nodeType == 1 && !dom.isBlock(sibling) && dom.isEmpty(sibling) && !nonEmptyElements[sibling.nodeName.toLowerCase()]) {
|
||||
dom.remove(sibling);
|
||||
}
|
||||
|
||||
// Remove the temp element we inserted
|
||||
dom.remove('__tmp');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function removeBlockQuoteOnBackSpace() {
|
||||
// Add block quote deletion handler
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
var rng, container, offset, root, parent;
|
||||
|
||||
if (e.isDefaultPrevented() || e.keyCode != VK.BACKSPACE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Gecko
|
||||
if (tinymce.isGecko) {
|
||||
removeHrOnBackspace(ed);
|
||||
focusBody(ed);
|
||||
removeStylesWhenDeletingAccrossBlockElements(ed);
|
||||
rng = selection.getRng();
|
||||
container = rng.startContainer;
|
||||
offset = rng.startOffset;
|
||||
root = dom.getRoot();
|
||||
parent = container;
|
||||
|
||||
if (!rng.collapsed || offset !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
while (parent && parent.parentNode && parent.parentNode.firstChild == parent && parent.parentNode != root) {
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
// Is the cursor at the beginning of a blockquote?
|
||||
if (parent.tagName === 'BLOCKQUOTE') {
|
||||
// Remove the blockquote
|
||||
editor.formatter.toggle('blockquote', null, parent);
|
||||
|
||||
// Move the caret to the beginning of container
|
||||
rng.setStart(container, 0);
|
||||
rng.setEnd(container, 0);
|
||||
selection.setRng(rng);
|
||||
selection.collapse(false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function setGeckoEditingOptions() {
|
||||
function setOpts() {
|
||||
editor._refreshContentEditable();
|
||||
|
||||
setEditorCommandState("StyleWithCSS", false);
|
||||
setEditorCommandState("enableInlineTableEditing", false);
|
||||
|
||||
if (!settings.object_resizing) {
|
||||
setEditorCommandState("enableObjectResizing", false);
|
||||
}
|
||||
};
|
||||
|
||||
if (!settings.readonly) {
|
||||
editor.onBeforeExecCommand.add(setOpts);
|
||||
editor.onMouseDown.add(setOpts);
|
||||
}
|
||||
});
|
||||
})(tinymce);
|
||||
};
|
||||
|
||||
function addBrAfterLastLinks() {
|
||||
function fixLinks(editor, o) {
|
||||
tinymce.each(dom.select('a'), function(node) {
|
||||
var parentNode = node.parentNode, root = dom.getRoot();
|
||||
|
||||
if (parentNode.lastChild === node) {
|
||||
while (parentNode && !dom.isBlock(parentNode)) {
|
||||
if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) {
|
||||
return;
|
||||
}
|
||||
|
||||
parentNode = parentNode.parentNode;
|
||||
}
|
||||
|
||||
dom.add(parentNode, 'br', {'data-mce-bogus' : 1});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
editor.onExecCommand.add(function(editor, cmd) {
|
||||
if (cmd === 'CreateLink') {
|
||||
fixLinks(editor);
|
||||
}
|
||||
});
|
||||
|
||||
editor.onSetContent.add(selection.onSetContent.add(fixLinks));
|
||||
};
|
||||
|
||||
function removeGhostSelection() {
|
||||
function repaint(sender, args) {
|
||||
if (!sender || !args.initial) {
|
||||
editor.execCommand('mceRepaint');
|
||||
}
|
||||
};
|
||||
|
||||
editor.onUndo.add(repaint);
|
||||
editor.onRedo.add(repaint);
|
||||
editor.onSetContent.add(repaint);
|
||||
};
|
||||
|
||||
function deleteImageOnBackSpace() {
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
if (!e.isDefaultPrevented() && e.keyCode == 8 && selection.getNode().nodeName == 'IMG') {
|
||||
e.preventDefault();
|
||||
editor.undoManager.beforeChange();
|
||||
dom.remove(selection.getNode());
|
||||
editor.undoManager.add();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// All browsers
|
||||
disableBackspaceIntoATable();
|
||||
removeBlockQuoteOnBackSpace();
|
||||
emptyEditorWhenDeleting();
|
||||
|
||||
// WebKit
|
||||
if (tinymce.isWebKit) {
|
||||
keepInlineElementOnDeleteBackspace();
|
||||
cleanupStylesWhenDeleting();
|
||||
inputMethodFocus();
|
||||
selectControlElements();
|
||||
|
||||
// iOS
|
||||
if (tinymce.isIDevice) {
|
||||
selectionChangeNodeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
// IE
|
||||
if (tinymce.isIE) {
|
||||
removeHrOnBackspace();
|
||||
ensureBodyHasRoleApplication();
|
||||
addNewLinesBeforeBrInPre();
|
||||
removePreSerializedStylesWhenSelectingControls();
|
||||
deleteImageOnBackSpace();
|
||||
}
|
||||
|
||||
// Gecko
|
||||
if (tinymce.isGecko) {
|
||||
removeHrOnBackspace();
|
||||
focusBody();
|
||||
removeStylesWhenDeletingAccrossBlockElements();
|
||||
setGeckoEditingOptions();
|
||||
addBrAfterLastLinks();
|
||||
removeGhostSelection();
|
||||
}
|
||||
};
|
||||
(function(tinymce) {
|
||||
var namedEntities, baseEntities, reverseEntities,
|
||||
attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
|
||||
|
|
@ -1511,8 +1740,7 @@ tinymce.create('static tinymce.util.XHR', {
|
|||
'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' +
|
||||
'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' +
|
||||
'80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' +
|
||||
'811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro'
|
||||
, 32);
|
||||
'811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro', 32);
|
||||
|
||||
tinymce.html = tinymce.html || {};
|
||||
|
||||
|
|
@ -1723,7 +1951,27 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
str = str.replace(/\\([\'\";:])/g, "$1");
|
||||
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
function processUrl(match, url, url2, url3, str, str2) {
|
||||
str = str || str2;
|
||||
|
||||
if (str) {
|
||||
str = decode(str);
|
||||
|
||||
// Force strings into single quote format
|
||||
return "'" + str.replace(/\'/g, "\\'") + "'";
|
||||
}
|
||||
|
||||
url = decode(url || url2 || url3);
|
||||
|
||||
// Convert the URL to relative/absolute depending on config
|
||||
if (urlConverter)
|
||||
url = urlConverter.call(urlConverterScope, url, 'style');
|
||||
|
||||
// Output new URL format
|
||||
return "url('" + url.replace(/\'/g, "\\'") + "')";
|
||||
};
|
||||
|
||||
if (css) {
|
||||
// Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing
|
||||
|
|
@ -1747,26 +1995,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
value = value.replace(rgbRegExp, toHex);
|
||||
|
||||
// Convert URLs and force them into url('value') format
|
||||
value = value.replace(urlOrStrRegExp, function(match, url, url2, url3, str, str2) {
|
||||
str = str || str2;
|
||||
|
||||
if (str) {
|
||||
str = decode(str);
|
||||
|
||||
// Force strings into single quote format
|
||||
return "'" + str.replace(/\'/g, "\\'") + "'";
|
||||
}
|
||||
|
||||
url = decode(url || url2 || url3);
|
||||
|
||||
// Convert the URL to relative/absolute depending on config
|
||||
if (urlConverter)
|
||||
url = urlConverter.call(urlConverterScope, url, 'style');
|
||||
|
||||
// Output new URL format
|
||||
return "url('" + url.replace(/\'/g, "\\'") + "')";
|
||||
});
|
||||
|
||||
value = value.replace(urlOrStrRegExp, processUrl);
|
||||
styles[name] = isEncoded ? decode(value, true) : value;
|
||||
}
|
||||
|
||||
|
|
@ -1934,7 +2163,8 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
'span[A][B]' +
|
||||
'ins[A|cite|datetime][B]' +
|
||||
'del[A|cite|datetime][B]' +
|
||||
'figure[A][C|legend]' +
|
||||
'figure[A][C|legend|figcaption]' +
|
||||
'figcaption[A][C]' +
|
||||
'img[A|alt|src|height|width|usemap|ismap][]' +
|
||||
'iframe[A|name|src|height|width|sandbox|seamless][]' +
|
||||
'embed[A|src|height|width|type][]' +
|
||||
|
|
@ -2161,7 +2391,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object', shortEndedElementsMap);
|
||||
blockElementsMap = createLookupTable('block_elements', 'h1 h2 h3 h4 h5 h6 hr p div address pre form table tbody thead tfoot ' +
|
||||
'th tr td li ol ul caption blockquote center dl dt dd dir fieldset ' +
|
||||
'noscript menu isindex samp header footer article section hgroup aside nav');
|
||||
'noscript menu isindex samp header footer article section hgroup aside nav figure');
|
||||
|
||||
// Converts a wildcard expression string to a regexp for example *a will become /.*a/.
|
||||
function patternToRegExp(str) {
|
||||
|
|
@ -2173,7 +2403,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
function addValidElements(valid_elements) {
|
||||
var ei, el, ai, al, yl, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder,
|
||||
prefix, outputName, globalAttributes, globalAttributesOrder, transElement, key, childKey, value,
|
||||
elementRuleRegExp = /^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,
|
||||
elementRuleRegExp = /^([#+\-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,
|
||||
attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,
|
||||
hasPatternsRegExp = /[*?+]/;
|
||||
|
||||
|
|
@ -2546,6 +2776,47 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
}
|
||||
};
|
||||
|
||||
function parseAttribute(match, name, value, val2, val3) {
|
||||
var attrRule, i;
|
||||
|
||||
name = name.toLowerCase();
|
||||
value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
|
||||
|
||||
// Validate name and value
|
||||
if (validate && !isInternalElement && name.indexOf('data-') !== 0) {
|
||||
attrRule = validAttributesMap[name];
|
||||
|
||||
// Find rule by pattern matching
|
||||
if (!attrRule && validAttributePatterns) {
|
||||
i = validAttributePatterns.length;
|
||||
while (i--) {
|
||||
attrRule = validAttributePatterns[i];
|
||||
if (attrRule.pattern.test(name))
|
||||
break;
|
||||
}
|
||||
|
||||
// No rule matched
|
||||
if (i === -1)
|
||||
attrRule = null;
|
||||
}
|
||||
|
||||
// No attribute rule found
|
||||
if (!attrRule)
|
||||
return;
|
||||
|
||||
// Validate value
|
||||
if (attrRule.validValues && !(value in attrRule.validValues))
|
||||
return;
|
||||
}
|
||||
|
||||
// Add attribute to list and map
|
||||
attrList.map[name] = value;
|
||||
attrList.push({
|
||||
name: name,
|
||||
value: value
|
||||
});
|
||||
};
|
||||
|
||||
// Precompile RegExps and map objects
|
||||
tokenRegExp = new RegExp('<(?:' +
|
||||
'(?:!--([\\w\\W]*?)-->)|' + // Comment
|
||||
|
|
@ -2553,7 +2824,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
'(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE
|
||||
'(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI
|
||||
'(?:\\/([^>]+)>)|' + // End element
|
||||
'(?:([A-Za-z0-9\-\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
|
||||
'(?:([A-Za-z0-9\\-\\:]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element
|
||||
')', 'g');
|
||||
|
||||
attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;
|
||||
|
|
@ -2620,46 +2891,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
attrList = [];
|
||||
attrList.map = {};
|
||||
|
||||
attribsValue.replace(attrRegExp, function(match, name, value, val2, val3) {
|
||||
var attrRule, i;
|
||||
|
||||
name = name.toLowerCase();
|
||||
value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute
|
||||
|
||||
// Validate name and value
|
||||
if (validate && !isInternalElement && name.indexOf('data-') !== 0) {
|
||||
attrRule = validAttributesMap[name];
|
||||
|
||||
// Find rule by pattern matching
|
||||
if (!attrRule && validAttributePatterns) {
|
||||
i = validAttributePatterns.length;
|
||||
while (i--) {
|
||||
attrRule = validAttributePatterns[i];
|
||||
if (attrRule.pattern.test(name))
|
||||
break;
|
||||
}
|
||||
|
||||
// No rule matched
|
||||
if (i === -1)
|
||||
attrRule = null;
|
||||
}
|
||||
|
||||
// No attribute rule found
|
||||
if (!attrRule)
|
||||
return;
|
||||
|
||||
// Validate value
|
||||
if (attrRule.validValues && !(value in attrRule.validValues))
|
||||
return;
|
||||
}
|
||||
|
||||
// Add attribute to list and map
|
||||
attrList.map[name] = value;
|
||||
attrList.push({
|
||||
name: name,
|
||||
value: value
|
||||
});
|
||||
});
|
||||
attribsValue.replace(attrRegExp, parseAttribute);
|
||||
} else {
|
||||
attrList = [];
|
||||
attrList.map = {};
|
||||
|
|
@ -3281,7 +3513,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
self.parse = function(html, args) {
|
||||
var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate,
|
||||
blockElements, startWhiteSpaceRegExp, invalidChildren = [], isInWhiteSpacePreservedElement,
|
||||
endWhiteSpaceRegExp, allWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName;
|
||||
endWhiteSpaceRegExp, allWhiteSpaceRegExp, isAllWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName;
|
||||
|
||||
args = args || {};
|
||||
matchedNodes = {};
|
||||
|
|
@ -3296,6 +3528,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
startWhiteSpaceRegExp = /^[ \t\r\n]+/;
|
||||
endWhiteSpaceRegExp = /[ \t\r\n]+$/;
|
||||
allWhiteSpaceRegExp = /[ \t\r\n]+/g;
|
||||
isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/;
|
||||
|
||||
function addRootBlocks() {
|
||||
var node = rootNode.firstChild, next, rootBlockNode;
|
||||
|
|
@ -3448,10 +3681,12 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
if (elementRule) {
|
||||
if (blockElements[name]) {
|
||||
if (!isInWhiteSpacePreservedElement) {
|
||||
// Trim whitespace at beginning of block
|
||||
for (textNode = node.firstChild; textNode && textNode.type === 3; ) {
|
||||
// Trim whitespace of the first node in a block
|
||||
textNode = node.firstChild;
|
||||
if (textNode && textNode.type === 3) {
|
||||
text = textNode.value.replace(startWhiteSpaceRegExp, '');
|
||||
|
||||
// Any characters left after trim or should we remove it
|
||||
if (text.length > 0) {
|
||||
textNode.value = text;
|
||||
textNode = textNode.next;
|
||||
|
|
@ -3460,12 +3695,27 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
textNode.remove();
|
||||
textNode = sibling;
|
||||
}
|
||||
|
||||
// Remove any pure whitespace siblings
|
||||
while (textNode && textNode.type === 3) {
|
||||
text = textNode.value;
|
||||
sibling = textNode.next;
|
||||
|
||||
if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
|
||||
textNode.remove();
|
||||
textNode = sibling;
|
||||
}
|
||||
|
||||
textNode = sibling;
|
||||
}
|
||||
}
|
||||
|
||||
// Trim whitespace at end of block
|
||||
for (textNode = node.lastChild; textNode && textNode.type === 3; ) {
|
||||
// Trim whitespace of the last node in a block
|
||||
textNode = node.lastChild;
|
||||
if (textNode && textNode.type === 3) {
|
||||
text = textNode.value.replace(endWhiteSpaceRegExp, '');
|
||||
|
||||
// Any characters left after trim or should we remove it
|
||||
if (text.length > 0) {
|
||||
textNode.value = text;
|
||||
textNode = textNode.prev;
|
||||
|
|
@ -3474,6 +3724,19 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
textNode.remove();
|
||||
textNode = sibling;
|
||||
}
|
||||
|
||||
// Remove any pure whitespace siblings
|
||||
while (textNode && textNode.type === 3) {
|
||||
text = textNode.value;
|
||||
sibling = textNode.prev;
|
||||
|
||||
if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) {
|
||||
textNode.remove();
|
||||
textNode = sibling;
|
||||
}
|
||||
|
||||
textNode = sibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3578,8 +3841,8 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
// these elements and keep br elements that where intended to be there intact
|
||||
if (settings.remove_trailing_brs) {
|
||||
self.addNodeFilter('br', function(nodes, name) {
|
||||
var i, l = nodes.length, node, blockElements = schema.getBlockElements(),
|
||||
nonEmptyElements = schema.getNonEmptyElements(), parent, prev, prevName;
|
||||
var i, l = nodes.length, node, blockElements = tinymce.extend({}, schema.getBlockElements()),
|
||||
nonEmptyElements = schema.getNonEmptyElements(), parent, lastParent, prev, prevName;
|
||||
|
||||
// Remove brs from body element as well
|
||||
blockElements.body = 1;
|
||||
|
|
@ -3590,7 +3853,7 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
parent = node.parent;
|
||||
|
||||
if (blockElements[node.parent.name] && node === parent.lastChild) {
|
||||
// Loop all nodes to the right of the current node and check for other BR elements
|
||||
// Loop all nodes to the left of the current node and check for other BR elements
|
||||
// excluding bookmarks since they are invisible
|
||||
prev = node.prev;
|
||||
while (prev) {
|
||||
|
|
@ -3628,6 +3891,46 @@ tinymce.html.Styles = function(settings, schema) {
|
|||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Replaces BR elements inside inline elements like <p><b><i><br></i></b></p> so they become <p><b><i> </i></b></p>
|
||||
lastParent = node;
|
||||
while (parent.firstChild === lastParent && parent.lastChild === lastParent) {
|
||||
lastParent = parent;
|
||||
|
||||
if (blockElements[parent.name]) {
|
||||
break;
|
||||
}
|
||||
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
if (lastParent === parent) {
|
||||
textNode = new tinymce.html.Node('#text', 3);
|
||||
textNode.value = '\u00a0';
|
||||
node.replace(textNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included.
|
||||
if (!settings.allow_html_in_named_anchor) {
|
||||
self.addAttributeFilter('name', function(nodes, name) {
|
||||
var i = nodes.length, sibling, prevSibling, parent, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
if (node.name === 'a' && node.firstChild) {
|
||||
parent = node.parent;
|
||||
|
||||
// Move children after current node
|
||||
sibling = node.lastChild;
|
||||
do {
|
||||
prevSibling = sibling.prev;
|
||||
parent.insert(sibling, node);
|
||||
sibling = prevSibling;
|
||||
} while (sibling);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -3776,7 +4079,7 @@ tinymce.html.Writer = function(settings) {
|
|||
writer.cdata(node.value);
|
||||
},
|
||||
|
||||
// Document fragment
|
||||
// Document fragment
|
||||
11: function(node) {
|
||||
if ((node = node.firstChild)) {
|
||||
do {
|
||||
|
|
@ -4314,7 +4617,11 @@ tinymce.dom = {};
|
|||
return self.bind(target, events instanceof Array ? events.join(' ') : events, func, scope);
|
||||
};
|
||||
|
||||
self.remove = function(target, events, func) {
|
||||
self.remove = function(target, events, func, scope) {
|
||||
if (!target) {
|
||||
return self;
|
||||
}
|
||||
|
||||
// Old API supported direct ID assignment
|
||||
if (typeof(target) === "string") {
|
||||
target = document.getElementById(target);
|
||||
|
|
@ -4322,7 +4629,7 @@ tinymce.dom = {};
|
|||
|
||||
// Old API supported multiple targets
|
||||
if (target instanceof Array) {
|
||||
var i = target;
|
||||
var i = target.length;
|
||||
|
||||
while (i--) {
|
||||
self.remove(target[i], events, func, scope);
|
||||
|
|
@ -4379,6 +4686,46 @@ tinymce.dom = {};
|
|||
namespace = 0;
|
||||
})(tinymce.dom, 'data-mce-expando'); // Namespace and expando
|
||||
|
||||
tinymce.dom.TreeWalker = function(start_node, root_node) {
|
||||
var node = start_node;
|
||||
|
||||
function findSibling(node, start_name, sibling_name, shallow) {
|
||||
var sibling, parent;
|
||||
|
||||
if (node) {
|
||||
// Walk into nodes if it has a start
|
||||
if (!shallow && node[start_name])
|
||||
return node[start_name];
|
||||
|
||||
// Return the sibling if it has one
|
||||
if (node != root_node) {
|
||||
sibling = node[sibling_name];
|
||||
if (sibling)
|
||||
return sibling;
|
||||
|
||||
// Walk up the parents to look for siblings
|
||||
for (parent = node.parentNode; parent && parent != root_node; parent = parent.parentNode) {
|
||||
sibling = parent[sibling_name];
|
||||
if (sibling)
|
||||
return sibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.current = function() {
|
||||
return node;
|
||||
};
|
||||
|
||||
this.next = function(shallow) {
|
||||
return (node = findSibling(node, 'firstChild', 'nextSibling', shallow));
|
||||
};
|
||||
|
||||
this.prev = function(shallow) {
|
||||
return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));
|
||||
};
|
||||
};
|
||||
|
||||
(function(tinymce) {
|
||||
// Shorten names
|
||||
var each = tinymce.each,
|
||||
|
|
@ -4568,8 +4915,8 @@ tinymce.dom = {};
|
|||
h = 0;
|
||||
|
||||
return {
|
||||
w : parseInt(w) || e.offsetWidth || e.clientWidth,
|
||||
h : parseInt(h) || e.offsetHeight || e.clientHeight
|
||||
w : parseInt(w, 10) || e.offsetWidth || e.clientWidth,
|
||||
h : parseInt(h, 10) || e.offsetHeight || e.clientHeight
|
||||
};
|
||||
},
|
||||
|
||||
|
|
@ -5093,7 +5440,7 @@ tinymce.dom = {};
|
|||
if (!u)
|
||||
u = '';
|
||||
|
||||
head = t.select('head')[0];
|
||||
head = d.getElementsByTagName('head')[0];
|
||||
|
||||
each(u.split(','), function(u) {
|
||||
var link;
|
||||
|
|
@ -5369,7 +5716,7 @@ tinymce.dom = {};
|
|||
var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);
|
||||
|
||||
function hex(s) {
|
||||
s = parseInt(s).toString(16);
|
||||
s = parseInt(s, 10).toString(16);
|
||||
|
||||
return s.length > 1 ? s : '0' + s; // 0 -> 00
|
||||
};
|
||||
|
|
@ -5622,7 +5969,7 @@ tinymce.dom = {};
|
|||
// Also keep text nodes with only spaces if surrounded by spans.
|
||||
// eg. "<p><span>a</span> <span>b</span></p>" should keep space between a and b
|
||||
var trimmedLength = tinymce.trim(node.nodeValue).length;
|
||||
if (!t.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength == 0 && surroundedBySpans(node))
|
||||
if (!t.isBlock(node.parentNode) || trimmedLength > 0 || trimmedLength === 0 && surroundedBySpans(node))
|
||||
return;
|
||||
} else if (type == 1) {
|
||||
// If the only child is a bookmark then move it up
|
||||
|
|
@ -5683,6 +6030,25 @@ tinymce.dom = {};
|
|||
return this.events.fire(target, name, evt);
|
||||
},
|
||||
|
||||
// Returns the content editable state of a node
|
||||
getContentEditable: function(node) {
|
||||
var contentEditable;
|
||||
|
||||
// Check type
|
||||
if (node.nodeType != 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Check for fake content editable
|
||||
contentEditable = node.getAttribute("data-mce-contenteditable");
|
||||
if (contentEditable && contentEditable !== "inherit") {
|
||||
return contentEditable;
|
||||
}
|
||||
|
||||
// Check for real content editable
|
||||
return node.contentEditable !== "inherit" ? node.contentEditable : null;
|
||||
},
|
||||
|
||||
|
||||
_findSib : function(node, selector, name) {
|
||||
var t = this, f = selector;
|
||||
|
|
@ -6502,7 +6868,7 @@ tinymce.dom = {};
|
|||
// We need to walk char by char since rng.text or rng.htmlText will trim line endings
|
||||
offset = 0;
|
||||
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
|
||||
if (checkRng.move('character', 1) == 0 || parent != checkRng.parentElement()) {
|
||||
if (checkRng.move('character', 1) === 0 || parent != checkRng.parentElement()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -6515,7 +6881,7 @@ tinymce.dom = {};
|
|||
// Walk character by character in text node until we hit the selected range endpoint, hit the end of document or parent isn't the right one
|
||||
offset = 0;
|
||||
while (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) !== 0) {
|
||||
if (checkRng.move('character', -1) == 0 || parent != checkRng.parentElement()) {
|
||||
if (checkRng.move('character', -1) === 0 || parent != checkRng.parentElement()) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -6681,7 +7047,7 @@ tinymce.dom = {};
|
|||
var rng = selection.getRng(), start, end, bookmark = {};
|
||||
|
||||
function getIndexes(node) {
|
||||
var node, parent, root, children, i, indexes = [];
|
||||
var parent, root, children, i, indexes = [];
|
||||
|
||||
parent = node.parentNode;
|
||||
root = dom.getRoot().parentNode;
|
||||
|
|
@ -6846,13 +7212,18 @@ tinymce.dom = {};
|
|||
// If single element selection then try making a control selection out of it
|
||||
if (startContainer == endContainer && startContainer.nodeType == 1) {
|
||||
// Trick to place the caret inside an empty block element like <p></p>
|
||||
if (!startContainer.hasChildNodes()) {
|
||||
startContainer.innerHTML = '<span>\uFEFF</span><span>\uFEFF</span>';
|
||||
ieRng.moveToElementText(startContainer.lastChild);
|
||||
ieRng.select();
|
||||
dom.doc.selection.clear();
|
||||
startContainer.innerHTML = '';
|
||||
return;
|
||||
if (startOffset == endOffset && !startContainer.hasChildNodes()) {
|
||||
if (startContainer.canHaveHTML) {
|
||||
startContainer.innerHTML = '<span>\uFEFF</span><span>\uFEFF</span>';
|
||||
ieRng.moveToElementText(startContainer.lastChild);
|
||||
ieRng.select();
|
||||
dom.doc.selection.clear();
|
||||
startContainer.innerHTML = '';
|
||||
return;
|
||||
} else {
|
||||
startOffset = dom.nodeIndex(startContainer);
|
||||
startContainer = startContainer.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
if (startOffset == endOffset - 1) {
|
||||
|
|
@ -6885,29 +7256,33 @@ tinymce.dom = {};
|
|||
|
||||
|
||||
/*
|
||||
* Sizzle CSS Selector Engine - v1.0
|
||||
* Copyright 2009, The Dojo Foundation
|
||||
* Sizzle CSS Selector Engine
|
||||
* Copyright, The Dojo Foundation
|
||||
* Released under the MIT, BSD, and GPL Licenses.
|
||||
* More information: http://sizzlejs.com/
|
||||
*/
|
||||
(function(){
|
||||
|
||||
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
|
||||
expando = "sizcache",
|
||||
done = 0,
|
||||
toString = Object.prototype.toString,
|
||||
hasDuplicate = false,
|
||||
baseHasDuplicate = true;
|
||||
baseHasDuplicate = true,
|
||||
rBackslash = /\\/g,
|
||||
rReturn = /\r\n/g,
|
||||
rNonWord = /\W/;
|
||||
|
||||
// Here we check if the JavaScript engine is using some sort of
|
||||
// optimization where it does not always call our comparision
|
||||
// function. If that is the case, discard the hasDuplicate value.
|
||||
// Thus far that includes Google Chrome.
|
||||
[0, 0].sort(function(){
|
||||
[0, 0].sort(function() {
|
||||
baseHasDuplicate = false;
|
||||
return 0;
|
||||
});
|
||||
|
||||
var Sizzle = function(selector, context, results, seed) {
|
||||
var Sizzle = function( selector, context, results, seed ) {
|
||||
results = results || [];
|
||||
context = context || document;
|
||||
|
||||
|
|
@ -6916,24 +7291,27 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
if ( !selector || typeof selector !== "string" ) {
|
||||
return results;
|
||||
}
|
||||
|
||||
var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),
|
||||
soFar = selector, ret, cur, pop, i;
|
||||
|
||||
var m, set, checkSet, extra, ret, cur, pop, i,
|
||||
prune = true,
|
||||
contextXML = Sizzle.isXML( context ),
|
||||
parts = [],
|
||||
soFar = selector;
|
||||
|
||||
// Reset the position of the chunker regexp (start from head)
|
||||
do {
|
||||
chunker.exec("");
|
||||
m = chunker.exec(soFar);
|
||||
chunker.exec( "" );
|
||||
m = chunker.exec( soFar );
|
||||
|
||||
if ( m ) {
|
||||
soFar = m[3];
|
||||
|
||||
|
||||
parts.push( m[1] );
|
||||
|
||||
|
||||
if ( m[2] ) {
|
||||
extra = m[3];
|
||||
break;
|
||||
|
|
@ -6942,8 +7320,10 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
} while ( m );
|
||||
|
||||
if ( parts.length > 1 && origPOS.exec( selector ) ) {
|
||||
|
||||
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
|
||||
set = posProcess( parts[0] + parts[1], context );
|
||||
set = posProcess( parts[0] + parts[1], context, seed );
|
||||
|
||||
} else {
|
||||
set = Expr.relative[ parts[0] ] ?
|
||||
[ context ] :
|
||||
|
|
@ -6955,27 +7335,35 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
if ( Expr.relative[ selector ] ) {
|
||||
selector += parts.shift();
|
||||
}
|
||||
|
||||
set = posProcess( selector, set );
|
||||
|
||||
set = posProcess( selector, set, seed );
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Take a shortcut and set the context if the root selector is an ID
|
||||
// (but not if it'll be faster if the inner selector is an ID)
|
||||
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
|
||||
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
|
||||
|
||||
ret = Sizzle.find( parts.shift(), context, contextXML );
|
||||
context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
|
||||
context = ret.expr ?
|
||||
Sizzle.filter( ret.expr, ret.set )[0] :
|
||||
ret.set[0];
|
||||
}
|
||||
|
||||
if ( context ) {
|
||||
ret = seed ?
|
||||
{ expr: parts.pop(), set: makeArray(seed) } :
|
||||
Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
|
||||
set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
|
||||
|
||||
set = ret.expr ?
|
||||
Sizzle.filter( ret.expr, ret.set ) :
|
||||
ret.set;
|
||||
|
||||
if ( parts.length > 0 ) {
|
||||
checkSet = makeArray(set);
|
||||
checkSet = makeArray( set );
|
||||
|
||||
} else {
|
||||
prune = false;
|
||||
}
|
||||
|
|
@ -6996,6 +7384,7 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
|
||||
Expr.relative[ cur ]( checkSet, pop, contextXML );
|
||||
}
|
||||
|
||||
} else {
|
||||
checkSet = parts = [];
|
||||
}
|
||||
|
|
@ -7012,12 +7401,14 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
if ( toString.call(checkSet) === "[object Array]" ) {
|
||||
if ( !prune ) {
|
||||
results.push.apply( results, checkSet );
|
||||
|
||||
} else if ( context && context.nodeType === 1 ) {
|
||||
for ( i = 0; checkSet[i] != null; i++ ) {
|
||||
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
|
||||
results.push( set[i] );
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for ( i = 0; checkSet[i] != null; i++ ) {
|
||||
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
|
||||
|
|
@ -7025,6 +7416,7 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
makeArray( checkSet, results );
|
||||
}
|
||||
|
|
@ -7037,15 +7429,15 @@ var Sizzle = function(selector, context, results, seed) {
|
|||
return results;
|
||||
};
|
||||
|
||||
Sizzle.uniqueSort = function(results){
|
||||
Sizzle.uniqueSort = function( results ) {
|
||||
if ( sortOrder ) {
|
||||
hasDuplicate = baseHasDuplicate;
|
||||
results.sort(sortOrder);
|
||||
results.sort( sortOrder );
|
||||
|
||||
if ( hasDuplicate ) {
|
||||
for ( var i = 1; i < results.length; i++ ) {
|
||||
if ( results[i] === results[i-1] ) {
|
||||
results.splice(i--, 1);
|
||||
if ( results[i] === results[ i - 1 ] ) {
|
||||
results.splice( i--, 1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7054,27 +7446,32 @@ Sizzle.uniqueSort = function(results){
|
|||
return results;
|
||||
};
|
||||
|
||||
Sizzle.matches = function(expr, set){
|
||||
return Sizzle(expr, null, null, set);
|
||||
Sizzle.matches = function( expr, set ) {
|
||||
return Sizzle( expr, null, null, set );
|
||||
};
|
||||
|
||||
Sizzle.find = function(expr, context, isXML){
|
||||
var set;
|
||||
Sizzle.matchesSelector = function( node, expr ) {
|
||||
return Sizzle( expr, null, null, [node] ).length > 0;
|
||||
};
|
||||
|
||||
Sizzle.find = function( expr, context, isXML ) {
|
||||
var set, i, len, match, type, left;
|
||||
|
||||
if ( !expr ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
|
||||
var type = Expr.order[i], match;
|
||||
|
||||
for ( i = 0, len = Expr.order.length; i < len; i++ ) {
|
||||
type = Expr.order[i];
|
||||
|
||||
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
|
||||
var left = match[1];
|
||||
match.splice(1,1);
|
||||
left = match[1];
|
||||
match.splice( 1, 1 );
|
||||
|
||||
if ( left.substr( left.length - 1 ) !== "\\" ) {
|
||||
match[1] = (match[1] || "").replace(/\\/g, "");
|
||||
match[1] = (match[1] || "").replace( rBackslash, "" );
|
||||
set = Expr.find[ type ]( match, context, isXML );
|
||||
|
||||
if ( set != null ) {
|
||||
expr = expr.replace( Expr.match[ type ], "" );
|
||||
break;
|
||||
|
|
@ -7084,20 +7481,29 @@ Sizzle.find = function(expr, context, isXML){
|
|||
}
|
||||
|
||||
if ( !set ) {
|
||||
set = context.getElementsByTagName("*");
|
||||
set = typeof context.getElementsByTagName !== "undefined" ?
|
||||
context.getElementsByTagName( "*" ) :
|
||||
[];
|
||||
}
|
||||
|
||||
return {set: set, expr: expr};
|
||||
return { set: set, expr: expr };
|
||||
};
|
||||
|
||||
Sizzle.filter = function(expr, set, inplace, not){
|
||||
var old = expr, result = [], curLoop = set, match, anyFound,
|
||||
isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);
|
||||
Sizzle.filter = function( expr, set, inplace, not ) {
|
||||
var match, anyFound,
|
||||
type, found, item, filter, left,
|
||||
i, pass,
|
||||
old = expr,
|
||||
result = [],
|
||||
curLoop = set,
|
||||
isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
|
||||
|
||||
while ( expr && set.length ) {
|
||||
for ( var type in Expr.filter ) {
|
||||
for ( type in Expr.filter ) {
|
||||
if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
|
||||
var filter = Expr.filter[ type ], found, item, left = match[1];
|
||||
filter = Expr.filter[ type ];
|
||||
left = match[1];
|
||||
|
||||
anyFound = false;
|
||||
|
||||
match.splice(1,1);
|
||||
|
|
@ -7115,23 +7521,26 @@ Sizzle.filter = function(expr, set, inplace, not){
|
|||
|
||||
if ( !match ) {
|
||||
anyFound = found = true;
|
||||
|
||||
} else if ( match === true ) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ( match ) {
|
||||
for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
|
||||
for ( i = 0; (item = curLoop[i]) != null; i++ ) {
|
||||
if ( item ) {
|
||||
found = filter( item, match, i, curLoop );
|
||||
var pass = not ^ !!found;
|
||||
pass = not ^ found;
|
||||
|
||||
if ( inplace && found != null ) {
|
||||
if ( pass ) {
|
||||
anyFound = true;
|
||||
|
||||
} else {
|
||||
curLoop[i] = false;
|
||||
}
|
||||
|
||||
} else if ( pass ) {
|
||||
result.push( item );
|
||||
anyFound = true;
|
||||
|
|
@ -7160,6 +7569,7 @@ Sizzle.filter = function(expr, set, inplace, not){
|
|||
if ( expr === old ) {
|
||||
if ( anyFound == null ) {
|
||||
Sizzle.error( expr );
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
|
@ -7172,35 +7582,78 @@ Sizzle.filter = function(expr, set, inplace, not){
|
|||
};
|
||||
|
||||
Sizzle.error = function( msg ) {
|
||||
throw "Syntax error, unrecognized expression: " + msg;
|
||||
throw new Error( "Syntax error, unrecognized expression: " + msg );
|
||||
};
|
||||
|
||||
var getText = Sizzle.getText = function( elem ) {
|
||||
var i, node,
|
||||
nodeType = elem.nodeType,
|
||||
ret = "";
|
||||
|
||||
if ( nodeType ) {
|
||||
if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
|
||||
// Use textContent || innerText for elements
|
||||
if ( typeof elem.textContent === 'string' ) {
|
||||
return elem.textContent;
|
||||
} else if ( typeof elem.innerText === 'string' ) {
|
||||
// Replace IE's carriage returns
|
||||
return elem.innerText.replace( rReturn, '' );
|
||||
} else {
|
||||
// Traverse it's children
|
||||
for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
|
||||
ret += getText( elem );
|
||||
}
|
||||
}
|
||||
} else if ( nodeType === 3 || nodeType === 4 ) {
|
||||
return elem.nodeValue;
|
||||
}
|
||||
} else {
|
||||
|
||||
// If no nodeType, this is expected to be an array
|
||||
for ( i = 0; (node = elem[i]); i++ ) {
|
||||
// Do not traverse comment nodes
|
||||
if ( node.nodeType !== 8 ) {
|
||||
ret += getText( node );
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
var Expr = Sizzle.selectors = {
|
||||
order: [ "ID", "NAME", "TAG" ],
|
||||
|
||||
match: {
|
||||
ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
|
||||
CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
|
||||
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
|
||||
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
|
||||
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
|
||||
TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
|
||||
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
|
||||
CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
|
||||
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
|
||||
PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
|
||||
},
|
||||
|
||||
leftMatch: {},
|
||||
|
||||
attrMap: {
|
||||
"class": "className",
|
||||
"for": "htmlFor"
|
||||
},
|
||||
|
||||
attrHandle: {
|
||||
href: function(elem){
|
||||
return elem.getAttribute("href");
|
||||
href: function( elem ) {
|
||||
return elem.getAttribute( "href" );
|
||||
},
|
||||
type: function( elem ) {
|
||||
return elem.getAttribute( "type" );
|
||||
}
|
||||
},
|
||||
|
||||
relative: {
|
||||
"+": function(checkSet, part){
|
||||
var isPartStr = typeof part === "string",
|
||||
isTag = isPartStr && !/\W/.test(part),
|
||||
isTag = isPartStr && !rNonWord.test( part ),
|
||||
isPartStrNotTag = isPartStr && !isTag;
|
||||
|
||||
if ( isTag ) {
|
||||
|
|
@ -7221,23 +7674,29 @@ var Expr = Sizzle.selectors = {
|
|||
Sizzle.filter( part, checkSet, true );
|
||||
}
|
||||
},
|
||||
">": function(checkSet, part){
|
||||
var isPartStr = typeof part === "string",
|
||||
elem, i = 0, l = checkSet.length;
|
||||
|
||||
if ( isPartStr && !/\W/.test(part) ) {
|
||||
">": function( checkSet, part ) {
|
||||
var elem,
|
||||
isPartStr = typeof part === "string",
|
||||
i = 0,
|
||||
l = checkSet.length;
|
||||
|
||||
if ( isPartStr && !rNonWord.test( part ) ) {
|
||||
part = part.toLowerCase();
|
||||
|
||||
for ( ; i < l; i++ ) {
|
||||
elem = checkSet[i];
|
||||
|
||||
if ( elem ) {
|
||||
var parent = elem.parentNode;
|
||||
checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
for ( ; i < l; i++ ) {
|
||||
elem = checkSet[i];
|
||||
|
||||
if ( elem ) {
|
||||
checkSet[i] = isPartStr ?
|
||||
elem.parentNode :
|
||||
|
|
@ -7250,39 +7709,50 @@ var Expr = Sizzle.selectors = {
|
|||
}
|
||||
}
|
||||
},
|
||||
|
||||
"": function(checkSet, part, isXML){
|
||||
var doneName = done++, checkFn = dirCheck, nodeCheck;
|
||||
var nodeCheck,
|
||||
doneName = done++,
|
||||
checkFn = dirCheck;
|
||||
|
||||
if ( typeof part === "string" && !/\W/.test(part) ) {
|
||||
if ( typeof part === "string" && !rNonWord.test( part ) ) {
|
||||
part = part.toLowerCase();
|
||||
nodeCheck = part;
|
||||
checkFn = dirNodeCheck;
|
||||
}
|
||||
|
||||
checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
|
||||
checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
|
||||
},
|
||||
"~": function(checkSet, part, isXML){
|
||||
var doneName = done++, checkFn = dirCheck, nodeCheck;
|
||||
|
||||
if ( typeof part === "string" && !/\W/.test(part) ) {
|
||||
"~": function( checkSet, part, isXML ) {
|
||||
var nodeCheck,
|
||||
doneName = done++,
|
||||
checkFn = dirCheck;
|
||||
|
||||
if ( typeof part === "string" && !rNonWord.test( part ) ) {
|
||||
part = part.toLowerCase();
|
||||
nodeCheck = part;
|
||||
checkFn = dirNodeCheck;
|
||||
}
|
||||
|
||||
checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
|
||||
checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
|
||||
}
|
||||
},
|
||||
|
||||
find: {
|
||||
ID: function(match, context, isXML){
|
||||
ID: function( match, context, isXML ) {
|
||||
if ( typeof context.getElementById !== "undefined" && !isXML ) {
|
||||
var m = context.getElementById(match[1]);
|
||||
return m ? [m] : [];
|
||||
// Check parentNode to catch when Blackberry 4.6 returns
|
||||
// nodes that are no longer in the document #6963
|
||||
return m && m.parentNode ? [m] : [];
|
||||
}
|
||||
},
|
||||
NAME: function(match, context){
|
||||
|
||||
NAME: function( match, context ) {
|
||||
if ( typeof context.getElementsByName !== "undefined" ) {
|
||||
var ret = [], results = context.getElementsByName(match[1]);
|
||||
var ret = [],
|
||||
results = context.getElementsByName( match[1] );
|
||||
|
||||
for ( var i = 0, l = results.length; i < l; i++ ) {
|
||||
if ( results[i].getAttribute("name") === match[1] ) {
|
||||
|
|
@ -7293,13 +7763,16 @@ var Expr = Sizzle.selectors = {
|
|||
return ret.length === 0 ? null : ret;
|
||||
}
|
||||
},
|
||||
TAG: function(match, context){
|
||||
return context.getElementsByTagName(match[1]);
|
||||
|
||||
TAG: function( match, context ) {
|
||||
if ( typeof context.getElementsByTagName !== "undefined" ) {
|
||||
return context.getElementsByTagName( match[1] );
|
||||
}
|
||||
}
|
||||
},
|
||||
preFilter: {
|
||||
CLASS: function(match, curLoop, inplace, result, not, isXML){
|
||||
match = " " + match[1].replace(/\\/g, "") + " ";
|
||||
CLASS: function( match, curLoop, inplace, result, not, isXML ) {
|
||||
match = " " + match[1].replace( rBackslash, "" ) + " ";
|
||||
|
||||
if ( isXML ) {
|
||||
return match;
|
||||
|
|
@ -7307,10 +7780,11 @@ var Expr = Sizzle.selectors = {
|
|||
|
||||
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
|
||||
if ( elem ) {
|
||||
if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
|
||||
if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
|
||||
if ( !inplace ) {
|
||||
result.push( elem );
|
||||
}
|
||||
|
||||
} else if ( inplace ) {
|
||||
curLoop[i] = false;
|
||||
}
|
||||
|
|
@ -7319,16 +7793,25 @@ var Expr = Sizzle.selectors = {
|
|||
|
||||
return false;
|
||||
},
|
||||
ID: function(match){
|
||||
return match[1].replace(/\\/g, "");
|
||||
|
||||
ID: function( match ) {
|
||||
return match[1].replace( rBackslash, "" );
|
||||
},
|
||||
TAG: function(match, curLoop){
|
||||
return match[1].toLowerCase();
|
||||
|
||||
TAG: function( match, curLoop ) {
|
||||
return match[1].replace( rBackslash, "" ).toLowerCase();
|
||||
},
|
||||
CHILD: function(match){
|
||||
|
||||
CHILD: function( match ) {
|
||||
if ( match[1] === "nth" ) {
|
||||
if ( !match[2] ) {
|
||||
Sizzle.error( match[0] );
|
||||
}
|
||||
|
||||
match[2] = match[2].replace(/^\+|\s*/g, '');
|
||||
|
||||
// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
|
||||
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
|
||||
var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
|
||||
match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
|
||||
!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
|
||||
|
||||
|
|
@ -7336,141 +7819,196 @@ var Expr = Sizzle.selectors = {
|
|||
match[2] = (test[1] + (test[2] || 1)) - 0;
|
||||
match[3] = test[3] - 0;
|
||||
}
|
||||
else if ( match[2] ) {
|
||||
Sizzle.error( match[0] );
|
||||
}
|
||||
|
||||
// TODO: Move to normal caching system
|
||||
match[0] = done++;
|
||||
|
||||
return match;
|
||||
},
|
||||
ATTR: function(match, curLoop, inplace, result, not, isXML){
|
||||
var name = match[1].replace(/\\/g, "");
|
||||
|
||||
|
||||
ATTR: function( match, curLoop, inplace, result, not, isXML ) {
|
||||
var name = match[1] = match[1].replace( rBackslash, "" );
|
||||
|
||||
if ( !isXML && Expr.attrMap[name] ) {
|
||||
match[1] = Expr.attrMap[name];
|
||||
}
|
||||
|
||||
// Handle if an un-quoted value was used
|
||||
match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
|
||||
|
||||
if ( match[2] === "~=" ) {
|
||||
match[4] = " " + match[4] + " ";
|
||||
}
|
||||
|
||||
return match;
|
||||
},
|
||||
PSEUDO: function(match, curLoop, inplace, result, not){
|
||||
|
||||
PSEUDO: function( match, curLoop, inplace, result, not ) {
|
||||
if ( match[1] === "not" ) {
|
||||
// If we're dealing with a complex expression, or a simple one
|
||||
if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
|
||||
match[3] = Sizzle(match[3], null, null, curLoop);
|
||||
|
||||
} else {
|
||||
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
|
||||
|
||||
if ( !inplace ) {
|
||||
result.push.apply( result, ret );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return match;
|
||||
},
|
||||
POS: function(match){
|
||||
|
||||
POS: function( match ) {
|
||||
match.unshift( true );
|
||||
|
||||
return match;
|
||||
}
|
||||
},
|
||||
|
||||
filters: {
|
||||
enabled: function(elem){
|
||||
enabled: function( elem ) {
|
||||
return elem.disabled === false && elem.type !== "hidden";
|
||||
},
|
||||
disabled: function(elem){
|
||||
|
||||
disabled: function( elem ) {
|
||||
return elem.disabled === true;
|
||||
},
|
||||
checked: function(elem){
|
||||
|
||||
checked: function( elem ) {
|
||||
return elem.checked === true;
|
||||
},
|
||||
selected: function(elem){
|
||||
|
||||
selected: function( elem ) {
|
||||
// Accessing this property makes selected-by-default
|
||||
// options in Safari work properly
|
||||
elem.parentNode.selectedIndex;
|
||||
if ( elem.parentNode ) {
|
||||
elem.parentNode.selectedIndex;
|
||||
}
|
||||
|
||||
return elem.selected === true;
|
||||
},
|
||||
parent: function(elem){
|
||||
|
||||
parent: function( elem ) {
|
||||
return !!elem.firstChild;
|
||||
},
|
||||
empty: function(elem){
|
||||
|
||||
empty: function( elem ) {
|
||||
return !elem.firstChild;
|
||||
},
|
||||
has: function(elem, i, match){
|
||||
|
||||
has: function( elem, i, match ) {
|
||||
return !!Sizzle( match[3], elem ).length;
|
||||
},
|
||||
header: function(elem){
|
||||
|
||||
header: function( elem ) {
|
||||
return (/h\d/i).test( elem.nodeName );
|
||||
},
|
||||
text: function(elem){
|
||||
return "text" === elem.type;
|
||||
|
||||
text: function( elem ) {
|
||||
var attr = elem.getAttribute( "type" ), type = elem.type;
|
||||
// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
|
||||
// use getAttribute instead to test this case
|
||||
return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
|
||||
},
|
||||
radio: function(elem){
|
||||
return "radio" === elem.type;
|
||||
|
||||
radio: function( elem ) {
|
||||
return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
|
||||
},
|
||||
checkbox: function(elem){
|
||||
return "checkbox" === elem.type;
|
||||
|
||||
checkbox: function( elem ) {
|
||||
return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
|
||||
},
|
||||
file: function(elem){
|
||||
return "file" === elem.type;
|
||||
|
||||
file: function( elem ) {
|
||||
return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
|
||||
},
|
||||
password: function(elem){
|
||||
return "password" === elem.type;
|
||||
|
||||
password: function( elem ) {
|
||||
return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
|
||||
},
|
||||
submit: function(elem){
|
||||
return "submit" === elem.type;
|
||||
|
||||
submit: function( elem ) {
|
||||
var name = elem.nodeName.toLowerCase();
|
||||
return (name === "input" || name === "button") && "submit" === elem.type;
|
||||
},
|
||||
image: function(elem){
|
||||
return "image" === elem.type;
|
||||
|
||||
image: function( elem ) {
|
||||
return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
|
||||
},
|
||||
reset: function(elem){
|
||||
return "reset" === elem.type;
|
||||
|
||||
reset: function( elem ) {
|
||||
var name = elem.nodeName.toLowerCase();
|
||||
return (name === "input" || name === "button") && "reset" === elem.type;
|
||||
},
|
||||
button: function(elem){
|
||||
return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
|
||||
|
||||
button: function( elem ) {
|
||||
var name = elem.nodeName.toLowerCase();
|
||||
return name === "input" && "button" === elem.type || name === "button";
|
||||
},
|
||||
input: function(elem){
|
||||
return (/input|select|textarea|button/i).test(elem.nodeName);
|
||||
|
||||
input: function( elem ) {
|
||||
return (/input|select|textarea|button/i).test( elem.nodeName );
|
||||
},
|
||||
|
||||
focus: function( elem ) {
|
||||
return elem === elem.ownerDocument.activeElement;
|
||||
}
|
||||
},
|
||||
setFilters: {
|
||||
first: function(elem, i){
|
||||
first: function( elem, i ) {
|
||||
return i === 0;
|
||||
},
|
||||
last: function(elem, i, match, array){
|
||||
|
||||
last: function( elem, i, match, array ) {
|
||||
return i === array.length - 1;
|
||||
},
|
||||
even: function(elem, i){
|
||||
|
||||
even: function( elem, i ) {
|
||||
return i % 2 === 0;
|
||||
},
|
||||
odd: function(elem, i){
|
||||
|
||||
odd: function( elem, i ) {
|
||||
return i % 2 === 1;
|
||||
},
|
||||
lt: function(elem, i, match){
|
||||
|
||||
lt: function( elem, i, match ) {
|
||||
return i < match[3] - 0;
|
||||
},
|
||||
gt: function(elem, i, match){
|
||||
|
||||
gt: function( elem, i, match ) {
|
||||
return i > match[3] - 0;
|
||||
},
|
||||
nth: function(elem, i, match){
|
||||
|
||||
nth: function( elem, i, match ) {
|
||||
return match[3] - 0 === i;
|
||||
},
|
||||
eq: function(elem, i, match){
|
||||
|
||||
eq: function( elem, i, match ) {
|
||||
return match[3] - 0 === i;
|
||||
}
|
||||
},
|
||||
filter: {
|
||||
PSEUDO: function(elem, match, i, array){
|
||||
var name = match[1], filter = Expr.filters[ name ];
|
||||
PSEUDO: function( elem, match, i, array ) {
|
||||
var name = match[1],
|
||||
filter = Expr.filters[ name ];
|
||||
|
||||
if ( filter ) {
|
||||
return filter( elem, i, match, array );
|
||||
|
||||
} else if ( name === "contains" ) {
|
||||
return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
|
||||
return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
|
||||
|
||||
} else if ( name === "not" ) {
|
||||
var not = match[3];
|
||||
|
||||
|
|
@ -7481,72 +8019,96 @@ var Expr = Sizzle.selectors = {
|
|||
}
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
Sizzle.error( "Syntax error, unrecognized expression: " + name );
|
||||
Sizzle.error( name );
|
||||
}
|
||||
},
|
||||
CHILD: function(elem, match){
|
||||
var type = match[1], node = elem;
|
||||
switch (type) {
|
||||
case 'only':
|
||||
case 'first':
|
||||
while ( (node = node.previousSibling) ) {
|
||||
if ( node.nodeType === 1 ) {
|
||||
return false;
|
||||
|
||||
CHILD: function( elem, match ) {
|
||||
var first, last,
|
||||
doneName, parent, cache,
|
||||
count, diff,
|
||||
type = match[1],
|
||||
node = elem;
|
||||
|
||||
switch ( type ) {
|
||||
case "only":
|
||||
case "first":
|
||||
while ( (node = node.previousSibling) ) {
|
||||
if ( node.nodeType === 1 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if ( type === "first" ) {
|
||||
return true;
|
||||
|
||||
if ( type === "first" ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
node = elem;
|
||||
case 'last':
|
||||
while ( (node = node.nextSibling) ) {
|
||||
if ( node.nodeType === 1 ) {
|
||||
return false;
|
||||
|
||||
/* falls through */
|
||||
case "last":
|
||||
while ( (node = node.nextSibling) ) {
|
||||
if ( node.nodeType === 1 ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
case 'nth':
|
||||
var first = match[2], last = match[3];
|
||||
|
||||
case "nth":
|
||||
first = match[2];
|
||||
last = match[3];
|
||||
|
||||
if ( first === 1 && last === 0 ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var doneName = match[0],
|
||||
parent = elem.parentNode;
|
||||
|
||||
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
|
||||
var count = 0;
|
||||
|
||||
doneName = match[0];
|
||||
parent = elem.parentNode;
|
||||
|
||||
if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
|
||||
count = 0;
|
||||
|
||||
for ( node = parent.firstChild; node; node = node.nextSibling ) {
|
||||
if ( node.nodeType === 1 ) {
|
||||
node.nodeIndex = ++count;
|
||||
}
|
||||
}
|
||||
parent.sizcache = doneName;
|
||||
}
|
||||
|
||||
parent[ expando ] = doneName;
|
||||
}
|
||||
|
||||
var diff = elem.nodeIndex - last;
|
||||
|
||||
diff = elem.nodeIndex - last;
|
||||
|
||||
if ( first === 0 ) {
|
||||
return diff === 0;
|
||||
|
||||
} else {
|
||||
return ( diff % first === 0 && diff / first >= 0 );
|
||||
}
|
||||
}
|
||||
},
|
||||
ID: function(elem, match){
|
||||
|
||||
ID: function( elem, match ) {
|
||||
return elem.nodeType === 1 && elem.getAttribute("id") === match;
|
||||
},
|
||||
TAG: function(elem, match){
|
||||
return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
|
||||
|
||||
TAG: function( elem, match ) {
|
||||
return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
|
||||
},
|
||||
CLASS: function(elem, match){
|
||||
|
||||
CLASS: function( elem, match ) {
|
||||
return (" " + (elem.className || elem.getAttribute("class")) + " ")
|
||||
.indexOf( match ) > -1;
|
||||
},
|
||||
ATTR: function(elem, match){
|
||||
|
||||
ATTR: function( elem, match ) {
|
||||
var name = match[1],
|
||||
result = Expr.attrHandle[ name ] ?
|
||||
result = Sizzle.attr ?
|
||||
Sizzle.attr( elem, name ) :
|
||||
Expr.attrHandle[ name ] ?
|
||||
Expr.attrHandle[ name ]( elem ) :
|
||||
elem[ name ] != null ?
|
||||
elem[ name ] :
|
||||
|
|
@ -7557,6 +8119,8 @@ var Expr = Sizzle.selectors = {
|
|||
|
||||
return result == null ?
|
||||
type === "!=" :
|
||||
!type && Sizzle.attr ?
|
||||
result != null :
|
||||
type === "=" ?
|
||||
value === check :
|
||||
type === "*=" ?
|
||||
|
|
@ -7575,8 +8139,10 @@ var Expr = Sizzle.selectors = {
|
|||
value === check || value.substr(0, check.length + 1) === check + "-" :
|
||||
false;
|
||||
},
|
||||
POS: function(elem, match, i, array){
|
||||
var name = match[2], filter = Expr.setFilters[ name ];
|
||||
|
||||
POS: function( elem, match, i, array ) {
|
||||
var name = match[2],
|
||||
filter = Expr.setFilters[ name ];
|
||||
|
||||
if ( filter ) {
|
||||
return filter( elem, i, match, array );
|
||||
|
|
@ -7594,15 +8160,18 @@ for ( var type in Expr.match ) {
|
|||
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
|
||||
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
|
||||
}
|
||||
// Expose origPOS
|
||||
// "global" as in regardless of relation to brackets/parens
|
||||
Expr.match.globalPOS = origPOS;
|
||||
|
||||
var makeArray = function(array, results) {
|
||||
var makeArray = function( array, results ) {
|
||||
array = Array.prototype.slice.call( array, 0 );
|
||||
|
||||
if ( results ) {
|
||||
results.push.apply( results, array );
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
return array;
|
||||
};
|
||||
|
||||
|
|
@ -7614,17 +8183,20 @@ try {
|
|||
Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
|
||||
|
||||
// Provide a fallback method if it does not work
|
||||
} catch(e){
|
||||
makeArray = function(array, results) {
|
||||
var ret = results || [], i = 0;
|
||||
} catch( e ) {
|
||||
makeArray = function( array, results ) {
|
||||
var i = 0,
|
||||
ret = results || [];
|
||||
|
||||
if ( toString.call(array) === "[object Array]" ) {
|
||||
Array.prototype.push.apply( ret, array );
|
||||
|
||||
} else {
|
||||
if ( typeof array.length === "number" ) {
|
||||
for ( var l = array.length; i < l; i++ ) {
|
||||
ret.push( array[i] );
|
||||
}
|
||||
|
||||
} else {
|
||||
for ( ; array[i]; i++ ) {
|
||||
ret.push( array[i] );
|
||||
|
|
@ -7636,110 +8208,141 @@ try {
|
|||
};
|
||||
}
|
||||
|
||||
var sortOrder;
|
||||
var sortOrder, siblingCheck;
|
||||
|
||||
if ( document.documentElement.compareDocumentPosition ) {
|
||||
sortOrder = function( a, b ) {
|
||||
if ( a === b ) {
|
||||
hasDuplicate = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
|
||||
if ( a == b ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return a.compareDocumentPosition ? -1 : 1;
|
||||
}
|
||||
|
||||
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
|
||||
if ( ret === 0 ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return ret;
|
||||
return a.compareDocumentPosition(b) & 4 ? -1 : 1;
|
||||
};
|
||||
} else if ( "sourceIndex" in document.documentElement ) {
|
||||
|
||||
} else {
|
||||
sortOrder = function( a, b ) {
|
||||
if ( !a.sourceIndex || !b.sourceIndex ) {
|
||||
if ( a == b ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return a.sourceIndex ? -1 : 1;
|
||||
// The nodes are identical, we can exit early
|
||||
if ( a === b ) {
|
||||
hasDuplicate = true;
|
||||
return 0;
|
||||
|
||||
// Fallback to using sourceIndex (in IE) if it's available on both nodes
|
||||
} else if ( a.sourceIndex && b.sourceIndex ) {
|
||||
return a.sourceIndex - b.sourceIndex;
|
||||
}
|
||||
|
||||
var ret = a.sourceIndex - b.sourceIndex;
|
||||
if ( ret === 0 ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
} else if ( document.createRange ) {
|
||||
sortOrder = function( a, b ) {
|
||||
if ( !a.ownerDocument || !b.ownerDocument ) {
|
||||
if ( a == b ) {
|
||||
hasDuplicate = true;
|
||||
}
|
||||
return a.ownerDocument ? -1 : 1;
|
||||
var al, bl,
|
||||
ap = [],
|
||||
bp = [],
|
||||
aup = a.parentNode,
|
||||
bup = b.parentNode,
|
||||
cur = aup;
|
||||
|
||||
// If the nodes are siblings (or identical) we can do a quick check
|
||||
if ( aup === bup ) {
|
||||
return siblingCheck( a, b );
|
||||
|
||||
// If no parents were found then the nodes are disconnected
|
||||
} else if ( !aup ) {
|
||||
return -1;
|
||||
|
||||
} else if ( !bup ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
|
||||
aRange.setStart(a, 0);
|
||||
aRange.setEnd(a, 0);
|
||||
bRange.setStart(b, 0);
|
||||
bRange.setEnd(b, 0);
|
||||
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
|
||||
if ( ret === 0 ) {
|
||||
hasDuplicate = true;
|
||||
// Otherwise they're somewhere else in the tree so we need
|
||||
// to build up a full list of the parentNodes for comparison
|
||||
while ( cur ) {
|
||||
ap.unshift( cur );
|
||||
cur = cur.parentNode;
|
||||
}
|
||||
return ret;
|
||||
|
||||
cur = bup;
|
||||
|
||||
while ( cur ) {
|
||||
bp.unshift( cur );
|
||||
cur = cur.parentNode;
|
||||
}
|
||||
|
||||
al = ap.length;
|
||||
bl = bp.length;
|
||||
|
||||
// Start walking down the tree looking for a discrepancy
|
||||
for ( var i = 0; i < al && i < bl; i++ ) {
|
||||
if ( ap[i] !== bp[i] ) {
|
||||
return siblingCheck( ap[i], bp[i] );
|
||||
}
|
||||
}
|
||||
|
||||
// We ended someplace up the tree so do a sibling check
|
||||
return i === al ?
|
||||
siblingCheck( a, bp[i], -1 ) :
|
||||
siblingCheck( ap[i], b, 1 );
|
||||
};
|
||||
|
||||
siblingCheck = function( a, b, ret ) {
|
||||
if ( a === b ) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
var cur = a.nextSibling;
|
||||
|
||||
while ( cur ) {
|
||||
if ( cur === b ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
cur = cur.nextSibling;
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
}
|
||||
|
||||
// Utility function for retreiving the text value of an array of DOM nodes
|
||||
Sizzle.getText = function( elems ) {
|
||||
var ret = "", elem;
|
||||
|
||||
for ( var i = 0; elems[i]; i++ ) {
|
||||
elem = elems[i];
|
||||
|
||||
// Get the text from text nodes and CDATA nodes
|
||||
if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
|
||||
ret += elem.nodeValue;
|
||||
|
||||
// Traverse everything else, except comment nodes
|
||||
} else if ( elem.nodeType !== 8 ) {
|
||||
ret += Sizzle.getText( elem.childNodes );
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
// Check to see if the browser returns elements by name when
|
||||
// querying by getElementById (and provide a workaround)
|
||||
(function(){
|
||||
// We're going to inject a fake input element with a specified name
|
||||
var form = document.createElement("div"),
|
||||
id = "script" + (new Date()).getTime();
|
||||
id = "script" + (new Date()).getTime(),
|
||||
root = document.documentElement;
|
||||
|
||||
form.innerHTML = "<a name='" + id + "'/>";
|
||||
|
||||
// Inject it into the root element, check its status, and remove it quickly
|
||||
var root = document.documentElement;
|
||||
root.insertBefore( form, root.firstChild );
|
||||
|
||||
// The workaround has to do additional checks after a getElementById
|
||||
// Which slows things down for other browsers (hence the branching)
|
||||
if ( document.getElementById( id ) ) {
|
||||
Expr.find.ID = function(match, context, isXML){
|
||||
Expr.find.ID = function( match, context, isXML ) {
|
||||
if ( typeof context.getElementById !== "undefined" && !isXML ) {
|
||||
var m = context.getElementById(match[1]);
|
||||
return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
|
||||
|
||||
return m ?
|
||||
m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
|
||||
[m] :
|
||||
undefined :
|
||||
[];
|
||||
}
|
||||
};
|
||||
|
||||
Expr.filter.ID = function(elem, match){
|
||||
Expr.filter.ID = function( elem, match ) {
|
||||
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
|
||||
|
||||
return elem.nodeType === 1 && node && node.nodeValue === match;
|
||||
};
|
||||
}
|
||||
|
||||
root.removeChild( form );
|
||||
root = form = null; // release memory in IE
|
||||
|
||||
// release memory in IE
|
||||
root = form = null;
|
||||
})();
|
||||
|
||||
(function(){
|
||||
|
|
@ -7752,8 +8355,8 @@ Sizzle.getText = function( elems ) {
|
|||
|
||||
// Make sure no comments are found
|
||||
if ( div.getElementsByTagName("*").length > 0 ) {
|
||||
Expr.find.TAG = function(match, context){
|
||||
var results = context.getElementsByTagName(match[1]);
|
||||
Expr.find.TAG = function( match, context ) {
|
||||
var results = context.getElementsByTagName( match[1] );
|
||||
|
||||
// Filter out possible comments
|
||||
if ( match[1] === "*" ) {
|
||||
|
|
@ -7774,19 +8377,25 @@ Sizzle.getText = function( elems ) {
|
|||
|
||||
// Check to see if an attribute returns normalized href attributes
|
||||
div.innerHTML = "<a href='#'></a>";
|
||||
|
||||
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
|
||||
div.firstChild.getAttribute("href") !== "#" ) {
|
||||
Expr.attrHandle.href = function(elem){
|
||||
return elem.getAttribute("href", 2);
|
||||
|
||||
Expr.attrHandle.href = function( elem ) {
|
||||
return elem.getAttribute( "href", 2 );
|
||||
};
|
||||
}
|
||||
|
||||
div = null; // release memory in IE
|
||||
// release memory in IE
|
||||
div = null;
|
||||
})();
|
||||
|
||||
if ( document.querySelectorAll ) {
|
||||
(function(){
|
||||
var oldSizzle = Sizzle, div = document.createElement("div");
|
||||
var oldSizzle = Sizzle,
|
||||
div = document.createElement("div"),
|
||||
id = "__sizzle__";
|
||||
|
||||
div.innerHTML = "<p class='TEST'></p>";
|
||||
|
||||
// Safari can't handle uppercase or unicode characters when
|
||||
|
|
@ -7794,18 +8403,89 @@ if ( document.querySelectorAll ) {
|
|||
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Sizzle = function(query, context, extra, seed){
|
||||
|
||||
Sizzle = function( query, context, extra, seed ) {
|
||||
context = context || document;
|
||||
|
||||
// Only use querySelectorAll on non-XML documents
|
||||
// (ID selectors don't work in non-HTML documents)
|
||||
if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) {
|
||||
try {
|
||||
return makeArray( context.querySelectorAll(query), extra );
|
||||
} catch(e){}
|
||||
if ( !seed && !Sizzle.isXML(context) ) {
|
||||
// See if we find a selector to speed up
|
||||
var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
|
||||
|
||||
if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
|
||||
// Speed-up: Sizzle("TAG")
|
||||
if ( match[1] ) {
|
||||
return makeArray( context.getElementsByTagName( query ), extra );
|
||||
|
||||
// Speed-up: Sizzle(".CLASS")
|
||||
} else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
|
||||
return makeArray( context.getElementsByClassName( match[2] ), extra );
|
||||
}
|
||||
}
|
||||
|
||||
if ( context.nodeType === 9 ) {
|
||||
// Speed-up: Sizzle("body")
|
||||
// The body element only exists once, optimize finding it
|
||||
if ( query === "body" && context.body ) {
|
||||
return makeArray( [ context.body ], extra );
|
||||
|
||||
// Speed-up: Sizzle("#ID")
|
||||
} else if ( match && match[3] ) {
|
||||
var elem = context.getElementById( match[3] );
|
||||
|
||||
// Check parentNode to catch when Blackberry 4.6 returns
|
||||
// nodes that are no longer in the document #6963
|
||||
if ( elem && elem.parentNode ) {
|
||||
// Handle the case where IE and Opera return items
|
||||
// by name instead of ID
|
||||
if ( elem.id === match[3] ) {
|
||||
return makeArray( [ elem ], extra );
|
||||
}
|
||||
|
||||
} else {
|
||||
return makeArray( [], extra );
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return makeArray( context.querySelectorAll(query), extra );
|
||||
} catch(qsaError) {}
|
||||
|
||||
// qSA works strangely on Element-rooted queries
|
||||
// We can work around this by specifying an extra ID on the root
|
||||
// and working up from there (Thanks to Andrew Dupont for the technique)
|
||||
// IE 8 doesn't work on object elements
|
||||
} else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
|
||||
var oldContext = context,
|
||||
old = context.getAttribute( "id" ),
|
||||
nid = old || id,
|
||||
hasParent = context.parentNode,
|
||||
relativeHierarchySelector = /^\s*[+~]/.test( query );
|
||||
|
||||
if ( !old ) {
|
||||
context.setAttribute( "id", nid );
|
||||
} else {
|
||||
nid = nid.replace( /'/g, "\\$&" );
|
||||
}
|
||||
if ( relativeHierarchySelector && hasParent ) {
|
||||
context = context.parentNode;
|
||||
}
|
||||
|
||||
try {
|
||||
if ( !relativeHierarchySelector || hasParent ) {
|
||||
return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
|
||||
}
|
||||
|
||||
} catch(pseudoError) {
|
||||
} finally {
|
||||
if ( !old ) {
|
||||
oldContext.removeAttribute( "id" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return oldSizzle(query, context, extra, seed);
|
||||
};
|
||||
|
||||
|
|
@ -7813,10 +8493,55 @@ if ( document.querySelectorAll ) {
|
|||
Sizzle[ prop ] = oldSizzle[ prop ];
|
||||
}
|
||||
|
||||
div = null; // release memory in IE
|
||||
// release memory in IE
|
||||
div = null;
|
||||
})();
|
||||
}
|
||||
|
||||
(function(){
|
||||
var html = document.documentElement,
|
||||
matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
|
||||
|
||||
if ( matches ) {
|
||||
// Check to see if it's possible to do matchesSelector
|
||||
// on a disconnected node (IE 9 fails this)
|
||||
var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
|
||||
pseudoWorks = false;
|
||||
|
||||
try {
|
||||
// This should fail with an exception
|
||||
// Gecko does not error, returns false instead
|
||||
matches.call( document.documentElement, "[test!='']:sizzle" );
|
||||
|
||||
} catch( pseudoError ) {
|
||||
pseudoWorks = true;
|
||||
}
|
||||
|
||||
Sizzle.matchesSelector = function( node, expr ) {
|
||||
// Make sure that attribute selectors are quoted
|
||||
expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
|
||||
|
||||
if ( !Sizzle.isXML( node ) ) {
|
||||
try {
|
||||
if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
|
||||
var ret = matches.call( node, expr );
|
||||
|
||||
// IE 9's matchesSelector returns false on disconnected nodes
|
||||
if ( ret || !disconnectedMatch ||
|
||||
// As well, disconnected nodes are said to be in a document
|
||||
// fragment in IE 9, so check for that
|
||||
node.document && node.document.nodeType !== 11 ) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
} catch(e) {}
|
||||
}
|
||||
|
||||
return Sizzle(expr, null, null, [node]).length > 0;
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
(function(){
|
||||
var div = document.createElement("div");
|
||||
|
||||
|
|
@ -7834,32 +8559,35 @@ if ( document.querySelectorAll ) {
|
|||
if ( div.getElementsByClassName("e").length === 1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Expr.order.splice(1, 0, "CLASS");
|
||||
Expr.find.CLASS = function(match, context, isXML) {
|
||||
Expr.find.CLASS = function( match, context, isXML ) {
|
||||
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
|
||||
return context.getElementsByClassName(match[1]);
|
||||
}
|
||||
};
|
||||
|
||||
div = null; // release memory in IE
|
||||
// release memory in IE
|
||||
div = null;
|
||||
})();
|
||||
|
||||
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
|
||||
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
|
||||
var elem = checkSet[i];
|
||||
|
||||
if ( elem ) {
|
||||
elem = elem[dir];
|
||||
var match = false;
|
||||
|
||||
elem = elem[dir];
|
||||
|
||||
while ( elem ) {
|
||||
if ( elem.sizcache === doneName ) {
|
||||
if ( elem[ expando ] === doneName ) {
|
||||
match = checkSet[elem.sizset];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( elem.nodeType === 1 && !isXML ){
|
||||
elem.sizcache = doneName;
|
||||
elem[ expando ] = doneName;
|
||||
elem.sizset = i;
|
||||
}
|
||||
|
||||
|
|
@ -7879,21 +8607,24 @@ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
|
|||
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
|
||||
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
|
||||
var elem = checkSet[i];
|
||||
|
||||
if ( elem ) {
|
||||
elem = elem[dir];
|
||||
var match = false;
|
||||
|
||||
elem = elem[dir];
|
||||
|
||||
while ( elem ) {
|
||||
if ( elem.sizcache === doneName ) {
|
||||
if ( elem[ expando ] === doneName ) {
|
||||
match = checkSet[elem.sizset];
|
||||
break;
|
||||
}
|
||||
|
||||
if ( elem.nodeType === 1 ) {
|
||||
if ( !isXML ) {
|
||||
elem.sizcache = doneName;
|
||||
elem[ expando ] = doneName;
|
||||
elem.sizset = i;
|
||||
}
|
||||
|
||||
if ( typeof cur !== "string" ) {
|
||||
if ( elem === cur ) {
|
||||
match = true;
|
||||
|
|
@ -7914,21 +8645,34 @@ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
|
|||
}
|
||||
}
|
||||
|
||||
Sizzle.contains = document.compareDocumentPosition ? function(a, b){
|
||||
return !!(a.compareDocumentPosition(b) & 16);
|
||||
} : function(a, b){
|
||||
return a !== b && (a.contains ? a.contains(b) : true);
|
||||
};
|
||||
if ( document.documentElement.contains ) {
|
||||
Sizzle.contains = function( a, b ) {
|
||||
return a !== b && (a.contains ? a.contains(b) : true);
|
||||
};
|
||||
|
||||
Sizzle.isXML = function(elem){
|
||||
} else if ( document.documentElement.compareDocumentPosition ) {
|
||||
Sizzle.contains = function( a, b ) {
|
||||
return !!(a.compareDocumentPosition(b) & 16);
|
||||
};
|
||||
|
||||
} else {
|
||||
Sizzle.contains = function() {
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
Sizzle.isXML = function( elem ) {
|
||||
// documentElement is verified for cases where it doesn't yet exist
|
||||
// (such as loading iframes in IE - #4833)
|
||||
// (such as loading iframes in IE - #4833)
|
||||
var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
|
||||
|
||||
return documentElement ? documentElement.nodeName !== "HTML" : false;
|
||||
};
|
||||
|
||||
var posProcess = function(selector, context){
|
||||
var tmpSet = [], later = "", match,
|
||||
var posProcess = function( selector, context, seed ) {
|
||||
var match,
|
||||
tmpSet = [],
|
||||
later = "",
|
||||
root = context.nodeType ? [context] : context;
|
||||
|
||||
// Position selectors must be done after the filter
|
||||
|
|
@ -7941,7 +8685,7 @@ var posProcess = function(selector, context){
|
|||
selector = Expr.relative[selector] ? selector + "*" : selector;
|
||||
|
||||
for ( var i = 0, l = root.length; i < l; i++ ) {
|
||||
Sizzle( selector, root[i], tmpSet );
|
||||
Sizzle( selector, root[i], tmpSet, seed );
|
||||
}
|
||||
|
||||
return Sizzle.filter( later, tmpSet );
|
||||
|
|
@ -7970,20 +8714,20 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
('getPos,getRect,getParent,add,setStyle,getStyle,setStyles,' +
|
||||
'setAttrib,setAttribs,getAttrib,addClass,removeClass,' +
|
||||
'hasClass,getOuterHTML,setOuterHTML,remove,show,hide,' +
|
||||
'isHidden,setHTML,get').split(/,/)
|
||||
, function(k) {
|
||||
t[k] = function() {
|
||||
var a = [id], i;
|
||||
'isHidden,setHTML,get').split(/,/), function(k) {
|
||||
t[k] = function() {
|
||||
var a = [id], i;
|
||||
|
||||
for (i = 0; i < arguments.length; i++)
|
||||
a.push(arguments[i]);
|
||||
for (i = 0; i < arguments.length; i++)
|
||||
a.push(arguments[i]);
|
||||
|
||||
a = dom[k].apply(dom, a);
|
||||
t.update(k);
|
||||
a = dom[k].apply(dom, a);
|
||||
t.update(k);
|
||||
|
||||
return a;
|
||||
};
|
||||
});
|
||||
return a;
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
tinymce.extend(t, {
|
||||
on : function(n, f, s) {
|
||||
|
|
@ -8069,7 +8813,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
};
|
||||
|
||||
// Shorten names
|
||||
var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;
|
||||
var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each, TreeWalker = tinymce.dom.TreeWalker;
|
||||
|
||||
tinymce.create('tinymce.dom.Selection', {
|
||||
Selection : function(dom, win, serializer) {
|
||||
|
|
@ -8176,7 +8920,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
} else {
|
||||
rng.deleteContents();
|
||||
|
||||
if (doc.body.childNodes.length == 0) {
|
||||
if (doc.body.childNodes.length === 0) {
|
||||
doc.body.innerHTML = content;
|
||||
} else {
|
||||
// createContextualFragment doesn't exists in IE 9 DOMRanges
|
||||
|
|
@ -8312,46 +9056,69 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
return index;
|
||||
};
|
||||
|
||||
if (type == 2) {
|
||||
function getLocation() {
|
||||
var rng = t.getRng(true), root = dom.getRoot(), bookmark = {};
|
||||
function normalizeTableCellSelection(rng) {
|
||||
function moveEndPoint(start) {
|
||||
var container, offset, childNodes, prefix = start ? 'start' : 'end';
|
||||
|
||||
function getPoint(rng, start) {
|
||||
var container = rng[start ? 'startContainer' : 'endContainer'],
|
||||
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
||||
container = rng[prefix + 'Container'];
|
||||
offset = rng[prefix + 'Offset'];
|
||||
|
||||
if (container.nodeType == 3) {
|
||||
if (normalized) {
|
||||
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling)
|
||||
offset += node.nodeValue.length;
|
||||
}
|
||||
|
||||
point.push(offset);
|
||||
} else {
|
||||
childNodes = container.childNodes;
|
||||
|
||||
if (offset >= childNodes.length && childNodes.length) {
|
||||
after = 1;
|
||||
offset = Math.max(0, childNodes.length - 1);
|
||||
}
|
||||
|
||||
point.push(t.dom.nodeIndex(childNodes[offset], normalized) + after);
|
||||
if (container.nodeType == 1 && container.nodeName == "TR") {
|
||||
childNodes = container.childNodes;
|
||||
container = childNodes[Math.min(start ? offset : offset - 1, childNodes.length - 1)];
|
||||
if (container) {
|
||||
offset = start ? 0 : container.childNodes.length;
|
||||
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
||||
}
|
||||
|
||||
for (; container && container != root; container = container.parentNode)
|
||||
point.push(t.dom.nodeIndex(container, normalized));
|
||||
|
||||
return point;
|
||||
};
|
||||
|
||||
bookmark.start = getPoint(rng, true);
|
||||
|
||||
if (!t.isCollapsed())
|
||||
bookmark.end = getPoint(rng);
|
||||
|
||||
return bookmark;
|
||||
}
|
||||
};
|
||||
|
||||
moveEndPoint(true);
|
||||
moveEndPoint();
|
||||
|
||||
return rng;
|
||||
};
|
||||
|
||||
function getLocation() {
|
||||
var rng = t.getRng(true), root = dom.getRoot(), bookmark = {};
|
||||
|
||||
function getPoint(rng, start) {
|
||||
var container = rng[start ? 'startContainer' : 'endContainer'],
|
||||
offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;
|
||||
|
||||
if (container.nodeType == 3) {
|
||||
if (normalized) {
|
||||
for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling)
|
||||
offset += node.nodeValue.length;
|
||||
}
|
||||
|
||||
point.push(offset);
|
||||
} else {
|
||||
childNodes = container.childNodes;
|
||||
|
||||
if (offset >= childNodes.length && childNodes.length) {
|
||||
after = 1;
|
||||
offset = Math.max(0, childNodes.length - 1);
|
||||
}
|
||||
|
||||
point.push(t.dom.nodeIndex(childNodes[offset], normalized) + after);
|
||||
}
|
||||
|
||||
for (; container && container != root; container = container.parentNode)
|
||||
point.push(t.dom.nodeIndex(container, normalized));
|
||||
|
||||
return point;
|
||||
};
|
||||
|
||||
bookmark.start = getPoint(rng, true);
|
||||
|
||||
if (!t.isCollapsed())
|
||||
bookmark.end = getPoint(rng);
|
||||
|
||||
return bookmark;
|
||||
};
|
||||
|
||||
if (type == 2) {
|
||||
if (t.tridentSel)
|
||||
return t.tridentSel.getBookmark(type);
|
||||
|
||||
|
|
@ -8384,7 +9151,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
|
||||
// Detect the empty space after block elements in IE and move the end back one character <p></p>] becomes <p>]</p>
|
||||
rng.moveToElementText(rng2.parentElement());
|
||||
if (rng.compareEndPoints('StartToEnd', rng2) == 0)
|
||||
if (rng.compareEndPoints('StartToEnd', rng2) === 0)
|
||||
rng2.move('character', -1);
|
||||
|
||||
rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');
|
||||
|
|
@ -8406,13 +9173,8 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
if (name == 'IMG')
|
||||
return {name : name, index : findIndex(name, element)};
|
||||
|
||||
// Can't insert a node into the root of document WebKit defaults to document
|
||||
if (rng.startContainer.nodeType == 9) {
|
||||
return;
|
||||
}
|
||||
|
||||
// W3C method
|
||||
rng2 = rng.cloneRange();
|
||||
rng2 = normalizeTableCellSelection(rng.cloneRange());
|
||||
|
||||
// Insert end marker
|
||||
if (!collapsed) {
|
||||
|
|
@ -8420,6 +9182,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
rng2.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_end', style : styles}, chr));
|
||||
}
|
||||
|
||||
rng = normalizeTableCellSelection(rng);
|
||||
rng.collapse(true);
|
||||
rng.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_start', style : styles}, chr));
|
||||
}
|
||||
|
|
@ -8432,45 +9195,115 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
moveToBookmark : function(bookmark) {
|
||||
var t = this, dom = t.dom, marker1, marker2, rng, root, startContainer, endContainer, startOffset, endOffset;
|
||||
|
||||
function setEndPoint(start) {
|
||||
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
||||
|
||||
if (point) {
|
||||
offset = point[0];
|
||||
|
||||
// Find container node
|
||||
for (node = root, i = point.length - 1; i >= 1; i--) {
|
||||
children = node.childNodes;
|
||||
|
||||
if (point[i] > children.length - 1)
|
||||
return;
|
||||
|
||||
node = children[point[i]];
|
||||
}
|
||||
|
||||
// Move text offset to best suitable location
|
||||
if (node.nodeType === 3)
|
||||
offset = Math.min(point[0], node.nodeValue.length);
|
||||
|
||||
// Move element offset to best suitable location
|
||||
if (node.nodeType === 1)
|
||||
offset = Math.min(point[0], node.childNodes.length);
|
||||
|
||||
// Set offset within container node
|
||||
if (start)
|
||||
rng.setStart(node, offset);
|
||||
else
|
||||
rng.setEnd(node, offset);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
function restoreEndPoint(suffix) {
|
||||
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
||||
|
||||
if (marker) {
|
||||
node = marker.parentNode;
|
||||
|
||||
if (suffix == 'start') {
|
||||
if (!keep) {
|
||||
idx = dom.nodeIndex(marker);
|
||||
} else {
|
||||
node = marker.firstChild;
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
startContainer = endContainer = node;
|
||||
startOffset = endOffset = idx;
|
||||
} else {
|
||||
if (!keep) {
|
||||
idx = dom.nodeIndex(marker);
|
||||
} else {
|
||||
node = marker.firstChild;
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
endContainer = node;
|
||||
endOffset = idx;
|
||||
}
|
||||
|
||||
if (!keep) {
|
||||
prev = marker.previousSibling;
|
||||
next = marker.nextSibling;
|
||||
|
||||
// Remove all marker text nodes
|
||||
each(tinymce.grep(marker.childNodes), function(node) {
|
||||
if (node.nodeType == 3)
|
||||
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
||||
});
|
||||
|
||||
// Remove marker but keep children if for example contents where inserted into the marker
|
||||
// Also remove duplicated instances of the marker for example by a split operation or by WebKit auto split on paste feature
|
||||
while (marker = dom.get(bookmark.id + '_' + suffix))
|
||||
dom.remove(marker, 1);
|
||||
|
||||
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
||||
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market isn't worth the effort. Sorry, Opera but it's just a fact
|
||||
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !tinymce.isOpera) {
|
||||
idx = prev.nodeValue.length;
|
||||
prev.appendData(next.nodeValue);
|
||||
dom.remove(next);
|
||||
|
||||
if (suffix == 'start') {
|
||||
startContainer = endContainer = prev;
|
||||
startOffset = endOffset = idx;
|
||||
} else {
|
||||
endContainer = prev;
|
||||
endOffset = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function addBogus(node) {
|
||||
// Adds a bogus BR element for empty block elements
|
||||
if (dom.isBlock(node) && !node.innerHTML && !isIE)
|
||||
node.innerHTML = '<br data-mce-bogus="1" />';
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
if (bookmark) {
|
||||
if (bookmark.start) {
|
||||
rng = dom.createRng();
|
||||
root = dom.getRoot();
|
||||
|
||||
function setEndPoint(start) {
|
||||
var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;
|
||||
|
||||
if (point) {
|
||||
offset = point[0];
|
||||
|
||||
// Find container node
|
||||
for (node = root, i = point.length - 1; i >= 1; i--) {
|
||||
children = node.childNodes;
|
||||
|
||||
if (point[i] > children.length - 1)
|
||||
return;
|
||||
|
||||
node = children[point[i]];
|
||||
}
|
||||
|
||||
// Move text offset to best suitable location
|
||||
if (node.nodeType === 3)
|
||||
offset = Math.min(point[0], node.nodeValue.length);
|
||||
|
||||
// Move element offset to best suitable location
|
||||
if (node.nodeType === 1)
|
||||
offset = Math.min(point[0], node.childNodes.length);
|
||||
|
||||
// Set offset within container node
|
||||
if (start)
|
||||
rng.setStart(node, offset);
|
||||
else
|
||||
rng.setEnd(node, offset);
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (t.tridentSel)
|
||||
return t.tridentSel.moveToBookmark(bookmark);
|
||||
|
||||
|
|
@ -8478,76 +9311,6 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
t.setRng(rng);
|
||||
}
|
||||
} else if (bookmark.id) {
|
||||
function restoreEndPoint(suffix) {
|
||||
var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;
|
||||
|
||||
if (marker) {
|
||||
node = marker.parentNode;
|
||||
|
||||
if (suffix == 'start') {
|
||||
if (!keep) {
|
||||
idx = dom.nodeIndex(marker);
|
||||
} else {
|
||||
node = marker.firstChild;
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
startContainer = endContainer = node;
|
||||
startOffset = endOffset = idx;
|
||||
} else {
|
||||
if (!keep) {
|
||||
idx = dom.nodeIndex(marker);
|
||||
} else {
|
||||
node = marker.firstChild;
|
||||
idx = 1;
|
||||
}
|
||||
|
||||
endContainer = node;
|
||||
endOffset = idx;
|
||||
}
|
||||
|
||||
if (!keep) {
|
||||
prev = marker.previousSibling;
|
||||
next = marker.nextSibling;
|
||||
|
||||
// Remove all marker text nodes
|
||||
each(tinymce.grep(marker.childNodes), function(node) {
|
||||
if (node.nodeType == 3)
|
||||
node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');
|
||||
});
|
||||
|
||||
// Remove marker but keep children if for example contents where inserted into the marker
|
||||
// Also remove duplicated instances of the marker for example by a split operation or by WebKit auto split on paste feature
|
||||
while (marker = dom.get(bookmark.id + '_' + suffix))
|
||||
dom.remove(marker, 1);
|
||||
|
||||
// If siblings are text nodes then merge them unless it's Opera since it some how removes the node
|
||||
// and we are sniffing since adding a lot of detection code for a browser with 3% of the market isn't worth the effort. Sorry, Opera but it's just a fact
|
||||
if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !tinymce.isOpera) {
|
||||
idx = prev.nodeValue.length;
|
||||
prev.appendData(next.nodeValue);
|
||||
dom.remove(next);
|
||||
|
||||
if (suffix == 'start') {
|
||||
startContainer = endContainer = prev;
|
||||
startOffset = endOffset = idx;
|
||||
} else {
|
||||
endContainer = prev;
|
||||
endOffset = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function addBogus(node) {
|
||||
// Adds a bogus BR element for empty block elements or just a space on IE since it renders BR elements incorrectly
|
||||
if (dom.isBlock(node) && !node.innerHTML)
|
||||
node.innerHTML = !isIE ? '<br data-mce-bogus="1" />' : ' ';
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
// Restore start/end points
|
||||
restoreEndPoint('start');
|
||||
restoreEndPoint('end');
|
||||
|
|
@ -8568,6 +9331,32 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
select : function(node, content) {
|
||||
var t = this, dom = t.dom, rng = dom.createRng(), idx;
|
||||
|
||||
function setPoint(node, start) {
|
||||
var walker = new TreeWalker(node, node);
|
||||
|
||||
do {
|
||||
// Text node
|
||||
if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length !== 0) {
|
||||
if (start)
|
||||
rng.setStart(node, 0);
|
||||
else
|
||||
rng.setEnd(node, node.nodeValue.length);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// BR element
|
||||
if (node.nodeName == 'BR') {
|
||||
if (start)
|
||||
rng.setStartBefore(node);
|
||||
else
|
||||
rng.setEndBefore(node);
|
||||
|
||||
return;
|
||||
}
|
||||
} while (node = (start ? walker.next() : walker.prev()));
|
||||
};
|
||||
|
||||
if (node) {
|
||||
idx = dom.nodeIndex(node);
|
||||
rng.setStart(node.parentNode, idx);
|
||||
|
|
@ -8575,32 +9364,6 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
|
||||
// Find first/last text node or BR element
|
||||
if (content) {
|
||||
function setPoint(node, start) {
|
||||
var walker = new tinymce.dom.TreeWalker(node, node);
|
||||
|
||||
do {
|
||||
// Text node
|
||||
if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length != 0) {
|
||||
if (start)
|
||||
rng.setStart(node, 0);
|
||||
else
|
||||
rng.setEnd(node, node.nodeValue.length);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// BR element
|
||||
if (node.nodeName == 'BR') {
|
||||
if (start)
|
||||
rng.setStartBefore(node);
|
||||
else
|
||||
rng.setEndBefore(node);
|
||||
|
||||
return;
|
||||
}
|
||||
} while (node = (start ? walker.next() : walker.prev()));
|
||||
};
|
||||
|
||||
setPoint(node, 1);
|
||||
setPoint(node);
|
||||
}
|
||||
|
|
@ -8644,48 +9407,58 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
},
|
||||
|
||||
getRng : function(w3c) {
|
||||
var t = this, s, r, elm, doc = t.win.document;
|
||||
var self = this, selection, rng, elm, doc = self.win.document;
|
||||
|
||||
// Found tridentSel object then we need to use that one
|
||||
if (w3c && t.tridentSel)
|
||||
return t.tridentSel.getRangeAt(0);
|
||||
if (w3c && self.tridentSel) {
|
||||
return self.tridentSel.getRangeAt(0);
|
||||
}
|
||||
|
||||
try {
|
||||
if (s = t.getSel())
|
||||
r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : doc.createRange());
|
||||
if (selection = self.getSel()) {
|
||||
rng = selection.rangeCount > 0 ? selection.getRangeAt(0) : (selection.createRange ? selection.createRange() : doc.createRange());
|
||||
}
|
||||
} catch (ex) {
|
||||
// IE throws unspecified error here if TinyMCE is placed in a frame/iframe
|
||||
}
|
||||
|
||||
// We have W3C ranges and it's IE then fake control selection since IE9 doesn't handle that correctly yet
|
||||
if (tinymce.isIE && r && r.setStart && doc.selection.createRange().item) {
|
||||
if (tinymce.isIE && rng && rng.setStart && doc.selection.createRange().item) {
|
||||
elm = doc.selection.createRange().item(0);
|
||||
r = doc.createRange();
|
||||
r.setStartBefore(elm);
|
||||
r.setEndAfter(elm);
|
||||
rng = doc.createRange();
|
||||
rng.setStartBefore(elm);
|
||||
rng.setEndAfter(elm);
|
||||
}
|
||||
|
||||
// No range found then create an empty one
|
||||
// This can occur when the editor is placed in a hidden container element on Gecko
|
||||
// Or on IE when there was an exception
|
||||
if (!r)
|
||||
r = doc.createRange ? doc.createRange() : doc.body.createTextRange();
|
||||
if (!rng) {
|
||||
rng = doc.createRange ? doc.createRange() : doc.body.createTextRange();
|
||||
}
|
||||
|
||||
if (t.selectedRange && t.explicitRange) {
|
||||
if (r.compareBoundaryPoints(r.START_TO_START, t.selectedRange) === 0 && r.compareBoundaryPoints(r.END_TO_END, t.selectedRange) === 0) {
|
||||
// If range is at start of document then move it to start of body
|
||||
if (rng.setStart && rng.startContainer.nodeType === 9 && rng.collapsed) {
|
||||
elm = self.dom.getRoot();
|
||||
rng.setStart(elm, 0);
|
||||
rng.setEnd(elm, 0);
|
||||
}
|
||||
|
||||
if (self.selectedRange && self.explicitRange) {
|
||||
if (rng.compareBoundaryPoints(rng.START_TO_START, self.selectedRange) === 0 && rng.compareBoundaryPoints(rng.END_TO_END, self.selectedRange) === 0) {
|
||||
// Safari, Opera and Chrome only ever select text which causes the range to change.
|
||||
// This lets us use the originally set range if the selection hasn't been changed by the user.
|
||||
r = t.explicitRange;
|
||||
rng = self.explicitRange;
|
||||
} else {
|
||||
t.selectedRange = null;
|
||||
t.explicitRange = null;
|
||||
self.selectedRange = null;
|
||||
self.explicitRange = null;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
return rng;
|
||||
},
|
||||
|
||||
setRng : function(r) {
|
||||
setRng : function(r, forward) {
|
||||
var s, t = this;
|
||||
|
||||
if (!t.tridentSel) {
|
||||
|
|
@ -8701,6 +9474,13 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
}
|
||||
|
||||
s.addRange(r);
|
||||
|
||||
// Forward is set to false and we have an extend function
|
||||
if (forward === false && s.extend) {
|
||||
s.collapse(r.endContainer, r.endOffset);
|
||||
s.extend(r.startContainer, r.startOffset);
|
||||
}
|
||||
|
||||
// adding range isn't always successful so we need to check range count otherwise an exception can occur
|
||||
t.selectedRange = s.rangeCount > 0 ? s.getRangeAt(0) : null;
|
||||
}
|
||||
|
|
@ -8735,6 +9515,14 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
getNode : function() {
|
||||
var t = this, rng = t.getRng(), sel = t.getSel(), elm, start = rng.startContainer, end = rng.endContainer;
|
||||
|
||||
function skipEmptyTextNodes(n, forwards) {
|
||||
var orig = n;
|
||||
while (n && n.nodeType === 3 && n.length === 0) {
|
||||
n = forwards ? n.nextSibling : n.previousSibling;
|
||||
}
|
||||
return n || orig;
|
||||
};
|
||||
|
||||
// Range maybe lost after the editor is made visible again
|
||||
if (!rng)
|
||||
return t.dom.getRoot();
|
||||
|
|
@ -8758,13 +9546,6 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
// Handle cases where the selection is immediately wrapped around a node and return that node instead of it's parent.
|
||||
// This happens when you double click an underlined word in FireFox.
|
||||
if (start.nodeType === 3 && end.nodeType === 3) {
|
||||
function skipEmptyTextNodes(n, forwards) {
|
||||
var orig = n;
|
||||
while (n && n.nodeType === 3 && n.length === 0) {
|
||||
n = forwards ? n.nextSibling : n.previousSibling;
|
||||
}
|
||||
return n || orig;
|
||||
}
|
||||
if (start.length === rng.startOffset) {
|
||||
start = skipEmptyTextNodes(start.nextSibling, true);
|
||||
} else {
|
||||
|
|
@ -8802,7 +9583,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
if (sb && eb && sb != eb) {
|
||||
n = sb;
|
||||
|
||||
var walker = new tinymce.dom.TreeWalker(sb, dom.getRoot());
|
||||
var walker = new TreeWalker(sb, dom.getRoot());
|
||||
while ((n = walker.next()) && n != eb) {
|
||||
if (dom.isBlock(n))
|
||||
bl.push(n);
|
||||
|
|
@ -8815,54 +9596,120 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
return bl;
|
||||
},
|
||||
|
||||
isForward: function(){
|
||||
var dom = this.dom, sel = this.getSel(), anchorRange, focusRange;
|
||||
|
||||
// No support for selection direction then always return true
|
||||
if (!sel || sel.anchorNode == null || sel.focusNode == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
anchorRange = dom.createRng();
|
||||
anchorRange.setStart(sel.anchorNode, sel.anchorOffset);
|
||||
anchorRange.collapse(true);
|
||||
|
||||
focusRange = dom.createRng();
|
||||
focusRange.setStart(sel.focusNode, sel.focusOffset);
|
||||
focusRange.collapse(true);
|
||||
|
||||
return anchorRange.compareBoundaryPoints(anchorRange.START_TO_START, focusRange) <= 0;
|
||||
},
|
||||
|
||||
normalize : function() {
|
||||
var self = this, rng, normalized;
|
||||
|
||||
// TODO:
|
||||
// Retain selection direction.
|
||||
// Lean left/right on Gecko for inline elements.
|
||||
// Run this on mouse up/key up when the user manually moves the selection
|
||||
|
||||
// Normalize only on non IE browsers for now
|
||||
if (tinymce.isIE)
|
||||
return;
|
||||
var self = this, rng, normalized, collapsed, node, sibling;
|
||||
|
||||
function normalizeEndPoint(start) {
|
||||
var container, offset, walker, dom = self.dom, body = dom.getRoot(), node;
|
||||
var container, offset, walker, dom = self.dom, body = dom.getRoot(), node, nonEmptyElementsMap, nodeName;
|
||||
|
||||
function hasBrBeforeAfter(node, left) {
|
||||
var walker = new TreeWalker(node, dom.getParent(node.parentNode, dom.isBlock) || body);
|
||||
|
||||
while (node = walker[left ? 'prev' : 'next']()) {
|
||||
if (node.nodeName === "BR") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Walks the dom left/right to find a suitable text node to move the endpoint into
|
||||
// It will only walk within the current parent block or body and will stop if it hits a block or a BR/IMG
|
||||
function findTextNodeRelative(left, startNode) {
|
||||
var walker, lastInlineElement;
|
||||
|
||||
startNode = startNode || container;
|
||||
walker = new TreeWalker(startNode, dom.getParent(startNode.parentNode, dom.isBlock) || body);
|
||||
|
||||
// Walk left until we hit a text node we can move to or a block/br/img
|
||||
while (node = walker[left ? 'prev' : 'next']()) {
|
||||
// Found text node that has a length
|
||||
if (node.nodeType === 3 && node.nodeValue.length > 0) {
|
||||
container = node;
|
||||
offset = left ? node.nodeValue.length : 0;
|
||||
normalized = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Break if we find a block or a BR/IMG/INPUT etc
|
||||
if (dom.isBlock(node) || nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastInlineElement = node;
|
||||
}
|
||||
|
||||
// Only fetch the last inline element when in caret mode for now
|
||||
if (collapsed && lastInlineElement) {
|
||||
container = lastInlineElement;
|
||||
normalized = true;
|
||||
offset = 0;
|
||||
}
|
||||
};
|
||||
|
||||
container = rng[(start ? 'start' : 'end') + 'Container'];
|
||||
offset = rng[(start ? 'start' : 'end') + 'Offset'];
|
||||
nonEmptyElementsMap = dom.schema.getNonEmptyElements();
|
||||
|
||||
// If the container is a document move it to the body element
|
||||
if (container.nodeType === 9) {
|
||||
container = container.body;
|
||||
container = dom.getRoot();
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// If the container is body try move it into the closest text node or position
|
||||
// TODO: Add more logic here to handle element selection cases
|
||||
if (container === body) {
|
||||
// If start is before/after a image, table etc
|
||||
if (start) {
|
||||
node = container.childNodes[offset > 0 ? offset - 1 : 0];
|
||||
if (node) {
|
||||
nodeName = node.nodeName.toLowerCase();
|
||||
if (nonEmptyElementsMap[node.nodeName] || node.nodeName == "TABLE") {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the index
|
||||
if (container.hasChildNodes()) {
|
||||
container = container.childNodes[Math.min(!start && offset > 0 ? offset - 1 : offset, container.childNodes.length - 1)];
|
||||
offset = 0;
|
||||
|
||||
// Don't walk into elements that doesn't have any child nodes like a IMG
|
||||
if (container.hasChildNodes()) {
|
||||
if (container.hasChildNodes() && !/TABLE/.test(container.nodeName)) {
|
||||
// Walk the DOM to find a text node to place the caret at or a BR
|
||||
node = container;
|
||||
walker = new tinymce.dom.TreeWalker(container, body);
|
||||
walker = new TreeWalker(container, body);
|
||||
|
||||
do {
|
||||
// Found a text node use that position
|
||||
if (node.nodeType === 3) {
|
||||
offset = start ? 0 : node.nodeValue.length - 1;
|
||||
if (node.nodeType === 3 && node.nodeValue.length > 0) {
|
||||
offset = start ? 0 : node.nodeValue.length;
|
||||
container = node;
|
||||
normalized = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Found a BR/IMG element that we can place the caret before
|
||||
if (/^(BR|IMG)$/.test(node.nodeName)) {
|
||||
if (nonEmptyElementsMap[node.nodeName.toLowerCase()]) {
|
||||
offset = dom.nodeIndex(node);
|
||||
container = node.parentNode;
|
||||
|
||||
|
|
@ -8879,23 +9726,61 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
}
|
||||
}
|
||||
|
||||
// Lean the caret to the left if possible
|
||||
if (collapsed) {
|
||||
// So this: <b>x</b><i>|x</i>
|
||||
// Becomes: <b>x|</b><i>x</i>
|
||||
// Seems that only gecko has issues with this
|
||||
if (container.nodeType === 3 && offset === 0) {
|
||||
findTextNodeRelative(true);
|
||||
}
|
||||
|
||||
// Lean left into empty inline elements when the caret is before a BR
|
||||
// So this: <i><b></b><i>|<br></i>
|
||||
// Becomes: <i><b>|</b><i><br></i>
|
||||
// Seems that only gecko has issues with this
|
||||
if (container.nodeType === 1) {
|
||||
node = container.childNodes[offset];
|
||||
if(node && node.nodeName === 'BR' && !hasBrBeforeAfter(node) && !hasBrBeforeAfter(node, true)) {
|
||||
findTextNodeRelative(true, container.childNodes[offset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Lean the start of the selection right if possible
|
||||
// So this: x[<b>x]</b>
|
||||
// Becomes: x<b>[x]</b>
|
||||
if (start && !collapsed && container.nodeType === 3 && offset === container.nodeValue.length) {
|
||||
findTextNodeRelative(false);
|
||||
}
|
||||
|
||||
// Set endpoint if it was normalized
|
||||
if (normalized)
|
||||
rng['set' + (start ? 'Start' : 'End')](container, offset);
|
||||
};
|
||||
|
||||
// Normalize only on non IE browsers for now
|
||||
if (tinymce.isIE)
|
||||
return;
|
||||
|
||||
rng = self.getRng();
|
||||
collapsed = rng.collapsed;
|
||||
|
||||
// Normalize the end points
|
||||
normalizeEndPoint(true);
|
||||
|
||||
if (!rng.collapsed)
|
||||
if (!collapsed)
|
||||
normalizeEndPoint();
|
||||
|
||||
// Set the selection if it was normalized
|
||||
if (normalized) {
|
||||
// If it was collapsed then make sure it still is
|
||||
if (collapsed) {
|
||||
rng.collapse(true);
|
||||
}
|
||||
|
||||
//console.log(self.dom.dumpRng(rng));
|
||||
self.setRng(rng);
|
||||
self.setRng(rng, self.isForward());
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -8913,9 +9798,6 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
_fixIESelection : function() {
|
||||
var dom = this.dom, doc = dom.doc, body = doc.body, started, startRng, htmlElm;
|
||||
|
||||
// Make HTML element unselectable since we are going to handle selection by hand
|
||||
doc.documentElement.unselectable = true;
|
||||
|
||||
// Return range from point or null if it failed
|
||||
function rngFromPoint(x, y) {
|
||||
var rng = body.createTextRange();
|
||||
|
|
@ -8965,6 +9847,9 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
startRng = started = 0;
|
||||
};
|
||||
|
||||
// Make HTML element unselectable since we are going to handle selection by hand
|
||||
doc.documentElement.unselectable = true;
|
||||
|
||||
// Detect when user selects outside BODY
|
||||
dom.bind(doc, ['mousedown', 'contextmenu'], function(e) {
|
||||
if (e.target.nodeName === 'HTML') {
|
||||
|
|
@ -9039,13 +9924,13 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
}
|
||||
});
|
||||
|
||||
// Remove internal classes mceItem<..>
|
||||
// Remove internal classes mceItem<..> or mceSelected
|
||||
htmlParser.addAttributeFilter('class', function(nodes, name) {
|
||||
var i = nodes.length, node, value;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
value = node.attr('class').replace(/\s*mce(Item\w+|Selected)\s*/g, '');
|
||||
value = node.attr('class').replace(/(?:^|\s)mce(Item\w+|Selected)(?!\S)/g, '');
|
||||
node.attr('class', value.length > 0 ? value : null);
|
||||
}
|
||||
});
|
||||
|
|
@ -9223,7 +10108,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
|
||||
// Parse and serialize HTML
|
||||
args.content = htmlSerializer.serialize(
|
||||
htmlParser.parse(args.getInner ? node.innerHTML : tinymce.trim(dom.getOuterHTML(node), args), args)
|
||||
htmlParser.parse(tinymce.trim(args.getInner ? node.innerHTML : dom.getOuterHTML(node)), args)
|
||||
);
|
||||
|
||||
// Replace all BOM characters for now until we can find a better solution
|
||||
|
|
@ -9263,7 +10148,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
scriptLoadedCallbacks = {},
|
||||
queueLoadedCallbacks = [],
|
||||
loading = 0,
|
||||
undefined;
|
||||
undef;
|
||||
|
||||
function loadScript(url, callback) {
|
||||
var t = this, dom = tinymce.DOM, elm, uri, loc, id;
|
||||
|
|
@ -9372,7 +10257,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
var item, state = states[url];
|
||||
|
||||
// Add url to load queue
|
||||
if (state == undefined) {
|
||||
if (state == undef) {
|
||||
queue.push(url);
|
||||
states[url] = QUEUED;
|
||||
}
|
||||
|
|
@ -9402,7 +10287,7 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
callback.func.call(callback.scope);
|
||||
});
|
||||
|
||||
scriptLoadedCallbacks[url] = undefined;
|
||||
scriptLoadedCallbacks[url] = undef;
|
||||
};
|
||||
|
||||
queueLoadedCallbacks.push({
|
||||
|
|
@ -9459,46 +10344,6 @@ window.tinymce.dom.Sizzle = Sizzle;
|
|||
tinymce.ScriptLoader = new tinymce.dom.ScriptLoader();
|
||||
})(tinymce);
|
||||
|
||||
tinymce.dom.TreeWalker = function(start_node, root_node) {
|
||||
var node = start_node;
|
||||
|
||||
function findSibling(node, start_name, sibling_name, shallow) {
|
||||
var sibling, parent;
|
||||
|
||||
if (node) {
|
||||
// Walk into nodes if it has a start
|
||||
if (!shallow && node[start_name])
|
||||
return node[start_name];
|
||||
|
||||
// Return the sibling if it has one
|
||||
if (node != root_node) {
|
||||
sibling = node[sibling_name];
|
||||
if (sibling)
|
||||
return sibling;
|
||||
|
||||
// Walk up the parents to look for siblings
|
||||
for (parent = node.parentNode; parent && parent != root_node; parent = parent.parentNode) {
|
||||
sibling = parent[sibling_name];
|
||||
if (sibling)
|
||||
return sibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.current = function() {
|
||||
return node;
|
||||
};
|
||||
|
||||
this.next = function(shallow) {
|
||||
return (node = findSibling(node, 'firstChild', 'nextSibling', shallow));
|
||||
};
|
||||
|
||||
this.prev = function(shallow) {
|
||||
return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));
|
||||
};
|
||||
};
|
||||
|
||||
(function(tinymce) {
|
||||
tinymce.dom.RangeUtils = function(dom) {
|
||||
var INVISIBLE_CHAR = '\uFEFF';
|
||||
|
|
@ -10159,8 +11004,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
update : function() {
|
||||
var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;
|
||||
|
||||
tw = s.max_width ? Math.min(tb.clientWidth, s.max_width) : tb.clientWidth;
|
||||
th = s.max_height ? Math.min(tb.clientHeight, s.max_height) : tb.clientHeight;
|
||||
tw = s.max_width ? Math.min(tb.offsetWidth, s.max_width) : tb.offsetWidth;
|
||||
th = s.max_height ? Math.min(tb.offsetHeight, s.max_height) : tb.offsetHeight;
|
||||
|
||||
if (!DOM.boxModel)
|
||||
t.element.setStyles({width : tw + 2, height : th + 2});
|
||||
|
|
@ -10519,7 +11364,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
})(tinymce);
|
||||
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, undef;
|
||||
|
||||
tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {
|
||||
ListBox : function(id, s, ed) {
|
||||
|
|
@ -10546,7 +11391,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
|
||||
t.marked = {};
|
||||
|
||||
if (va == undefined)
|
||||
if (va == undef)
|
||||
return t.selectByIndex(-1);
|
||||
|
||||
// Is string or number make function selector
|
||||
|
|
@ -10638,7 +11483,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
showMenu : function() {
|
||||
var t = this, p2, e = DOM.get(this.id), m;
|
||||
|
||||
if (t.isDisabled() || t.items.length == 0)
|
||||
if (t.isDisabled() || t.items.length === 0)
|
||||
return;
|
||||
|
||||
if (t.menu && t.menu.isMenuVisible)
|
||||
|
|
@ -10705,7 +11550,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
m = t.settings.control_manager.createDropMenu(t.id + '_menu', {
|
||||
menu_line : 1,
|
||||
'class' : t.classPrefix + 'Menu mceNoIcons',
|
||||
max_width : 150,
|
||||
max_width : 250,
|
||||
max_height : 150
|
||||
});
|
||||
|
||||
|
|
@ -10725,7 +11570,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
|
||||
each(t.items, function(o) {
|
||||
// No value then treat it as a title
|
||||
if (o.value === undefined) {
|
||||
if (o.value === undef) {
|
||||
m.add({
|
||||
title : o.title,
|
||||
role : "option",
|
||||
|
|
@ -10815,7 +11660,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
})(tinymce);
|
||||
|
||||
(function(tinymce) {
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, undef;
|
||||
|
||||
tinymce.create('tinymce.ui.NativeListBox:tinymce.ui.ListBox', {
|
||||
NativeListBox : function(id, s) {
|
||||
|
|
@ -10835,7 +11680,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
select : function(va) {
|
||||
var t = this, fv, f;
|
||||
|
||||
if (va == undefined)
|
||||
if (va == undef)
|
||||
return t.selectByIndex(-1);
|
||||
|
||||
// Is string or number make function selector
|
||||
|
|
@ -10988,7 +11833,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
m.settings.vp_offset_x = p2.x;
|
||||
m.settings.vp_offset_y = p2.y;
|
||||
m.settings.keyboard_focus = t._focused;
|
||||
m.showMenu(0, e.clientHeight);
|
||||
m.showMenu(0, e.firstChild.clientHeight);
|
||||
|
||||
Event.add(DOM.doc, 'mousedown', t.hideMenu, t);
|
||||
t.setState('Selected', 1);
|
||||
|
|
@ -11172,7 +12017,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
p2 = DOM.getPos(e);
|
||||
DOM.setStyles(t.id + '_menu', {
|
||||
left : p2.x,
|
||||
top : p2.y + e.clientHeight,
|
||||
top : p2.y + e.firstChild.clientHeight,
|
||||
zIndex : 200000
|
||||
});
|
||||
e = 0;
|
||||
|
|
@ -11215,7 +12060,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
renderMenu : function() {
|
||||
var t = this, m, i = 0, s = t.settings, n, tb, tr, w, context;
|
||||
|
||||
w = DOM.add(s.menu_container, 'div', {role: 'listbox', id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});
|
||||
w = DOM.add(s.menu_container, 'div', {role: 'listbox', id : t.id + '_menu', 'class' : s.menu_class + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});
|
||||
m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});
|
||||
DOM.add(m, 'span', {'class' : 'mceMenuLine'});
|
||||
|
||||
|
|
@ -11244,7 +12089,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
|
|||
|
||||
// adding a proper ARIA role = button causes JAWS to read things incorrectly on IE.
|
||||
if (!tinymce.isIE ) {
|
||||
settings['role']= 'option';
|
||||
settings.role = 'option';
|
||||
}
|
||||
|
||||
n = DOM.add(n, 'a', settings);
|
||||
|
|
@ -11540,7 +12385,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
if (typeof u === "object")
|
||||
url = u.prefix + u.resource + u.suffix;
|
||||
|
||||
if (url.indexOf('/') != 0 && url.indexOf('://') == -1)
|
||||
if (url.indexOf('/') !== 0 && url.indexOf('://') == -1)
|
||||
url = tinymce.baseURL + '/' + url;
|
||||
|
||||
t.urls[n] = url.substring(0, url.lastIndexOf('/'));
|
||||
|
|
@ -11564,7 +12409,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
DOM = tinymce.DOM, Event = tinymce.dom.Event,
|
||||
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
|
||||
explode = tinymce.explode,
|
||||
Dispatcher = tinymce.util.Dispatcher, undefined, instanceCounter = 0;
|
||||
Dispatcher = tinymce.util.Dispatcher, undef, instanceCounter = 0;
|
||||
|
||||
// Setup some URLs where the editor API is located and where the document is
|
||||
tinymce.documentBaseURL = window.location.href.replace(/[\?#].*$/, '').replace(/[\/\\][^\/]+$/, '');
|
||||
|
|
@ -11634,6 +12479,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
return f.apply(s || this, Array.prototype.slice.call(arguments, 2));
|
||||
};
|
||||
|
||||
function hasClass(n, c) {
|
||||
return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
|
||||
};
|
||||
|
||||
s = extend({
|
||||
theme : "simple",
|
||||
language : "en"
|
||||
|
|
@ -11677,10 +12526,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
|
||||
case "textareas":
|
||||
case "specific_textareas":
|
||||
function hasClass(n, c) {
|
||||
return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c);
|
||||
};
|
||||
|
||||
each(DOM.select('textarea'), function(elm) {
|
||||
if (s.editor_deselector && hasClass(elm, s.editor_deselector))
|
||||
return;
|
||||
|
|
@ -11741,7 +12586,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
},
|
||||
|
||||
get : function(id) {
|
||||
if (id === undefined)
|
||||
if (id === undef)
|
||||
return this.editors;
|
||||
|
||||
return this.editors[id];
|
||||
|
|
@ -11794,6 +12639,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
execCommand : function(c, u, v) {
|
||||
var t = this, ed = t.get(v), w;
|
||||
|
||||
function clr() {
|
||||
ed.destroy();
|
||||
w.detachEvent('onunload', clr);
|
||||
w = w.tinyMCE = w.tinymce = null; // IE leak
|
||||
};
|
||||
|
||||
// Manager commands
|
||||
switch (c) {
|
||||
case "mceFocus":
|
||||
|
|
@ -11822,12 +12673,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
|
||||
// Fix IE memory leaks
|
||||
if (tinymce.isIE) {
|
||||
function clr() {
|
||||
ed.destroy();
|
||||
w.detachEvent('onunload', clr);
|
||||
w = w.tinyMCE = w.tinymce = null; // IE leak
|
||||
};
|
||||
|
||||
w.attachEvent('onunload', clr);
|
||||
}
|
||||
|
||||
|
|
@ -11910,108 +12755,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
(function(tinymce) {
|
||||
// Shorten these names
|
||||
var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend,
|
||||
Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isGecko = tinymce.isGecko,
|
||||
each = tinymce.each, isGecko = tinymce.isGecko,
|
||||
isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is,
|
||||
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
|
||||
inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode, VK = tinymce.VK;
|
||||
explode = tinymce.explode;
|
||||
|
||||
tinymce.create('tinymce.Editor', {
|
||||
Editor : function(id, s) {
|
||||
var t = this;
|
||||
Editor : function(id, settings) {
|
||||
var self = this, TRUE = true;
|
||||
|
||||
t.id = t.editorId = id;
|
||||
|
||||
t.execCommands = {};
|
||||
t.queryStateCommands = {};
|
||||
t.queryValueCommands = {};
|
||||
|
||||
t.isNotDirty = false;
|
||||
|
||||
t.plugins = {};
|
||||
|
||||
// Add events to the editor
|
||||
each([
|
||||
'onPreInit',
|
||||
|
||||
'onBeforeRenderUI',
|
||||
|
||||
'onPostRender',
|
||||
|
||||
'onLoad',
|
||||
|
||||
'onInit',
|
||||
|
||||
'onRemove',
|
||||
|
||||
'onActivate',
|
||||
|
||||
'onDeactivate',
|
||||
|
||||
'onClick',
|
||||
|
||||
'onEvent',
|
||||
|
||||
'onMouseUp',
|
||||
|
||||
'onMouseDown',
|
||||
|
||||
'onDblClick',
|
||||
|
||||
'onKeyDown',
|
||||
|
||||
'onKeyUp',
|
||||
|
||||
'onKeyPress',
|
||||
|
||||
'onContextMenu',
|
||||
|
||||
'onSubmit',
|
||||
|
||||
'onReset',
|
||||
|
||||
'onPaste',
|
||||
|
||||
'onPreProcess',
|
||||
|
||||
'onPostProcess',
|
||||
|
||||
'onBeforeSetContent',
|
||||
|
||||
'onBeforeGetContent',
|
||||
|
||||
'onSetContent',
|
||||
|
||||
'onGetContent',
|
||||
|
||||
'onLoadContent',
|
||||
|
||||
'onSaveContent',
|
||||
|
||||
'onNodeChange',
|
||||
|
||||
'onChange',
|
||||
|
||||
'onBeforeExecCommand',
|
||||
|
||||
'onExecCommand',
|
||||
|
||||
'onUndo',
|
||||
|
||||
'onRedo',
|
||||
|
||||
'onVisualAid',
|
||||
|
||||
'onSetProgressState',
|
||||
|
||||
'onSetAttrib'
|
||||
], function(e) {
|
||||
t[e] = new Dispatcher(t);
|
||||
});
|
||||
|
||||
t.settings = s = extend({
|
||||
self.settings = settings = extend({
|
||||
id : id,
|
||||
language : 'en',
|
||||
docs_language : 'en',
|
||||
theme : 'simple',
|
||||
skin : 'default',
|
||||
delta_width : 0,
|
||||
|
|
@ -12019,58 +12774,63 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
popup_css : '',
|
||||
plugins : '',
|
||||
document_base_url : tinymce.documentBaseURL,
|
||||
add_form_submit_trigger : 1,
|
||||
submit_patch : 1,
|
||||
add_unload_trigger : 1,
|
||||
convert_urls : 1,
|
||||
relative_urls : 1,
|
||||
remove_script_host : 1,
|
||||
table_inline_editing : 0,
|
||||
object_resizing : 1,
|
||||
cleanup : 1,
|
||||
accessibility_focus : 1,
|
||||
custom_shortcuts : 1,
|
||||
custom_undo_redo_keyboard_shortcuts : 1,
|
||||
custom_undo_redo_restore_selection : 1,
|
||||
custom_undo_redo : 1,
|
||||
add_form_submit_trigger : TRUE,
|
||||
submit_patch : TRUE,
|
||||
add_unload_trigger : TRUE,
|
||||
convert_urls : TRUE,
|
||||
relative_urls : TRUE,
|
||||
remove_script_host : TRUE,
|
||||
table_inline_editing : false,
|
||||
object_resizing : TRUE,
|
||||
accessibility_focus : TRUE,
|
||||
doctype : tinymce.isIE6 ? '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' : '<!DOCTYPE>', // Use old doctype on IE 6 to avoid horizontal scroll
|
||||
visual_table_class : 'mceItemTable',
|
||||
visual : 1,
|
||||
visual : TRUE,
|
||||
font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
|
||||
font_size_legacy_values : 'xx-small,small,medium,large,x-large,xx-large,300%', // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
|
||||
apply_source_formatting : 1,
|
||||
apply_source_formatting : TRUE,
|
||||
directionality : 'ltr',
|
||||
forced_root_block : 'p',
|
||||
hidden_input : 1,
|
||||
padd_empty_editor : 1,
|
||||
render_ui : 1,
|
||||
init_theme : 1,
|
||||
force_p_newlines : 1,
|
||||
hidden_input : TRUE,
|
||||
padd_empty_editor : TRUE,
|
||||
render_ui : TRUE,
|
||||
indentation : '30px',
|
||||
keep_styles : 1,
|
||||
fix_table_elements : 1,
|
||||
inline_styles : 1,
|
||||
convert_fonts_to_spans : true,
|
||||
fix_table_elements : TRUE,
|
||||
inline_styles : TRUE,
|
||||
convert_fonts_to_spans : TRUE,
|
||||
indent : 'simple',
|
||||
indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside',
|
||||
indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside',
|
||||
validate : true,
|
||||
indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure',
|
||||
indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr,section,article,hgroup,aside,figure',
|
||||
validate : TRUE,
|
||||
entity_encoding : 'named',
|
||||
url_converter : t.convertURL,
|
||||
url_converter_scope : t,
|
||||
ie7_compat : true
|
||||
}, s);
|
||||
url_converter : self.convertURL,
|
||||
url_converter_scope : self,
|
||||
ie7_compat : TRUE
|
||||
}, settings);
|
||||
|
||||
t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
|
||||
self.id = self.editorId = id;
|
||||
|
||||
self.isNotDirty = false;
|
||||
|
||||
self.plugins = {};
|
||||
|
||||
self.documentBaseURI = new tinymce.util.URI(settings.document_base_url || tinymce.documentBaseURL, {
|
||||
base_uri : tinyMCE.baseURI
|
||||
});
|
||||
|
||||
t.baseURI = tinymce.baseURI;
|
||||
self.baseURI = tinymce.baseURI;
|
||||
|
||||
t.contentCSS = [];
|
||||
self.contentCSS = [];
|
||||
|
||||
// Creates all events like onClick, onSetContent etc see Editor.Events.js for the actual logic
|
||||
self.setupEvents();
|
||||
|
||||
// Internal command handler objects
|
||||
self.execCommands = {};
|
||||
self.queryStateCommands = {};
|
||||
self.queryValueCommands = {};
|
||||
|
||||
// Call setup
|
||||
t.execCallback('setup', t);
|
||||
self.execCallback('setup', self);
|
||||
},
|
||||
|
||||
render : function(nst) {
|
||||
|
|
@ -12091,8 +12851,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
return;
|
||||
|
||||
// Is a iPad/iPhone and not on iOS5, then skip initialization. We need to sniff
|
||||
// here since the browser says it has contentEditable support but there is no visible
|
||||
// caret We will remove this check ones Apple implements full contentEditable support
|
||||
// here since the browser says it has contentEditable support but there is no visible caret.
|
||||
if (tinymce.isIDevice && !tinymce.isIOS5)
|
||||
return;
|
||||
|
||||
|
|
@ -12171,9 +12930,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
var dependencies = PluginManager.dependencies(p);
|
||||
each(dependencies, function(dep) {
|
||||
var defaultSettings = {prefix:'plugins/', resource: dep, suffix:'/editor_plugin' + tinymce.suffix + '.js'};
|
||||
var dep = PluginManager.createUrl(defaultSettings, dep);
|
||||
dep = PluginManager.createUrl(defaultSettings, dep);
|
||||
PluginManager.load(dep.resource, dep);
|
||||
|
||||
});
|
||||
} else {
|
||||
// Skip safari plugin, since it is removed as of 3.3b1
|
||||
|
|
@ -12207,7 +12965,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
o = ThemeManager.get(s.theme);
|
||||
t.theme = new o();
|
||||
|
||||
if (t.theme.init && s.init_theme)
|
||||
if (t.theme.init)
|
||||
t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, ''));
|
||||
}
|
||||
function initPlugin(p) {
|
||||
|
|
@ -12243,51 +13001,27 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
|
||||
t.controlManager = new tinymce.ControlManager(t);
|
||||
|
||||
if (s.custom_undo_redo) {
|
||||
t.onBeforeExecCommand.add(function(ed, cmd, ui, val, a) {
|
||||
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
|
||||
t.undoManager.beforeChange();
|
||||
});
|
||||
|
||||
t.onExecCommand.add(function(ed, cmd, ui, val, a) {
|
||||
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
|
||||
t.undoManager.add();
|
||||
});
|
||||
}
|
||||
|
||||
t.onExecCommand.add(function(ed, c) {
|
||||
// Don't refresh the select lists until caret move
|
||||
if (!/^(FontName|FontSize)$/.test(c))
|
||||
t.nodeChanged();
|
||||
});
|
||||
|
||||
// Remove ghost selections on images and tables in Gecko
|
||||
if (isGecko) {
|
||||
function repaint(a, o) {
|
||||
if (!o || !o.initial)
|
||||
t.execCommand('mceRepaint');
|
||||
};
|
||||
|
||||
t.onUndo.add(repaint);
|
||||
t.onRedo.add(repaint);
|
||||
t.onSetContent.add(repaint);
|
||||
}
|
||||
|
||||
// Enables users to override the control factory
|
||||
t.onBeforeRenderUI.dispatch(t, t.controlManager);
|
||||
|
||||
// Measure box
|
||||
if (s.render_ui) {
|
||||
if (s.render_ui && t.theme) {
|
||||
w = s.width || e.style.width || e.offsetWidth;
|
||||
h = s.height || e.style.height || e.offsetHeight;
|
||||
t.orgDisplay = e.style.display;
|
||||
re = /^[0-9\.]+(|px)$/i;
|
||||
|
||||
if (re.test('' + w))
|
||||
w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);
|
||||
w = Math.max(parseInt(w, 10) + (o.deltaWidth || 0), 100);
|
||||
|
||||
if (re.test('' + h))
|
||||
h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
|
||||
h = Math.max(parseInt(h, 10) + (o.deltaHeight || 0), 100);
|
||||
|
||||
// Render UI
|
||||
o = t.theme.renderUI({
|
||||
|
|
@ -12301,6 +13035,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
t.editorContainer = o.editorContainer;
|
||||
}
|
||||
|
||||
// Load specified content CSS last
|
||||
if (s.content_css) {
|
||||
each(explode(s.content_css), function(u) {
|
||||
t.contentCSS.push(t.documentBaseURI.toAbsolute(u));
|
||||
});
|
||||
}
|
||||
|
||||
// Content editable mode ends here
|
||||
if (s.content_editable) {
|
||||
e = n = o = null; // Fix IE leak
|
||||
return t.initContentBody();
|
||||
}
|
||||
|
||||
// User specified a document.domain value
|
||||
if (document.domain && location.hostname != document.domain)
|
||||
|
|
@ -12312,13 +13058,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
height : h
|
||||
});
|
||||
|
||||
// Load specified content CSS last
|
||||
if (s.content_css) {
|
||||
tinymce.each(explode(s.content_css), function(u) {
|
||||
t.contentCSS.push(t.documentBaseURI.toAbsolute(u));
|
||||
});
|
||||
}
|
||||
|
||||
h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');
|
||||
if (h < 100)
|
||||
h = 100;
|
||||
|
|
@ -12362,7 +13101,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
// Domain relaxing enabled, then set document domain
|
||||
if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
|
||||
// We need to write the contents here in IE since multiple writes messes up refresh button and back button
|
||||
u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';
|
||||
u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.initContentBody();})()';
|
||||
}
|
||||
|
||||
// Create iframe
|
||||
|
|
@ -12386,73 +13125,61 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
DOM.setAttrib(t.id, 'aria-hidden', true);
|
||||
|
||||
if (!tinymce.relaxedDomain || !u)
|
||||
t.setupIframe();
|
||||
t.initContentBody();
|
||||
|
||||
e = n = o = null; // Cleanup
|
||||
},
|
||||
|
||||
setupIframe : function() {
|
||||
var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
|
||||
initContentBody : function() {
|
||||
var self = this, settings = self.settings, targetElm = DOM.get(self.id), doc = self.getDoc(), html, body;
|
||||
|
||||
// Setup iframe body
|
||||
if (!isIE || !tinymce.relaxedDomain) {
|
||||
d.open();
|
||||
d.write(t.iframeHTML);
|
||||
d.close();
|
||||
if ((!isIE || !tinymce.relaxedDomain) && !settings.content_editable) {
|
||||
doc.open();
|
||||
doc.write(self.iframeHTML);
|
||||
doc.close();
|
||||
|
||||
if (tinymce.relaxedDomain)
|
||||
d.domain = tinymce.relaxedDomain;
|
||||
doc.domain = tinymce.relaxedDomain;
|
||||
}
|
||||
|
||||
if (settings.content_editable) {
|
||||
DOM.addClass(targetElm, 'mceContentBody');
|
||||
self.contentDocument = doc = settings.content_document || document;
|
||||
self.contentWindow = settings.content_window || window;
|
||||
self.bodyElement = targetElm;
|
||||
|
||||
// Prevent leak in IE
|
||||
settings.content_document = settings.content_window = null;
|
||||
}
|
||||
|
||||
// It will not steal focus while setting contentEditable
|
||||
b = t.getBody();
|
||||
b.disabled = true;
|
||||
body = self.getBody();
|
||||
body.disabled = true;
|
||||
|
||||
if (!s.readonly)
|
||||
b.contentEditable = true;
|
||||
if (!settings.readonly)
|
||||
body.contentEditable = self.getParam('content_editable_state', true);
|
||||
|
||||
b.disabled = false;
|
||||
body.disabled = false;
|
||||
|
||||
t.schema = new tinymce.html.Schema(s);
|
||||
self.schema = new tinymce.html.Schema(settings);
|
||||
|
||||
t.dom = new tinymce.dom.DOMUtils(t.getDoc(), {
|
||||
self.dom = new tinymce.dom.DOMUtils(doc, {
|
||||
keep_values : true,
|
||||
url_converter : t.convertURL,
|
||||
url_converter_scope : t,
|
||||
hex_colors : s.force_hex_style_colors,
|
||||
class_filter : s.class_filter,
|
||||
update_styles : 1,
|
||||
fix_ie_paragraphs : 1,
|
||||
schema : t.schema
|
||||
url_converter : self.convertURL,
|
||||
url_converter_scope : self,
|
||||
hex_colors : settings.force_hex_style_colors,
|
||||
class_filter : settings.class_filter,
|
||||
update_styles : true,
|
||||
root_element : settings.content_editable ? self.id : null,
|
||||
schema : self.schema
|
||||
});
|
||||
|
||||
t.parser = new tinymce.html.DomParser(s, t.schema);
|
||||
|
||||
// Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included.
|
||||
if (!t.settings.allow_html_in_named_anchor) {
|
||||
t.parser.addAttributeFilter('name', function(nodes, name) {
|
||||
var i = nodes.length, sibling, prevSibling, parent, node;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
if (node.name === 'a' && node.firstChild) {
|
||||
parent = node.parent;
|
||||
|
||||
// Move children after current node
|
||||
sibling = node.lastChild;
|
||||
do {
|
||||
prevSibling = sibling.prev;
|
||||
parent.insert(sibling, node);
|
||||
sibling = prevSibling;
|
||||
} while (sibling);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
self.parser = new tinymce.html.DomParser(settings, self.schema);
|
||||
|
||||
// Convert src and href into data-mce-src, data-mce-href and data-mce-style
|
||||
t.parser.addAttributeFilter('src,href,style', function(nodes, name) {
|
||||
var i = nodes.length, node, dom = t.dom, value, internalName;
|
||||
self.parser.addAttributeFilter('src,href,style', function(nodes, name) {
|
||||
var i = nodes.length, node, dom = self.dom, value, internalName;
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
|
|
@ -12464,13 +13191,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
if (name === "style")
|
||||
node.attr(internalName, dom.serializeStyle(dom.parseStyle(value), node.name));
|
||||
else
|
||||
node.attr(internalName, t.convertURL(value, name, node.name));
|
||||
node.attr(internalName, self.convertURL(value, name, node.name));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Keep scripts from executing
|
||||
t.parser.addNodeFilter('script', function(nodes, name) {
|
||||
self.parser.addNodeFilter('script', function(nodes, name) {
|
||||
var i = nodes.length, node;
|
||||
|
||||
while (i--) {
|
||||
|
|
@ -12479,7 +13206,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
}
|
||||
});
|
||||
|
||||
t.parser.addNodeFilter('#cdata', function(nodes, name) {
|
||||
self.parser.addNodeFilter('#cdata', function(nodes, name) {
|
||||
var i = nodes.length, node;
|
||||
|
||||
while (i--) {
|
||||
|
|
@ -12490,8 +13217,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
}
|
||||
});
|
||||
|
||||
t.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) {
|
||||
var i = nodes.length, node, nonEmptyElements = t.schema.getNonEmptyElements();
|
||||
self.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) {
|
||||
var i = nodes.length, node, nonEmptyElements = self.schema.getNonEmptyElements();
|
||||
|
||||
while (i--) {
|
||||
node = nodes[i];
|
||||
|
|
@ -12501,306 +13228,89 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
}
|
||||
});
|
||||
|
||||
t.serializer = new tinymce.dom.Serializer(s, t.dom, t.schema);
|
||||
self.serializer = new tinymce.dom.Serializer(settings, self.dom, self.schema);
|
||||
|
||||
t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);
|
||||
self.selection = new tinymce.dom.Selection(self.dom, self.getWin(), self.serializer);
|
||||
|
||||
t.formatter = new tinymce.Formatter(this);
|
||||
self.formatter = new tinymce.Formatter(self);
|
||||
|
||||
// Register default formats
|
||||
t.formatter.register({
|
||||
alignleft : [
|
||||
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}, defaultBlock: 'div'},
|
||||
{selector : 'img,table', collapsed : false, styles : {'float' : 'left'}}
|
||||
],
|
||||
self.undoManager = new tinymce.UndoManager(self);
|
||||
|
||||
aligncenter : [
|
||||
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}, defaultBlock: 'div'},
|
||||
{selector : 'img', collapsed : false, styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}},
|
||||
{selector : 'table', collapsed : false, styles : {marginLeft : 'auto', marginRight : 'auto'}}
|
||||
],
|
||||
|
||||
alignright : [
|
||||
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}, defaultBlock: 'div'},
|
||||
{selector : 'img,table', collapsed : false, styles : {'float' : 'right'}}
|
||||
],
|
||||
|
||||
alignfull : [
|
||||
{selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'justify'}, defaultBlock: 'div'}
|
||||
],
|
||||
|
||||
bold : [
|
||||
{inline : 'strong', remove : 'all'},
|
||||
{inline : 'span', styles : {fontWeight : 'bold'}},
|
||||
{inline : 'b', remove : 'all'}
|
||||
],
|
||||
|
||||
italic : [
|
||||
{inline : 'em', remove : 'all'},
|
||||
{inline : 'span', styles : {fontStyle : 'italic'}},
|
||||
{inline : 'i', remove : 'all'}
|
||||
],
|
||||
|
||||
underline : [
|
||||
{inline : 'span', styles : {textDecoration : 'underline'}, exact : true},
|
||||
{inline : 'u', remove : 'all'}
|
||||
],
|
||||
|
||||
strikethrough : [
|
||||
{inline : 'span', styles : {textDecoration : 'line-through'}, exact : true},
|
||||
{inline : 'strike', remove : 'all'}
|
||||
],
|
||||
|
||||
forecolor : {inline : 'span', styles : {color : '%value'}, wrap_links : false},
|
||||
hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}, wrap_links : false},
|
||||
fontname : {inline : 'span', styles : {fontFamily : '%value'}},
|
||||
fontsize : {inline : 'span', styles : {fontSize : '%value'}},
|
||||
fontsize_class : {inline : 'span', attributes : {'class' : '%value'}},
|
||||
blockquote : {block : 'blockquote', wrapper : 1, remove : 'all'},
|
||||
subscript : {inline : 'sub'},
|
||||
superscript : {inline : 'sup'},
|
||||
|
||||
link : {inline : 'a', selector : 'a', remove : 'all', split : true, deep : true,
|
||||
onmatch : function(node) {
|
||||
return true;
|
||||
},
|
||||
|
||||
onformat : function(elm, fmt, vars) {
|
||||
each(vars, function(value, key) {
|
||||
t.dom.setAttrib(elm, key, value);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
removeformat : [
|
||||
{selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true},
|
||||
{selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true},
|
||||
{selector : '*', attributes : ['style', 'class'], split : false, expand : false, deep : true}
|
||||
]
|
||||
});
|
||||
|
||||
// Register default block formats
|
||||
each('p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp'.split(/\s/), function(name) {
|
||||
t.formatter.register(name, {block : name, remove : 'all'});
|
||||
});
|
||||
|
||||
// Register user defined formats
|
||||
t.formatter.register(t.settings.formats);
|
||||
|
||||
t.undoManager = new tinymce.UndoManager(t);
|
||||
self.forceBlocks = new tinymce.ForceBlocks(self);
|
||||
self.enterKey = new tinymce.EnterKey(self);
|
||||
self.editorCommands = new tinymce.EditorCommands(self);
|
||||
|
||||
// Pass through
|
||||
t.undoManager.onAdd.add(function(um, l) {
|
||||
if (um.hasUndo())
|
||||
return t.onChange.dispatch(t, l, um);
|
||||
self.serializer.onPreProcess.add(function(se, o) {
|
||||
return self.onPreProcess.dispatch(self, o, se);
|
||||
});
|
||||
|
||||
t.undoManager.onUndo.add(function(um, l) {
|
||||
return t.onUndo.dispatch(t, l, um);
|
||||
self.serializer.onPostProcess.add(function(se, o) {
|
||||
return self.onPostProcess.dispatch(self, o, se);
|
||||
});
|
||||
|
||||
t.undoManager.onRedo.add(function(um, l) {
|
||||
return t.onRedo.dispatch(t, l, um);
|
||||
});
|
||||
self.onPreInit.dispatch(self);
|
||||
|
||||
t.forceBlocks = new tinymce.ForceBlocks(t);
|
||||
t.enterKey = new tinymce.EnterKey(t);
|
||||
if (!settings.gecko_spellcheck)
|
||||
doc.body.spellcheck = false;
|
||||
|
||||
t.editorCommands = new tinymce.EditorCommands(t);
|
||||
|
||||
// Pass through
|
||||
t.serializer.onPreProcess.add(function(se, o) {
|
||||
return t.onPreProcess.dispatch(t, o, se);
|
||||
});
|
||||
|
||||
t.serializer.onPostProcess.add(function(se, o) {
|
||||
return t.onPostProcess.dispatch(t, o, se);
|
||||
});
|
||||
|
||||
t.onPreInit.dispatch(t);
|
||||
|
||||
if (!s.gecko_spellcheck)
|
||||
t.getBody().spellcheck = 0;
|
||||
|
||||
if (!s.readonly)
|
||||
t._addEvents();
|
||||
|
||||
t.controlManager.onPostRender.dispatch(t, t.controlManager);
|
||||
t.onPostRender.dispatch(t);
|
||||
|
||||
t.quirks = new tinymce.util.Quirks(this);
|
||||
|
||||
if (s.directionality)
|
||||
t.getBody().dir = s.directionality;
|
||||
|
||||
if (s.nowrap)
|
||||
t.getBody().style.whiteSpace = "nowrap";
|
||||
|
||||
if (s.handle_node_change_callback) {
|
||||
t.onNodeChange.add(function(ed, cm, n) {
|
||||
t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());
|
||||
});
|
||||
if (!settings.readonly) {
|
||||
self.bindNativeEvents();
|
||||
}
|
||||
|
||||
if (s.save_callback) {
|
||||
t.onSaveContent.add(function(ed, o) {
|
||||
var h = t.execCallback('save_callback', t.id, o.content, t.getBody());
|
||||
self.controlManager.onPostRender.dispatch(self, self.controlManager);
|
||||
self.onPostRender.dispatch(self);
|
||||
|
||||
if (h)
|
||||
o.content = h;
|
||||
});
|
||||
}
|
||||
self.quirks = tinymce.util.Quirks(self);
|
||||
|
||||
if (s.onchange_callback) {
|
||||
t.onChange.add(function(ed, l) {
|
||||
t.execCallback('onchange_callback', t, l);
|
||||
});
|
||||
}
|
||||
if (settings.directionality)
|
||||
body.dir = settings.directionality;
|
||||
|
||||
if (s.protect) {
|
||||
t.onBeforeSetContent.add(function(ed, o) {
|
||||
if (s.protect) {
|
||||
each(s.protect, function(pattern) {
|
||||
o.content = o.content.replace(pattern, function(str) {
|
||||
return '<!--mce:protected ' + escape(str) + '-->';
|
||||
});
|
||||
if (settings.nowrap)
|
||||
body.style.whiteSpace = "nowrap";
|
||||
|
||||
if (settings.protect) {
|
||||
self.onBeforeSetContent.add(function(ed, o) {
|
||||
each(settings.protect, function(pattern) {
|
||||
o.content = o.content.replace(pattern, function(str) {
|
||||
return '<!--mce:protected ' + escape(str) + '-->';
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (s.convert_newlines_to_brs) {
|
||||
t.onBeforeSetContent.add(function(ed, o) {
|
||||
if (o.initial)
|
||||
o.content = o.content.replace(/\r?\n/g, '<br />');
|
||||
});
|
||||
}
|
||||
|
||||
if (s.preformatted) {
|
||||
t.onPostProcess.add(function(ed, o) {
|
||||
o.content = o.content.replace(/^\s*<pre.*?>/, '');
|
||||
o.content = o.content.replace(/<\/pre>\s*$/, '');
|
||||
|
||||
if (o.set)
|
||||
o.content = '<pre class="mceItemHidden">' + o.content + '</pre>';
|
||||
});
|
||||
}
|
||||
|
||||
if (s.verify_css_classes) {
|
||||
t.serializer.attribValueFilter = function(n, v) {
|
||||
var s, cl;
|
||||
|
||||
if (n == 'class') {
|
||||
// Build regexp for classes
|
||||
if (!t.classesRE) {
|
||||
cl = t.dom.getClasses();
|
||||
|
||||
if (cl.length > 0) {
|
||||
s = '';
|
||||
|
||||
each (cl, function(o) {
|
||||
s += (s ? '|' : '') + o['class'];
|
||||
});
|
||||
|
||||
t.classesRE = new RegExp('(' + s + ')', 'gi');
|
||||
}
|
||||
}
|
||||
|
||||
return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : '';
|
||||
}
|
||||
|
||||
return v;
|
||||
};
|
||||
}
|
||||
|
||||
if (s.cleanup_callback) {
|
||||
t.onBeforeSetContent.add(function(ed, o) {
|
||||
o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
|
||||
});
|
||||
|
||||
t.onPreProcess.add(function(ed, o) {
|
||||
if (o.set)
|
||||
t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
|
||||
|
||||
if (o.get)
|
||||
t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
|
||||
});
|
||||
|
||||
t.onPostProcess.add(function(ed, o) {
|
||||
if (o.set)
|
||||
o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
|
||||
|
||||
if (o.get)
|
||||
o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
|
||||
});
|
||||
}
|
||||
|
||||
if (s.save_callback) {
|
||||
t.onGetContent.add(function(ed, o) {
|
||||
if (o.save)
|
||||
o.content = t.execCallback('save_callback', t.id, o.content, t.getBody());
|
||||
});
|
||||
}
|
||||
|
||||
if (s.handle_event_callback) {
|
||||
t.onEvent.add(function(ed, e, o) {
|
||||
if (t.execCallback('handle_event_callback', e, ed, o) === false)
|
||||
Event.cancel(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Add visual aids when new contents is added
|
||||
t.onSetContent.add(function() {
|
||||
t.addVisual(t.getBody());
|
||||
self.onSetContent.add(function() {
|
||||
self.addVisual(self.getBody());
|
||||
});
|
||||
|
||||
// Remove empty contents
|
||||
if (s.padd_empty_editor) {
|
||||
t.onPostProcess.add(function(ed, o) {
|
||||
if (settings.padd_empty_editor) {
|
||||
self.onPostProcess.add(function(ed, o) {
|
||||
o.content = o.content.replace(/^(<p[^>]*>( | |\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/, '');
|
||||
});
|
||||
}
|
||||
|
||||
if (isGecko) {
|
||||
// Fix gecko link bug, when a link is placed at the end of block elements there is
|
||||
// no way to move the caret behind the link. This fix adds a bogus br element after the link
|
||||
function fixLinks(ed, o) {
|
||||
each(ed.dom.select('a'), function(n) {
|
||||
var pn = n.parentNode;
|
||||
self.load({initial : true, format : 'html'});
|
||||
self.startContent = self.getContent({format : 'raw'});
|
||||
|
||||
if (ed.dom.isBlock(pn) && pn.lastChild === n)
|
||||
ed.dom.add(pn, 'br', {'data-mce-bogus' : 1});
|
||||
});
|
||||
};
|
||||
self.initialized = true;
|
||||
|
||||
t.onExecCommand.add(function(ed, cmd) {
|
||||
if (cmd === 'CreateLink')
|
||||
fixLinks(ed);
|
||||
});
|
||||
|
||||
t.onSetContent.add(t.selection.onSetContent.add(fixLinks));
|
||||
}
|
||||
|
||||
t.load({initial : true, format : 'html'});
|
||||
t.startContent = t.getContent({format : 'raw'});
|
||||
t.undoManager.add();
|
||||
t.initialized = true;
|
||||
|
||||
t.onInit.dispatch(t);
|
||||
t.execCallback('setupcontent_callback', t.id, t.getBody(), t.getDoc());
|
||||
t.execCallback('init_instance_callback', t);
|
||||
t.focus(true);
|
||||
t.nodeChanged({initial : 1});
|
||||
self.onInit.dispatch(self);
|
||||
self.execCallback('setupcontent_callback', self.id, body, doc);
|
||||
self.execCallback('init_instance_callback', self);
|
||||
self.focus(true);
|
||||
self.nodeChanged({initial : true});
|
||||
|
||||
// Load specified content CSS last
|
||||
each(t.contentCSS, function(u) {
|
||||
t.dom.loadCSS(u);
|
||||
each(self.contentCSS, function(url) {
|
||||
self.dom.loadCSS(url);
|
||||
});
|
||||
|
||||
// Handle auto focus
|
||||
if (s.auto_focus) {
|
||||
if (settings.auto_focus) {
|
||||
setTimeout(function () {
|
||||
var ed = tinymce.get(s.auto_focus);
|
||||
var ed = tinymce.get(settings.auto_focus);
|
||||
|
||||
ed.selection.select(ed.getBody(), 1);
|
||||
ed.selection.collapse(1);
|
||||
|
|
@ -12809,29 +13319,41 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
}, 100);
|
||||
}
|
||||
|
||||
e = null;
|
||||
// Clean up references for IE
|
||||
targetElm = doc = body = null;
|
||||
},
|
||||
|
||||
focus : function(skip_focus) {
|
||||
var oed, self = this, selection = self.selection, contentEditable = self.settings.content_editable, ieRng, controlElm, doc = self.getDoc(), body;
|
||||
|
||||
focus : function(sf) {
|
||||
var oed, t = this, selection = t.selection, ce = t.settings.content_editable, ieRng, controlElm, doc = t.getDoc();
|
||||
|
||||
if (!sf) {
|
||||
if (!skip_focus) {
|
||||
// Get selected control element
|
||||
ieRng = selection.getRng();
|
||||
if (ieRng.item) {
|
||||
controlElm = ieRng.item(0);
|
||||
}
|
||||
|
||||
t._refreshContentEditable();
|
||||
self._refreshContentEditable();
|
||||
|
||||
// Is not content editable
|
||||
if (!ce)
|
||||
t.getWin().focus();
|
||||
// Focus the window iframe
|
||||
if (!contentEditable) {
|
||||
self.getWin().focus();
|
||||
}
|
||||
|
||||
// Focus the body as well since it's contentEditable
|
||||
if (tinymce.isGecko) {
|
||||
t.getBody().focus();
|
||||
if (tinymce.isGecko || contentEditable) {
|
||||
body = self.getBody();
|
||||
|
||||
// Check for setActive since it doesn't scroll to the element
|
||||
if (body.setActive) {
|
||||
body.setActive();
|
||||
} else {
|
||||
body.focus();
|
||||
}
|
||||
|
||||
if (contentEditable) {
|
||||
selection.normalize();
|
||||
}
|
||||
}
|
||||
|
||||
// Restore selected control element
|
||||
|
|
@ -12842,17 +13364,16 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
ieRng.addElement(controlElm);
|
||||
ieRng.select();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (tinymce.activeEditor != t) {
|
||||
if (tinymce.activeEditor != self) {
|
||||
if ((oed = tinymce.activeEditor) != null)
|
||||
oed.onDeactivate.dispatch(oed, t);
|
||||
oed.onDeactivate.dispatch(oed, self);
|
||||
|
||||
t.onActivate.dispatch(t, oed);
|
||||
self.onActivate.dispatch(self, oed);
|
||||
}
|
||||
|
||||
tinymce._setActive(t);
|
||||
tinymce._setActive(self);
|
||||
},
|
||||
|
||||
execCallback : function(n) {
|
||||
|
|
@ -12884,7 +13405,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
if (!s)
|
||||
return '';
|
||||
|
||||
return i18n[c + '.' + s] || s.replace(/{\#([^}]+)\}/g, function(a, b) {
|
||||
return i18n[c + '.' + s] || s.replace(/\{\#([^\}]+)\}/g, function(a, b) {
|
||||
return i18n[c + '.' + b] || '{#' + b + '}';
|
||||
});
|
||||
},
|
||||
|
|
@ -12918,37 +13439,40 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
},
|
||||
|
||||
nodeChanged : function(o) {
|
||||
var t = this, s = t.selection, n = s.getStart() || t.getBody();
|
||||
var self = this, selection = self.selection, node;
|
||||
|
||||
// Fix for bug #1896577 it seems that this can not be fired while the editor is loading
|
||||
if (t.initialized) {
|
||||
if (self.initialized) {
|
||||
o = o || {};
|
||||
n = isIE && n.ownerDocument != t.getDoc() ? t.getBody() : n; // Fix for IE initial state
|
||||
|
||||
// Get start node
|
||||
node = selection.getStart() || self.getBody();
|
||||
node = isIE && node.ownerDocument != self.getDoc() ? self.getBody() : node; // Fix for IE initial state
|
||||
|
||||
// Get parents and add them to object
|
||||
o.parents = [];
|
||||
t.dom.getParent(n, function(node) {
|
||||
self.dom.getParent(node, function(node) {
|
||||
if (node.nodeName == 'BODY')
|
||||
return true;
|
||||
|
||||
o.parents.push(node);
|
||||
});
|
||||
|
||||
t.onNodeChange.dispatch(
|
||||
t,
|
||||
o ? o.controlManager || t.controlManager : t.controlManager,
|
||||
n,
|
||||
s.isCollapsed(),
|
||||
self.onNodeChange.dispatch(
|
||||
self,
|
||||
o ? o.controlManager || self.controlManager : self.controlManager,
|
||||
node,
|
||||
selection.isCollapsed(),
|
||||
o
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
addButton : function(n, s) {
|
||||
var t = this;
|
||||
addButton : function(name, settings) {
|
||||
var self = this;
|
||||
|
||||
t.buttons = t.buttons || {};
|
||||
t.buttons[n] = s;
|
||||
self.buttons = self.buttons || {};
|
||||
self.buttons[name] = settings;
|
||||
},
|
||||
|
||||
addCommand : function(name, callback, scope) {
|
||||
|
|
@ -12966,7 +13490,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
addShortcut : function(pa, desc, cmd_func, sc) {
|
||||
var t = this, c;
|
||||
|
||||
if (!t.settings.custom_shortcuts)
|
||||
if (t.settings.custom_shortcuts === false)
|
||||
return false;
|
||||
|
||||
t.shortcuts = t.shortcuts || {};
|
||||
|
|
@ -12991,7 +13515,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
var o = {
|
||||
func : cmd_func,
|
||||
scope : sc || this,
|
||||
desc : desc,
|
||||
desc : t.translate(desc),
|
||||
alt : false,
|
||||
ctrl : false,
|
||||
shift : false
|
||||
|
|
@ -13133,24 +13657,24 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
},
|
||||
|
||||
show : function() {
|
||||
var t = this;
|
||||
var self = this;
|
||||
|
||||
DOM.show(t.getContainer());
|
||||
DOM.hide(t.id);
|
||||
t.load();
|
||||
DOM.show(self.getContainer());
|
||||
DOM.hide(self.id);
|
||||
self.load();
|
||||
},
|
||||
|
||||
hide : function() {
|
||||
var t = this, d = t.getDoc();
|
||||
var self = this, doc = self.getDoc();
|
||||
|
||||
// Fixed bug where IE has a blinking cursor left from the editor
|
||||
if (isIE && d)
|
||||
d.execCommand('SelectAll');
|
||||
if (isIE && doc)
|
||||
doc.execCommand('SelectAll');
|
||||
|
||||
// We must save before we hide so Safari doesn't crash
|
||||
t.save();
|
||||
DOM.hide(t.getContainer());
|
||||
DOM.setStyle(t.id, 'display', t.orgDisplay);
|
||||
self.save();
|
||||
DOM.hide(self.getContainer());
|
||||
DOM.setStyle(self.id, 'display', self.orgDisplay);
|
||||
},
|
||||
|
||||
isHidden : function() {
|
||||
|
|
@ -13192,12 +13716,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
o = o || {};
|
||||
o.save = true;
|
||||
|
||||
// Add undo level will trigger onchange event
|
||||
if (!o.no_events) {
|
||||
t.undoManager.typing = false;
|
||||
t.undoManager.add();
|
||||
}
|
||||
|
||||
o.element = e;
|
||||
h = o.content = t.getContent(o);
|
||||
|
||||
|
|
@ -13283,6 +13801,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
args = args || {};
|
||||
args.format = args.format || 'html';
|
||||
args.get = true;
|
||||
args.getInner = true;
|
||||
|
||||
// Do preprocessing
|
||||
if (!args.no_events)
|
||||
|
|
@ -13310,12 +13829,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
},
|
||||
|
||||
getContainer : function() {
|
||||
var t = this;
|
||||
var self = this;
|
||||
|
||||
if (!t.container)
|
||||
t.container = DOM.get(t.editorContainer || t.id + '_parent');
|
||||
if (!self.container)
|
||||
self.container = DOM.get(self.editorContainer || self.id + '_parent');
|
||||
|
||||
return t.container;
|
||||
return self.container;
|
||||
},
|
||||
|
||||
getContentAreaContainer : function() {
|
||||
|
|
@ -13327,125 +13846,125 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
},
|
||||
|
||||
getWin : function() {
|
||||
var t = this, e;
|
||||
var self = this, elm;
|
||||
|
||||
if (!t.contentWindow) {
|
||||
e = DOM.get(t.id + "_ifr");
|
||||
if (!self.contentWindow) {
|
||||
elm = DOM.get(self.id + "_ifr");
|
||||
|
||||
if (e)
|
||||
t.contentWindow = e.contentWindow;
|
||||
if (elm)
|
||||
self.contentWindow = elm.contentWindow;
|
||||
}
|
||||
|
||||
return t.contentWindow;
|
||||
return self.contentWindow;
|
||||
},
|
||||
|
||||
getDoc : function() {
|
||||
var t = this, w;
|
||||
var self = this, win;
|
||||
|
||||
if (!t.contentDocument) {
|
||||
w = t.getWin();
|
||||
if (!self.contentDocument) {
|
||||
win = self.getWin();
|
||||
|
||||
if (w)
|
||||
t.contentDocument = w.document;
|
||||
if (win)
|
||||
self.contentDocument = win.document;
|
||||
}
|
||||
|
||||
return t.contentDocument;
|
||||
return self.contentDocument;
|
||||
},
|
||||
|
||||
getBody : function() {
|
||||
return this.bodyElement || this.getDoc().body;
|
||||
},
|
||||
|
||||
convertURL : function(u, n, e) {
|
||||
var t = this, s = t.settings;
|
||||
convertURL : function(url, name, elm) {
|
||||
var self = this, settings = self.settings;
|
||||
|
||||
// Use callback instead
|
||||
if (s.urlconverter_callback)
|
||||
return t.execCallback('urlconverter_callback', u, e, true, n);
|
||||
if (settings.urlconverter_callback)
|
||||
return self.execCallback('urlconverter_callback', url, elm, true, name);
|
||||
|
||||
// Don't convert link href since thats the CSS files that gets loaded into the editor also skip local file URLs
|
||||
if (!s.convert_urls || (e && e.nodeName == 'LINK') || u.indexOf('file:') === 0)
|
||||
return u;
|
||||
if (!settings.convert_urls || (elm && elm.nodeName == 'LINK') || url.indexOf('file:') === 0)
|
||||
return url;
|
||||
|
||||
// Convert to relative
|
||||
if (s.relative_urls)
|
||||
return t.documentBaseURI.toRelative(u);
|
||||
if (settings.relative_urls)
|
||||
return self.documentBaseURI.toRelative(url);
|
||||
|
||||
// Convert to absolute
|
||||
u = t.documentBaseURI.toAbsolute(u, s.remove_script_host);
|
||||
url = self.documentBaseURI.toAbsolute(url, settings.remove_script_host);
|
||||
|
||||
return u;
|
||||
return url;
|
||||
},
|
||||
|
||||
addVisual : function(e) {
|
||||
var t = this, s = t.settings;
|
||||
addVisual : function(elm) {
|
||||
var self = this, settings = self.settings, dom = self.dom, cls;
|
||||
|
||||
e = e || t.getBody();
|
||||
elm = elm || self.getBody();
|
||||
|
||||
if (!is(t.hasVisual))
|
||||
t.hasVisual = s.visual;
|
||||
if (!is(self.hasVisual))
|
||||
self.hasVisual = settings.visual;
|
||||
|
||||
each(t.dom.select('table,a', e), function(e) {
|
||||
var v;
|
||||
each(dom.select('table,a', elm), function(elm) {
|
||||
var value;
|
||||
|
||||
switch (e.nodeName) {
|
||||
switch (elm.nodeName) {
|
||||
case 'TABLE':
|
||||
v = t.dom.getAttrib(e, 'border');
|
||||
cls = settings.visual_table_class || 'mceItemTable';
|
||||
value = dom.getAttrib(elm, 'border');
|
||||
|
||||
if (!v || v == '0') {
|
||||
if (t.hasVisual)
|
||||
t.dom.addClass(e, s.visual_table_class);
|
||||
if (!value || value == '0') {
|
||||
if (self.hasVisual)
|
||||
dom.addClass(elm, cls);
|
||||
else
|
||||
t.dom.removeClass(e, s.visual_table_class);
|
||||
dom.removeClass(elm, cls);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
case 'A':
|
||||
v = t.dom.getAttrib(e, 'name');
|
||||
value = dom.getAttrib(elm, 'name');
|
||||
cls = 'mceItemAnchor';
|
||||
|
||||
if (v) {
|
||||
if (t.hasVisual)
|
||||
t.dom.addClass(e, 'mceItemAnchor');
|
||||
if (value) {
|
||||
if (self.hasVisual)
|
||||
dom.addClass(elm, cls);
|
||||
else
|
||||
t.dom.removeClass(e, 'mceItemAnchor');
|
||||
dom.removeClass(elm, cls);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
t.onVisualAid.dispatch(t, e, t.hasVisual);
|
||||
self.onVisualAid.dispatch(self, elm, self.hasVisual);
|
||||
},
|
||||
|
||||
remove : function() {
|
||||
var t = this, e = t.getContainer();
|
||||
var self = this, elm = self.getContainer();
|
||||
|
||||
if (!t.removed) {
|
||||
t.removed = 1; // Cancels post remove event execution
|
||||
t.hide();
|
||||
|
||||
// Remove all events
|
||||
if (!self.removed) {
|
||||
self.removed = 1; // Cancels post remove event execution
|
||||
self.hide();
|
||||
|
||||
// Don't clear the window or document if content editable
|
||||
// is enabled since other instances might still be present
|
||||
if (!t.settings.content_editable) {
|
||||
Event.clear(t.getWin());
|
||||
Event.clear(t.getDoc());
|
||||
if (!self.settings.content_editable) {
|
||||
Event.clear(self.getWin());
|
||||
Event.clear(self.getDoc());
|
||||
}
|
||||
|
||||
Event.clear(t.getBody());
|
||||
Event.clear(t.formElement);
|
||||
Event.unbind(e);
|
||||
Event.clear(self.getBody());
|
||||
Event.clear(self.formElement);
|
||||
Event.unbind(elm);
|
||||
|
||||
t.execCallback('remove_instance_callback', t);
|
||||
t.onRemove.dispatch(t);
|
||||
self.execCallback('remove_instance_callback', self);
|
||||
self.onRemove.dispatch(self);
|
||||
|
||||
// Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command
|
||||
t.onExecCommand.listeners = [];
|
||||
self.onExecCommand.listeners = [];
|
||||
|
||||
tinymce.remove(t);
|
||||
DOM.remove(e);
|
||||
tinymce.remove(self);
|
||||
DOM.remove(elm);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -13492,343 +14011,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
|
||||
// Internal functions
|
||||
|
||||
_addEvents : function() {
|
||||
// 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset
|
||||
var t = this, i, s = t.settings, dom = t.dom, lo = {
|
||||
mouseup : 'onMouseUp',
|
||||
mousedown : 'onMouseDown',
|
||||
click : 'onClick',
|
||||
keyup : 'onKeyUp',
|
||||
keydown : 'onKeyDown',
|
||||
keypress : 'onKeyPress',
|
||||
submit : 'onSubmit',
|
||||
reset : 'onReset',
|
||||
contextmenu : 'onContextMenu',
|
||||
dblclick : 'onDblClick',
|
||||
paste : 'onPaste' // Doesn't work in all browsers yet
|
||||
};
|
||||
|
||||
function eventHandler(e, o) {
|
||||
var ty = e.type;
|
||||
|
||||
// Don't fire events when it's removed
|
||||
if (t.removed)
|
||||
return;
|
||||
|
||||
// Generic event handler
|
||||
if (t.onEvent.dispatch(t, e, o) !== false) {
|
||||
// Specific event handler
|
||||
t[lo[e.fakeType || e.type]].dispatch(t, e, o);
|
||||
}
|
||||
};
|
||||
|
||||
// Add DOM events
|
||||
each(lo, function(v, k) {
|
||||
switch (k) {
|
||||
case 'contextmenu':
|
||||
dom.bind(t.getDoc(), k, eventHandler);
|
||||
break;
|
||||
|
||||
case 'paste':
|
||||
dom.bind(t.getBody(), k, function(e) {
|
||||
eventHandler(e);
|
||||
});
|
||||
break;
|
||||
|
||||
case 'submit':
|
||||
case 'reset':
|
||||
dom.bind(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);
|
||||
break;
|
||||
|
||||
default:
|
||||
dom.bind(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);
|
||||
}
|
||||
});
|
||||
|
||||
dom.bind(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {
|
||||
t.focus(true);
|
||||
});
|
||||
|
||||
|
||||
// Fixes bug where a specified document_base_uri could result in broken images
|
||||
// This will also fix drag drop of images in Gecko
|
||||
if (tinymce.isGecko) {
|
||||
dom.bind(t.getDoc(), 'DOMNodeInserted', function(e) {
|
||||
var v;
|
||||
|
||||
e = e.target;
|
||||
|
||||
if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('data-mce-src')))
|
||||
e.src = t.documentBaseURI.toAbsolute(v);
|
||||
});
|
||||
}
|
||||
|
||||
// Set various midas options in Gecko
|
||||
if (isGecko) {
|
||||
function setOpts() {
|
||||
var t = this, d = t.getDoc(), s = t.settings;
|
||||
|
||||
if (isGecko && !s.readonly) {
|
||||
t._refreshContentEditable();
|
||||
|
||||
try {
|
||||
// Try new Gecko method
|
||||
d.execCommand("styleWithCSS", 0, false);
|
||||
} catch (ex) {
|
||||
// Use old method
|
||||
if (!t._isHidden())
|
||||
try {d.execCommand("useCSS", 0, true);} catch (ex) {}
|
||||
}
|
||||
|
||||
if (!s.table_inline_editing)
|
||||
try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {}
|
||||
|
||||
if (!s.object_resizing)
|
||||
try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {}
|
||||
}
|
||||
};
|
||||
|
||||
t.onBeforeExecCommand.add(setOpts);
|
||||
t.onMouseDown.add(setOpts);
|
||||
}
|
||||
|
||||
// Add node change handlers
|
||||
t.onMouseUp.add(t.nodeChanged);
|
||||
//t.onClick.add(t.nodeChanged);
|
||||
t.onKeyUp.add(function(ed, e) {
|
||||
var c = e.keyCode;
|
||||
|
||||
if ((c >= 33 && c <= 36) || (c >= 37 && c <= 40) || c == 13 || c == 45 || c == 46 || c == 8 || (tinymce.isMac && (c == 91 || c == 93)) || e.ctrlKey)
|
||||
t.nodeChanged();
|
||||
});
|
||||
|
||||
|
||||
// Add block quote deletion handler
|
||||
t.onKeyDown.add(function(ed, e) {
|
||||
if (e.keyCode != VK.BACKSPACE)
|
||||
return;
|
||||
|
||||
var rng = ed.selection.getRng();
|
||||
if (!rng.collapsed)
|
||||
return;
|
||||
|
||||
var n = rng.startContainer;
|
||||
var offset = rng.startOffset;
|
||||
|
||||
while (n && n.nodeType && n.nodeType != 1 && n.parentNode)
|
||||
n = n.parentNode;
|
||||
|
||||
// Is the cursor at the beginning of a blockquote?
|
||||
if (n && n.parentNode && n.parentNode.tagName === 'BLOCKQUOTE' && n.parentNode.firstChild == n && offset == 0) {
|
||||
// Remove the blockquote
|
||||
ed.formatter.toggle('blockquote', null, n.parentNode);
|
||||
|
||||
// Move the caret to the beginning of n
|
||||
rng.setStart(n, 0);
|
||||
rng.setEnd(n, 0);
|
||||
ed.selection.setRng(rng);
|
||||
ed.selection.collapse(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Add reset handler
|
||||
t.onReset.add(function() {
|
||||
t.setContent(t.startContent, {format : 'raw'});
|
||||
});
|
||||
|
||||
// Add shortcuts
|
||||
if (s.custom_shortcuts) {
|
||||
if (s.custom_undo_redo_keyboard_shortcuts) {
|
||||
t.addShortcut('ctrl+z', t.getLang('undo_desc'), 'Undo');
|
||||
t.addShortcut('ctrl+y', t.getLang('redo_desc'), 'Redo');
|
||||
}
|
||||
|
||||
// Add default shortcuts for gecko
|
||||
t.addShortcut('ctrl+b', t.getLang('bold_desc'), 'Bold');
|
||||
t.addShortcut('ctrl+i', t.getLang('italic_desc'), 'Italic');
|
||||
t.addShortcut('ctrl+u', t.getLang('underline_desc'), 'Underline');
|
||||
|
||||
// BlockFormat shortcuts keys
|
||||
for (i=1; i<=6; i++)
|
||||
t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]);
|
||||
|
||||
t.addShortcut('ctrl+7', '', ['FormatBlock', false, 'p']);
|
||||
t.addShortcut('ctrl+8', '', ['FormatBlock', false, 'div']);
|
||||
t.addShortcut('ctrl+9', '', ['FormatBlock', false, 'address']);
|
||||
|
||||
function find(e) {
|
||||
var v = null;
|
||||
|
||||
if (!e.altKey && !e.ctrlKey && !e.metaKey)
|
||||
return v;
|
||||
|
||||
each(t.shortcuts, function(o) {
|
||||
if (tinymce.isMac && o.ctrl != e.metaKey)
|
||||
return;
|
||||
else if (!tinymce.isMac && o.ctrl != e.ctrlKey)
|
||||
return;
|
||||
|
||||
if (o.alt != e.altKey)
|
||||
return;
|
||||
|
||||
if (o.shift != e.shiftKey)
|
||||
return;
|
||||
|
||||
if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) {
|
||||
v = o;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
};
|
||||
|
||||
t.onKeyUp.add(function(ed, e) {
|
||||
var o = find(e);
|
||||
|
||||
if (o)
|
||||
return Event.cancel(e);
|
||||
});
|
||||
|
||||
t.onKeyPress.add(function(ed, e) {
|
||||
var o = find(e);
|
||||
|
||||
if (o)
|
||||
return Event.cancel(e);
|
||||
});
|
||||
|
||||
t.onKeyDown.add(function(ed, e) {
|
||||
var o = find(e);
|
||||
|
||||
if (o) {
|
||||
o.func.call(o.scope);
|
||||
return Event.cancel(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (tinymce.isIE) {
|
||||
// Fix so resize will only update the width and height attributes not the styles of an image
|
||||
// It will also block mceItemNoResize items
|
||||
dom.bind(t.getDoc(), 'controlselect', function(e) {
|
||||
var re = t.resizeInfo, cb;
|
||||
|
||||
e = e.target;
|
||||
|
||||
// Don't do this action for non image elements
|
||||
if (e.nodeName !== 'IMG')
|
||||
return;
|
||||
|
||||
if (re)
|
||||
dom.unbind(re.node, re.ev, re.cb);
|
||||
|
||||
if (!dom.hasClass(e, 'mceItemNoResize')) {
|
||||
ev = 'resizeend';
|
||||
cb = dom.bind(e, ev, function(e) {
|
||||
var v;
|
||||
|
||||
e = e.target;
|
||||
|
||||
if (v = dom.getStyle(e, 'width')) {
|
||||
dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));
|
||||
dom.setStyle(e, 'width', '');
|
||||
}
|
||||
|
||||
if (v = dom.getStyle(e, 'height')) {
|
||||
dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));
|
||||
dom.setStyle(e, 'height', '');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ev = 'resizestart';
|
||||
cb = dom.bind(e, 'resizestart', Event.cancel, Event);
|
||||
}
|
||||
|
||||
re = t.resizeInfo = {
|
||||
node : e,
|
||||
ev : ev,
|
||||
cb : cb
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
if (tinymce.isOpera) {
|
||||
t.onClick.add(function(ed, e) {
|
||||
Event.prevent(e);
|
||||
});
|
||||
}
|
||||
|
||||
// Add custom undo/redo handlers
|
||||
if (s.custom_undo_redo) {
|
||||
function addUndo() {
|
||||
t.undoManager.typing = false;
|
||||
t.undoManager.add();
|
||||
};
|
||||
|
||||
var focusLostFunc = tinymce.isGecko ? 'blur' : 'focusout';
|
||||
dom.bind(t.getDoc(), focusLostFunc, function(e){
|
||||
if (!t.removed && t.undoManager.typing)
|
||||
addUndo();
|
||||
});
|
||||
|
||||
// Add undo level when contents is drag/dropped within the editor
|
||||
t.dom.bind(t.dom.getRoot(), 'dragend', function(e) {
|
||||
addUndo();
|
||||
});
|
||||
|
||||
t.onKeyUp.add(function(ed, e) {
|
||||
var keyCode = e.keyCode;
|
||||
|
||||
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || e.ctrlKey)
|
||||
addUndo();
|
||||
});
|
||||
|
||||
t.onKeyDown.add(function(ed, e) {
|
||||
var keyCode = e.keyCode, sel;
|
||||
|
||||
if (keyCode == 8) {
|
||||
sel = t.getDoc().selection;
|
||||
|
||||
// Fix IE control + backspace browser bug
|
||||
if (sel && sel.createRange && sel.createRange().item) {
|
||||
t.undoManager.beforeChange();
|
||||
ed.dom.remove(sel.createRange().item(0));
|
||||
addUndo();
|
||||
|
||||
return Event.cancel(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Is caracter positon keys left,right,up,down,home,end,pgdown,pgup,enter
|
||||
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45) {
|
||||
// Add position before enter key is pressed, used by IE since it still uses the default browser behavior
|
||||
// Todo: Remove this once we normalize enter behavior on IE
|
||||
if (tinymce.isIE && keyCode == 13)
|
||||
t.undoManager.beforeChange();
|
||||
|
||||
if (t.undoManager.typing)
|
||||
addUndo();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If key isn't shift,ctrl,alt,capslock,metakey
|
||||
if ((keyCode < 16 || keyCode > 20) && keyCode != 224 && keyCode != 91 && !t.undoManager.typing) {
|
||||
t.undoManager.beforeChange();
|
||||
t.undoManager.typing = true;
|
||||
t.undoManager.add();
|
||||
}
|
||||
});
|
||||
|
||||
t.onMouseDown.add(function() {
|
||||
if (t.undoManager.typing)
|
||||
addUndo();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
_refreshContentEditable : function() {
|
||||
var self = this, body, parent;
|
||||
|
||||
|
|
@ -13852,14 +14034,294 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
|
||||
// Weird, wheres that cursor selection?
|
||||
s = this.selection.getSel();
|
||||
return (!s || !s.rangeCount || s.rangeCount == 0);
|
||||
return (!s || !s.rangeCount || s.rangeCount === 0);
|
||||
}
|
||||
});
|
||||
})(tinymce);
|
||||
(function(tinymce) {
|
||||
var each = tinymce.each;
|
||||
|
||||
tinymce.Editor.prototype.setupEvents = function() {
|
||||
var self = this, settings = self.settings;
|
||||
|
||||
// Add events to the editor
|
||||
each([
|
||||
'onPreInit',
|
||||
|
||||
'onBeforeRenderUI',
|
||||
|
||||
'onPostRender',
|
||||
|
||||
'onLoad',
|
||||
|
||||
'onInit',
|
||||
|
||||
'onRemove',
|
||||
|
||||
'onActivate',
|
||||
|
||||
'onDeactivate',
|
||||
|
||||
'onClick',
|
||||
|
||||
'onEvent',
|
||||
|
||||
'onMouseUp',
|
||||
|
||||
'onMouseDown',
|
||||
|
||||
'onDblClick',
|
||||
|
||||
'onKeyDown',
|
||||
|
||||
'onKeyUp',
|
||||
|
||||
'onKeyPress',
|
||||
|
||||
'onContextMenu',
|
||||
|
||||
'onSubmit',
|
||||
|
||||
'onReset',
|
||||
|
||||
'onPaste',
|
||||
|
||||
'onPreProcess',
|
||||
|
||||
'onPostProcess',
|
||||
|
||||
'onBeforeSetContent',
|
||||
|
||||
'onBeforeGetContent',
|
||||
|
||||
'onSetContent',
|
||||
|
||||
'onGetContent',
|
||||
|
||||
'onLoadContent',
|
||||
|
||||
'onSaveContent',
|
||||
|
||||
'onNodeChange',
|
||||
|
||||
'onChange',
|
||||
|
||||
'onBeforeExecCommand',
|
||||
|
||||
'onExecCommand',
|
||||
|
||||
'onUndo',
|
||||
|
||||
'onRedo',
|
||||
|
||||
'onVisualAid',
|
||||
|
||||
'onSetProgressState',
|
||||
|
||||
'onSetAttrib'
|
||||
], function(name) {
|
||||
self[name] = new tinymce.util.Dispatcher(self);
|
||||
});
|
||||
|
||||
// Handle legacy cleanup_callback option
|
||||
if (settings.cleanup_callback) {
|
||||
self.onBeforeSetContent.add(function(ed, o) {
|
||||
o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
|
||||
});
|
||||
|
||||
self.onPreProcess.add(function(ed, o) {
|
||||
if (o.set)
|
||||
ed.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
|
||||
|
||||
if (o.get)
|
||||
ed.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
|
||||
});
|
||||
|
||||
self.onPostProcess.add(function(ed, o) {
|
||||
if (o.set)
|
||||
o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
|
||||
|
||||
if (o.get)
|
||||
o.content = ed.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
|
||||
});
|
||||
}
|
||||
|
||||
// Handle legacy save_callback option
|
||||
if (settings.save_callback) {
|
||||
self.onGetContent.add(function(ed, o) {
|
||||
if (o.save)
|
||||
o.content = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());
|
||||
});
|
||||
}
|
||||
|
||||
// Handle legacy handle_event_callback option
|
||||
if (settings.handle_event_callback) {
|
||||
self.onEvent.add(function(ed, e, o) {
|
||||
if (self.execCallback('handle_event_callback', e, ed, o) === false)
|
||||
Event.cancel(e);
|
||||
});
|
||||
}
|
||||
|
||||
// Handle legacy handle_node_change_callback option
|
||||
if (settings.handle_node_change_callback) {
|
||||
self.onNodeChange.add(function(ed, cm, n) {
|
||||
ed.execCallback('handle_node_change_callback', ed.id, n, -1, -1, true, ed.selection.isCollapsed());
|
||||
});
|
||||
}
|
||||
|
||||
// Handle legacy save_callback option
|
||||
if (settings.save_callback) {
|
||||
self.onSaveContent.add(function(ed, o) {
|
||||
var h = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());
|
||||
|
||||
if (h)
|
||||
o.content = h;
|
||||
});
|
||||
}
|
||||
|
||||
// Handle legacy onchange_callback option
|
||||
if (settings.onchange_callback) {
|
||||
self.onChange.add(function(ed, l) {
|
||||
ed.execCallback('onchange_callback', ed, l);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
tinymce.Editor.prototype.bindNativeEvents = function() {
|
||||
// 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset
|
||||
var self = this, i, settings = self.settings, dom = self.dom, nativeToDispatcherMap;
|
||||
|
||||
nativeToDispatcherMap = {
|
||||
mouseup : 'onMouseUp',
|
||||
mousedown : 'onMouseDown',
|
||||
click : 'onClick',
|
||||
keyup : 'onKeyUp',
|
||||
keydown : 'onKeyDown',
|
||||
keypress : 'onKeyPress',
|
||||
submit : 'onSubmit',
|
||||
reset : 'onReset',
|
||||
contextmenu : 'onContextMenu',
|
||||
dblclick : 'onDblClick',
|
||||
paste : 'onPaste' // Doesn't work in all browsers yet
|
||||
};
|
||||
|
||||
// Handler that takes a native event and sends it out to a dispatcher like onKeyDown
|
||||
function eventHandler(evt, args) {
|
||||
var type = evt.type;
|
||||
|
||||
// Don't fire events when it's removed
|
||||
if (self.removed)
|
||||
return;
|
||||
|
||||
// Sends the native event out to a global dispatcher then to the specific event dispatcher
|
||||
if (self.onEvent.dispatch(self, evt, args) !== false) {
|
||||
self[nativeToDispatcherMap[evt.fakeType || evt.type]].dispatch(self, evt, args);
|
||||
}
|
||||
};
|
||||
|
||||
// Opera doesn't support focus event for contentEditable elements so we need to fake it
|
||||
function doOperaFocus(e) {
|
||||
self.focus(true);
|
||||
};
|
||||
|
||||
function nodeChanged() {
|
||||
// Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i>
|
||||
self.selection.normalize();
|
||||
self.nodeChanged();
|
||||
}
|
||||
|
||||
// Add DOM events
|
||||
each(nativeToDispatcherMap, function(dispatcherName, nativeName) {
|
||||
var root = settings.content_editable ? self.getBody() : self.getDoc();
|
||||
|
||||
switch (nativeName) {
|
||||
case 'contextmenu':
|
||||
dom.bind(root, nativeName, eventHandler);
|
||||
break;
|
||||
|
||||
case 'paste':
|
||||
dom.bind(self.getBody(), nativeName, eventHandler);
|
||||
break;
|
||||
|
||||
case 'submit':
|
||||
case 'reset':
|
||||
dom.bind(self.getElement().form || tinymce.DOM.getParent(self.id, 'form'), nativeName, eventHandler);
|
||||
break;
|
||||
|
||||
default:
|
||||
dom.bind(root, nativeName, eventHandler);
|
||||
}
|
||||
});
|
||||
|
||||
// Set the editor as active when focused
|
||||
dom.bind(settings.content_editable ? self.getBody() : (tinymce.isGecko ? self.getDoc() : self.getWin()), 'focus', function(e) {
|
||||
self.focus(true);
|
||||
});
|
||||
|
||||
if (settings.content_editable && tinymce.isOpera) {
|
||||
dom.bind(self.getBody(), 'click', doOperaFocus);
|
||||
dom.bind(self.getBody(), 'keydown', doOperaFocus);
|
||||
}
|
||||
|
||||
// Add node change handler
|
||||
self.onMouseUp.add(nodeChanged);
|
||||
|
||||
self.onKeyUp.add(function(ed, e) {
|
||||
var keyCode = e.keyCode;
|
||||
|
||||
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || keyCode == 46 || keyCode == 8 || (tinymce.isMac && (keyCode == 91 || keyCode == 93)) || e.ctrlKey)
|
||||
nodeChanged();
|
||||
});
|
||||
|
||||
// Add reset handler
|
||||
self.onReset.add(function() {
|
||||
self.setContent(self.startContent, {format : 'raw'});
|
||||
});
|
||||
|
||||
// Add shortcuts
|
||||
function handleShortcut(e, execute) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey) {
|
||||
each(self.shortcuts, function(shortcut) {
|
||||
var ctrlState = tinymce.isMac ? e.metaKey : e.ctrlKey;
|
||||
|
||||
if (shortcut.ctrl != ctrlState || shortcut.alt != e.altKey || shortcut.shift != e.shiftKey)
|
||||
return;
|
||||
|
||||
if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) {
|
||||
e.preventDefault();
|
||||
|
||||
if (execute) {
|
||||
shortcut.func.call(shortcut.scope);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
self.onKeyUp.add(function(ed, e) {
|
||||
handleShortcut(e);
|
||||
});
|
||||
|
||||
self.onKeyPress.add(function(ed, e) {
|
||||
handleShortcut(e);
|
||||
});
|
||||
|
||||
self.onKeyDown.add(function(ed, e) {
|
||||
handleShortcut(e, true);
|
||||
});
|
||||
|
||||
if (tinymce.isOpera) {
|
||||
self.onClick.add(function(ed, e) {
|
||||
e.preventDefault();
|
||||
});
|
||||
}
|
||||
};
|
||||
})(tinymce);
|
||||
(function(tinymce) {
|
||||
// Added for compression purposes
|
||||
var each = tinymce.each, undefined, TRUE = true, FALSE = false;
|
||||
var each = tinymce.each, undef, TRUE = true, FALSE = false;
|
||||
|
||||
tinymce.EditorCommands = function(editor) {
|
||||
var dom = editor.dom,
|
||||
|
|
@ -13922,10 +14384,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
// Private methods
|
||||
|
||||
function execNativeCommand(command, ui, value) {
|
||||
if (ui === undefined)
|
||||
if (ui === undef)
|
||||
ui = FALSE;
|
||||
|
||||
if (value === undefined)
|
||||
if (value === undef)
|
||||
value = null;
|
||||
|
||||
return editor.getDoc().execCommand(command, ui, value);
|
||||
|
|
@ -13936,7 +14398,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
};
|
||||
|
||||
function toggleFormat(name, value) {
|
||||
formatter.toggle(name, value ? {value : value} : undefined);
|
||||
formatter.toggle(name, value ? {value : value} : undef);
|
||||
};
|
||||
|
||||
function storeSelection(type) {
|
||||
|
|
@ -14336,9 +14798,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
// Override justify commands
|
||||
'JustifyLeft,JustifyCenter,JustifyRight,JustifyFull' : function(command) {
|
||||
var name = 'align' + command.substring(7);
|
||||
// Use Formatter.matchNode instead of Formatter.match so that we don't match on parent node. This fixes bug where for both left
|
||||
// and right align buttons can be active. This could occur when selected nodes have align right and the parent has align left.
|
||||
var nodes = selection.isCollapsed() ? [selection.getNode()] : selection.getSelectedBlocks();
|
||||
var nodes = selection.isCollapsed() ? [dom.getParent(selection.getNode(), dom.isBlock)] : selection.getSelectedBlocks();
|
||||
var matches = tinymce.map(nodes, function(node) {
|
||||
return !!formatter.matchNode(node, name);
|
||||
});
|
||||
|
|
@ -14389,17 +14849,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
}, 'value');
|
||||
|
||||
// Add undo manager logic
|
||||
if (settings.custom_undo_redo) {
|
||||
addCommands({
|
||||
Undo : function() {
|
||||
editor.undoManager.undo();
|
||||
},
|
||||
addCommands({
|
||||
Undo : function() {
|
||||
editor.undoManager.undo();
|
||||
},
|
||||
|
||||
Redo : function() {
|
||||
editor.undoManager.redo();
|
||||
}
|
||||
});
|
||||
}
|
||||
Redo : function() {
|
||||
editor.undoManager.redo();
|
||||
}
|
||||
});
|
||||
};
|
||||
})(tinymce);
|
||||
|
||||
|
|
@ -14407,21 +14865,116 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
var Dispatcher = tinymce.util.Dispatcher;
|
||||
|
||||
tinymce.UndoManager = function(editor) {
|
||||
var self, index = 0, data = [], beforeBookmark;
|
||||
var self, index = 0, data = [], beforeBookmark, onAdd, onUndo, onRedo;
|
||||
|
||||
function getContent() {
|
||||
// Remove whitespace before/after and remove pure bogus nodes
|
||||
return tinymce.trim(editor.getContent({format : 'raw', no_events : 1}).replace(/<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\/span>/g, ''));
|
||||
};
|
||||
|
||||
return self = {
|
||||
function addNonTypingUndoLevel() {
|
||||
self.typing = false;
|
||||
self.add();
|
||||
};
|
||||
|
||||
// Create event instances
|
||||
onAdd = new Dispatcher(self);
|
||||
onUndo = new Dispatcher(self);
|
||||
onRedo = new Dispatcher(self);
|
||||
|
||||
// Pass though onAdd event from UndoManager to Editor as onChange
|
||||
onAdd.add(function(undoman, level) {
|
||||
if (undoman.hasUndo())
|
||||
return editor.onChange.dispatch(editor, level, undoman);
|
||||
});
|
||||
|
||||
// Pass though onUndo event from UndoManager to Editor
|
||||
onUndo.add(function(undoman, level) {
|
||||
return editor.onUndo.dispatch(editor, level, undoman);
|
||||
});
|
||||
|
||||
// Pass though onRedo event from UndoManager to Editor
|
||||
onRedo.add(function(undoman, level) {
|
||||
return editor.onRedo.dispatch(editor, level, undoman);
|
||||
});
|
||||
|
||||
// Add initial undo level when the editor is initialized
|
||||
editor.onInit.add(function() {
|
||||
self.add();
|
||||
});
|
||||
|
||||
// Get position before an execCommand is processed
|
||||
editor.onBeforeExecCommand.add(function(ed, cmd, ui, val, args) {
|
||||
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!args || !args.skip_undo)) {
|
||||
self.beforeChange();
|
||||
}
|
||||
});
|
||||
|
||||
// Add undo level after an execCommand call was made
|
||||
editor.onExecCommand.add(function(ed, cmd, ui, val, args) {
|
||||
if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!args || !args.skip_undo)) {
|
||||
self.add();
|
||||
}
|
||||
});
|
||||
|
||||
// Add undo level on save contents, drag end and blur/focusout
|
||||
editor.onSaveContent.add(addNonTypingUndoLevel);
|
||||
editor.dom.bind(editor.dom.getRoot(), 'dragend', addNonTypingUndoLevel);
|
||||
editor.dom.bind(editor.getDoc(), tinymce.isGecko ? 'blur' : 'focusout', function(e) {
|
||||
if (!editor.removed && self.typing) {
|
||||
addNonTypingUndoLevel();
|
||||
}
|
||||
});
|
||||
|
||||
editor.onKeyUp.add(function(editor, e) {
|
||||
var keyCode = e.keyCode;
|
||||
|
||||
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45 || keyCode == 13 || e.ctrlKey) {
|
||||
addNonTypingUndoLevel();
|
||||
}
|
||||
});
|
||||
|
||||
editor.onKeyDown.add(function(editor, e) {
|
||||
var keyCode = e.keyCode;
|
||||
|
||||
// Is caracter positon keys left,right,up,down,home,end,pgdown,pgup,enter
|
||||
if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45) {
|
||||
if (self.typing) {
|
||||
addNonTypingUndoLevel();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// If key isn't shift,ctrl,alt,capslock,metakey
|
||||
if ((keyCode < 16 || keyCode > 20) && keyCode != 224 && keyCode != 91 && !self.typing) {
|
||||
self.beforeChange();
|
||||
self.typing = true;
|
||||
self.add();
|
||||
}
|
||||
});
|
||||
|
||||
editor.onMouseDown.add(function(editor, e) {
|
||||
if (self.typing) {
|
||||
addNonTypingUndoLevel();
|
||||
}
|
||||
});
|
||||
|
||||
// Add keyboard shortcuts for undo/redo keys
|
||||
editor.addShortcut('ctrl+z', 'undo_desc', 'Undo');
|
||||
editor.addShortcut('ctrl+y', 'redo_desc', 'Redo');
|
||||
|
||||
self = {
|
||||
// Explose for debugging reasons
|
||||
data : data,
|
||||
|
||||
typing : false,
|
||||
|
||||
onAdd : new Dispatcher(self),
|
||||
onAdd : onAdd,
|
||||
|
||||
onUndo : new Dispatcher(self),
|
||||
onUndo : onUndo,
|
||||
|
||||
onRedo : new Dispatcher(self),
|
||||
onRedo : onRedo,
|
||||
|
||||
beforeChange : function() {
|
||||
beforeBookmark = editor.selection.getBookmark(2, true);
|
||||
|
|
@ -14518,96 +15071,103 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
|
|||
return index < data.length - 1 && !this.typing;
|
||||
}
|
||||
};
|
||||
|
||||
return self;
|
||||
};
|
||||
})(tinymce);
|
||||
|
||||
tinymce.ForceBlocks = function(editor) {
|
||||
var settings = editor.settings, dom = editor.dom, selection = editor.selection, blockElements = editor.schema.getBlockElements();
|
||||
|
||||
// Force root blocks
|
||||
if (settings.forced_root_block) {
|
||||
function addRootBlocks() {
|
||||
var node = selection.getStart(), rootNode = editor.getBody(), rng, startContainer, startOffset, endContainer, endOffset, rootBlockNode, tempNode, offset = -0xFFFFFF;
|
||||
function addRootBlocks() {
|
||||
var node = selection.getStart(), rootNode = editor.getBody(), rng, startContainer, startOffset, endContainer, endOffset, rootBlockNode, tempNode, offset = -0xFFFFFF, wrapped;
|
||||
|
||||
if (!node || node.nodeType !== 1 || !settings.forced_root_block)
|
||||
if (!node || node.nodeType !== 1 || !settings.forced_root_block)
|
||||
return;
|
||||
|
||||
// Check if node is wrapped in block
|
||||
while (node && node != rootNode) {
|
||||
if (blockElements[node.nodeName])
|
||||
return;
|
||||
|
||||
// Check if node is wrapped in block
|
||||
while (node != rootNode) {
|
||||
if (blockElements[node.nodeName])
|
||||
return;
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
node = node.parentNode;
|
||||
// Get current selection
|
||||
rng = selection.getRng();
|
||||
if (rng.setStart) {
|
||||
startContainer = rng.startContainer;
|
||||
startOffset = rng.startOffset;
|
||||
endContainer = rng.endContainer;
|
||||
endOffset = rng.endOffset;
|
||||
} else {
|
||||
// Force control range into text range
|
||||
if (rng.item) {
|
||||
node = rng.item(0);
|
||||
rng = editor.getDoc().body.createTextRange();
|
||||
rng.moveToElementText(node);
|
||||
}
|
||||
|
||||
// Get current selection
|
||||
rng = selection.getRng();
|
||||
if (rng.setStart) {
|
||||
startContainer = rng.startContainer;
|
||||
startOffset = rng.startOffset;
|
||||
endContainer = rng.endContainer;
|
||||
endOffset = rng.endOffset;
|
||||
} else {
|
||||
// Force control range into text range
|
||||
if (rng.item) {
|
||||
node = rng.item(0);
|
||||
rng = editor.getDoc().body.createTextRange();
|
||||
rng.moveToElementText(node);
|
||||
}
|
||||
tmpRng = rng.duplicate();
|
||||
tmpRng.collapse(true);
|
||||
startOffset = tmpRng.move('character', offset) * -1;
|
||||
|
||||
if (!tmpRng.collapsed) {
|
||||
tmpRng = rng.duplicate();
|
||||
tmpRng.collapse(true);
|
||||
startOffset = tmpRng.move('character', offset) * -1;
|
||||
|
||||
if (!tmpRng.collapsed) {
|
||||
tmpRng = rng.duplicate();
|
||||
tmpRng.collapse(false);
|
||||
endOffset = (tmpRng.move('character', offset) * -1) - startOffset;
|
||||
}
|
||||
tmpRng.collapse(false);
|
||||
endOffset = (tmpRng.move('character', offset) * -1) - startOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap non block elements and text nodes
|
||||
for (node = rootNode.firstChild; node; node) {
|
||||
if (node.nodeType === 3 || (node.nodeType == 1 && !blockElements[node.nodeName])) {
|
||||
if (!rootBlockNode) {
|
||||
rootBlockNode = dom.create(settings.forced_root_block);
|
||||
node.parentNode.insertBefore(rootBlockNode, node);
|
||||
}
|
||||
|
||||
tempNode = node;
|
||||
node = node.nextSibling;
|
||||
rootBlockNode.appendChild(tempNode);
|
||||
} else {
|
||||
rootBlockNode = null;
|
||||
node = node.nextSibling;
|
||||
// Wrap non block elements and text nodes
|
||||
node = rootNode.firstChild;
|
||||
while (node) {
|
||||
if (node.nodeType === 3 || (node.nodeType == 1 && !blockElements[node.nodeName])) {
|
||||
if (!rootBlockNode) {
|
||||
rootBlockNode = dom.create(settings.forced_root_block);
|
||||
node.parentNode.insertBefore(rootBlockNode, node);
|
||||
wrapped = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (rng.setStart) {
|
||||
rng.setStart(startContainer, startOffset);
|
||||
rng.setEnd(endContainer, endOffset);
|
||||
selection.setRng(rng);
|
||||
tempNode = node;
|
||||
node = node.nextSibling;
|
||||
rootBlockNode.appendChild(tempNode);
|
||||
} else {
|
||||
try {
|
||||
rng = editor.getDoc().body.createTextRange();
|
||||
rng.moveToElementText(rootNode);
|
||||
rng.collapse(true);
|
||||
rng.moveStart('character', startOffset);
|
||||
|
||||
if (endOffset > 0)
|
||||
rng.moveEnd('character', endOffset);
|
||||
|
||||
rng.select();
|
||||
} catch (ex) {
|
||||
// Ignore
|
||||
}
|
||||
rootBlockNode = null;
|
||||
node = node.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
if (rng.setStart) {
|
||||
rng.setStart(startContainer, startOffset);
|
||||
rng.setEnd(endContainer, endOffset);
|
||||
selection.setRng(rng);
|
||||
} else {
|
||||
try {
|
||||
rng = editor.getDoc().body.createTextRange();
|
||||
rng.moveToElementText(rootNode);
|
||||
rng.collapse(true);
|
||||
rng.moveStart('character', startOffset);
|
||||
|
||||
if (endOffset > 0)
|
||||
rng.moveEnd('character', endOffset);
|
||||
|
||||
rng.select();
|
||||
} catch (ex) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
// Only trigger nodeChange when we wrapped nodes to prevent a forever loop
|
||||
if (wrapped) {
|
||||
editor.nodeChanged();
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// Force root blocks
|
||||
if (settings.forced_root_block) {
|
||||
editor.onKeyUp.add(addRootBlocks);
|
||||
editor.onClick.add(addRootBlocks);
|
||||
editor.onNodeChange.add(addRootBlocks);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -14703,6 +15263,8 @@ tinymce.ForceBlocks = function(editor) {
|
|||
if (v = ed.getParam('skin_variant'))
|
||||
s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);
|
||||
|
||||
s['class'] += ed.settings.directionality == "rtl" ? ' mceRtl' : '';
|
||||
|
||||
id = t.prefix + id;
|
||||
cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;
|
||||
c = t.controls[id] = new cls(id, s);
|
||||
|
|
@ -15121,20 +15683,8 @@ tinymce.ForceBlocks = function(editor) {
|
|||
MCE_ATTR_RE = /^(src|href|style)$/,
|
||||
FALSE = false,
|
||||
TRUE = true,
|
||||
undefined;
|
||||
|
||||
// Returns the content editable state of a node
|
||||
function getContentEditable(node) {
|
||||
var contentEditable = node.getAttribute("data-mce-contenteditable");
|
||||
|
||||
// Check for fake content editable
|
||||
if (contentEditable && contentEditable !== "inherit") {
|
||||
return contentEditable;
|
||||
}
|
||||
|
||||
// Check for real content editable
|
||||
return node.contentEditable !== "inherit" ? node.contentEditable : null;
|
||||
};
|
||||
undef,
|
||||
getContentEditable = dom.getContentEditable;
|
||||
|
||||
function isArray(obj) {
|
||||
return obj instanceof Array;
|
||||
|
|
@ -15148,6 +15698,103 @@ tinymce.ForceBlocks = function(editor) {
|
|||
return node.nodeType === 1 && node.id === '_mce_caret';
|
||||
};
|
||||
|
||||
function defaultFormats() {
|
||||
register({
|
||||
alignleft : [
|
||||
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}, defaultBlock: 'div'},
|
||||
{selector : 'img,table', collapsed : false, styles : {'float' : 'left'}}
|
||||
],
|
||||
|
||||
aligncenter : [
|
||||
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}, defaultBlock: 'div'},
|
||||
{selector : 'img', collapsed : false, styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}},
|
||||
{selector : 'table', collapsed : false, styles : {marginLeft : 'auto', marginRight : 'auto'}}
|
||||
],
|
||||
|
||||
alignright : [
|
||||
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}, defaultBlock: 'div'},
|
||||
{selector : 'img,table', collapsed : false, styles : {'float' : 'right'}}
|
||||
],
|
||||
|
||||
alignfull : [
|
||||
{selector : 'figure,p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'justify'}, defaultBlock: 'div'}
|
||||
],
|
||||
|
||||
bold : [
|
||||
{inline : 'strong', remove : 'all'},
|
||||
{inline : 'span', styles : {fontWeight : 'bold'}},
|
||||
{inline : 'b', remove : 'all'}
|
||||
],
|
||||
|
||||
italic : [
|
||||
{inline : 'em', remove : 'all'},
|
||||
{inline : 'span', styles : {fontStyle : 'italic'}},
|
||||
{inline : 'i', remove : 'all'}
|
||||
],
|
||||
|
||||
underline : [
|
||||
{inline : 'span', styles : {textDecoration : 'underline'}, exact : true},
|
||||
{inline : 'u', remove : 'all'}
|
||||
],
|
||||
|
||||
strikethrough : [
|
||||
{inline : 'span', styles : {textDecoration : 'line-through'}, exact : true},
|
||||
{inline : 'strike', remove : 'all'}
|
||||
],
|
||||
|
||||
forecolor : {inline : 'span', styles : {color : '%value'}, wrap_links : false},
|
||||
hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}, wrap_links : false},
|
||||
fontname : {inline : 'span', styles : {fontFamily : '%value'}},
|
||||
fontsize : {inline : 'span', styles : {fontSize : '%value'}},
|
||||
fontsize_class : {inline : 'span', attributes : {'class' : '%value'}},
|
||||
blockquote : {block : 'blockquote', wrapper : 1, remove : 'all'},
|
||||
subscript : {inline : 'sub'},
|
||||
superscript : {inline : 'sup'},
|
||||
|
||||
link : {inline : 'a', selector : 'a', remove : 'all', split : true, deep : true,
|
||||
onmatch : function(node) {
|
||||
return true;
|
||||
},
|
||||
|
||||
onformat : function(elm, fmt, vars) {
|
||||
each(vars, function(value, key) {
|
||||
dom.setAttrib(elm, key, value);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
removeformat : [
|
||||
{selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true},
|
||||
{selector : 'span', attributes : ['style', 'class'], remove : 'empty', split : true, expand : false, deep : true},
|
||||
{selector : '*', attributes : ['style', 'class'], split : false, expand : false, deep : true}
|
||||
]
|
||||
});
|
||||
|
||||
// Register default block formats
|
||||
each('p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp'.split(/\s/), function(name) {
|
||||
register(name, {block : name, remove : 'all'});
|
||||
});
|
||||
|
||||
// Register user defined formats
|
||||
register(ed.settings.formats);
|
||||
};
|
||||
|
||||
function addKeyboardShortcuts() {
|
||||
// Add some inline shortcuts
|
||||
ed.addShortcut('ctrl+b', 'bold_desc', 'Bold');
|
||||
ed.addShortcut('ctrl+i', 'italic_desc', 'Italic');
|
||||
ed.addShortcut('ctrl+u', 'underline_desc', 'Underline');
|
||||
|
||||
// BlockFormat shortcuts keys
|
||||
for (var i = 1; i <= 6; i++) {
|
||||
ed.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]);
|
||||
}
|
||||
|
||||
ed.addShortcut('ctrl+7', '', ['FormatBlock', false, 'p']);
|
||||
ed.addShortcut('ctrl+8', '', ['FormatBlock', false, 'div']);
|
||||
ed.addShortcut('ctrl+9', '', ['FormatBlock', false, 'address']);
|
||||
};
|
||||
|
||||
// Public functions
|
||||
|
||||
function get(name) {
|
||||
|
|
@ -15167,15 +15814,15 @@ tinymce.ForceBlocks = function(editor) {
|
|||
each(format, function(format) {
|
||||
// Set deep to false by default on selector formats this to avoid removing
|
||||
// alignment on images inside paragraphs when alignment is changed on paragraphs
|
||||
if (format.deep === undefined)
|
||||
if (format.deep === undef)
|
||||
format.deep = !format.selector;
|
||||
|
||||
// Default to true
|
||||
if (format.split === undefined)
|
||||
if (format.split === undef)
|
||||
format.split = !format.selector || format.inline;
|
||||
|
||||
// Default to true
|
||||
if (format.remove === undefined && format.selector && !format.inline)
|
||||
if (format.remove === undef && format.selector && !format.inline)
|
||||
format.remove = 'none';
|
||||
|
||||
// Mark format as a mixed format inline + block level
|
||||
|
|
@ -15248,7 +15895,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
function findSelectionEnd(start, end) {
|
||||
var walker = new TreeWalker(end);
|
||||
for (node = walker.current(); node; node = walker.prev()) {
|
||||
if (node.childNodes.length > 1 || node == start) {
|
||||
if (node.childNodes.length > 1 || node == start || node.tagName == 'BR') {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
|
@ -15260,7 +15907,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
var start = rng.startContainer;
|
||||
var end = rng.endContainer;
|
||||
|
||||
if (start != end && rng.endOffset == 0) {
|
||||
if (start != end && rng.endOffset === 0) {
|
||||
var newEnd = findSelectionEnd(start, end);
|
||||
var endOffset = newEnd.nodeType == 3 ? newEnd.length : newEnd.childNodes.length;
|
||||
|
||||
|
|
@ -15720,7 +16367,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
};
|
||||
|
||||
function removeRngStyle(rng) {
|
||||
var startContainer, endContainer;
|
||||
var startContainer, endContainer, node;
|
||||
|
||||
rng = expandRng(rng, formatList, TRUE);
|
||||
|
||||
|
|
@ -15729,6 +16376,12 @@ tinymce.ForceBlocks = function(editor) {
|
|||
endContainer = getContainer(rng);
|
||||
|
||||
if (startContainer != endContainer) {
|
||||
// WebKit will render the table incorrectly if we wrap a TD in a SPAN so lets see if the can use the first child instead
|
||||
// This will happen if you tripple click a table cell and use remove formatting
|
||||
if (/^(TR|TD)$/.test(startContainer.nodeName) && startContainer.firstChild) {
|
||||
startContainer = (startContainer.nodeName == "TD" ? startContainer.firstChild : startContainer.firstChild.firstChild) || startContainer;
|
||||
}
|
||||
|
||||
// Wrap start/end nodes in span element since these might be cloned/moved
|
||||
startContainer = wrap(startContainer, 'span', {id : '_start', 'data-mce-type' : 'bookmark'});
|
||||
endContainer = wrap(endContainer, 'span', {id : '_end', 'data-mce-type' : 'bookmark'});
|
||||
|
|
@ -15790,20 +16443,12 @@ tinymce.ForceBlocks = function(editor) {
|
|||
ed.nodeChanged();
|
||||
} else
|
||||
performCaretAction('remove', name, vars);
|
||||
|
||||
// Removed this logic since it breaks unit tests and produces empty caret elements since they will be destroyed in the cleanup process
|
||||
// Also there must be a better way to rerender a table and I couldn't reproduce the case causing this might be some old WebKit
|
||||
/*
|
||||
// When you remove formatting from a table cell in WebKit (cell, not the contents of a cell) there is a rendering issue with column width
|
||||
if (tinymce.isWebKit) {
|
||||
ed.execCommand('mceCleanup');
|
||||
}*/
|
||||
};
|
||||
|
||||
function toggle(name, vars, node) {
|
||||
var fmt = get(name);
|
||||
|
||||
if (match(name, vars, node) && (!('toggle' in fmt[0]) || fmt[0]['toggle']))
|
||||
if (match(name, vars, node) && (!('toggle' in fmt[0]) || fmt[0].toggle))
|
||||
remove(name, vars, node);
|
||||
else
|
||||
apply(name, vars, node);
|
||||
|
|
@ -15823,7 +16468,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
// Check all items
|
||||
if (items) {
|
||||
// Non indexed object
|
||||
if (items.length === undefined) {
|
||||
if (items.length === undef) {
|
||||
for (key in items) {
|
||||
if (items.hasOwnProperty(key)) {
|
||||
if (item_name === 'attributes')
|
||||
|
|
@ -15961,6 +16606,10 @@ tinymce.ForceBlocks = function(editor) {
|
|||
canApply : canApply
|
||||
});
|
||||
|
||||
// Initialize
|
||||
defaultFormats();
|
||||
addKeyboardShortcuts();
|
||||
|
||||
// Private functions
|
||||
|
||||
function matchName(node, format) {
|
||||
|
|
@ -16027,15 +16676,15 @@ tinymce.ForceBlocks = function(editor) {
|
|||
};
|
||||
|
||||
function expandRng(rng, format, remove) {
|
||||
var sibling, lastIdx, leaf,
|
||||
var sibling, lastIdx, leaf, endPoint,
|
||||
startContainer = rng.startContainer,
|
||||
startOffset = rng.startOffset,
|
||||
endContainer = rng.endContainer,
|
||||
endOffset = rng.endOffset, sibling, lastIdx, leaf, endPoint;
|
||||
endOffset = rng.endOffset;
|
||||
|
||||
// This function walks up the tree if there is no siblings before/after the node
|
||||
function findParentContainer(start) {
|
||||
var container, parent, child, sibling, siblingName;
|
||||
var container, parent, child, sibling, siblingName, root;
|
||||
|
||||
container = parent = start ? startContainer : endContainer;
|
||||
siblingName = start ? 'previousSibling' : 'nextSibling';
|
||||
|
|
@ -16075,7 +16724,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
// This function walks down the tree to find the leaf at the selection.
|
||||
// The offset is also returned as if node initially a leaf, the offset may be in the middle of the text node.
|
||||
function findLeaf(node, offset) {
|
||||
if (offset === undefined)
|
||||
if (offset === undef)
|
||||
offset = node.nodeType === 3 ? node.length : node.childNodes.length;
|
||||
while (node && node.hasChildNodes()) {
|
||||
node = node.childNodes[offset];
|
||||
|
|
@ -16118,6 +16767,125 @@ tinymce.ForceBlocks = function(editor) {
|
|||
return node;
|
||||
};
|
||||
|
||||
function findWordEndPoint(container, offset, start) {
|
||||
var walker, node, pos, lastTextNode;
|
||||
|
||||
function findSpace(node, offset) {
|
||||
var pos, pos2, str = node.nodeValue;
|
||||
|
||||
if (typeof(offset) == "undefined") {
|
||||
offset = start ? str.length : 0;
|
||||
}
|
||||
|
||||
if (start) {
|
||||
pos = str.lastIndexOf(' ', offset);
|
||||
pos2 = str.lastIndexOf('\u00a0', offset);
|
||||
pos = pos > pos2 ? pos : pos2;
|
||||
|
||||
// Include the space on remove to avoid tag soup
|
||||
if (pos !== -1 && !remove) {
|
||||
pos++;
|
||||
}
|
||||
} else {
|
||||
pos = str.indexOf(' ', offset);
|
||||
pos2 = str.indexOf('\u00a0', offset);
|
||||
pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2;
|
||||
}
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
if (container.nodeType === 3) {
|
||||
pos = findSpace(container, offset);
|
||||
|
||||
if (pos !== -1) {
|
||||
return {container : container, offset : pos};
|
||||
}
|
||||
|
||||
lastTextNode = container;
|
||||
}
|
||||
|
||||
// Walk the nodes inside the block
|
||||
walker = new TreeWalker(container, dom.getParent(container, isBlock) || ed.getBody());
|
||||
while (node = walker[start ? 'prev' : 'next']()) {
|
||||
if (node.nodeType === 3) {
|
||||
lastTextNode = node;
|
||||
pos = findSpace(node);
|
||||
|
||||
if (pos !== -1) {
|
||||
return {container : node, offset : pos};
|
||||
}
|
||||
} else if (isBlock(node)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastTextNode) {
|
||||
if (start) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = lastTextNode.length;
|
||||
}
|
||||
|
||||
return {container: lastTextNode, offset: offset};
|
||||
}
|
||||
};
|
||||
|
||||
function findSelectorEndPoint(container, sibling_name) {
|
||||
var parents, i, y, curFormat;
|
||||
|
||||
if (container.nodeType == 3 && container.nodeValue.length === 0 && container[sibling_name])
|
||||
container = container[sibling_name];
|
||||
|
||||
parents = getParents(container);
|
||||
for (i = 0; i < parents.length; i++) {
|
||||
for (y = 0; y < format.length; y++) {
|
||||
curFormat = format[y];
|
||||
|
||||
// If collapsed state is set then skip formats that doesn't match that
|
||||
if ("collapsed" in curFormat && curFormat.collapsed !== rng.collapsed)
|
||||
continue;
|
||||
|
||||
if (dom.is(parents[i], curFormat.selector))
|
||||
return parents[i];
|
||||
}
|
||||
}
|
||||
|
||||
return container;
|
||||
};
|
||||
|
||||
function findBlockEndPoint(container, sibling_name, sibling_name2) {
|
||||
var node;
|
||||
|
||||
// Expand to block of similar type
|
||||
if (!format[0].wrapper)
|
||||
node = dom.getParent(container, format[0].block);
|
||||
|
||||
// Expand to first wrappable block element or any block element
|
||||
if (!node)
|
||||
node = dom.getParent(container.nodeType == 3 ? container.parentNode : container, isBlock);
|
||||
|
||||
// Exclude inner lists from wrapping
|
||||
if (node && format[0].wrapper)
|
||||
node = getParents(node, 'ul,ol').reverse()[0] || node;
|
||||
|
||||
// Didn't find a block element look for first/last wrappable element
|
||||
if (!node) {
|
||||
node = container;
|
||||
|
||||
while (node[sibling_name] && !isBlock(node[sibling_name])) {
|
||||
node = node[sibling_name];
|
||||
|
||||
// Break on BR but include it will be removed later on
|
||||
// we can't remove it now since we need to check if it can be wrapped
|
||||
if (isEq(node, 'br'))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return node || container;
|
||||
};
|
||||
|
||||
// Expand to closest contentEditable element
|
||||
startContainer = findParentContentEditable(startContainer);
|
||||
endContainer = findParentContentEditable(endContainer);
|
||||
|
|
@ -16141,70 +16909,6 @@ tinymce.ForceBlocks = function(editor) {
|
|||
|
||||
if (format[0].inline) {
|
||||
if (rng.collapsed) {
|
||||
function findWordEndPoint(container, offset, start) {
|
||||
var walker, node, pos, lastTextNode;
|
||||
|
||||
function findSpace(node, offset) {
|
||||
var pos, pos2, str = node.nodeValue;
|
||||
|
||||
if (typeof(offset) == "undefined") {
|
||||
offset = start ? str.length : 0;
|
||||
}
|
||||
|
||||
if (start) {
|
||||
pos = str.lastIndexOf(' ', offset);
|
||||
pos2 = str.lastIndexOf('\u00a0', offset);
|
||||
pos = pos > pos2 ? pos : pos2;
|
||||
|
||||
// Include the space on remove to avoid tag soup
|
||||
if (pos !== -1 && !remove) {
|
||||
pos++;
|
||||
}
|
||||
} else {
|
||||
pos = str.indexOf(' ', offset);
|
||||
pos2 = str.indexOf('\u00a0', offset);
|
||||
pos = pos !== -1 && (pos2 === -1 || pos < pos2) ? pos : pos2;
|
||||
}
|
||||
|
||||
return pos;
|
||||
};
|
||||
|
||||
if (container.nodeType === 3) {
|
||||
pos = findSpace(container, offset);
|
||||
|
||||
if (pos !== -1) {
|
||||
return {container : container, offset : pos};
|
||||
}
|
||||
|
||||
lastTextNode = container;
|
||||
}
|
||||
|
||||
// Walk the nodes inside the block
|
||||
walker = new TreeWalker(container, dom.getParent(container, isBlock) || ed.getBody());
|
||||
while (node = walker[start ? 'prev' : 'next']()) {
|
||||
if (node.nodeType === 3) {
|
||||
lastTextNode = node;
|
||||
pos = findSpace(node);
|
||||
|
||||
if (pos !== -1) {
|
||||
return {container : node, offset : pos};
|
||||
}
|
||||
} else if (isBlock(node)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastTextNode) {
|
||||
if (start) {
|
||||
offset = 0;
|
||||
} else {
|
||||
offset = lastTextNode.length;
|
||||
}
|
||||
|
||||
return {container: lastTextNode, offset: offset};
|
||||
}
|
||||
}
|
||||
|
||||
// Expand left to closest word boundery
|
||||
endPoint = findWordEndPoint(startContainer, startOffset, true);
|
||||
if (endPoint) {
|
||||
|
|
@ -16232,9 +16936,6 @@ tinymce.ForceBlocks = function(editor) {
|
|||
if (leaf.offset > 1) {
|
||||
endContainer = leaf.node;
|
||||
endContainer.splitText(leaf.offset - 1);
|
||||
} else if (leaf.node.previousSibling) {
|
||||
// TODO: Figure out why this is in here
|
||||
//endContainer = leaf.node.previousSibling;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -16256,29 +16957,6 @@ tinymce.ForceBlocks = function(editor) {
|
|||
|
||||
// Expand start/end container to matching selector
|
||||
if (format[0].selector && format[0].expand !== FALSE && !format[0].inline) {
|
||||
function findSelectorEndPoint(container, sibling_name) {
|
||||
var parents, i, y, curFormat;
|
||||
|
||||
if (container.nodeType == 3 && container.nodeValue.length == 0 && container[sibling_name])
|
||||
container = container[sibling_name];
|
||||
|
||||
parents = getParents(container);
|
||||
for (i = 0; i < parents.length; i++) {
|
||||
for (y = 0; y < format.length; y++) {
|
||||
curFormat = format[y];
|
||||
|
||||
// If collapsed state is set then skip formats that doesn't match that
|
||||
if ("collapsed" in curFormat && curFormat.collapsed !== rng.collapsed)
|
||||
continue;
|
||||
|
||||
if (dom.is(parents[i], curFormat.selector))
|
||||
return parents[i];
|
||||
}
|
||||
}
|
||||
|
||||
return container;
|
||||
};
|
||||
|
||||
// Find new startContainer/endContainer if there is better one
|
||||
startContainer = findSelectorEndPoint(startContainer, 'previousSibling');
|
||||
endContainer = findSelectorEndPoint(endContainer, 'nextSibling');
|
||||
|
|
@ -16286,38 +16964,6 @@ tinymce.ForceBlocks = function(editor) {
|
|||
|
||||
// Expand start/end container to matching block element or text node
|
||||
if (format[0].block || format[0].selector) {
|
||||
function findBlockEndPoint(container, sibling_name, sibling_name2) {
|
||||
var node;
|
||||
|
||||
// Expand to block of similar type
|
||||
if (!format[0].wrapper)
|
||||
node = dom.getParent(container, format[0].block);
|
||||
|
||||
// Expand to first wrappable block element or any block element
|
||||
if (!node)
|
||||
node = dom.getParent(container.nodeType == 3 ? container.parentNode : container, isBlock);
|
||||
|
||||
// Exclude inner lists from wrapping
|
||||
if (node && format[0].wrapper)
|
||||
node = getParents(node, 'ul,ol').reverse()[0] || node;
|
||||
|
||||
// Didn't find a block element look for first/last wrappable element
|
||||
if (!node) {
|
||||
node = container;
|
||||
|
||||
while (node[sibling_name] && !isBlock(node[sibling_name])) {
|
||||
node = node[sibling_name];
|
||||
|
||||
// Break on BR but include it will be removed later on
|
||||
// we can't remove it now since we need to check if it can be wrapped
|
||||
if (isEq(node, 'br'))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return node || container;
|
||||
};
|
||||
|
||||
// Find new startContainer/endContainer if there is better one
|
||||
startContainer = findBlockEndPoint(startContainer, 'previousSibling');
|
||||
endContainer = findBlockEndPoint(endContainer, 'nextSibling');
|
||||
|
|
@ -16454,14 +17100,14 @@ tinymce.ForceBlocks = function(editor) {
|
|||
function removeNode(node, format) {
|
||||
var parentNode = node.parentNode, rootBlockElm;
|
||||
|
||||
function find(node, next, inc) {
|
||||
node = getNonWhiteSpaceSibling(node, next, inc);
|
||||
|
||||
return !node || (node.nodeName == 'BR' || isBlock(node));
|
||||
};
|
||||
|
||||
if (format.block) {
|
||||
if (!forcedRootBlock) {
|
||||
function find(node, next, inc) {
|
||||
node = getNonWhiteSpaceSibling(node, next, inc);
|
||||
|
||||
return !node || (node.nodeName == 'BR' || isBlock(node));
|
||||
};
|
||||
|
||||
// Append BR elements if needed before we remove the block
|
||||
if (isBlock(node) && !isBlock(parentNode)) {
|
||||
if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1))
|
||||
|
|
@ -16541,7 +17187,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
value = obj2[name];
|
||||
|
||||
// Obj2 doesn't have obj1 item
|
||||
if (value === undefined)
|
||||
if (value === undef)
|
||||
return FALSE;
|
||||
|
||||
// Obj2 item has a different value
|
||||
|
|
@ -16574,20 +17220,20 @@ tinymce.ForceBlocks = function(editor) {
|
|||
return TRUE;
|
||||
};
|
||||
|
||||
function findElementSibling(node, sibling_name) {
|
||||
for (sibling = node; sibling; sibling = sibling[sibling_name]) {
|
||||
if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0)
|
||||
return node;
|
||||
|
||||
if (sibling.nodeType == 1 && !isBookmarkNode(sibling))
|
||||
return sibling;
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
// Check if next/prev exists and that they are elements
|
||||
if (prev && next) {
|
||||
function findElementSibling(node, sibling_name) {
|
||||
for (sibling = node; sibling; sibling = sibling[sibling_name]) {
|
||||
if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0)
|
||||
return node;
|
||||
|
||||
if (sibling.nodeType == 1 && !isBookmarkNode(sibling))
|
||||
return sibling;
|
||||
}
|
||||
|
||||
return node;
|
||||
};
|
||||
|
||||
// If previous sibling is empty then jump over it
|
||||
prev = findElementSibling(prev, 'previousSibling');
|
||||
next = findElementSibling(next, 'nextSibling');
|
||||
|
|
@ -16641,7 +17287,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
}
|
||||
|
||||
// If end text node is excluded then walk to the previous node
|
||||
if (container.nodeType === 3 && !start && offset == 0) {
|
||||
if (container.nodeType === 3 && !start && offset === 0) {
|
||||
container = new TreeWalker(container, ed.getBody()).prev() || container;
|
||||
}
|
||||
|
||||
|
|
@ -16894,6 +17540,15 @@ tinymce.ForceBlocks = function(editor) {
|
|||
}
|
||||
});
|
||||
|
||||
// Remove bogus state if they got filled by contents using editor.selection.setContent
|
||||
selection.onSetContent.add(function() {
|
||||
dom.getParent(selection.getStart(), function(node) {
|
||||
if (node.id !== caretContainerId && dom.getAttrib(node, 'data-mce-bogus') && !dom.isEmpty(node)) {
|
||||
dom.setAttrib(node, 'data-mce-bogus', null);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
self._hasCaretEvents = true;
|
||||
}
|
||||
|
||||
|
|
@ -16907,14 +17562,15 @@ tinymce.ForceBlocks = function(editor) {
|
|||
|
||||
function moveStart(rng) {
|
||||
var container = rng.startContainer,
|
||||
offset = rng.startOffset,
|
||||
offset = rng.startOffset, isAtEndOfText,
|
||||
walker, node, nodes, tmpNode;
|
||||
|
||||
// Convert text node into index if possible
|
||||
if (container.nodeType == 3 && offset >= container.nodeValue.length) {
|
||||
// Get the parent container location and walk from there
|
||||
offset = nodeIndex(container);
|
||||
container = container.parentNode;
|
||||
offset = nodeIndex(container) + 1;
|
||||
isAtEndOfText = true;
|
||||
}
|
||||
|
||||
// Move startContainer/startOffset in to a suitable node
|
||||
|
|
@ -16924,7 +17580,7 @@ tinymce.ForceBlocks = function(editor) {
|
|||
walker = new TreeWalker(container, dom.getParent(container, dom.isBlock));
|
||||
|
||||
// If offset is at end of the parent node walk to the next one
|
||||
if (offset > nodes.length - 1)
|
||||
if (offset > nodes.length - 1 || isAtEndOfText)
|
||||
walker.next();
|
||||
|
||||
for (node = walker.current(); node; node = walker.next()) {
|
||||
|
|
@ -16950,25 +17606,35 @@ tinymce.ForceBlocks = function(editor) {
|
|||
tinymce.onAddEditor.add(function(tinymce, ed) {
|
||||
var filters, fontSizes, dom, settings = ed.settings;
|
||||
|
||||
function replaceWithSpan(node, styles) {
|
||||
tinymce.each(styles, function(value, name) {
|
||||
if (value)
|
||||
dom.setStyle(node, name, value);
|
||||
});
|
||||
|
||||
dom.rename(node, 'span');
|
||||
};
|
||||
|
||||
function convert(editor, params) {
|
||||
dom = editor.dom;
|
||||
|
||||
if (settings.convert_fonts_to_spans) {
|
||||
tinymce.each(dom.select('font,u,strike', params.node), function(node) {
|
||||
filters[node.nodeName.toLowerCase()](ed.dom, node);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (settings.inline_styles) {
|
||||
fontSizes = tinymce.explode(settings.font_size_legacy_values);
|
||||
|
||||
function replaceWithSpan(node, styles) {
|
||||
tinymce.each(styles, function(value, name) {
|
||||
if (value)
|
||||
dom.setStyle(node, name, value);
|
||||
});
|
||||
|
||||
dom.rename(node, 'span');
|
||||
};
|
||||
|
||||
filters = {
|
||||
font : function(dom, node) {
|
||||
replaceWithSpan(node, {
|
||||
backgroundColor : node.style.backgroundColor,
|
||||
color : node.color,
|
||||
fontFamily : node.face,
|
||||
fontSize : fontSizes[parseInt(node.size) - 1]
|
||||
fontSize : fontSizes[parseInt(node.size, 10) - 1]
|
||||
});
|
||||
},
|
||||
|
||||
|
|
@ -16985,16 +17651,6 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
}
|
||||
};
|
||||
|
||||
function convert(editor, params) {
|
||||
dom = editor.dom;
|
||||
|
||||
if (settings.convert_fonts_to_spans) {
|
||||
tinymce.each(dom.select('font,u,strike', params.node), function(node) {
|
||||
filters[node.nodeName.toLowerCase()](ed.dom, node);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ed.onPreProcess.add(convert);
|
||||
ed.onSetContent.add(convert);
|
||||
|
||||
|
|
@ -17011,16 +17667,21 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
var dom = editor.dom, selection = editor.selection, settings = editor.settings, undoManager = editor.undoManager;
|
||||
|
||||
function handleEnterKey(evt) {
|
||||
var rng = selection.getRng(true), tmpRng, container, offset, parentBlock, newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName;
|
||||
var rng = selection.getRng(true), tmpRng, editableRoot, container, offset, parentBlock, documentMode,
|
||||
newBlock, fragment, containerBlock, parentBlockName, containerBlockName, newBlockName, isAfterLastNodeInContainer;
|
||||
|
||||
// Returns true if the block can be split into two blocks or not
|
||||
function canSplitBlock(node) {
|
||||
return node && dom.isBlock(node) && !/^(TD|TH|CAPTION)$/.test(node.nodeName) && !/^(fixed|absolute)/i.test(node.style.position);
|
||||
return node &&
|
||||
dom.isBlock(node) &&
|
||||
!/^(TD|TH|CAPTION)$/.test(node.nodeName) &&
|
||||
!/^(fixed|absolute)/i.test(node.style.position) &&
|
||||
dom.getContentEditable(node) !== "true";
|
||||
};
|
||||
|
||||
// Moves the caret to a suitable position within the root for example in the first non pure whitespace text node or before an image
|
||||
function moveToCaretPosition(root) {
|
||||
var walker, node, rng, y, viewPort, lastNode = root;
|
||||
var walker, node, rng, y, viewPort, lastNode = root, tempElm;
|
||||
|
||||
rng = dom.createRng();
|
||||
|
||||
|
|
@ -17050,8 +17711,19 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
}
|
||||
} else {
|
||||
if (root.nodeName == 'BR') {
|
||||
rng.setStartAfter(root);
|
||||
rng.setEndAfter(root);
|
||||
if (root.nextSibling && dom.isBlock(root.nextSibling)) {
|
||||
// Trick on older IE versions to render the caret before the BR between two lists
|
||||
if (!documentMode || documentMode < 9) {
|
||||
tempElm = dom.create('br');
|
||||
root.parentNode.insertBefore(tempElm, root);
|
||||
}
|
||||
|
||||
rng.setStartBefore(root);
|
||||
rng.setEndBefore(root);
|
||||
} else {
|
||||
rng.setStartAfter(root);
|
||||
rng.setEndAfter(root);
|
||||
}
|
||||
} else {
|
||||
rng.setStart(root, 0);
|
||||
rng.setEnd(root, 0);
|
||||
|
|
@ -17060,6 +17732,9 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
|
||||
selection.setRng(rng);
|
||||
|
||||
// Remove tempElm created for old IE:s
|
||||
dom.remove(tempElm);
|
||||
|
||||
viewPort = dom.getViewPort(editor.getWin());
|
||||
|
||||
// scrollIntoView seems to scroll the parent window in most browsers now including FF 3.0b4 so it's time to stop using it and do it our selfs
|
||||
|
|
@ -17074,24 +17749,26 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
function createNewBlock(name) {
|
||||
var node = container, block, clonedNode, caretNode;
|
||||
|
||||
block = name ? dom.create(name) : parentBlock.cloneNode(false);
|
||||
block = name || parentBlockName == "TABLE" ? dom.create(name || newBlockName) : parentBlock.cloneNode(false);
|
||||
caretNode = block;
|
||||
|
||||
// Clone any parent styles
|
||||
do {
|
||||
if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) {
|
||||
clonedNode = node.cloneNode(false);
|
||||
dom.setAttrib(clonedNode, 'id', ''); // Remove ID since it needs to be document unique
|
||||
if (settings.keep_styles !== false) {
|
||||
do {
|
||||
if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) {
|
||||
clonedNode = node.cloneNode(false);
|
||||
dom.setAttrib(clonedNode, 'id', ''); // Remove ID since it needs to be document unique
|
||||
|
||||
if (block.hasChildNodes()) {
|
||||
clonedNode.appendChild(block.firstChild);
|
||||
block.appendChild(clonedNode);
|
||||
} else {
|
||||
caretNode = clonedNode;
|
||||
block.appendChild(clonedNode);
|
||||
if (block.hasChildNodes()) {
|
||||
clonedNode.appendChild(block.firstChild);
|
||||
block.appendChild(clonedNode);
|
||||
} else {
|
||||
caretNode = clonedNode;
|
||||
block.appendChild(clonedNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (node = node.parentNode);
|
||||
} while (node = node.parentNode);
|
||||
}
|
||||
|
||||
// BR is needed in empty blocks on non IE browsers
|
||||
if (!tinymce.isIE) {
|
||||
|
|
@ -17103,13 +17780,23 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
|
||||
// Returns true/false if the caret is at the start/end of the parent block element
|
||||
function isCaretAtStartOrEndOfBlock(start) {
|
||||
var walker, node;
|
||||
var walker, node, name;
|
||||
|
||||
// Caret is in the middle of a text node like "a|b"
|
||||
if (container.nodeType == 3 && (start ? offset > 0 : offset < container.nodeValue.length)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If after the last element in block node edge case for #5091
|
||||
if (container.parentNode == parentBlock && isAfterLastNodeInContainer && !start) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Caret can be before/after a table
|
||||
if (container.nodeName === "TABLE" || (container.previousSibling && container.previousSibling.nodeName == "TABLE")) {
|
||||
return (isAfterLastNodeInContainer && !start) || (!isAfterLastNodeInContainer && start);
|
||||
}
|
||||
|
||||
// Walk the DOM and look for text nodes or non empty elements
|
||||
walker = new TreeWalker(container, parentBlock);
|
||||
while (node = (start ? walker.prev() : walker.next())) {
|
||||
|
|
@ -17134,15 +17821,15 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
|
||||
// Wraps any text nodes or inline elements in the specified forced root block name
|
||||
function wrapSelfAndSiblingsInDefaultBlock(container, offset) {
|
||||
var newBlock, parentBlock, startNode, node, next;
|
||||
var newBlock, parentBlock, startNode, node, next, blockName = newBlockName || 'P';
|
||||
|
||||
// Not in a block element or in a table cell or caption
|
||||
parentBlock = dom.getParent(container, dom.isBlock);
|
||||
if (newBlockName && !evt.shiftKey && (!parentBlock || !canSplitBlock(parentBlock))) {
|
||||
parentBlock = parentBlock || dom.getRoot();
|
||||
if (!parentBlock || !canSplitBlock(parentBlock)) {
|
||||
parentBlock = parentBlock || editableRoot;
|
||||
|
||||
if (!parentBlock.hasChildNodes()) {
|
||||
newBlock = dom.create(newBlockName);
|
||||
newBlock = dom.create(blockName);
|
||||
parentBlock.appendChild(newBlock);
|
||||
rng.setStart(newBlock, 0);
|
||||
rng.setEnd(newBlock, 0);
|
||||
|
|
@ -17162,7 +17849,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
}
|
||||
|
||||
if (startNode) {
|
||||
newBlock = dom.create(newBlockName);
|
||||
newBlock = dom.create(blockName);
|
||||
startNode.parentNode.insertBefore(newBlock, startNode);
|
||||
|
||||
// Start wrapping until we hit a block
|
||||
|
|
@ -17241,7 +17928,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
|
||||
// Inserts a BR element if the forced_root_block option is set to false or empty string
|
||||
function insertBr() {
|
||||
var brElm, extraBr, documentMode;
|
||||
var brElm, extraBr;
|
||||
|
||||
if (container && container.nodeType == 3 && offset >= container.nodeValue.length) {
|
||||
// Insert extra BR element at the end block elements
|
||||
|
|
@ -17258,7 +17945,6 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
rng.insertNode(brElm);
|
||||
|
||||
// Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it
|
||||
documentMode = dom.doc.documentMode;
|
||||
if (tinymce.isIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) {
|
||||
brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm);
|
||||
}
|
||||
|
|
@ -17285,7 +17971,23 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
node = node.firstChild;
|
||||
} while (node);
|
||||
};
|
||||
|
||||
|
||||
function getEditableRoot(node) {
|
||||
var root = dom.getRoot(), parent, editableRoot;
|
||||
|
||||
// Get all parents until we hit a non editable parent or the root
|
||||
parent = node;
|
||||
while (parent !== root && dom.getContentEditable(parent) !== "false") {
|
||||
if (dom.getContentEditable(parent) === "true") {
|
||||
editableRoot = parent;
|
||||
}
|
||||
|
||||
parent = parent.parentNode;
|
||||
}
|
||||
|
||||
return parent !== root ? editableRoot : root;
|
||||
};
|
||||
|
||||
// Delete any selected contents
|
||||
if (!rng.collapsed) {
|
||||
editor.execCommand('Delete');
|
||||
|
|
@ -17302,18 +18004,40 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
offset = rng.startOffset;
|
||||
newBlockName = settings.forced_root_block;
|
||||
newBlockName = newBlockName ? newBlockName.toUpperCase() : '';
|
||||
documentMode = dom.doc.documentMode;
|
||||
|
||||
// Resolve node index
|
||||
if (container.nodeType == 1 && container.hasChildNodes()) {
|
||||
isAfterLastNodeInContainer = offset > container.childNodes.length - 1;
|
||||
container = container.childNodes[Math.min(offset, container.childNodes.length - 1)] || container;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
// Get editable root node normaly the body element but sometimes a div or span
|
||||
editableRoot = getEditableRoot(container);
|
||||
|
||||
// If there is no editable root then enter is done inside a contentEditable false element
|
||||
if (!editableRoot) {
|
||||
return;
|
||||
}
|
||||
|
||||
undoManager.beforeChange();
|
||||
|
||||
// If editable root isn't block nor the root of the editor
|
||||
if (!dom.isBlock(editableRoot) && editableRoot != dom.getRoot()) {
|
||||
if (!newBlockName || evt.shiftKey) {
|
||||
insertBr();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Wrap the current node and it's sibling in a default block if it's needed.
|
||||
// for example this <td>text|<b>text2</b></td> will become this <td><p>text|<b>text2</p></b></td>
|
||||
container = wrapSelfAndSiblingsInDefaultBlock(container, offset);
|
||||
// This won't happen if root blocks are disabled or the shiftKey is pressed
|
||||
if ((newBlockName && !evt.shiftKey) || (!newBlockName && evt.shiftKey)) {
|
||||
container = wrapSelfAndSiblingsInDefaultBlock(container, offset);
|
||||
}
|
||||
|
||||
// Find parent block and setup empty block paddings
|
||||
parentBlock = dom.getParent(container, dom.isBlock);
|
||||
|
|
@ -17394,3 +18118,4 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
|
|||
});
|
||||
};
|
||||
})(tinymce);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue