diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..003b03a15b610264f81227dc1e5cc5fce133d27e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.settings +.buildpath +.project diff --git a/.project b/.project deleted file mode 100644 index 00dbf3048f3a12a350592e7ba23ecc6b78576116..0000000000000000000000000000000000000000 --- a/.project +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<projectDescription> - <name>UNL_WDNTinyMCE</name> - <comment></comment> - <projects> - </projects> - <buildSpec> - <buildCommand> - <name>org.eclipse.wst.jsdt.core.javascriptValidator</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.wst.validation.validationbuilder</name> - <arguments> - </arguments> - </buildCommand> - <buildCommand> - <name>org.eclipse.dltk.core.scriptbuilder</name> - <arguments> - </arguments> - </buildCommand> - </buildSpec> - <natures> - <nature>org.eclipse.php.core.PHPNature</nature> - <nature>org.eclipse.wst.jsdt.core.jsNature</nature> - </natures> -</projectDescription> diff --git a/UNLexample.shtml b/UNLexample.shtml index 2ecb2617cea8026f709863dba8071a9f0469ea4d..db167781b6583c8ea8baa0f8907ee0e9948441db 100644 --- a/UNLexample.shtml +++ b/UNLexample.shtml @@ -9,16 +9,16 @@ <!--#include virtual="/wdn/templates_3.1/includes/metanfavico.html" --> <!-- Membership and regular participation in the UNL Web Developer Network - is required to use the UNL templates. Visit the WDN site at + is required to use the UNL templates. Visit the WDN site at http://wdn.unl.edu/. Click the WDN Registry link to log in and register your unl.edu site. All UNL template code is the property of the UNL Web Developer Network. - The code seen in a source code view is not, and may not be used as, a - template. You may not use this code, a reverse-engineered version of + The code seen in a source code view is not, and may not be used as, a + template. You may not use this code, a reverse-engineered version of this code, or its associated visual presentation in whole or in part to create a derivative work. This message may not be removed from any pages based on the UNL site template. - + $Id$ --> <!--#include virtual="/wdn/templates_3.1/includes/scriptsandstyles.html" --> @@ -31,7 +31,7 @@ <!-- tinymce stuff --> <script type="text/javascript"> -/* +/* * TinyMCE example usage with UNL templates */ @@ -98,41 +98,41 @@ The Title of My Site <nav id="breadcrumbs"> <!-- WDN: see glossary item 'breadcrumbs' --> <h3 class="wdn_list_descriptor hidden">Breadcrumbs</h3> - + <!-- InstanceBeginEditable name="breadcrumbs" --> <ul> <li><a href="http://www.unl.edu/" title="University of Nebraska–Lincoln">UNL</a></li> <li class="selected"><a href="#" title="Site Title">Site Title</a></li> <li>Page Title</li> </ul> - + <!-- InstanceEndEditable --> </nav> <div id="wdn_navigation_wrapper"> <nav id="navigation" role="navigation"> <h3 class="wdn_list_descriptor hidden">Navigation</h3> - + <!-- InstanceBeginEditable name="navlinks" --> <ul><li><a href="http://www.unl.edu/" title="UNL homepage">UNL</a></li></ul> - + <!-- InstanceEndEditable --> </nav> </div> </div> <div id="wdn_content_wrapper"> <div id="pagetitle"> - + <!-- InstanceBeginEditable name="pagetitle" --> <h1>This is your page title. It's now an <h1>, baby!</h1> - + <!-- InstanceEndEditable --> </div> <div id="maincontent" role="main"> <!--THIS IS THE MAIN CONTENT AREA; WDN: see glossary item 'main content area' --> - + <!-- InstanceBeginEditable name="maincontentarea" --> - - + + <form method="post" action="http://tinymce.moxiecode.com/dump.php?example=true"> @@ -155,7 +155,7 @@ The Title of My Site Nam nisi elit, cursus in rhoncus sit amet, pulvinar laoreet leo. Nam sed lectus quam, ut sagittis tellus. Quisque dignissim mauris a augue rutrum tempor. Donec vitae purus nec massa vestibulum ornare sit amet id tellus. Nunc quam mauris, fermentum nec lacinia eget, sollicitudin nec ante. Aliquam molestie volutpat dapibus. Nunc interdum viverra sodales. Morbi laoreet pulvinar gravida. Quisque ut turpis sagittis nunc accumsan vehicula. Duis elementum congue ultrices. Cras faucibus feugiat arcu quis lacinia. In hac habitasse platea dictumst. Pellentesque fermentum magna sit amet tellus varius ullamcorper. Vestibulum at urna augue, eget varius neque. Fusce facilisis venenatis dapibus. Integer non sem at arcu euismod tempor nec sed nisl. Morbi ultricies, mauris ut ultricies adipiscing, felis odio condimentum massa, et luctus est nunc nec eros. </p> </div> - + <div class="grid3"> <div class="zenbox"><h3>zenbox title</h3>this is text in a zenbox</div> </div> @@ -193,32 +193,32 @@ The Title of My Site <!--#include virtual="/wdn/templates_3.1/includes/feedback.html" --> </div> <div class="footer_col" id="wdn_footer_related"> - + <!-- InstanceBeginEditable name="leftcollinks" --> <h3>Related Links</h3> - + <!-- InstanceEndEditable --> </div> <div class="footer_col" id="wdn_footer_contact"> - + <!-- InstanceBeginEditable name="contactinfo" --> <h3>Contact Us</h3> - + <!-- InstanceEndEditable --> </div> <div class="footer_col" id="wdn_footer_share"> <!--#include virtual="/wdn/templates_3.1/includes/socialmediashare.html" --> </div> - + <!-- InstanceBeginEditable name="optionalfooter" --> - + <!-- InstanceEndEditable --> <div id="wdn_copyright"> <div> - + <!-- InstanceBeginEditable name="footercontent" --> © 2012 - + <!-- InstanceEndEditable --> <!--#include virtual="/wdn/templates_3.1/includes/wdn.html" --> </div> diff --git a/changelog.txt b/changelog.txt index 015a7d126dccc8a186b6c49e01a6002d87bad624..69b7ae50c7132c19b41b9e2629bd1f5c35b047a6 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,180 @@ +Version 3.5.8 (2012-11-20) + Fixed bug where html5 data attributes where stripped from contents. + Fixed bug where toolbar was annouced multiple times with JAWS on Firefox. + Fixed bug where the editor view whouldn't scroll to BR elements when using shift+enter or br enter mode. + Fixed bug where a JS error would be thrown when trying to paste table rows then the rows clipboard was empty. + Fixed bug with auto detection logic for youtube urls in the media plugin. + Fixed bug where the formatter would throw errors if you used the jQuery version of TinyMCE and the latest jQuery. + Fixed bug where the latest WebKit versions would produce span elements when deleting text between blocks. + Fixed bug where the autolink plugin would produce DOM exceptions when pressing shift+enter inside a block element. + Fixed bug where toggling of blockquotes when using br enter mode would produce an exception. + Fixed bug where focusing out of the body of the editor wouldn't properly add an undo level. + Fixed issue with warning message being displayed on IE 9+ about the meta header fix for IE 8. +Version 3.5.7 (2012-09-20) + Changed table row properties dialog to not update multiple rows when row type is header or footer. + Fixed bug in hyperlink dialog for IE9 where links with no target attr set had target value of -- + Changing toolbars to have a toolbar role for FF keyboard navigation works correctly. + Fixed bug where applying formatting to an empty block element would produce redundant spans. + Fixed bug where caret formatting on IE wouldn't properly apply if you pressed enter/return. + Fixed bug where loading TinyMCE using an async script wouldn't properly initialize editors. + Fixed bug where some white space would be removed after inline elements before block elements. + Fixed bug where it wouldn't properly parse attributes with a single backslash as it's contents. + Fixed bug where noscript elements would loose it's contents on older IE versions. + Fixed bug where backspace inside empty blockquote wouldn't delete it properly. + Fixed bug where custom elements with . in their names wouldn't work properly. + Fixed bug where the custom_elements option didn't properly setup the block elements schema structure. + Fixed bug where the custom_elements option didn't auto populate the extended_valid_elements. + Fixed bug where the whole TD element would get blcok formatted when there where BR elements in it. + Fixed bug where IE 9 might crash if the editor was hidden and specific styles where applied to surrounding contents. + Fixed bug where shift+enter inside a table cell on Gecko would produce an zero width non breaking space between tr:s. + Fixed bug where the advlink dialog wouldn't properly populate the anchors dropdown if the HTML5 schema was used. + Fixed issue with missing autofocus attribute on input element when using the HTML5 schema. + Fixed issue where enter inside a block contained within an LI element wouldn't produce a new LI. +Version 3.5.6 (2012-07-26) + Added "text" as a valid option to the editor.getContent format option. Makes it easier to get a text representation of the editor contents. + Fixed bug where resizing an image to less that 0x0 pixels would display the ghost image at an incorrect position. + Fixed bug where the remove format button would produce extra paragraphs on WebKit if all of the contents was selected. + Fixed issue where edge resize handles on images of wouldn't scale it with the same aspect ratio. + Fixed so force_p_newlines option works again since some users want mixed mode paragraphs. + Fixed so directionality plugin modifies the dir attribute of all selected blocks in the editor. + Fixed bug where backspace/delete of a custom element would move it's attributes to the parent block on Gecko. +Version 3.5.5 (2012-07-19) + Added full resize support for images and tables on WebKit/Opera. It now behaves just like Gecko. + Added automatic embed support for Vimeo, Stream.cz and Google Maps in media plugin. Patch contributed by Jakub Matas. + Fixed bug where the lists plugin wouldn't properly remove all li elements when toggling selected items of. Patched by Taku AMANO. + Fixed bug where the lists plugin would remove the entire list if you pressed deleted at the beginning of the first element. Patched by Taku AMANO. + Fixed bug where the ordered/unordered list buttons could both be enabled if you nested lists. Patch contributed by Craig Petchell. + Fixed bug where shift+enter wouldn't produce a BR in a LI when having forced_root_blocks set to false. + Fixed bug where scrollbars aren't visible in fullscreen when window is resized. + Fixed bug with updating the border size using the advimage dialog on IE 9. + Fixed bug where the selection of inner elements on IE 8 in contentEditable mode would select the whole parent element. + Fixed bug where the enter key would produce an empty anchor if you pressed it at the space after a link on IE. + Fixed bug where autolink plugin would produce an exception for specific html see bug #5365 + Fixed so the formatChanged function takes an optional "similar" parameter to use while matching the format. +Version 3.5.4.1 (2012-06-24) + Fixed issue with Shift+A selecting all contents on Chrome. +Version 3.5.4 (2012-06-21) + Added missing mouse events to HTML5 schema. Some events needs to be manually defined though since the spec is huge. + Added image resizing for WebKit browsers by faking the whole resize behavior. + Fixed bug in context menu plugin where listener to hide menu wasn't removed correctly. + Fixed bug where media plugin wouldn't use placeholder size for the object/video elements. + Fixed bug where jQuery plugin would break attr function in jQuery 1.7.2. + Fixed bug where jQuery plugin would throw an error if you used the tinymce pseudo selector when TinyMCE wasn't loaded. + Fixed so encoding option gets applied when using jQuery val() or attr() to extract the contents. + Fixed so any non valid width/height passed to media plugin would get parsed to proper integer or percent values. +Version 3.5.3 (2012-06-19) + Added missing wbr element to HTML5 schema. + Added new mceToggleFormat command. Enabled you to toggle a specific format on/off. + Fixed bug where undo/redo state didn't update correctly after executing an execCommand call. + Fixed bug where the editor would get auto focused on IE running in quirks mode. + Fixed bug where pressing enter before an IMG or INPUT element wouldn't properly split the block. + Fixed bug where backspace would navigate back when selecting control types on IE. + Fixed bug where the editor remove method would unbind events for controls outside the editor instance UI. + Fixed bug where the autosave plugin would try to store a draft copy of editors that where removed. + Fixed bug where floated elements wouldn't expand the block created when pressing enter on non IE browsers. + Fixed bug where the caret would be placed in the wrong location when pressing enter at the beginning of a block. + Fixed bug where it wasn't possible to block events using the handle_event_callback option. + Fixed bug where keyboard navigation of the ColorSplitButton.js didn't work correctly. + Fixed bug where keyboard navigation didn't work correctly on split buttons. + Fixed bug where the legacy Event.add function didn't properly handle multiple id:s passed in. + Fixed bug where the caret would disappear on IE when selecting all contents and pressing backspace/delete. + Fixed bug where the getStart/getEnd methods would sometimes return elements from the wrong document on IE. + Fixed so paragraphs gets created if you press enter inside a form element. +Version 3.5.2 (2012-05-31) + Added new formatChanged method to tinymce.Formatter class. Enables easier state change handling of formats. + Added new selectorChanged method to tinymce.dom.Selection class. Enables easier state change handling of matching CSS selectors. + Changed the default theme to be advanced instead of simple since most users uses the advanced theme. + Changed so the theme_advanced_buttons doesn't have a default set if one button row is specified. + Changed the theme_advanced_toolbar_align default value to "left". + Changed the theme_advanced_toolbar_location default value to "top". + Changed the theme_advanced_statusbar_location default value to "bottom". + Fixed bug where the simple link dialog would remove class and target attributes from links when updating them if the drop downs wasn't visible. + Fixed bug where the link/unlink buttons wouldn't get disabled once a link was created by the autolink plugin logic. + Fixed bug where the border attribute was missing in the HTML5 schema. + Fixed bug where the legacyoutput plugin would use inline styles for font color. + Fixed bug where editing of anchor names wouldn't produce an undo level. + Fixed bug where the table plugin would delete the last empty block element in the editor. + Fixed bug where pasting table rows when they where selected would make it impossible to editor that table row. + Fixed bug with pressing enter in IE while having a select list focused would produce a JS error. + Fixed bug where it wasn't possible to merge table cells by selecting them and using merge from context menu. + Removed summary from HTML5 table attributes and fixed so this and other deprecated table fields gets hidden in the table dialog. +Version 3.5.1.1 (2012-05-25) + Fixed bug with control creation where plugin specific controls didn't work as expected. +Version 3.5.1 (2012-05-25) + Added new onBeforeAdd event to UndoManager patch contributed by Dan Rumney. + Added support for overriding the theme rendering logic by using a custom function. + Fixed bug where links wasn't automatically created by the autolink plugin on old IE versions when pressing enter in BR mode. + Fixed bug where enter on older IE versions wouldn't produce a new paragraph if the previous sibling paragraph was empty. + Fixed bug where toString on a faked DOM range on older IE versions wouldn't return a proper string. + Fixed bug where named anchors wouldn't work properly when schema was set to HTML5. + Fixed bug where HTML5 datalist options wasn't correctly parsed or indented. + Fixed bug where linking would add anchors around block elements when the HTML5 schema was used. + Fixed issue where the autolink plugin wouldn't properly handle mailto:user@domain.com. + Optimized initialization and reduced rendering flicker by hiding the target element while initializing. +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. @@ -298,1201 +475,3 @@ Version 3.4 (2011-03-10) 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. diff --git a/examples/full.html b/examples/full.html index 39c2060b2c235a7b19b5782bae5897c8ed2f04f5..84b76ca7a15129d09900812f0c3cf04f277f7f98 100644 --- a/examples/full.html +++ b/examples/full.html @@ -10,13 +10,13 @@ // General options mode : "textareas", theme : "advanced", - plugins : "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,advlist,autosave", + plugins : "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,advlist,autosave,visualblocks", // Theme options theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect", theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor", theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen", - theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak,restoredraft", + theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak,restoredraft,visualblocks", theme_advanced_toolbar_location : "top", theme_advanced_toolbar_align : "left", theme_advanced_statusbar_location : "bottom", diff --git a/examples/index.html b/examples/index.html index 6ebfbea574bf069060492de99bf5001ed6ebb832..6a735cf86a6956aa436da82b87d8fad24d6eecea 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,10 +1,98 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd"> -<html> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> <head> - <title>TinyMCE examples</title> +<title>Full featured example using jQuery plugin</title> + +<!-- Load jQuery --> +<script type="text/javascript" src="http://www.google.com/jsapi"></script> +<script type="text/javascript"> + google.load("jquery", "1"); +</script> + +<!-- Load TinyMCE --> +<script type="text/javascript" src="../jscripts/tiny_mce/jquery.tinymce.js"></script> +<script type="text/javascript"> + $().ready(function() { + $('textarea.tinymce').tinymce({ + // Location of TinyMCE script + script_url : '../jscripts/tiny_mce/tiny_mce.js', + + // General options + theme : "advanced", + plugins : "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,advlist", + + // Theme options + theme_advanced_buttons1 : "save,newdocument,|,bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,styleselect,formatselect,fontselect,fontsizeselect", + theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code,|,insertdate,inserttime,preview,|,forecolor,backcolor", + theme_advanced_buttons3 : "tablecontrols,|,hr,removeformat,visualaid,|,sub,sup,|,charmap,emotions,iespell,media,advhr,|,print,|,ltr,rtl,|,fullscreen", + theme_advanced_buttons4 : "insertlayer,moveforward,movebackward,absolute,|,styleprops,|,cite,abbr,acronym,del,ins,attribs,|,visualchars,nonbreaking,template,pagebreak", + theme_advanced_toolbar_location : "top", + theme_advanced_toolbar_align : "left", + theme_advanced_statusbar_location : "bottom", + theme_advanced_resizing : true, + + // Example content CSS (should be your site CSS) + content_css : "css/content.css", + + // Drop lists for link/image/media/template dialogs + template_external_list_url : "lists/template_list.js", + external_link_list_url : "lists/link_list.js", + external_image_list_url : "lists/image_list.js", + media_external_list_url : "lists/media_list.js", + + // Replace values for the template plugin + template_replace_values : { + username : "Some User", + staffid : "991234" + } + }); + }); +</script> +<!-- /TinyMCE --> + </head> -<frameset cols="180,80%"> - <frame src="menu.html" name="menu" /> - <frame src="full.html" name="main" /> -</frameset> +<body> + +<form method="post" action="http://tinymce.moxiecode.com/dump.php?example=true"> + <div> + <h3>Full featured example using jQuery plugin</h3> + + <p> + This example shows how TinyMCE can be lazy loaded using jQuery. The jQuery plugin will also attach it's self to various jQuery methods to make it more easy to get/set editor contents etc. + </p> + + <!-- Gets replaced with TinyMCE, remember HTML in a textarea should be encoded --> + <div> + <textarea id="elm1" name="elm1" rows="15" cols="80" style="width: 80%" class="tinymce"> + <p> + This is some example text that you can edit inside the <strong>TinyMCE editor</strong>. + </p> + <p> + Nam nisi elit, cursus in rhoncus sit amet, pulvinar laoreet leo. Nam sed lectus quam, ut sagittis tellus. Quisque dignissim mauris a augue rutrum tempor. Donec vitae purus nec massa vestibulum ornare sit amet id tellus. Nunc quam mauris, fermentum nec lacinia eget, sollicitudin nec ante. Aliquam molestie volutpat dapibus. Nunc interdum viverra sodales. Morbi laoreet pulvinar gravida. Quisque ut turpis sagittis nunc accumsan vehicula. Duis elementum congue ultrices. Cras faucibus feugiat arcu quis lacinia. In hac habitasse platea dictumst. Pellentesque fermentum magna sit amet tellus varius ullamcorper. Vestibulum at urna augue, eget varius neque. Fusce facilisis venenatis dapibus. Integer non sem at arcu euismod tempor nec sed nisl. Morbi ultricies, mauris ut ultricies adipiscing, felis odio condimentum massa, et luctus est nunc nec eros. + </p> + </textarea> + </div> + + <!-- Some integration calls --> + <a href="javascript:;" onclick="$('#elm1').tinymce().show();return false;">[Show]</a> + <a href="javascript:;" onclick="$('#elm1').tinymce().hide();return false;">[Hide]</a> + <a href="javascript:;" onclick="$('#elm1').tinymce().execCommand('Bold');return false;">[Bold]</a> + <a href="javascript:;" onclick="alert($('#elm1').html());return false;">[Get contents]</a> + <a href="javascript:;" onclick="alert($('#elm1').tinymce().selection.getContent());return false;">[Get selected HTML]</a> + <a href="javascript:;" onclick="alert($('#elm1').tinymce().selection.getContent({format : 'text'}));return false;">[Get selected text]</a> + <a href="javascript:;" onclick="alert($('#elm1').tinymce().selection.getNode().nodeName);return false;">[Get selected element]</a> + <a href="javascript:;" onclick="$('#elm1').tinymce().execCommand('mceInsertContent',false,'<b>Hello world!!</b>');return false;">[Insert HTML]</a> + <a href="javascript:;" onclick="$('#elm1').tinymce().execCommand('mceReplaceContent',false,'<b>{$selection}</b>');return false;">[Replace selection]</a> + + <br /> + <input type="submit" name="save" value="Submit" /> + <input type="reset" name="reset" value="Reset" /> + </div> +</form> +<script type="text/javascript"> +if (document.location.protocol == 'file:') { + alert("The examples might not work properly on the local file system due to security settings in your browser. Please use a real webserver."); +} +</script> +</body> </html> diff --git a/examples/lists/media_list.js b/examples/lists/media_list.js index 79b3f1bfe0afbc3014cfc368f3d8e14a6569248d..2e049587cb51af913666b5dae68f7122a6d85dc2 100644 --- a/examples/lists/media_list.js +++ b/examples/lists/media_list.js @@ -10,5 +10,5 @@ var tinyMCEMediaList = [ ["Some RealMedia", "media/sample.rm"], ["Some Shockwave", "media/sample.dcr"], ["Some Video", "media/sample.mp4"], - ["Some FLV", "media/sample.flv"], + ["Some FLV", "media/sample.flv"] ]; \ No newline at end of file diff --git a/jquery.tinymce.js b/jquery.tinymce.js index 3d1e8eb79858a60d7fede6279fb55d5fb6b1132a..b4d0c3977a8fa921af4b907aceffdd2a95fd90ec 100644 --- a/jquery.tinymce.js +++ b/jquery.tinymce.js @@ -1 +1 @@ -(function(b){var e,d,a=[],c=window;b.fn.tinymce=function(j){var p=this,g,k,h,m,i,l="",n="";if(!p.length){return p}if(!j){return tinyMCE.get(p[0].id)}function o(){var r=[],q=0;if(f){f();f=null}p.each(function(t,u){var s,w=u.id,v=j.oninit;if(!w){u.id=w=tinymce.DOM.uniqueId()}s=new tinymce.Editor(w,j);r.push(s);if(v){s.onInit.add(function(){var x,y=v;if(++q==r.length){if(tinymce.is(y,"string")){x=(y.indexOf(".")===-1)?null:tinymce.resolve(y.replace(/\.\w+$/,""));y=tinymce.resolve(y)}y.apply(x||tinymce,r)}})}});b.each(r,function(t,s){s.render()})}if(!c.tinymce&&!d&&(g=j.script_url)){d=1;h=g.substring(0,g.lastIndexOf("/"));if(/_(src|dev)\.js/g.test(g)){n="_src"}m=g.lastIndexOf("?");if(m!=-1){l=g.substring(m+1)}c.tinyMCEPreInit=c.tinyMCEPreInit||{base:h,suffix:n,query:l};if(g.indexOf("gzip")!=-1){i=j.language||"en";g=g+(/\?/.test(g)?"&":"?")+"js=true&core=true&suffix="+escape(n)+"&themes="+escape(j.theme)+"&plugins="+escape(j.plugins)+"&languages="+i;if(!c.tinyMCE_GZ){tinyMCE_GZ={start:function(){tinymce.suffix=n;function q(r){tinymce.ScriptLoader.markDone(tinyMCE.baseURI.toAbsolute(r))}q("langs/"+i+".js");q("themes/"+j.theme+"/editor_template"+n+".js");q("themes/"+j.theme+"/langs/"+i+".js");b.each(j.plugins.split(","),function(s,r){if(r){q("plugins/"+r+"/editor_plugin"+n+".js");q("plugins/"+r+"/langs/"+i+".js")}})},end:function(){}}}}b.ajax({type:"GET",url:g,dataType:"script",cache:true,success:function(){tinymce.dom.Event.domLoaded=1;d=2;if(j.script_loaded){j.script_loaded()}o();b.each(a,function(q,r){r()})}})}else{if(d===1){a.push(o)}else{o()}}return p};b.extend(b.expr[":"],{tinymce:function(g){return g.id&&!!tinyMCE.get(g.id)}});function f(){function i(l){if(l==="remove"){this.each(function(n,o){var m=h(o);if(m){m.remove()}})}this.find("span.mceEditor,div.mceEditor").each(function(n,o){var m=tinyMCE.get(o.id.replace(/_parent$/,""));if(m){m.remove()}})}function k(n){var m=this,l;if(n!==e){i.call(m);m.each(function(p,q){var o;if(o=tinyMCE.get(q.id)){o.setContent(n)}})}else{if(m.length>0){if(l=tinyMCE.get(m[0].id)){return l.getContent()}}}}function h(m){var l=null;(m)&&(m.id)&&(c.tinymce)&&(l=tinyMCE.get(m.id));return l}function g(l){return !!((l)&&(l.length)&&(c.tinymce)&&(l.is(":tinymce")))}var j={};b.each(["text","html","val"],function(n,l){var o=j[l]=b.fn[l],m=(l==="text");b.fn[l]=function(s){var p=this;if(!g(p)){return o.apply(p,arguments)}if(s!==e){k.call(p.filter(":tinymce"),s);o.apply(p.not(":tinymce"),arguments);return p}else{var r="";var q=arguments;(m?p:p.eq(0)).each(function(u,v){var t=h(v);r+=t?(m?t.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):t.getContent()):o.apply(b(v),q)});return r}}});b.each(["append","prepend"],function(n,m){var o=j[m]=b.fn[m],l=(m==="prepend");b.fn[m]=function(q){var p=this;if(!g(p)){return o.apply(p,arguments)}if(q!==e){p.filter(":tinymce").each(function(s,t){var r=h(t);r&&r.setContent(l?q+r.getContent():r.getContent()+q)});o.apply(p.not(":tinymce"),arguments);return p}}});b.each(["remove","replaceWith","replaceAll","empty"],function(m,l){var n=j[l]=b.fn[l];b.fn[l]=function(){i.call(this,l);return n.apply(this,arguments)}});j.attr=b.fn.attr;b.fn.attr=function(n,q,o){var m=this;if((!n)||(n!=="value")||(!g(m))){return j.attr.call(m,n,q,o)}if(q!==e){k.call(m.filter(":tinymce"),q);j.attr.call(m.not(":tinymce"),n,q,o);return m}else{var p=m[0],l=h(p);return l?l.getContent():j.attr.call(b(p),n,q,o)}}}})(WDN.jQuery); \ No newline at end of file +(function(c){var b,e,a=[],d=window;c.fn.tinymce=function(j){var p=this,g,k,h,m,i,l="",n="";if(!p.length){return p}if(!j){return tinyMCE.get(p[0].id)}p.css("visibility","hidden");function o(){var r=[],q=0;if(f){f();f=null}p.each(function(t,u){var s,w=u.id,v=j.oninit;if(!w){u.id=w=tinymce.DOM.uniqueId()}s=new tinymce.Editor(w,j);r.push(s);s.onInit.add(function(){var x,y=v;p.css("visibility","");if(v){if(++q==r.length){if(tinymce.is(y,"string")){x=(y.indexOf(".")===-1)?null:tinymce.resolve(y.replace(/\.\w+$/,""));y=tinymce.resolve(y)}y.apply(x||tinymce,r)}}})});c.each(r,function(t,s){s.render()})}if(!d.tinymce&&!e&&(g=j.script_url)){e=1;h=g.substring(0,g.lastIndexOf("/"));if(/_(src|dev)\.js/g.test(g)){n="_src"}m=g.lastIndexOf("?");if(m!=-1){l=g.substring(m+1)}d.tinyMCEPreInit=d.tinyMCEPreInit||{base:h,suffix:n,query:l};if(g.indexOf("gzip")!=-1){i=j.language||"en";g=g+(/\?/.test(g)?"&":"?")+"js=true&core=true&suffix="+escape(n)+"&themes="+escape(j.theme)+"&plugins="+escape(j.plugins)+"&languages="+i;if(!d.tinyMCE_GZ){tinyMCE_GZ={start:function(){tinymce.suffix=n;function q(r){tinymce.ScriptLoader.markDone(tinyMCE.baseURI.toAbsolute(r))}q("langs/"+i+".js");q("themes/"+j.theme+"/editor_template"+n+".js");q("themes/"+j.theme+"/langs/"+i+".js");c.each(j.plugins.split(","),function(s,r){if(r){q("plugins/"+r+"/editor_plugin"+n+".js");q("plugins/"+r+"/langs/"+i+".js")}})},end:function(){}}}}c.ajax({type:"GET",url:g,dataType:"script",cache:true,success:function(){tinymce.dom.Event.domLoaded=1;e=2;if(j.script_loaded){j.script_loaded()}o();c.each(a,function(q,r){r()})}})}else{if(e===1){a.push(o)}else{o()}}return p};c.extend(c.expr[":"],{tinymce:function(g){return !!(g.id&&"tinyMCE" in window&&tinyMCE.get(g.id))}});function f(){function i(l){if(l==="remove"){this.each(function(n,o){var m=h(o);if(m){m.remove()}})}this.find("span.mceEditor,div.mceEditor").each(function(n,o){var m=tinyMCE.get(o.id.replace(/_parent$/,""));if(m){m.remove()}})}function k(n){var m=this,l;if(n!==b){i.call(m);m.each(function(p,q){var o;if(o=tinyMCE.get(q.id)){o.setContent(n)}})}else{if(m.length>0){if(l=tinyMCE.get(m[0].id)){return l.getContent()}}}}function h(m){var l=null;(m)&&(m.id)&&(d.tinymce)&&(l=tinyMCE.get(m.id));return l}function g(l){return !!((l)&&(l.length)&&(d.tinymce)&&(l.is(":tinymce")))}var j={};c.each(["text","html","val"],function(n,l){var o=j[l]=c.fn[l],m=(l==="text");c.fn[l]=function(s){var p=this;if(!g(p)){return o.apply(p,arguments)}if(s!==b){k.call(p.filter(":tinymce"),s);o.apply(p.not(":tinymce"),arguments);return p}else{var r="";var q=arguments;(m?p:p.eq(0)).each(function(u,v){var t=h(v);r+=t?(m?t.getContent().replace(/<(?:"[^"]*"|'[^']*'|[^'">])*>/g,""):t.getContent({save:true})):o.apply(c(v),q)});return r}}});c.each(["append","prepend"],function(n,m){var o=j[m]=c.fn[m],l=(m==="prepend");c.fn[m]=function(q){var p=this;if(!g(p)){return o.apply(p,arguments)}if(q!==b){p.filter(":tinymce").each(function(s,t){var r=h(t);r&&r.setContent(l?q+r.getContent():r.getContent()+q)});o.apply(p.not(":tinymce"),arguments);return p}}});c.each(["remove","replaceWith","replaceAll","empty"],function(m,l){var n=j[l]=c.fn[l];c.fn[l]=function(){i.call(this,l);return n.apply(this,arguments)}});j.attr=c.fn.attr;c.fn.attr=function(o,q){var m=this,n=arguments;if((!o)||(o!=="value")||(!g(m))){if(q!==b){return j.attr.apply(m,n)}else{return j.attr.apply(m,n)}}if(q!==b){k.call(m.filter(":tinymce"),q);j.attr.apply(m.not(":tinymce"),n);return m}else{var p=m[0],l=h(p);return l?l.getContent({save:true}):j.attr.apply(c(p),n)}}}})(jQuery); \ No newline at end of file diff --git a/langs/en.js b/langs/en.js index 6379b0d9584d39b33c028c2e4d37aa16711e8d65..19324f74cd36bffdbfa93cdb359be351255a4dc1 100644 --- a/langs/en.js +++ b/langs/en.js @@ -1 +1 @@ -tinyMCE.addI18n({en:{common:{"more_colors":"More Colors...","invalid_data":"Error: Invalid values entered, these are marked in red.","popup_blocked":"Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool.","clipboard_no_support":"Currently not supported by your browser, use keyboard shortcuts instead.","clipboard_msg":"Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?","not_set":"-- Not Set --","class_name":"Class",browse:"Browse",close:"Close",cancel:"Cancel",update:"Update",insert:"Insert",apply:"Apply","edit_confirm":"Do you want to use the WYSIWYG mode for this textarea?","invalid_data_number":"{#field} must be a number","invalid_data_min":"{#field} must be a number greater than {#min}","invalid_data_size":"{#field} must be a number or percentage",value:"(value)"},contextmenu:{full:"Full",right:"Right",center:"Center",left:"Left",align:"Alignment"},insertdatetime:{"day_short":"Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun","day_long":"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday","months_short":"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec","months_long":"January,February,March,April,May,June,July,August,September,October,November,December","inserttime_desc":"Insert Time","insertdate_desc":"Insert Date","time_fmt":"%H:%M:%S","date_fmt":"%Y-%m-%d"},print:{"print_desc":"Print"},preview:{"preview_desc":"Preview"},directionality:{"rtl_desc":"Direction Right to Left","ltr_desc":"Direction Left to Right"},layer:{content:"New layer...","absolute_desc":"Toggle Absolute Positioning","backward_desc":"Move Backward","forward_desc":"Move Forward","insertlayer_desc":"Insert New Layer"},save:{"save_desc":"Save","cancel_desc":"Cancel All Changes"},nonbreaking:{"nonbreaking_desc":"Insert Non-Breaking Space Character"},iespell:{download:"ieSpell not detected. Do you want to install it now?","iespell_desc":"Check Spelling"},advhr:{"delta_height":"","delta_width":"","advhr_desc":"Insert Horizontal Line"},emotions:{"delta_height":"","delta_width":"","emotions_desc":"Emotions"},searchreplace:{"replace_desc":"Find/Replace","delta_width":"","delta_height":"","search_desc":"Find"},advimage:{"delta_width":"","image_desc":"Insert/Edit Image","delta_height":""},advlink:{"delta_height":"","delta_width":"","link_desc":"Insert/Edit Link"},xhtmlxtras:{"attribs_delta_height":"","attribs_delta_width":"","ins_delta_height":"","ins_delta_width":"","del_delta_height":"","del_delta_width":"","acronym_delta_height":"","acronym_delta_width":"","abbr_delta_height":"","abbr_delta_width":"","cite_delta_height":"","cite_delta_width":"","attribs_desc":"Insert/Edit Attributes","ins_desc":"Insertion","del_desc":"Deletion","acronym_desc":"Acronym","abbr_desc":"Abbreviation","cite_desc":"Citation"},style:{"delta_height":"","delta_width":"",desc:"Edit CSS Style"},paste:{"plaintext_mode_stick":"Paste is now in plain text mode. Click again to toggle back to regular paste mode.","plaintext_mode":"Paste is now in plain text mode. Click again to toggle back to regular paste mode. After you paste something you will be returned to regular paste mode.","selectall_desc":"Select All","paste_word_desc":"Paste from Word","paste_text_desc":"Paste as Plain Text"},"paste_dlg":{"word_title":"Use Ctrl+V on your keyboard to paste the text into the window.","text_linebreaks":"Keep Linebreaks","text_title":"Use Ctrl+V on your keyboard to paste the text into the window."},table:{"merge_cells_delta_height":"","merge_cells_delta_width":"","table_delta_height":"","table_delta_width":"","cellprops_delta_height":"","cellprops_delta_width":"","rowprops_delta_height":"","rowprops_delta_width":"",cell:"Cell",col:"Column",row:"Row",del:"Delete Table","copy_row_desc":"Copy Table Row","cut_row_desc":"Cut Table Row","paste_row_after_desc":"Paste Table Row After","paste_row_before_desc":"Paste Table Row Before","props_desc":"Table Properties","cell_desc":"Table Cell Properties","row_desc":"Table Row Properties","merge_cells_desc":"Merge Table Cells","split_cells_desc":"Split Merged Table Cells","delete_col_desc":"Delete Column","col_after_desc":"Insert Column After","col_before_desc":"Insert Column Before","delete_row_desc":"Delete Row","row_after_desc":"Insert Row After","row_before_desc":"Insert Row Before",desc:"Insert/Edit Table"},autosave:{"warning_message":"If you restore the saved content, you will lose all the content that is currently in the editor.\n\nAre you sure you want to restore the saved content?","restore_content":"Restore auto-saved content.","unload_msg":"The changes you made will be lost if you navigate away from this page."},fullscreen:{desc:"Toggle Full Screen Mode"},media:{"delta_height":"","delta_width":"",edit:"Edit Embedded Media",desc:"Insert/Edit Embedded Media"},fullpage:{desc:"Document Properties","delta_width":"","delta_height":""},template:{desc:"Insert Predefined Template Content"},visualchars:{desc:"Show/Hide Visual Control Characters"},spellchecker:{desc:"Toggle Spell Checker",menu:"Spell Checker Settings","ignore_word":"Ignore Word","ignore_words":"Ignore All",langs:"Languages",wait:"Please wait...",sug:"Suggestions","no_sug":"No Suggestions","no_mpell":"No misspellings found.","learn_word":"Learn word"},pagebreak:{desc:"Insert Page Break for Printing"},advlist:{types:"Types",def:"Default","lower_alpha":"Lower Alpha","lower_greek":"Lower Greek","lower_roman":"Lower Roman","upper_alpha":"Upper Alpha","upper_roman":"Upper Roman",circle:"Circle",disc:"Disc",square:"Square"},colors:{"333300":"Dark olive","993300":"Burnt orange","000000":"Black","003300":"Dark green","003366":"Dark azure","000080":"Navy Blue","333399":"Indigo","333333":"Very dark gray","800000":"Maroon",FF6600:"Orange","808000":"Olive","008000":"Green","008080":"Teal","0000FF":"Blue","666699":"Grayish blue","808080":"Gray",FF0000:"Red",FF9900:"Amber","99CC00":"Yellow green","339966":"Sea green","33CCCC":"Turquoise","3366FF":"Royal blue","800080":"Purple","999999":"Medium gray",FF00FF:"Magenta",FFCC00:"Gold",FFFF00:"Yellow","00FF00":"Lime","00FFFF":"Aqua","00CCFF":"Sky blue","993366":"Brown",C0C0C0:"Silver",FF99CC:"Pink",FFCC99:"Peach",FFFF99:"Light yellow",CCFFCC:"Pale green",CCFFFF:"Pale cyan","99CCFF":"Light sky blue",CC99FF:"Plum",FFFFFF:"White"},aria:{"rich_text_area":"Rich Text Area"},wordcount:{words:"Words:"}}}); \ No newline at end of file +tinyMCE.addI18n({en:{common:{"more_colors":"More Colors...","invalid_data":"Error: Invalid values entered, these are marked in red.","popup_blocked":"Sorry, but we have noticed that your popup-blocker has disabled a window that provides application functionality. You will need to disable popup blocking on this site in order to fully utilize this tool.","clipboard_no_support":"Currently not supported by your browser, use keyboard shortcuts instead.","clipboard_msg":"Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?","not_set":"-- Not Set --","class_name":"Class",browse:"Browse",close:"Close",cancel:"Cancel",update:"Update",insert:"Insert",apply:"Apply","edit_confirm":"Do you want to use the WYSIWYG mode for this textarea?","invalid_data_number":"{#field} must be a number","invalid_data_min":"{#field} must be a number greater than {#min}","invalid_data_size":"{#field} must be a number or percentage",value:"(value)"},contextmenu:{full:"Full",right:"Right",center:"Center",left:"Left",align:"Alignment"},insertdatetime:{"day_short":"Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun","day_long":"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday","months_short":"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec","months_long":"January,February,March,April,May,June,July,August,September,October,November,December","inserttime_desc":"Insert Time","insertdate_desc":"Insert Date","time_fmt":"%H:%M:%S","date_fmt":"%Y-%m-%d"},print:{"print_desc":"Print"},preview:{"preview_desc":"Preview"},directionality:{"rtl_desc":"Direction Right to Left","ltr_desc":"Direction Left to Right"},layer:{content:"New layer...","absolute_desc":"Toggle Absolute Positioning","backward_desc":"Move Backward","forward_desc":"Move Forward","insertlayer_desc":"Insert New Layer"},save:{"save_desc":"Save","cancel_desc":"Cancel All Changes"},nonbreaking:{"nonbreaking_desc":"Insert Non-Breaking Space Character"},iespell:{download:"ieSpell not detected. Do you want to install it now?","iespell_desc":"Check Spelling"},advhr:{"delta_height":"","delta_width":"","advhr_desc":"Insert Horizontal Line"},emotions:{"delta_height":"","delta_width":"","emotions_desc":"Emotions"},searchreplace:{"replace_desc":"Find/Replace","delta_width":"","delta_height":"","search_desc":"Find"},advimage:{"delta_width":"","image_desc":"Insert/Edit Image","delta_height":""},advlink:{"delta_height":"","delta_width":"","link_desc":"Insert/Edit Link"},xhtmlxtras:{"attribs_delta_height":"","attribs_delta_width":"","ins_delta_height":"","ins_delta_width":"","del_delta_height":"","del_delta_width":"","acronym_delta_height":"","acronym_delta_width":"","abbr_delta_height":"","abbr_delta_width":"","cite_delta_height":"","cite_delta_width":"","attribs_desc":"Insert/Edit Attributes","ins_desc":"Insertion","del_desc":"Deletion","acronym_desc":"Acronym","abbr_desc":"Abbreviation","cite_desc":"Citation"},style:{"delta_height":"","delta_width":"",desc:"Edit CSS Style"},paste:{"plaintext_mode_stick":"Paste is now in plain text mode. Click again to toggle back to regular paste mode.","plaintext_mode":"Paste is now in plain text mode. Click again to toggle back to regular paste mode. After you paste something you will be returned to regular paste mode.","selectall_desc":"Select All","paste_word_desc":"Paste from Word","paste_text_desc":"Paste as Plain Text"},"paste_dlg":{"word_title":"Use Ctrl+V on your keyboard to paste the text into the window.","text_linebreaks":"Keep Linebreaks","text_title":"Use Ctrl+V on your keyboard to paste the text into the window."},table:{"merge_cells_delta_height":"","merge_cells_delta_width":"","table_delta_height":"","table_delta_width":"","cellprops_delta_height":"","cellprops_delta_width":"","rowprops_delta_height":"","rowprops_delta_width":"",cell:"Cell",col:"Column",row:"Row",del:"Delete Table","copy_row_desc":"Copy Table Row","cut_row_desc":"Cut Table Row","paste_row_after_desc":"Paste Table Row After","paste_row_before_desc":"Paste Table Row Before","props_desc":"Table Properties","cell_desc":"Table Cell Properties","row_desc":"Table Row Properties","merge_cells_desc":"Merge Table Cells","split_cells_desc":"Split Merged Table Cells","delete_col_desc":"Delete Column","col_after_desc":"Insert Column After","col_before_desc":"Insert Column Before","delete_row_desc":"Delete Row","row_after_desc":"Insert Row After","row_before_desc":"Insert Row Before",desc:"Insert/Edit Table"},autosave:{"warning_message":"If you restore the saved content, you will lose all the content that is currently in the editor.\n\nAre you sure you want to restore the saved content?","restore_content":"Restore auto-saved content.","unload_msg":"The changes you made will be lost if you navigate away from this page."},fullscreen:{desc:"Toggle Full Screen Mode"},media:{"delta_height":"","delta_width":"",edit:"Edit Embedded Media",desc:"Insert/Edit Embedded Media"},fullpage:{desc:"Document Properties","delta_width":"","delta_height":""},template:{desc:"Insert Predefined Template Content"},visualchars:{desc:"Show/Hide Visual Control Characters"},spellchecker:{desc:"Toggle Spell Checker",menu:"Spell Checker Settings","ignore_word":"Ignore Word","ignore_words":"Ignore All",langs:"Languages",wait:"Please wait...",sug:"Suggestions","no_sug":"No Suggestions","no_mpell":"No misspellings found.","learn_word":"Learn word"},pagebreak:{desc:"Insert Page Break for Printing"},advlist:{types:"Types",def:"Default","lower_alpha":"Lower Alpha","lower_greek":"Lower Greek","lower_roman":"Lower Roman","upper_alpha":"Upper Alpha","upper_roman":"Upper Roman",circle:"Circle",disc:"Disc",square:"Square"},colors:{"333300":"Dark olive","993300":"Burnt orange","000000":"Black","003300":"Dark green","003366":"Dark azure","000080":"Navy Blue","333399":"Indigo","333333":"Very dark gray","800000":"Maroon",FF6600:"Orange","808000":"Olive","008000":"Green","008080":"Teal","0000FF":"Blue","666699":"Grayish blue","808080":"Gray",FF0000:"Red",FF9900:"Amber","99CC00":"Yellow green","339966":"Sea green","33CCCC":"Turquoise","3366FF":"Royal blue","800080":"Purple","999999":"Medium gray",FF00FF:"Magenta",FFCC00:"Gold",FFFF00:"Yellow","00FF00":"Lime","00FFFF":"Aqua","00CCFF":"Sky blue","993366":"Brown",C0C0C0:"Silver",FF99CC:"Pink",FFCC99:"Peach",FFFF99:"Light yellow",CCFFCC:"Pale green",CCFFFF:"Pale cyan","99CCFF":"Light sky blue",CC99FF:"Plum",FFFFFF:"White"},aria:{"rich_text_area":"Rich Text Area"},wordcount:{words:"Words:"},visualblocks:{desc:'Show/hide block elements'}}}); \ No newline at end of file diff --git a/plugins/advimage/js/image.js b/plugins/advimage/js/image.js index 0dec9dc839ffff75d080591afc039f4431eafbe8..f0b7c6eef58ce254a70697e9190c2a4768a0ee6d 100644 --- a/plugins/advimage/js/image.js +++ b/plugins/advimage/js/image.js @@ -314,13 +314,8 @@ var ImageDialog = { var f = document.forms[0]; if (!st) { - // Start UNL Change! - - // By default, we don't want width and height specified. - //f.elements.width.value = img.width; - //f.elements.height.value = img.height; - - // END UNL Change! + f.elements.width.value = img.width; + f.elements.height.value = img.height; } this.preloadImg = img; @@ -400,12 +395,14 @@ var ImageDialog = { if (v == '0') img.style.border = isIE ? '0' : '0 none none'; else { - if (b.length == 3 && b[isIE ? 2 : 1]) - bStyle = b[isIE ? 2 : 1]; + var isOldIE = tinymce.isIE && (!document.documentMode || document.documentMode < 9); + + if (b.length == 3 && b[isOldIE ? 2 : 1]) + bStyle = b[isOldIE ? 2 : 1]; else if (!bStyle || bStyle == 'none') bStyle = 'solid'; if (b.length == 3 && b[isIE ? 0 : 2]) - bColor = b[isIE ? 0 : 2]; + bColor = b[isOldIE ? 0 : 2]; else if (!bColor || bColor == 'none') bColor = 'black'; img.style.border = v + 'px ' + bStyle + ' ' + bColor; diff --git a/plugins/advlink/js/advlink.js b/plugins/advlink/js/advlink.js index 703138fa554e91640d4806ce16d987fe749bb3a0..f013aac1e71f27320598f89d57bd1c936fc6aaaf 100644 --- a/plugins/advlink/js/advlink.js +++ b/plugins/advlink/js/advlink.js @@ -64,13 +64,14 @@ function init() { if (elm != null && elm.nodeName == "A") action = "update"; - formObj.insert.value = tinyMCEPopup.getLang(action, 'Insert', true); + formObj.insert.value = tinyMCEPopup.getLang(action, 'Insert', true); setPopupControlsDisabled(true); if (action == "update") { var href = inst.dom.getAttrib(elm, 'href'); var onclick = inst.dom.getAttrib(elm, 'onclick'); + var linkTarget = inst.dom.getAttrib(elm, 'target') ? inst.dom.getAttrib(elm, 'target') : "_self"; // Setup form data setFormValue('href', href); @@ -98,7 +99,7 @@ function init() { setFormValue('onkeypress', inst.dom.getAttrib(elm, 'onkeypress')); setFormValue('onkeydown', inst.dom.getAttrib(elm, 'onkeydown')); setFormValue('onkeyup', inst.dom.getAttrib(elm, 'onkeyup')); - setFormValue('target', inst.dom.getAttrib(elm, 'target')); + setFormValue('target', linkTarget); setFormValue('classes', inst.dom.getAttrib(elm, 'class')); // Parse onclick data @@ -119,7 +120,7 @@ function init() { addClassesToList('classlist', 'advlink_styles'); selectByValue(formObj, 'classlist', inst.dom.getAttrib(elm, 'class'), true); - selectByValue(formObj, 'targetlist', inst.dom.getAttrib(elm, 'target'), true); + selectByValue(formObj, 'targetlist', linkTarget, true); } else addClassesToList('classlist', 'advlink_styles'); } @@ -377,6 +378,9 @@ function getAnchorListHTML(id, target) { for (i=0, len=nodes.length; i<len; i++) { if ((name = ed.dom.getAttrib(nodes[i], "name")) != "") html += '<option value="#' + name + '">' + name + '</option>'; + + if ((name = nodes[i].id) != "" && !nodes[i].href) + html += '<option value="#' + name + '">' + name + '</option>'; } if (html == "") @@ -488,7 +492,7 @@ function getLinkListHTML(elm_id, target_form_element, onchange_func) { var html = ""; html += '<select id="' + elm_id + '" name="' + elm_id + '"'; - html += ' class="mceLinkList" onfoc2us="tinyMCE.addSelectAccessibility(event, this, window);" onchange="this.form.' + target_form_element + '.value='; + html += ' class="mceLinkList" onchange="this.form.' + target_form_element + '.value='; html += 'this.options[this.selectedIndex].value;'; if (typeof(onchange_func) != "undefined") @@ -510,7 +514,7 @@ function getTargetListHTML(elm_id, target_form_element) { var targets = tinyMCEPopup.getParam('theme_advanced_link_targets', '').split(';'); var html = ''; - html += '<select id="' + elm_id + '" name="' + elm_id + '" onfocus="tinyMCE.addSelectAccessibility(event, this, window);" onchange="this.form.' + target_form_element + '.value='; + html += '<select id="' + elm_id + '" name="' + elm_id + '" onchange="this.form.' + target_form_element + '.value='; html += 'this.options[this.selectedIndex].value;">'; html += '<option value="_self">' + tinyMCEPopup.getLang('advlink_dlg.target_same') + '</option>'; html += '<option value="_blank">' + tinyMCEPopup.getLang('advlink_dlg.target_blank') + ' (_blank)</option>'; diff --git a/plugins/autolink/editor_plugin.js b/plugins/autolink/editor_plugin.js index fd293dca4b0c1bfa408a18009babd313e28b17cd..71d86bbecbc57552cb95d39195e54af3dce3fc3c 100644 --- a/plugins/autolink/editor_plugin.js +++ b/plugins/autolink/editor_plugin.js @@ -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\.)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}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)})(); \ No newline at end of file +(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}if(n.nodeType==3){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?f-2:0);a.setEnd(n,f>=1?f-1:0);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\.|(?:mailto:)?[A-Z0-9._%+-]+@)(.+)$/i);if(h){if(h[1]=="www."){h[1]="http://www."}else{if(/@$/.test(h[1])&&!/^mailto:/.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);i.nodeChanged();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)})(); \ No newline at end of file diff --git a/plugins/autolink/editor_plugin_src.js b/plugins/autolink/editor_plugin_src.js index 604da8b42d93ef0b4243db5cf8927bf4cf6a3830..5b61f7a20b16a4e6f91e761cc6b81f9860d9afc2 100644 --- a/plugins/autolink/editor_plugin_src.js +++ b/plugins/autolink/editor_plugin_src.js @@ -22,15 +22,15 @@ 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) { + 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) @@ -61,7 +61,7 @@ // 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(); + 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. @@ -89,8 +89,11 @@ while (endContainer.nodeType != 3 && endContainer.firstChild) endContainer = endContainer.firstChild; - r.setStart(endContainer, 0); - r.setEnd(endContainer, endContainer.nodeValue.length); + // Move range to text node + if (endContainer.nodeType == 3) { + r.setStart(endContainer, 0); + r.setEnd(endContainer, endContainer.nodeValue.length); + } } if (r.endOffset == 1) @@ -104,8 +107,8 @@ do { // Move the selection one character backwards. - r.setStart(endContainer, end - 2); - r.setEnd(endContainer, end - 1); + r.setStart(endContainer, end >= 2 ? end - 2 : 0); + r.setEnd(endContainer, end >= 1 ? end - 1 : 0); end -= 1; // Loop until one of the following is found: a blank space, , delimeter, (end-2) >= 0 @@ -124,12 +127,20 @@ 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\.)(.+)$/i); + matches = text.match(/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+-]+@)(.+)$/i); if (matches) { if (matches[1] == 'www.') { matches[1] = 'http://www.'; + } else if (/@$/.test(matches[1]) && !/^mailto:/.test(matches[1])) { + matches[1] = 'mailto:' + matches[1]; } bookmark = ed.selection.getBookmark(); @@ -137,6 +148,7 @@ ed.selection.setRng(r); tinyMCE.execCommand('createlink',false, matches[1] + matches[2]); ed.selection.moveToBookmark(bookmark); + ed.nodeChanged(); // TODO: Determine if this is still needed. if (tinyMCE.isWebKit) { diff --git a/plugins/autosave/editor_plugin.js b/plugins/autosave/editor_plugin.js index f7d0576008dfeac3297e4fcb3d384d25cd3247ee..6da98ff33a0503382a26f72564c969ee019f92b0 100644 --- a/plugins/autosave/editor_plugin.js +++ b/plugins/autosave/editor_plugin.js @@ -1 +1 @@ -(function(e){var c="autosave",g="restoredraft",b=true,f,d,a=e.util.Dispatcher;e.create("tinymce.plugins.AutoSave",{init:function(i,j){var h=this,l=i.settings;h.editor=i;function k(n){var m={s:1000,m:60000};n=/^(\d+)([ms]?)$/.exec(""+n);return(n[2]?m[n[2]]:1)*parseInt(n)}e.each({ask_before_unload:b,interval:"30s",retention:"20m",minlength:50},function(n,m){m=c+"_"+m;if(l[m]===f){l[m]=n}});l.autosave_interval=k(l.autosave_interval);l.autosave_retention=k(l.autosave_retention);i.addButton(g,{title:c+".restore_content",onclick:function(){if(i.getContent({draft:true}).replace(/\s| |<\/?p[^>]*>|<br[^>]*>/gi,"").length>0){i.windowManager.confirm(c+".warning_message",function(m){if(m){h.restoreDraft()}})}else{h.restoreDraft()}}});i.onNodeChange.add(function(){var m=i.controlManager;if(m.get(g)){m.setDisabled(g,!h.hasDraft())}});i.onInit.add(function(){if(i.controlManager.get(g)){h.setupStorage(i);setInterval(function(){h.storeDraft();i.nodeChanged()},l.autosave_interval)}});h.onStoreDraft=new a(h);h.onRestoreDraft=new a(h);h.onRemoveDraft=new a(h);if(!d){window.onbeforeunload=e.plugins.AutoSave._beforeUnloadHandler;d=b}},getInfo:function(){return{longname:"Auto save",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave",version:e.majorVersion+"."+e.minorVersion}},getExpDate:function(){return new Date(new Date().getTime()+this.editor.settings.autosave_retention).toUTCString()},setupStorage:function(i){var h=this,k=c+"_test",j="OK";h.key=c+i.id;e.each([function(){if(localStorage){localStorage.setItem(k,j);if(localStorage.getItem(k)===j){localStorage.removeItem(k);return localStorage}}},function(){if(sessionStorage){sessionStorage.setItem(k,j);if(sessionStorage.getItem(k)===j){sessionStorage.removeItem(k);return sessionStorage}}},function(){if(e.isIE){i.getElement().style.behavior="url('#default#userData')";return{autoExpires:b,setItem:function(l,n){var m=i.getElement();m.setAttribute(l,n);m.expires=h.getExpDate();try{m.save("TinyMCE")}catch(o){}},getItem:function(l){var m=i.getElement();try{m.load("TinyMCE");return m.getAttribute(l)}catch(n){return null}},removeItem:function(l){i.getElement().removeAttribute(l)}}}},],function(l){try{h.storage=l();if(h.storage){return false}}catch(m){}})},storeDraft:function(){var i=this,l=i.storage,j=i.editor,h,k;if(l){if(!l.getItem(i.key)&&!j.isDirty()){return}k=j.getContent({draft:true});if(k.length>j.settings.autosave_minlength){h=i.getExpDate();if(!i.storage.autoExpires){i.storage.setItem(i.key+"_expires",h)}i.storage.setItem(i.key,k);i.onStoreDraft.dispatch(i,{expires:h,content:k})}}},restoreDraft:function(){var h=this,j=h.storage,i;if(j){i=j.getItem(h.key);if(i){h.editor.setContent(i);h.onRestoreDraft.dispatch(h,{content:i})}}},hasDraft:function(){var h=this,k=h.storage,i,j;if(k){j=!!k.getItem(h.key);if(j){if(!h.storage.autoExpires){i=new Date(k.getItem(h.key+"_expires"));if(new Date().getTime()<i.getTime()){return b}h.removeDraft()}else{return b}}}return false},removeDraft:function(){var h=this,k=h.storage,i=h.key,j;if(k){j=k.getItem(i);k.removeItem(i);k.removeItem(i+"_expires");if(j){h.onRemoveDraft.dispatch(h,{content:j})}}},"static":{_beforeUnloadHandler:function(h){var i;e.each(tinyMCE.editors,function(j){if(j.plugins.autosave){j.plugins.autosave.storeDraft()}if(j.getParam("fullscreen_is_enabled")){return}if(!i&&j.isDirty()&&j.getParam("autosave_ask_before_unload")){i=j.getLang("autosave.unload_msg")}});return i}}});e.PluginManager.add("autosave",e.plugins.AutoSave)})(tinymce); \ No newline at end of file +(function(e){var c="autosave",g="restoredraft",b=true,f,d,a=e.util.Dispatcher;e.create("tinymce.plugins.AutoSave",{init:function(i,j){var h=this,l=i.settings;h.editor=i;function k(n){var m={s:1000,m:60000};n=/^(\d+)([ms]?)$/.exec(""+n);return(n[2]?m[n[2]]:1)*parseInt(n)}e.each({ask_before_unload:b,interval:"30s",retention:"20m",minlength:50},function(n,m){m=c+"_"+m;if(l[m]===f){l[m]=n}});l.autosave_interval=k(l.autosave_interval);l.autosave_retention=k(l.autosave_retention);i.addButton(g,{title:c+".restore_content",onclick:function(){if(i.getContent({draft:true}).replace(/\s| |<\/?p[^>]*>|<br[^>]*>/gi,"").length>0){i.windowManager.confirm(c+".warning_message",function(m){if(m){h.restoreDraft()}})}else{h.restoreDraft()}}});i.onNodeChange.add(function(){var m=i.controlManager;if(m.get(g)){m.setDisabled(g,!h.hasDraft())}});i.onInit.add(function(){if(i.controlManager.get(g)){h.setupStorage(i);setInterval(function(){if(!i.removed){h.storeDraft();i.nodeChanged()}},l.autosave_interval)}});h.onStoreDraft=new a(h);h.onRestoreDraft=new a(h);h.onRemoveDraft=new a(h);if(!d){window.onbeforeunload=e.plugins.AutoSave._beforeUnloadHandler;d=b}},getInfo:function(){return{longname:"Auto save",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/autosave",version:e.majorVersion+"."+e.minorVersion}},getExpDate:function(){return new Date(new Date().getTime()+this.editor.settings.autosave_retention).toUTCString()},setupStorage:function(i){var h=this,k=c+"_test",j="OK";h.key=c+i.id;e.each([function(){if(localStorage){localStorage.setItem(k,j);if(localStorage.getItem(k)===j){localStorage.removeItem(k);return localStorage}}},function(){if(sessionStorage){sessionStorage.setItem(k,j);if(sessionStorage.getItem(k)===j){sessionStorage.removeItem(k);return sessionStorage}}},function(){if(e.isIE){i.getElement().style.behavior="url('#default#userData')";return{autoExpires:b,setItem:function(l,n){var m=i.getElement();m.setAttribute(l,n);m.expires=h.getExpDate();try{m.save("TinyMCE")}catch(o){}},getItem:function(l){var m=i.getElement();try{m.load("TinyMCE");return m.getAttribute(l)}catch(n){return null}},removeItem:function(l){i.getElement().removeAttribute(l)}}}},],function(l){try{h.storage=l();if(h.storage){return false}}catch(m){}})},storeDraft:function(){var i=this,l=i.storage,j=i.editor,h,k;if(l){if(!l.getItem(i.key)&&!j.isDirty()){return}k=j.getContent({draft:true});if(k.length>j.settings.autosave_minlength){h=i.getExpDate();if(!i.storage.autoExpires){i.storage.setItem(i.key+"_expires",h)}i.storage.setItem(i.key,k);i.onStoreDraft.dispatch(i,{expires:h,content:k})}}},restoreDraft:function(){var h=this,j=h.storage,i;if(j){i=j.getItem(h.key);if(i){h.editor.setContent(i);h.onRestoreDraft.dispatch(h,{content:i})}}},hasDraft:function(){var h=this,k=h.storage,i,j;if(k){j=!!k.getItem(h.key);if(j){if(!h.storage.autoExpires){i=new Date(k.getItem(h.key+"_expires"));if(new Date().getTime()<i.getTime()){return b}h.removeDraft()}else{return b}}}return false},removeDraft:function(){var h=this,k=h.storage,i=h.key,j;if(k){j=k.getItem(i);k.removeItem(i);k.removeItem(i+"_expires");if(j){h.onRemoveDraft.dispatch(h,{content:j})}}},"static":{_beforeUnloadHandler:function(h){var i;e.each(tinyMCE.editors,function(j){if(j.plugins.autosave){j.plugins.autosave.storeDraft()}if(j.getParam("fullscreen_is_enabled")){return}if(!i&&j.isDirty()&&j.getParam("autosave_ask_before_unload")){i=j.getLang("autosave.unload_msg")}});return i}}});e.PluginManager.add("autosave",e.plugins.AutoSave)})(tinymce); \ No newline at end of file diff --git a/plugins/autosave/editor_plugin_src.js b/plugins/autosave/editor_plugin_src.js index 8311483f9413b21347663de54453843b30336d4b..8b308f5aac6525419207abcb01cfddecfdb5af2f 100644 --- a/plugins/autosave/editor_plugin_src.js +++ b/plugins/autosave/editor_plugin_src.js @@ -136,8 +136,10 @@ // Auto save contents each interval time setInterval(function() { - self.storeDraft(); - ed.nodeChanged(); + if (!ed.removed) { + self.storeDraft(); + ed.nodeChanged(); + } }, settings.autosave_interval); } }); diff --git a/plugins/contextmenu/editor_plugin.js b/plugins/contextmenu/editor_plugin.js index 4f99010e86832b12fd6cc5548df17435bf879f10..2ed042c3ae49dc1cddbe17fd985bdfb12cd16913 100644 --- a/plugins/contextmenu/editor_plugin.js +++ b/plugins/contextmenu/editor_plugin.js @@ -1 +1 @@ -(function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(e){var h=this,f,d,i;h.editor=e;d=e.settings.contextmenu_never_use_native;h.onContextMenu=new tinymce.util.Dispatcher(this);f=e.onContextMenu.add(function(j,k){if((i!==0?i:k.ctrlKey)&&!d){return}a.cancel(k);if(k.target.nodeName=="IMG"){j.selection.select(k.target)}h._getMenu(j).showMenu(k.clientX||k.pageX,k.clientY||k.pageY);a.add(j.getDoc(),"click",function(l){g(j,l)});j.nodeChanged()});e.onRemove.add(function(){if(h._menu){h._menu.removeAll()}});function g(j,k){i=0;if(k&&k.button==2){i=k.ctrlKey;return}if(h._menu){h._menu.removeAll();h._menu.destroy();a.remove(j.getDoc(),"click",g);h._menu=null}}e.onMouseDown.add(g);e.onKeyDown.add(g);e.onKeyDown.add(function(j,k){if(k.shiftKey&&!k.ctrlKey&&!k.altKey&&k.keyCode===121){a.cancel(k);f(j,k)}})},getInfo:function(){return{longname:"Contextmenu",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getMenu:function(e){var g=this,d=g._menu,j=e.selection,f=j.isCollapsed(),h=j.getNode()||e.getBody(),i,k;if(d){d.removeAll();d.destroy()}k=b.getPos(e.getContentAreaContainer());d=e.controlManager.createDropMenu("contextmenu",{offset_x:k.x+e.getParam("contextmenu_offset_x",0),offset_y:k.y+e.getParam("contextmenu_offset_y",0),constrain:1,keyboard_focus:true});g._menu=d;d.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(f);d.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(f);d.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((h.nodeName=="A"&&!e.dom.getAttrib(h,"name"))||!f){d.addSeparator();d.add({title:"advanced.link_desc",icon:"link",cmd:e.plugins.advlink?"mceAdvLink":"mceLink",ui:true});d.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}d.addSeparator();d.add({title:"advanced.image_desc",icon:"image",cmd:e.plugins.advimage?"mceAdvImage":"mceImage",ui:true});d.addSeparator();i=d.addMenu({title:"contextmenu.align"});i.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});i.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});i.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});i.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});g.onContextMenu.dispatch(g,d,h,f);return d}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})(); \ No newline at end of file +(function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(f){var i=this,g,d,j,e;i.editor=f;d=f.settings.contextmenu_never_use_native;i.onContextMenu=new tinymce.util.Dispatcher(this);e=function(k){h(f,k)};g=f.onContextMenu.add(function(k,l){if((j!==0?j:l.ctrlKey)&&!d){return}a.cancel(l);if(l.target.nodeName=="IMG"){k.selection.select(l.target)}i._getMenu(k).showMenu(l.clientX||l.pageX,l.clientY||l.pageY);a.add(k.getDoc(),"click",e);k.nodeChanged()});f.onRemove.add(function(){if(i._menu){i._menu.removeAll()}});function h(k,l){j=0;if(l&&l.button==2){j=l.ctrlKey;return}if(i._menu){i._menu.removeAll();i._menu.destroy();a.remove(k.getDoc(),"click",e);i._menu=null}}f.onMouseDown.add(h);f.onKeyDown.add(h);f.onKeyDown.add(function(k,l){if(l.shiftKey&&!l.ctrlKey&&!l.altKey&&l.keyCode===121){a.cancel(l);g(k,l)}})},getInfo:function(){return{longname:"Contextmenu",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/contextmenu",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_getMenu:function(e){var g=this,d=g._menu,j=e.selection,f=j.isCollapsed(),h=j.getNode()||e.getBody(),i,k;if(d){d.removeAll();d.destroy()}k=b.getPos(e.getContentAreaContainer());d=e.controlManager.createDropMenu("contextmenu",{offset_x:k.x+e.getParam("contextmenu_offset_x",0),offset_y:k.y+e.getParam("contextmenu_offset_y",0),constrain:1,keyboard_focus:true});g._menu=d;d.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(f);d.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(f);d.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((h.nodeName=="A"&&!e.dom.getAttrib(h,"name"))||!f){d.addSeparator();d.add({title:"advanced.link_desc",icon:"link",cmd:e.plugins.advlink?"mceAdvLink":"mceLink",ui:true});d.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}d.addSeparator();d.add({title:"advanced.image_desc",icon:"image",cmd:e.plugins.advimage?"mceAdvImage":"mceImage",ui:true});d.addSeparator();i=d.addMenu({title:"contextmenu.align"});i.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});i.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});i.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});i.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});g.onContextMenu.dispatch(g,d,h,f);return d}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})(); \ No newline at end of file diff --git a/plugins/contextmenu/editor_plugin_src.js b/plugins/contextmenu/editor_plugin_src.js index 004d011d09aa3f0d8a9fd2770fd288dba2d76f3a..48b0fff99f683fa78a6996bc421370726187269a 100644 --- a/plugins/contextmenu/editor_plugin_src.js +++ b/plugins/contextmenu/editor_plugin_src.js @@ -27,7 +27,7 @@ * @param {string} url Absolute URL to where the plugin is located. */ init : function(ed) { - var t = this, showMenu, contextmenuNeverUseNative, realCtrlKey; + var t = this, showMenu, contextmenuNeverUseNative, realCtrlKey, hideMenu; t.editor = ed; @@ -42,6 +42,10 @@ */ t.onContextMenu = new tinymce.util.Dispatcher(this); + hideMenu = function(e) { + hide(ed, e); + }; + showMenu = ed.onContextMenu.add(function(ed, e) { // Block TinyMCE menu on ctrlKey and work around Safari issue if ((realCtrlKey !== 0 ? realCtrlKey : e.ctrlKey) && !contextmenuNeverUseNative) @@ -54,13 +58,11 @@ ed.selection.select(e.target); t._getMenu(ed).showMenu(e.clientX || e.pageX, e.clientY || e.pageY); - Event.add(ed.getDoc(), 'click', function(e) { - hide(ed, e); - }); + Event.add(ed.getDoc(), 'click', hideMenu); ed.nodeChanged(); }); - + ed.onRemove.add(function() { if (t._menu) t._menu.removeAll(); @@ -78,8 +80,8 @@ if (t._menu) { t._menu.removeAll(); - t._menu.destroy(); - Event.remove(ed.getDoc(), 'click', hide); + t._menu.destroy(); + Event.remove(ed.getDoc(), 'click', hideMenu); t._menu = null; } }; diff --git a/plugins/directionality/editor_plugin.js b/plugins/directionality/editor_plugin.js index bce8e73995d05c6bdd18f476a595be3e633b9782..90847e78e34baeaab8c15e6da290c3ff9f1e2cc4 100644 --- a/plugins/directionality/editor_plugin.js +++ b/plugins/directionality/editor_plugin.js @@ -1 +1 @@ -(function(){tinymce.create("tinymce.plugins.Directionality",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceDirectionLTR",function(){var d=a.dom.getParent(a.selection.getNode(),a.dom.isBlock);if(d){if(a.dom.getAttrib(d,"dir")!="ltr"){a.dom.setAttrib(d,"dir","ltr")}else{a.dom.setAttrib(d,"dir","")}}a.nodeChanged()});a.addCommand("mceDirectionRTL",function(){var d=a.dom.getParent(a.selection.getNode(),a.dom.isBlock);if(d){if(a.dom.getAttrib(d,"dir")!="rtl"){a.dom.setAttrib(d,"dir","rtl")}else{a.dom.setAttrib(d,"dir","")}}a.nodeChanged()});a.addButton("ltr",{title:"directionality.ltr_desc",cmd:"mceDirectionLTR"});a.addButton("rtl",{title:"directionality.rtl_desc",cmd:"mceDirectionRTL"});a.onNodeChange.add(c._nodeChange,c)},getInfo:function(){return{longname:"Directionality",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_nodeChange:function(b,a,e){var d=b.dom,c;e=d.getParent(e,d.isBlock);if(!e){a.setDisabled("ltr",1);a.setDisabled("rtl",1);return}c=d.getAttrib(e,"dir");a.setActive("ltr",c=="ltr");a.setDisabled("ltr",0);a.setActive("rtl",c=="rtl");a.setDisabled("rtl",0)}});tinymce.PluginManager.add("directionality",tinymce.plugins.Directionality)})(); \ No newline at end of file +(function(){tinymce.create("tinymce.plugins.Directionality",{init:function(b,c){var d=this;d.editor=b;function a(e){var h=b.dom,g,f=b.selection.getSelectedBlocks();if(f.length){g=h.getAttrib(f[0],"dir");tinymce.each(f,function(i){if(!h.getParent(i.parentNode,"*[dir='"+e+"']",h.getRoot())){if(g!=e){h.setAttrib(i,"dir",e)}else{h.setAttrib(i,"dir",null)}}});b.nodeChanged()}}b.addCommand("mceDirectionLTR",function(){a("ltr")});b.addCommand("mceDirectionRTL",function(){a("rtl")});b.addButton("ltr",{title:"directionality.ltr_desc",cmd:"mceDirectionLTR"});b.addButton("rtl",{title:"directionality.rtl_desc",cmd:"mceDirectionRTL"});b.onNodeChange.add(d._nodeChange,d)},getInfo:function(){return{longname:"Directionality",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/directionality",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_nodeChange:function(b,a,e){var d=b.dom,c;e=d.getParent(e,d.isBlock);if(!e){a.setDisabled("ltr",1);a.setDisabled("rtl",1);return}c=d.getAttrib(e,"dir");a.setActive("ltr",c=="ltr");a.setDisabled("ltr",0);a.setActive("rtl",c=="rtl");a.setDisabled("rtl",0)}});tinymce.PluginManager.add("directionality",tinymce.plugins.Directionality)})(); \ No newline at end of file diff --git a/plugins/directionality/editor_plugin_src.js b/plugins/directionality/editor_plugin_src.js index 4444959bf31bb3a7a22b947305fafdbd5d446939..b1340141276c4eac2d2bb74c33cc243b5ef2bf45 100644 --- a/plugins/directionality/editor_plugin_src.js +++ b/plugins/directionality/editor_plugin_src.js @@ -15,30 +15,33 @@ t.editor = ed; - ed.addCommand('mceDirectionLTR', function() { - var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); - - if (e) { - if (ed.dom.getAttrib(e, "dir") != "ltr") - ed.dom.setAttrib(e, "dir", "ltr"); - else - ed.dom.setAttrib(e, "dir", ""); + function setDir(dir) { + var dom = ed.dom, curDir, blocks = ed.selection.getSelectedBlocks(); + + if (blocks.length) { + curDir = dom.getAttrib(blocks[0], "dir"); + + tinymce.each(blocks, function(block) { + // Add dir to block if the parent block doesn't already have that dir + if (!dom.getParent(block.parentNode, "*[dir='" + dir + "']", dom.getRoot())) { + if (curDir != dir) { + dom.setAttrib(block, "dir", dir); + } else { + dom.setAttrib(block, "dir", null); + } + } + }); + + ed.nodeChanged(); } + } - ed.nodeChanged(); + ed.addCommand('mceDirectionLTR', function() { + setDir("ltr"); }); ed.addCommand('mceDirectionRTL', function() { - var e = ed.dom.getParent(ed.selection.getNode(), ed.dom.isBlock); - - if (e) { - if (ed.dom.getAttrib(e, "dir") != "rtl") - ed.dom.setAttrib(e, "dir", "rtl"); - else - ed.dom.setAttrib(e, "dir", ""); - } - - ed.nodeChanged(); + setDir("rtl"); }); ed.addButton('ltr', {title : 'directionality.ltr_desc', cmd : 'mceDirectionLTR'}); diff --git a/plugins/fullscreen/editor_plugin.js b/plugins/fullscreen/editor_plugin.js index a6456f89dd86052508f8619cbf8070e89d54a755..a2eb0348392e93454246eca22df1c273f9524402 100644 --- a/plugins/fullscreen/editor_plugin.js +++ b/plugins/fullscreen/editor_plugin.js @@ -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)})(); \ No newline at end of file +(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().getElementsByTagName("table")[0]);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)})(); \ No newline at end of file diff --git a/plugins/fullscreen/editor_plugin_src.js b/plugins/fullscreen/editor_plugin_src.js index afa4f9b46ebf2e5967ab236285792872ad6ab77b..524b487aa087c560c3ce38b59430eaf5d2d3863c 100644 --- a/plugins/fullscreen/editor_plugin_src.js +++ b/plugins/fullscreen/editor_plugin_src.js @@ -65,7 +65,7 @@ // Fixes an IE bug where the scrollbars doesn't reappear if (tinymce.isIE && (s.fullscreen_html_overflow == 'visible' || s.fullscreen_html_overflow == 'scroll')) - s.fullscreen_html_overflow = 'auto'; + s.fullscreen_html_overflow = 'auto'; if (s.fullscreen_overflow == '0px') s.fullscreen_overflow = ''; @@ -79,13 +79,13 @@ 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'; n = DOM.add(DOM.doc.body, 'div', { - id : 'mce_fullscreen_container', + id : 'mce_fullscreen_container', style : 'position:' + posCss + ';left:0;width:' + vp.w + 'px;height:' + vp.h + 'px;z-index:200000;'}); DOM.add(n, 'div', {id : 'mce_fullscreen'}); @@ -127,7 +127,7 @@ var vp = tinymce.DOM.getViewPort(), fed = t.fullscreenEditor, outerSize, innerSize; // Get outer/inner size to get a delta size that can be used to calc the new iframe size - outerSize = fed.dom.getSize(fed.getContainer().firstChild); + outerSize = fed.dom.getSize(fed.getContainer().getElementsByTagName('table')[0]); innerSize = fed.dom.getSize(fed.getContainer().getElementsByTagName('iframe')[0]); fed.theme.resizeTo(vp.w - outerSize.w + innerSize.w, vp.h - outerSize.h + innerSize.h); @@ -156,4 +156,4 @@ // Register plugin tinymce.PluginManager.add('fullscreen', tinymce.plugins.FullScreenPlugin); -})(); \ No newline at end of file +})(); diff --git a/plugins/legacyoutput/editor_plugin.js b/plugins/legacyoutput/editor_plugin.js index b3a4ce31c5e76bf61a840e714054cb60980fa83f..2ed5f41ae47d58c2c566a746844187433a4edd63 100644 --- a/plugins/legacyoutput/editor_plugin.js +++ b/plugins/legacyoutput/editor_plugin.js @@ -1 +1 @@ -(function(a){a.onAddEditor.addToTop(function(c,b){b.settings.inline_styles=false});a.create("tinymce.plugins.LegacyOutput",{init:function(b){b.onInit.add(function(){var c="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",e=a.explode(b.settings.font_size_style_values),d=b.schema;b.formatter.register({alignleft:{selector:c,attributes:{align:"left"}},aligncenter:{selector:c,attributes:{align:"center"}},alignright:{selector:c,attributes:{align:"right"}},alignfull:{selector:c,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:true}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:true}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(f){return a.inArray(e,f.value)+1}}},forecolor:{inline:"font",styles:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}});a.each("b,i,u,strike".split(","),function(f){d.addValidElements(f+"[*]")});if(!d.getElementRule("font")){d.addValidElements("font[face|size|color|style]")}a.each(c.split(","),function(f){var h=d.getElementRule(f),g;if(h){if(!h.attributes.align){h.attributes.align={};h.attributesOrder.push("align")}}});b.onNodeChange.add(function(g,k){var j,f,h,i;f=g.dom.getParent(g.selection.getNode(),"font");if(f){h=f.face;i=f.size}if(j=k.get("fontselect")){j.select(function(l){return l==h})}if(j=k.get("fontsizeselect")){j.select(function(m){var l=a.inArray(e,m.fontSize);return l+1==i})}})})},getInfo:function(){return{longname:"LegacyOutput",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/legacyoutput",version:a.majorVersion+"."+a.minorVersion}}});a.PluginManager.add("legacyoutput",a.plugins.LegacyOutput)})(tinymce); \ No newline at end of file +(function(a){a.onAddEditor.addToTop(function(c,b){b.settings.inline_styles=false});a.create("tinymce.plugins.LegacyOutput",{init:function(b){b.onInit.add(function(){var c="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",e=a.explode(b.settings.font_size_style_values),d=b.schema;b.formatter.register({alignleft:{selector:c,attributes:{align:"left"}},aligncenter:{selector:c,attributes:{align:"center"}},alignright:{selector:c,attributes:{align:"right"}},alignfull:{selector:c,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:true}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:true}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(f){return a.inArray(e,f.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}});a.each("b,i,u,strike".split(","),function(f){d.addValidElements(f+"[*]")});if(!d.getElementRule("font")){d.addValidElements("font[face|size|color|style]")}a.each(c.split(","),function(f){var h=d.getElementRule(f),g;if(h){if(!h.attributes.align){h.attributes.align={};h.attributesOrder.push("align")}}});b.onNodeChange.add(function(g,k){var j,f,h,i;f=g.dom.getParent(g.selection.getNode(),"font");if(f){h=f.face;i=f.size}if(j=k.get("fontselect")){j.select(function(l){return l==h})}if(j=k.get("fontsizeselect")){j.select(function(m){var l=a.inArray(e,m.fontSize);return l+1==i})}})})},getInfo:function(){return{longname:"LegacyOutput",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/legacyoutput",version:a.majorVersion+"."+a.minorVersion}}});a.PluginManager.add("legacyoutput",a.plugins.LegacyOutput)})(tinymce); \ No newline at end of file diff --git a/plugins/legacyoutput/editor_plugin_src.js b/plugins/legacyoutput/editor_plugin_src.js index e627ec76e4bbc53445834d299dfe31bf6261f5b6..3cdcde579df2447ec25ea0f1603923d1c3820ddc 100644 --- a/plugins/legacyoutput/editor_plugin_src.js +++ b/plugins/legacyoutput/editor_plugin_src.js @@ -68,7 +68,7 @@ }, // Setup font elements for colors as well - forecolor : {inline : 'font', styles : {color : '%value'}}, + forecolor : {inline : 'font', attributes : {color : '%value'}}, hilitecolor : {inline : 'font', styles : {backgroundColor : '%value'}} }); diff --git a/plugins/lists/editor_plugin.js b/plugins/lists/editor_plugin.js index a5afe90eb96b0734fd37566779087a93d22b48dd..ec21b256ec1c033668a798f3848942f445303f95 100644 --- a/plugins/lists/editor_plugin.js +++ b/plugins/lists/editor_plugin.js @@ -1 +1 @@ -(function(){var e=tinymce.each,r=tinymce.dom.Event,g;function p(t,s){while(t&&(t.nodeType===8||(t.nodeType===3&&/^[ \t\n\r]*$/.test(t.nodeValue)))){t=s(t)}return t}function b(s){return p(s,function(t){return t.previousSibling})}function i(s){return p(s,function(t){return t.nextSibling})}function d(s,u,t){return s.dom.getParent(u,function(v){return tinymce.inArray(t,v)!==-1})}function n(s){return s&&(s.tagName==="OL"||s.tagName==="UL")}function c(u,v){var t,w,s;t=b(u.lastChild);while(n(t)){w=t;t=b(w.previousSibling)}if(w){s=v.create("li",{style:"list-style-type: none;"});v.split(u,w);v.insertAfter(s,w);s.appendChild(w);s.appendChild(w);u=s.previousSibling}return u}function m(t,s,u){t=a(t,s,u);return o(t,s,u)}function a(u,s,v){var t=b(u.previousSibling);if(t){return h(t,u,s?t:false,v)}else{return u}}function o(u,t,v){var s=i(u.nextSibling);if(s){return h(u,s,t?s:false,v)}else{return u}}function h(u,s,t,v){if(l(u,s,!!t,v)){return f(u,s,t)}else{if(u&&u.tagName==="LI"&&n(s)){u.appendChild(s)}}return s}function l(u,t,s,v){if(!u||!t){return false}else{if(u.tagName==="LI"&&t.tagName==="LI"){return t.style.listStyleType==="none"||j(t)}else{if(n(u)){return(u.tagName===t.tagName&&(s||u.style.listStyleType===t.style.listStyleType))||q(t)}else{return v&&u.tagName==="P"&&t.tagName==="P"}}}}function q(t){var s=i(t.firstChild),u=b(t.lastChild);return s&&u&&n(t)&&s===u&&(n(s)||s.style.listStyleType==="none"||j(s))}function j(u){var t=i(u.firstChild),s=b(u.lastChild);return t&&s&&t===s&&n(t)}function f(w,v,s){var u=b(w.lastChild),t=i(v.firstChild);if(w.tagName==="P"){w.appendChild(w.ownerDocument.createElement("br"))}while(v.firstChild){w.appendChild(v.firstChild)}if(s){w.style.listStyleType=s.style.listStyleType}v.parentNode.removeChild(v);h(u,t,false);return w}function k(t,u){var s;if(!u.is(t,"li,ol,ul")){s=u.getParent(t,"li");if(s){t=s}}return t}tinymce.create("tinymce.plugins.Lists",{init:function(y){var v="TABBING";var s="EMPTY";var J="ESCAPE";var z="PARAGRAPH";var N="UNKNOWN";var x=N;function E(U){return U.keyCode===tinymce.VK.TAB&&!(U.altKey||U.ctrlKey)&&(y.queryCommandState("InsertUnorderedList")||y.queryCommandState("InsertOrderedList"))}function w(){var U=B();var W=U.parentNode.parentNode;var V=U.parentNode.lastChild===U;return V&&!t(W)&&P(U)}function t(U){if(n(U)){return U.parentNode&&U.parentNode.tagName==="LI"}else{return U.tagName==="LI"}}function F(){return y.selection.isCollapsed()&&P(B())}function B(){var U=y.selection.getStart();return((U.tagName=="BR"||U.tagName=="")&&U.parentNode.tagName=="LI")?U.parentNode:U}function P(U){var V=U.childNodes.length;if(U.tagName==="LI"){return V==0?true:V==1&&(U.firstChild.tagName==""||U.firstChild.tagName=="BR"||H(U))}return false}function H(U){var V=tinymce.grep(U.parentNode.childNodes,function(Y){return Y.tagName=="LI"});var W=U==V[V.length-1];var X=U.firstChild;return tinymce.isIE9&&W&&(X.nodeValue==String.fromCharCode(160)||X.nodeValue==String.fromCharCode(32))}function T(U){return U.keyCode===tinymce.VK.ENTER}function A(U){return T(U)&&!U.shiftKey}function M(U){if(E(U)){return v}else{if(A(U)&&w()){return J}else{if(A(U)&&F()){return s}else{return N}}}}function D(U,V){if(x==v||x==s||tinymce.isGecko&&x==J){r.cancel(V)}}function C(){var U=y.selection.getRng(true);var V=U.startContainer;if(V.nodeType==3){var W=V.nodeValue;if(tinymce.isIE9&&W.length>1&&W.charCodeAt(W.length-1)==32){return(U.endOffset==W.length-1)}else{return(U.endOffset==W.length)}}else{if(V.nodeType==1){return U.endOffset==V.childNodes.length}}return false}function I(){var W=y.selection.getNode();var V="h1,h2,h3,h4,h5,h6,p,div";var U=y.dom.is(W,V)&&W.parentNode.tagName==="LI"&&W.parentNode.lastChild===W;return y.selection.isCollapsed()&&U&&C()}function K(W,Y){if(A(Y)&&I()){var X=W.selection.getNode();var V=W.dom.create("li");var U=W.dom.getParent(X,"li");W.dom.insertAfter(V,U);if(tinymce.isIE6||tinymce.isIE7||tinyMCE.isIE8){V.appendChild(W.dom.create(" "));W.selection.setCursorLocation(V,1)}else{if(tinyMCE.isGecko){setTimeout(function(){var Z=W.getDoc().createTextNode("\uFEFF");V.appendChild(Z);W.selection.setCursorLocation(V,0)},0)}else{W.selection.setCursorLocation(V,0)}}Y.preventDefault()}}function u(X,Z){var ac;if(!tinymce.isGecko){return}var V=X.selection.getStart();if(Z.keyCode!=tinymce.VK.BACKSPACE||V.tagName!=="IMG"){return}function W(ag){var ah=ag.firstChild;var af=null;do{if(!ah){break}if(ah.tagName==="LI"){af=ah}}while(ah=ah.nextSibling);return af}function ae(ag,af){while(ag.childNodes.length>0){af.appendChild(ag.childNodes[0])}}ac=V.parentNode.previousSibling;if(!ac){return}var aa;if(ac.tagName==="UL"||ac.tagName==="OL"){aa=ac}else{if(ac.previousSibling&&(ac.previousSibling.tagName==="UL"||ac.previousSibling.tagName==="OL")){aa=ac.previousSibling}else{return}}var ad=W(aa);var U=X.dom.createRng();U.setStart(ad,1);U.setEnd(ad,1);X.selection.setRng(U);X.selection.collapse(true);var Y=X.selection.getBookmark();var ab=V.parentNode.cloneNode(true);if(ab.tagName==="P"||ab.tagName==="DIV"){ae(ab,ad)}else{ad.appendChild(ab)}V.parentNode.parentNode.removeChild(V.parentNode);X.selection.moveToBookmark(Y)}function G(U){var V=y.dom.getParent(U,"ol,ul");if(V!=null){var W=V.lastChild;W.appendChild(y.getDoc().createElement(""));y.selection.setCursorLocation(W,0)}}this.ed=y;y.addCommand("Indent",this.indent,this);y.addCommand("Outdent",this.outdent,this);y.addCommand("InsertUnorderedList",function(){this.applyList("UL","OL")},this);y.addCommand("InsertOrderedList",function(){this.applyList("OL","UL")},this);y.onInit.add(function(){y.editorCommands.addCommands({outdent:function(){var V=y.selection,W=y.dom;function U(X){X=W.getParent(X,W.isBlock);return X&&(parseInt(y.dom.getStyle(X,"margin-left")||0,10)+parseInt(y.dom.getStyle(X,"padding-left")||0,10))>0}return U(V.getStart())||U(V.getEnd())||y.queryCommandState("InsertOrderedList")||y.queryCommandState("InsertUnorderedList")}},"state")});y.onKeyUp.add(function(V,W){if(x==v){V.execCommand(W.shiftKey?"Outdent":"Indent",true,null);x=N;return r.cancel(W)}else{if(x==s){var U=B();var Y=V.settings.list_outdent_on_enter===true||W.shiftKey;V.execCommand(Y?"Outdent":"Indent",true,null);if(tinymce.isIE){G(U)}return r.cancel(W)}else{if(x==J){if(tinymce.isIE6||tinymce.isIE7||tinymce.isIE8){var X=V.getDoc().createTextNode("\uFEFF");V.selection.getNode().appendChild(X)}else{if(tinymce.isIE9||tinymce.isGecko){V.execCommand("Outdent");return r.cancel(W)}}}}}});function L(V,U){var W=y.getDoc().createTextNode("\uFEFF");V.insertBefore(W,U);y.selection.setCursorLocation(W,0);y.execCommand("mceRepaint")}function R(V,X){if(T(X)){var U=B();if(U){var W=U.parentNode;var Y=W&&W.parentNode;if(Y&&Y.nodeName=="LI"&&Y.firstChild==W&&U==W.firstChild){L(Y,W)}}}}function S(V,X){if(T(X)){var U=B();if(V.dom.select("ul li",U).length===1){var W=U.firstChild;L(U,W)}}}function Q(V,Z){function W(ad,aa){var ac=[];var ae=new tinymce.dom.TreeWalker(aa,ad);for(var ab=ae.current();ab;ab=ae.next()){if(V.dom.is(ab,"ol,ul,li")){ac.push(ab)}}return ac}if(Z.keyCode==tinymce.VK.BACKSPACE){var U=B();if(U){var Y=V.dom.getParent(U,"ol,ul");if(Y&&Y.firstChild===U){var X=W(Y,U);V.execCommand("Outdent",false,X);V.undoManager.add();return r.cancel(Z)}}}}function O(V,X){var U=B();if(X.keyCode===tinymce.VK.BACKSPACE&&V.dom.is(U,"li")&&U.parentNode.firstChild!==U){if(V.dom.select("ul,ol",U).length===1){var Z=U.previousSibling;V.dom.remove(V.dom.select("br",U));V.dom.remove(U,true);var W=tinymce.grep(Z.childNodes,function(aa){return aa.nodeType===3});if(W.length===1){var Y=W[0];V.selection.setCursorLocation(Y,Y.length)}V.undoManager.add();return r.cancel(X)}}}y.onKeyDown.add(function(U,V){x=M(V)});y.onKeyDown.add(D);y.onKeyDown.add(u);y.onKeyDown.add(K);if(tinymce.isGecko){y.onKeyUp.add(R)}if(tinymce.isIE8){y.onKeyUp.add(S)}if(tinymce.isGecko||tinymce.isWebKit){y.onKeyDown.add(Q)}if(tinymce.isWebKit){y.onKeyDown.add(O)}},applyList:function(y,v){var C=this,z=C.ed,I=z.dom,s=[],H=false,u=false,w=false,B,G=z.selection.getSelectedBlocks();function E(t){if(t&&t.tagName==="BR"){I.remove(t)}}function F(M){var N=I.create(y),t;function L(O){if(O.style.marginLeft||O.style.paddingLeft){C.adjustPaddingFunction(false)(O)}}if(M.tagName==="LI"){}else{if(M.tagName==="P"||M.tagName==="DIV"||M.tagName==="BODY"){K(M,function(P,O){J(P,O,M.tagName==="BODY"?null:P.parentNode);t=P.parentNode;L(t);E(O)});if(t){if(t.tagName==="LI"&&(M.tagName==="P"||G.length>1)){I.split(t.parentNode.parentNode,t.parentNode)}m(t.parentNode,true)}return}else{t=I.create("li");I.insertAfter(t,M);t.appendChild(M);L(M);M=t}}I.insertAfter(N,M);N.appendChild(M);m(N,true);s.push(M)}function J(P,L,N){var t,O=P,M;while(!I.isBlock(P.parentNode)&&P.parentNode!==I.getRoot()){P=I.split(P.parentNode,P.previousSibling);P=P.nextSibling;O=P}if(N){t=N.cloneNode(true);P.parentNode.insertBefore(t,P);while(t.firstChild){I.remove(t.firstChild)}t=I.rename(t,"li")}else{t=I.create("li");P.parentNode.insertBefore(t,P)}while(O&&O!=L){M=O.nextSibling;t.appendChild(O);O=M}if(t.childNodes.length===0){t.innerHTML='<br _mce_bogus="1" />'}F(t)}function K(Q,T){var N,R,O=3,L=1,t="br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl";function P(X,U){var V=I.createRng(),W;g.keep=true;z.selection.moveToBookmark(g);g.keep=false;W=z.selection.getRng(true);if(!U){U=X.parentNode.lastChild}V.setStartBefore(X);V.setEndAfter(U);return !(V.compareBoundaryPoints(O,W)>0||V.compareBoundaryPoints(L,W)<=0)}function S(U){if(U.nextSibling){return U.nextSibling}if(!I.isBlock(U.parentNode)&&U.parentNode!==I.getRoot()){return S(U.parentNode)}}N=Q.firstChild;var M=false;e(I.select(t,Q),function(U){if(U.hasAttribute&&U.hasAttribute("_mce_bogus")){return true}if(P(N,U)){I.addClass(U,"_mce_tagged_br");N=S(U)}});M=(N&&P(N,undefined));N=Q.firstChild;e(I.select(t,Q),function(V){var U=S(V);if(V.hasAttribute&&V.hasAttribute("_mce_bogus")){return true}if(I.hasClass(V,"_mce_tagged_br")){T(N,V,R);R=null}else{R=V}N=U});if(M){T(N,undefined,R)}}function D(t){K(t,function(M,L,N){J(M,L);E(L);E(N)})}function A(t){if(tinymce.inArray(s,t)!==-1){return}if(t.parentNode.tagName===v){I.split(t.parentNode,t);F(t);o(t.parentNode,false)}s.push(t)}function x(M){var O,N,L,t;if(tinymce.inArray(s,M)!==-1){return}M=c(M,I);while(I.is(M.parentNode,"ol,ul,li")){I.split(M.parentNode,M)}s.push(M);M=I.rename(M,"p");L=m(M,false,z.settings.force_br_newlines);if(L===M){O=M.firstChild;while(O){if(I.isBlock(O)){O=I.split(O.parentNode,O);t=true;N=O.nextSibling&&O.nextSibling.firstChild}else{N=O.nextSibling;if(t&&O.tagName==="BR"){I.remove(O)}t=false}O=N}}}e(G,function(t){t=k(t,I);if(t.tagName===v||(t.tagName==="LI"&&t.parentNode.tagName===v)){u=true}else{if(t.tagName===y||(t.tagName==="LI"&&t.parentNode.tagName===y)){H=true}else{w=true}}});if(w&&!H||u||G.length===0){B={LI:A,H1:F,H2:F,H3:F,H4:F,H5:F,H6:F,P:F,BODY:F,DIV:G.length>1?F:D,defaultAction:D,elements:this.selectedBlocks()}}else{B={defaultAction:x,elements:this.selectedBlocks()}}this.process(B)},indent:function(){var u=this.ed,w=u.dom,x=[];function s(z){var y=w.create("li",{style:"list-style-type: none;"});w.insertAfter(y,z);return y}function t(B){var y=s(B),D=w.getParent(B,"ol,ul"),C=D.tagName,E=w.getStyle(D,"list-style-type"),A={},z;if(E!==""){A.style="list-style-type: "+E+";"}z=w.create(C,A);y.appendChild(z);return z}function v(z){if(!d(u,z,x)){z=c(z,w);var y=t(z);y.appendChild(z);m(y.parentNode,false);m(y,false);x.push(z)}}this.process({LI:v,defaultAction:this.adjustPaddingFunction(true),elements:this.selectedBlocks()})},outdent:function(y,x){var w=this,u=w.ed,z=u.dom,s=[];function A(t){var C,B,D;if(!d(u,t,s)){if(z.getStyle(t,"margin-left")!==""||z.getStyle(t,"padding-left")!==""){return w.adjustPaddingFunction(false)(t)}D=z.getStyle(t,"text-align",true);if(D==="center"||D==="right"){z.setStyle(t,"text-align","left");return}t=c(t,z);C=t.parentNode;B=t.parentNode.parentNode;if(B.tagName==="P"){z.split(B,t.parentNode)}else{z.split(C,t);if(B.tagName==="LI"){z.split(B,t)}else{if(!z.is(B,"ol,ul")){z.rename(t,"p")}}}s.push(t)}}var v=x&&tinymce.is(x,"array")?x:this.selectedBlocks();this.process({LI:A,defaultAction:this.adjustPaddingFunction(false),elements:v});e(s,m)},process:function(y){var F=this,w=F.ed.selection,z=F.ed.dom,E,u;function B(t){var s=tinymce.grep(t.childNodes,function(H){return !(H.nodeName==="BR"||H.nodeName==="SPAN"&&z.getAttrib(H,"data-mce-type")=="bookmark"||H.nodeType==3&&(H.nodeValue==String.fromCharCode(160)||H.nodeValue==""))});return s.length===0}function x(s){z.removeClass(s,"_mce_act_on");if(!s||s.nodeType!==1||E.length>1&&B(s)){return}s=k(s,z);var t=y[s.tagName];if(!t){t=y.defaultAction}t(s)}function v(s){F.splitSafeEach(s.childNodes,x)}function C(s,t){return t>=0&&s.hasChildNodes()&&t<s.childNodes.length&&s.childNodes[t].tagName==="BR"}function D(){var t=w.getNode();var s=z.getParent(t,"td");return s!==null}E=y.elements;u=w.getRng(true);if(!u.collapsed){if(C(u.endContainer,u.endOffset-1)){u.setEnd(u.endContainer,u.endOffset-1);w.setRng(u)}if(C(u.startContainer,u.startOffset)){u.setStart(u.startContainer,u.startOffset+1);w.setRng(u)}}if(tinymce.isIE8){var G=F.ed.selection.getNode();if(G.tagName==="LI"&&!(G.parentNode.lastChild===G)){var A=F.ed.getDoc().createTextNode("\uFEFF");G.appendChild(A)}}g=w.getBookmark();y.OL=y.UL=v;F.splitSafeEach(E,x);w.moveToBookmark(g);g=null;if(!D()){F.ed.execCommand("mceRepaint")}},splitSafeEach:function(t,s){if(tinymce.isGecko&&(/Firefox\/[12]\.[0-9]/.test(navigator.userAgent)||/Firefox\/3\.[0-4]/.test(navigator.userAgent))){this.classBasedEach(t,s)}else{e(t,s)}},classBasedEach:function(v,u){var w=this.ed.dom,s,t;e(v,function(x){w.addClass(x,"_mce_act_on")});s=w.select("._mce_act_on");while(s.length>0){t=s.shift();w.removeClass(t,"_mce_act_on");u(t);s=w.select("._mce_act_on")}},adjustPaddingFunction:function(u){var s,v,t=this.ed;s=t.settings.indentation;v=/[a-z%]+/i.exec(s);s=parseInt(s,10);return function(w){var y,x;y=parseInt(t.dom.getStyle(w,"margin-left")||0,10)+parseInt(t.dom.getStyle(w,"padding-left")||0,10);if(u){x=y+s}else{x=y-s}t.dom.setStyle(w,"padding-left","");t.dom.setStyle(w,"margin-left",x>0?x+v:"")}},selectedBlocks:function(){var s=this.ed;var t=s.selection.getSelectedBlocks();return t.length==0?[s.dom.getRoot()]:t},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)}()); \ No newline at end of file +(function(){var e=tinymce.each,r=tinymce.dom.Event,g;function p(t,s){while(t&&(t.nodeType===8||(t.nodeType===3&&/^[ \t\n\r]*$/.test(t.nodeValue)))){t=s(t)}return t}function b(s){return p(s,function(t){return t.previousSibling})}function i(s){return p(s,function(t){return t.nextSibling})}function d(s,u,t){return s.dom.getParent(u,function(v){return tinymce.inArray(t,v)!==-1})}function n(s){return s&&(s.tagName==="OL"||s.tagName==="UL")}function c(u,v){var t,w,s;t=b(u.lastChild);while(n(t)){w=t;t=b(w.previousSibling)}if(w){s=v.create("li",{style:"list-style-type: none;"});v.split(u,w);v.insertAfter(s,w);s.appendChild(w);s.appendChild(w);u=s.previousSibling}return u}function m(t,s,u){t=a(t,s,u);return o(t,s,u)}function a(u,s,v){var t=b(u.previousSibling);if(t){return h(t,u,s?t:false,v)}else{return u}}function o(u,t,v){var s=i(u.nextSibling);if(s){return h(u,s,t?s:false,v)}else{return u}}function h(u,s,t,v){if(l(u,s,!!t,v)){return f(u,s,t)}else{if(u&&u.tagName==="LI"&&n(s)){u.appendChild(s)}}return s}function l(u,t,s,v){if(!u||!t){return false}else{if(u.tagName==="LI"&&t.tagName==="LI"){return t.style.listStyleType==="none"||j(t)}else{if(n(u)){return(u.tagName===t.tagName&&(s||u.style.listStyleType===t.style.listStyleType))||q(t)}else{return v&&u.tagName==="P"&&t.tagName==="P"}}}}function q(t){var s=i(t.firstChild),u=b(t.lastChild);return s&&u&&n(t)&&s===u&&(n(s)||s.style.listStyleType==="none"||j(s))}function j(u){var t=i(u.firstChild),s=b(u.lastChild);return t&&s&&t===s&&n(t)}function f(w,v,s){var u=b(w.lastChild),t=i(v.firstChild);if(w.tagName==="P"){w.appendChild(w.ownerDocument.createElement("br"))}while(v.firstChild){w.appendChild(v.firstChild)}if(s){w.style.listStyleType=s.style.listStyleType}v.parentNode.removeChild(v);h(u,t,false);return w}function k(t,u){var s;if(!u.is(t,"li,ol,ul")){s=u.getParent(t,"li");if(s){t=s}}return t}tinymce.create("tinymce.plugins.Lists",{init:function(y){var v="TABBING";var s="EMPTY";var J="ESCAPE";var z="PARAGRAPH";var N="UNKNOWN";var x=N;function E(U){return U.keyCode===tinymce.VK.TAB&&!(U.altKey||U.ctrlKey)&&(y.queryCommandState("InsertUnorderedList")||y.queryCommandState("InsertOrderedList"))}function w(){var U=B();var W=U.parentNode.parentNode;var V=U.parentNode.lastChild===U;return V&&!t(W)&&P(U)}function t(U){if(n(U)){return U.parentNode&&U.parentNode.tagName==="LI"}else{return U.tagName==="LI"}}function F(){return y.selection.isCollapsed()&&P(B())}function B(){var U=y.selection.getStart();return((U.tagName=="BR"||U.tagName=="")&&U.parentNode.tagName=="LI")?U.parentNode:U}function P(U){var V=U.childNodes.length;if(U.tagName==="LI"){return V==0?true:V==1&&(U.firstChild.tagName==""||U.firstChild.tagName=="BR"||H(U))}return false}function H(U){var V=tinymce.grep(U.parentNode.childNodes,function(Y){return Y.tagName=="LI"});var W=U==V[V.length-1];var X=U.firstChild;return tinymce.isIE9&&W&&(X.nodeValue==String.fromCharCode(160)||X.nodeValue==String.fromCharCode(32))}function T(U){return U.keyCode===tinymce.VK.ENTER}function A(U){return T(U)&&!U.shiftKey}function M(U){if(E(U)){return v}else{if(A(U)&&w()){return N}else{if(A(U)&&F()){return s}else{return N}}}}function D(U,V){if(x==v||x==s||tinymce.isGecko&&x==J){r.cancel(V)}}function C(){var U=y.selection.getRng(true);var V=U.startContainer;if(V.nodeType==3){var W=V.nodeValue;if(tinymce.isIE9&&W.length>1&&W.charCodeAt(W.length-1)==32){return(U.endOffset==W.length-1)}else{return(U.endOffset==W.length)}}else{if(V.nodeType==1){return U.endOffset==V.childNodes.length}}return false}function I(){var W=y.selection.getNode();var V="h1,h2,h3,h4,h5,h6,p,div";var U=y.dom.is(W,V)&&W.parentNode.tagName==="LI"&&W.parentNode.lastChild===W;return y.selection.isCollapsed()&&U&&C()}function K(W,Y){if(A(Y)&&I()){var X=W.selection.getNode();var V=W.dom.create("li");var U=W.dom.getParent(X,"li");W.dom.insertAfter(V,U);if(tinymce.isIE6||tinymce.isIE7||tinyMCE.isIE8){W.selection.setCursorLocation(V,1)}else{W.selection.setCursorLocation(V,0)}Y.preventDefault()}}function u(X,Z){var ac;if(!tinymce.isGecko){return}var V=X.selection.getStart();if(Z.keyCode!=tinymce.VK.BACKSPACE||V.tagName!=="IMG"){return}function W(ag){var ah=ag.firstChild;var af=null;do{if(!ah){break}if(ah.tagName==="LI"){af=ah}}while(ah=ah.nextSibling);return af}function ae(ag,af){while(ag.childNodes.length>0){af.appendChild(ag.childNodes[0])}}ac=V.parentNode.previousSibling;if(!ac){return}var aa;if(ac.tagName==="UL"||ac.tagName==="OL"){aa=ac}else{if(ac.previousSibling&&(ac.previousSibling.tagName==="UL"||ac.previousSibling.tagName==="OL")){aa=ac.previousSibling}else{return}}var ad=W(aa);var U=X.dom.createRng();U.setStart(ad,1);U.setEnd(ad,1);X.selection.setRng(U);X.selection.collapse(true);var Y=X.selection.getBookmark();var ab=V.parentNode.cloneNode(true);if(ab.tagName==="P"||ab.tagName==="DIV"){ae(ab,ad)}else{ad.appendChild(ab)}V.parentNode.parentNode.removeChild(V.parentNode);X.selection.moveToBookmark(Y)}function G(U){var V=y.dom.getParent(U,"ol,ul");if(V!=null){var W=V.lastChild;y.selection.setCursorLocation(W,0)}}this.ed=y;y.addCommand("Indent",this.indent,this);y.addCommand("Outdent",this.outdent,this);y.addCommand("InsertUnorderedList",function(){this.applyList("UL","OL")},this);y.addCommand("InsertOrderedList",function(){this.applyList("OL","UL")},this);y.onInit.add(function(){y.editorCommands.addCommands({outdent:function(){var V=y.selection,W=y.dom;function U(X){X=W.getParent(X,W.isBlock);return X&&(parseInt(y.dom.getStyle(X,"margin-left")||0,10)+parseInt(y.dom.getStyle(X,"padding-left")||0,10))>0}return U(V.getStart())||U(V.getEnd())||y.queryCommandState("InsertOrderedList")||y.queryCommandState("InsertUnorderedList")}},"state")});y.onKeyUp.add(function(V,W){if(x==v){V.execCommand(W.shiftKey?"Outdent":"Indent",true,null);x=N;return r.cancel(W)}else{if(x==s){var U=B();var Y=V.settings.list_outdent_on_enter===true||W.shiftKey;V.execCommand(Y?"Outdent":"Indent",true,null);if(tinymce.isIE){G(U)}return r.cancel(W)}else{if(x==J){if(tinymce.isIE6||tinymce.isIE7||tinymce.isIE8){var X=V.getDoc().createTextNode("\uFEFF");V.selection.getNode().appendChild(X)}else{if(tinymce.isIE9||tinymce.isGecko){V.execCommand("Outdent");return r.cancel(W)}}}}}});function L(V,U){var W=y.getDoc().createTextNode("\uFEFF");V.insertBefore(W,U);y.selection.setCursorLocation(W,0);y.execCommand("mceRepaint")}function R(V,X){if(T(X)){var U=B();if(U){var W=U.parentNode;var Y=W&&W.parentNode;if(Y&&Y.nodeName=="LI"&&Y.firstChild==W&&U==W.firstChild){L(Y,W)}}}}function S(V,X){if(T(X)){var U=B();if(V.dom.select("ul li",U).length===1){var W=U.firstChild;L(U,W)}}}function Q(W,aa){function X(ab){var ad=[];var ae=new tinymce.dom.TreeWalker(ab.firstChild,ab);for(var ac=ae.current();ac;ac=ae.next()){if(W.dom.is(ac,"ol,ul,li")){ad.push(ac)}}return ad}if(aa.keyCode==tinymce.VK.BACKSPACE){var U=B();if(U){var Z=W.dom.getParent(U,"ol,ul"),V=W.selection.getRng();if(Z&&Z.firstChild===U&&V.startOffset==0){var Y=X(U);Y.unshift(U);W.execCommand("Outdent",false,Y);W.undoManager.add();return r.cancel(aa)}}}}function O(V,X){var U=B();if(X.keyCode===tinymce.VK.BACKSPACE&&V.dom.is(U,"li")&&U.parentNode.firstChild!==U){if(V.dom.select("ul,ol",U).length===1){var Z=U.previousSibling;V.dom.remove(V.dom.select("br",U));V.dom.remove(U,true);var W=tinymce.grep(Z.childNodes,function(aa){return aa.nodeType===3});if(W.length===1){var Y=W[0];V.selection.setCursorLocation(Y,Y.length)}V.undoManager.add();return r.cancel(X)}}}y.onKeyDown.add(function(U,V){x=M(V)});y.onKeyDown.add(D);y.onKeyDown.add(u);y.onKeyDown.add(K);if(tinymce.isGecko){y.onKeyUp.add(R)}if(tinymce.isIE8){y.onKeyUp.add(S)}if(tinymce.isGecko||tinymce.isWebKit){y.onKeyDown.add(Q)}if(tinymce.isWebKit){y.onKeyDown.add(O)}},applyList:function(y,v){var C=this,z=C.ed,I=z.dom,s=[],H=false,u=false,w=false,B,G=z.selection.getSelectedBlocks();function E(t){if(t&&t.tagName==="BR"){I.remove(t)}}function F(M){var N=I.create(y),t;function L(O){if(O.style.marginLeft||O.style.paddingLeft){C.adjustPaddingFunction(false)(O)}}if(M.tagName==="LI"){}else{if(M.tagName==="P"||M.tagName==="DIV"||M.tagName==="BODY"){K(M,function(P,O){J(P,O,M.tagName==="BODY"?null:P.parentNode);t=P.parentNode;L(t);E(O)});if(t){if(t.tagName==="LI"&&(M.tagName==="P"||G.length>1)){I.split(t.parentNode.parentNode,t.parentNode)}m(t.parentNode,true)}return}else{t=I.create("li");I.insertAfter(t,M);t.appendChild(M);L(M);M=t}}I.insertAfter(N,M);N.appendChild(M);m(N,true);s.push(M)}function J(P,L,N){var t,O=P,M;while(!I.isBlock(P.parentNode)&&P.parentNode!==I.getRoot()){P=I.split(P.parentNode,P.previousSibling);P=P.nextSibling;O=P}if(N){t=N.cloneNode(true);P.parentNode.insertBefore(t,P);while(t.firstChild){I.remove(t.firstChild)}t=I.rename(t,"li")}else{t=I.create("li");P.parentNode.insertBefore(t,P)}while(O&&O!=L){M=O.nextSibling;t.appendChild(O);O=M}if(t.childNodes.length===0){t.innerHTML='<br _mce_bogus="1" />'}F(t)}function K(Q,T){var N,R,O=3,L=1,t="br,ul,ol,p,div,h1,h2,h3,h4,h5,h6,table,blockquote,address,pre,form,center,dl";function P(X,U){var V=I.createRng(),W;g.keep=true;z.selection.moveToBookmark(g);g.keep=false;W=z.selection.getRng(true);if(!U){U=X.parentNode.lastChild}V.setStartBefore(X);V.setEndAfter(U);return !(V.compareBoundaryPoints(O,W)>0||V.compareBoundaryPoints(L,W)<=0)}function S(U){if(U.nextSibling){return U.nextSibling}if(!I.isBlock(U.parentNode)&&U.parentNode!==I.getRoot()){return S(U.parentNode)}}N=Q.firstChild;var M=false;e(I.select(t,Q),function(U){if(U.hasAttribute&&U.hasAttribute("_mce_bogus")){return true}if(P(N,U)){I.addClass(U,"_mce_tagged_br");N=S(U)}});M=(N&&P(N,undefined));N=Q.firstChild;e(I.select(t,Q),function(V){var U=S(V);if(V.hasAttribute&&V.hasAttribute("_mce_bogus")){return true}if(I.hasClass(V,"_mce_tagged_br")){T(N,V,R);R=null}else{R=V}N=U});if(M){T(N,undefined,R)}}function D(t){K(t,function(M,L,N){J(M,L);E(L);E(N)})}function A(t){if(tinymce.inArray(s,t)!==-1){return}if(t.parentNode.tagName===v){I.split(t.parentNode,t);F(t);o(t.parentNode,false)}s.push(t)}function x(M){var O,N,L,t;if(tinymce.inArray(s,M)!==-1){return}M=c(M,I);while(I.is(M.parentNode,"ol,ul,li")){I.split(M.parentNode,M)}s.push(M);M=I.rename(M,"p");L=m(M,false,z.settings.force_br_newlines);if(L===M){O=M.firstChild;while(O){if(I.isBlock(O)){O=I.split(O.parentNode,O);t=true;N=O.nextSibling&&O.nextSibling.firstChild}else{N=O.nextSibling;if(t&&O.tagName==="BR"){I.remove(O)}t=false}O=N}}}e(G,function(t){t=k(t,I);if(t.tagName===v||(t.tagName==="LI"&&t.parentNode.tagName===v)){u=true}else{if(t.tagName===y||(t.tagName==="LI"&&t.parentNode.tagName===y)){H=true}else{w=true}}});if(w&&!H||u||G.length===0){B={LI:A,H1:F,H2:F,H3:F,H4:F,H5:F,H6:F,P:F,BODY:F,DIV:G.length>1?F:D,defaultAction:D,elements:this.selectedBlocks()}}else{B={defaultAction:x,elements:this.selectedBlocks(),processEvenIfEmpty:true}}this.process(B)},indent:function(){var u=this.ed,w=u.dom,x=[];function s(z){var y=w.create("li",{style:"list-style-type: none;"});w.insertAfter(y,z);return y}function t(B){var y=s(B),D=w.getParent(B,"ol,ul"),C=D.tagName,E=w.getStyle(D,"list-style-type"),A={},z;if(E!==""){A.style="list-style-type: "+E+";"}z=w.create(C,A);y.appendChild(z);return z}function v(z){if(!d(u,z,x)){z=c(z,w);var y=t(z);y.appendChild(z);m(y.parentNode,false);m(y,false);x.push(z)}}this.process({LI:v,defaultAction:this.adjustPaddingFunction(true),elements:this.selectedBlocks()})},outdent:function(y,x){var w=this,u=w.ed,z=u.dom,s=[];function A(t){var C,B,D;if(!d(u,t,s)){if(z.getStyle(t,"margin-left")!==""||z.getStyle(t,"padding-left")!==""){return w.adjustPaddingFunction(false)(t)}D=z.getStyle(t,"text-align",true);if(D==="center"||D==="right"){z.setStyle(t,"text-align","left");return}t=c(t,z);C=t.parentNode;B=t.parentNode.parentNode;if(B.tagName==="P"){z.split(B,t.parentNode)}else{z.split(C,t);if(B.tagName==="LI"){z.split(B,t)}else{if(!z.is(B,"ol,ul")){z.rename(t,"p")}}}s.push(t)}}var v=x&&tinymce.is(x,"array")?x:this.selectedBlocks();this.process({LI:A,defaultAction:this.adjustPaddingFunction(false),elements:v});e(s,m)},process:function(y){var F=this,w=F.ed.selection,z=F.ed.dom,E,u;function B(t){var s=tinymce.grep(t.childNodes,function(H){return !(H.nodeName==="BR"||H.nodeName==="SPAN"&&z.getAttrib(H,"data-mce-type")=="bookmark"||H.nodeType==3&&(H.nodeValue==String.fromCharCode(160)||H.nodeValue==""))});return s.length===0}function x(s){z.removeClass(s,"_mce_act_on");if(!s||s.nodeType!==1||!y.processEvenIfEmpty&&E.length>1&&B(s)){return}s=k(s,z);var t=y[s.tagName];if(!t){t=y.defaultAction}t(s)}function v(s){F.splitSafeEach(s.childNodes,x,true)}function C(s,t){return t>=0&&s.hasChildNodes()&&t<s.childNodes.length&&s.childNodes[t].tagName==="BR"}function D(){var t=w.getNode();var s=z.getParent(t,"td");return s!==null}E=y.elements;u=w.getRng(true);if(!u.collapsed){if(C(u.endContainer,u.endOffset-1)){u.setEnd(u.endContainer,u.endOffset-1);w.setRng(u)}if(C(u.startContainer,u.startOffset)){u.setStart(u.startContainer,u.startOffset+1);w.setRng(u)}}if(tinymce.isIE8){var G=F.ed.selection.getNode();if(G.tagName==="LI"&&!(G.parentNode.lastChild===G)){var A=F.ed.getDoc().createTextNode("\uFEFF");G.appendChild(A)}}g=w.getBookmark();y.OL=y.UL=v;F.splitSafeEach(E,x);w.moveToBookmark(g);g=null;if(!D()){F.ed.execCommand("mceRepaint")}},splitSafeEach:function(u,t,s){if(s||(tinymce.isGecko&&(/Firefox\/[12]\.[0-9]/.test(navigator.userAgent)||/Firefox\/3\.[0-4]/.test(navigator.userAgent)))){this.classBasedEach(u,t)}else{e(u,t)}},classBasedEach:function(v,u){var w=this.ed.dom,s,t;e(v,function(x){w.addClass(x,"_mce_act_on")});s=w.select("._mce_act_on");while(s.length>0){t=s.shift();w.removeClass(t,"_mce_act_on");u(t);s=w.select("._mce_act_on")}},adjustPaddingFunction:function(u){var s,v,t=this.ed;s=t.settings.indentation;v=/[a-z%]+/i.exec(s);s=parseInt(s,10);return function(w){var y,x;y=parseInt(t.dom.getStyle(w,"margin-left")||0,10)+parseInt(t.dom.getStyle(w,"padding-left")||0,10);if(u){x=y+s}else{x=y-s}t.dom.setStyle(w,"padding-left","");t.dom.setStyle(w,"margin-left",x>0?x+v:"")}},selectedBlocks:function(){var s=this.ed,t=s.selection.getSelectedBlocks();return t.length==0?[s.dom.getRoot()]:t},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)}()); \ No newline at end of file diff --git a/plugins/lists/editor_plugin_src.js b/plugins/lists/editor_plugin_src.js index ebe4fa5c4e14856186180cd5d1839ded99d0c1ba..1000ef74556cb0bca8a2c171469bfb82fc918283 100644 --- a/plugins/lists/editor_plugin_src.js +++ b/plugins/lists/editor_plugin_src.js @@ -207,7 +207,9 @@ if (isTabInList(e)) { return LIST_TABBING; } else if (isEnterWithoutShift(e) && isOnLastListItem()) { - return LIST_ESCAPE; + // 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 { @@ -260,15 +262,9 @@ // Move caret to new list element. if (tinymce.isIE6 || tinymce.isIE7 || tinyMCE.isIE8) { - li.appendChild(ed.dom.create(" ")); // IE needs an element within the bullet point + // 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 if (tinyMCE.isGecko) { - // This setTimeout is a hack as FF behaves badly if there is no content after the bullet point - setTimeout(function () { - var n = ed.getDoc().createTextNode('\uFEFF'); - li.appendChild(n); - ed.selection.setCursorLocation(li, 0); - }, 0); } else { ed.selection.setCursorLocation(li, 0); } @@ -349,7 +345,8 @@ var list = ed.dom.getParent(li, 'ol,ul'); if (list != null) { var lastLi = list.lastChild; - lastLi.appendChild(ed.getDoc().createElement('')); + // 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); } } @@ -443,9 +440,9 @@ } function fixDeletingFirstCharOfList(ed, e) { - function listElements(list, li) { + function listElements(li) { var elements = []; - var walker = new tinymce.dom.TreeWalker(li, list); + var walker = new tinymce.dom.TreeWalker(li.firstChild, li); for (var node = walker.current(); node; node = walker.next()) { if (ed.dom.is(node, 'ol,ul,li')) { elements.push(node); @@ -457,9 +454,11 @@ 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); + var list = ed.dom.getParent(li, 'ol,ul'), + rng = ed.selection.getRng(); + if (list && list.firstChild === li && rng.startOffset == 0) { + var elements = listElements(li); + elements.unshift(li); ed.execCommand("Outdent", false, elements); ed.undoManager.add(); return Event.cancel(e); @@ -477,7 +476,7 @@ 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] + var textNode = textNodes[0]; ed.selection.setCursorLocation(textNode, textNode.length); } ed.undoManager.add(); @@ -725,7 +724,8 @@ } else { actions = { defaultAction: convertListItemToParagraph, - elements: this.selectedBlocks() + elements: this.selectedBlocks(), + processEvenIfEmpty: true }; } this.process(actions); @@ -829,7 +829,7 @@ function processElement(element) { dom.removeClass(element, '_mce_act_on'); - if (!element || element.nodeType !== 1 || selectedBlocks.length > 1 && isEmptyElement(element)) { + if (!element || element.nodeType !== 1 || ! actions.processEvenIfEmpty && selectedBlocks.length > 1 && isEmptyElement(element)) { return; } element = findItemToOperateOn(element, dom); @@ -841,7 +841,7 @@ } function recurse(element) { - t.splitSafeEach(element.childNodes, processElement); + t.splitSafeEach(element.childNodes, processElement, true); } function brAtEdgeOfSelection(container, offset) { @@ -892,9 +892,11 @@ } }, - splitSafeEach: function(elements, f) { - if (tinymce.isGecko && (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) || - /Firefox\/3\.[0-4]/.test(navigator.userAgent))) { + splitSafeEach: function(elements, f, forceClassBase) { + if (forceClassBase || + (tinymce.isGecko && + (/Firefox\/[12]\.[0-9]/.test(navigator.userAgent) || + /Firefox\/3\.[0-4]/.test(navigator.userAgent)))) { this.classBasedEach(elements, f); } else { each(elements, f); @@ -935,8 +937,7 @@ }, selectedBlocks: function() { - var ed = this.ed - var selectedBlocks = ed.selection.getSelectedBlocks(); + var ed = this.ed, selectedBlocks = ed.selection.getSelectedBlocks(); return selectedBlocks.length == 0 ? [ ed.dom.getRoot() ] : selectedBlocks; }, diff --git a/plugins/media/editor_plugin.js b/plugins/media/editor_plugin.js index 37b4320bd9faaafecacd72709810bff010f4e9e4..9ac42e0d21e4e9f6354f69d3ccbdf8bc9cbfddf9 100644 --- a/plugins/media/editor_plugin.js +++ b/plugins/media/editor_plugin.js @@ -1 +1 @@ -(function(){var d=tinymce.explode("id,name,width,height,style,align,class,hspace,vspace,bgcolor,type"),h=tinymce.makeMap(d.join(",")),b=tinymce.html.Node,f,a,g=tinymce.util.JSON,e;f=[["Flash","d27cdb6e-ae6d-11cf-96b8-444553540000","application/x-shockwave-flash","http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],["ShockWave","166b1bca-3f9c-11cf-8075-444553540000","application/x-director","http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"],["WindowsMedia","6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a","application/x-mplayer2","http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"],["QuickTime","02bf25d5-8c17-4b23-bc80-d3488abddc6b","video/quicktime","http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"],["RealMedia","cfcdaa03-8be4-11cf-b84b-0020afbbccfa","audio/x-pn-realaudio-plugin","http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],["Java","8ad9c840-044e-11d1-b3e9-00805f499d93","application/x-java-applet","http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"],["Silverlight","dfeaf541-f3e1-4c24-acac-99c30715084a","application/x-silverlight-2"],["Iframe"],["Video"],["EmbeddedAudio"],["Audio"]];function c(m){var l,j,k;if(m&&!m.splice){j=[];for(k=0;true;k++){if(m[k]){j[k]=m[k]}else{break}}return j}return m}tinymce.create("tinymce.plugins.MediaPlugin",{init:function(n,j){var r=this,l={},m,p,q,k;function o(i){return i&&i.nodeName==="IMG"&&n.dom.hasClass(i,"mceItemMedia")}r.editor=n;r.url=j;a="";for(m=0;m<f.length;m++){k=f[m][0];q={name:k,clsids:tinymce.explode(f[m][1]||""),mimes:tinymce.explode(f[m][2]||""),codebase:f[m][3]};for(p=0;p<q.clsids.length;p++){l["clsid:"+q.clsids[p]]=q}for(p=0;p<q.mimes.length;p++){l[q.mimes[p]]=q}l["mceItem"+k]=q;l[k.toLowerCase()]=q;a+=(a?"|":"")+k}tinymce.each(n.getParam("media_types","video=mp4,m4v,ogv,webm;silverlight=xap;flash=swf,flv;shockwave=dcr;quicktime=mov,qt,mpg,mpeg;shockwave=dcr;windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;realmedia=rm,ra,ram;java=jar;audio=mp3,ogg").split(";"),function(v){var s,u,t;v=v.split(/=/);u=tinymce.explode(v[1].toLowerCase());for(s=0;s<u.length;s++){t=l[v[0].toLowerCase()];if(t){l[u[s]]=t}}});a=new RegExp("write("+a+")\\(([^)]+)\\)");r.lookup=l;n.onPreInit.add(function(){n.schema.addValidElements("object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]");n.parser.addNodeFilter("object,embed,video,audio,script,iframe",function(s){var t=s.length;while(t--){r.objectToImg(s[t])}});n.serializer.addNodeFilter("img",function(s,u,t){var v=s.length,w;while(v--){w=s[v];if((w.attr("class")||"").indexOf("mceItemMedia")!==-1){r.imgToObject(w,t)}}})});n.onInit.add(function(){if(n.theme&&n.theme.onResolveName){n.theme.onResolveName.add(function(i,s){if(s.name==="img"&&n.dom.hasClass(s.node,"mceItemMedia")){s.name="media"}})}if(n&&n.plugins.contextmenu){n.plugins.contextmenu.onContextMenu.add(function(s,t,i){if(i.nodeName==="IMG"&&i.className.indexOf("mceItemMedia")!==-1){t.add({title:"media.edit",icon:"media",cmd:"mceMedia"})}})}});n.addCommand("mceMedia",function(){var s,i;i=n.selection.getNode();if(o(i)){s=n.dom.getAttrib(i,"data-mce-json");if(s){s=g.parse(s);tinymce.each(d,function(t){var u=n.dom.getAttrib(i,t);if(u){s[t]=u}});s.type=r.getType(i.className).name.toLowerCase()}}if(!s){s={type:"flash",video:{sources:[]},params:{}}}n.windowManager.open({file:j+"/media.htm",width:430+parseInt(n.getLang("media.delta_width",0)),height:500+parseInt(n.getLang("media.delta_height",0)),inline:1},{plugin_url:j,data:s})});n.addButton("media",{title:"media.desc",cmd:"mceMedia"});n.onNodeChange.add(function(s,i,t){i.setActive("media",o(t))})},convertUrl:function(k,n){var j=this,m=j.editor,l=m.settings,o=l.url_converter,i=l.url_converter_scope||j;if(!k){return k}if(n){return m.documentBaseURI.toAbsolute(k)}return o.call(i,k,"src","object")},getInfo:function(){return{longname:"Media",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media",version:tinymce.majorVersion+"."+tinymce.minorVersion}},dataToImg:function(m,k){var r=this,o=r.editor,p=o.documentBaseURI,j,q,n,l;m.params.src=r.convertUrl(m.params.src,k);q=m.video.attrs;if(q){q.src=r.convertUrl(q.src,k)}if(q){q.poster=r.convertUrl(q.poster,k)}j=c(m.video.sources);if(j){for(l=0;l<j.length;l++){j[l].src=r.convertUrl(j[l].src,k)}}n=r.editor.dom.create("img",{id:m.id,style:m.style,align:m.align,hspace:m.hspace,vspace:m.vspace,src:r.editor.theme.url+"/img/trans.gif","class":"mceItemMedia mceItem"+r.getType(m.type).name,"data-mce-json":g.serialize(m,"'")});n.width=m.width||(m.type=="audio"?"300":"320");n.height=m.height||(m.type=="audio"?"32":"240");return n},dataToHtml:function(i,j){return this.editor.serializer.serialize(this.dataToImg(i,j),{forced_root_block:"",force_absolute:j})},htmlToData:function(k){var j,i,l;l={type:"flash",video:{sources:[]},params:{}};j=this.editor.parser.parse(k);i=j.getAll("img")[0];if(i){l=g.parse(i.attr("data-mce-json"));l.type=this.getType(i.attr("class")).name.toLowerCase();tinymce.each(d,function(m){var n=i.attr(m);if(n){l[m]=n}})}return l},getType:function(m){var k,j,l;j=tinymce.explode(m," ");for(k=0;k<j.length;k++){l=this.lookup[j[k]];if(l){return l}}},imgToObject:function(z,o){var u=this,p=u.editor,C,H,j,t,I,y,G,w,k,E,s,q,A,D,m,x,l,B,F;function r(i,n){var M,L,N,K,J;J=p.getParam("flash_video_player_url",u.convertUrl(u.url+"/moxieplayer.swf"));if(J){M=p.documentBaseURI;G.params.src=J;if(p.getParam("flash_video_player_absvideourl",true)){i=M.toAbsolute(i||"",true);n=M.toAbsolute(n||"",true)}N="";L=p.getParam("flash_video_player_flashvars",{url:"$url",poster:"$poster"});tinymce.each(L,function(P,O){P=P.replace(/\$url/,i||"");P=P.replace(/\$poster/,n||"");if(P.length>0){N+=(N?"&":"")+O+"="+escape(P)}});if(N.length){G.params.flashvars=N}K=p.getParam("flash_video_player_params",{allowfullscreen:true,allowscriptaccess:true});tinymce.each(K,function(P,O){G.params[O]=""+P})}}G=z.attr("data-mce-json");if(!G){return}G=g.parse(G);q=this.getType(z.attr("class"));B=z.attr("data-mce-style");if(!B){B=z.attr("style");if(B){B=p.dom.serializeStyle(p.dom.parseStyle(B,"img"))}}if(q.name==="Iframe"){x=new b("iframe",1);tinymce.each(d,function(i){var n=z.attr(i);if(i=="class"&&n){n=n.replace(/mceItem.+ ?/g,"")}if(n&&n.length>0){x.attr(i,n)}});for(I in G.params){x.attr(I,G.params[I])}x.attr({style:B,src:G.params.src});z.replace(x);return}if(this.editor.settings.media_use_script){x=new b("script",1).attr("type","text/javascript");y=new b("#text",3);y.value="write"+q.name+"("+g.serialize(tinymce.extend(G.params,{width:z.attr("width"),height:z.attr("height")}))+");";x.append(y);z.replace(x);return}if(q.name==="Video"&&G.video.sources[0]){C=new b("video",1).attr(tinymce.extend({id:z.attr("id"),width:z.attr("width"),height:z.attr("height"),style:B},G.video.attrs));if(G.video.attrs){l=G.video.attrs.poster}k=G.video.sources=c(G.video.sources);for(A=0;A<k.length;A++){if(/\.mp4$/.test(k[A].src)){m=k[A].src}}if(!k[0].type){C.attr("src",k[0].src);k.splice(0,1)}for(A=0;A<k.length;A++){w=new b("source",1).attr(k[A]);w.shortEnded=true;C.append(w)}if(m){r(m,l);q=u.getType("flash")}else{G.params.src=""}}if(q.name==="Audio"&&G.video.sources[0]){F=new b("audio",1).attr(tinymce.extend({id:z.attr("id"),width:z.attr("width"),height:z.attr("height"),style:B},G.video.attrs));if(G.video.attrs){l=G.video.attrs.poster}k=G.video.sources=c(G.video.sources);if(!k[0].type){F.attr("src",k[0].src);k.splice(0,1)}for(A=0;A<k.length;A++){w=new b("source",1).attr(k[A]);w.shortEnded=true;F.append(w)}G.params.src=""}if(q.name==="EmbeddedAudio"){j=new b("embed",1);j.shortEnded=true;j.attr({id:z.attr("id"),width:z.attr("width"),height:z.attr("height"),style:B,type:z.attr("type")});for(I in G.params){j.attr(I,G.params[I])}tinymce.each(d,function(i){if(G[i]&&i!="type"){j.attr(i,G[i])}});G.params.src=""}if(G.params.src){if(/\.flv$/i.test(G.params.src)){r(G.params.src,"")}if(o&&o.force_absolute){G.params.src=p.documentBaseURI.toAbsolute(G.params.src)}H=new b("object",1).attr({id:z.attr("id"),width:z.attr("width"),height:z.attr("height"),style:B});tinymce.each(d,function(i){var n=G[i];if(i=="class"&&n){n=n.replace(/mceItem.+ ?/g,"")}if(n&&i!="type"){H.attr(i,n)}});for(I in G.params){s=new b("param",1);s.shortEnded=true;y=G.params[I];if(I==="src"&&q.name==="WindowsMedia"){I="url"}s.attr({name:I,value:y});H.append(s)}if(this.editor.getParam("media_strict",true)){H.attr({data:G.params.src,type:q.mimes[0]})}else{H.attr({classid:"clsid:"+q.clsids[0],codebase:q.codebase});j=new b("embed",1);j.shortEnded=true;j.attr({id:z.attr("id"),width:z.attr("width"),height:z.attr("height"),style:B,type:q.mimes[0]});for(I in G.params){j.attr(I,G.params[I])}tinymce.each(d,function(i){if(G[i]&&i!="type"){j.attr(i,G[i])}});H.append(j)}if(G.object_html){y=new b("#text",3);y.raw=true;y.value=G.object_html;H.append(y)}if(C){C.append(H)}}if(C){if(G.video_html){y=new b("#text",3);y.raw=true;y.value=G.video_html;C.append(y)}}if(F){if(G.video_html){y=new b("#text",3);y.raw=true;y.value=G.video_html;F.append(y)}}var v=C||F||H||j;if(v){z.replace(v)}else{z.remove()}},objectToImg:function(C){var L,k,F,s,M,N,y,A,x,G,E,t,q,I,B,l,K,o,H=this.lookup,m,z,v=this.editor.settings.url_converter,n=this.editor.settings.url_converter_scope,w,r,D,j;function u(i){return new tinymce.html.Serializer({inner:true,validate:false}).serialize(i)}function J(O,i){return H[(O.attr(i)||"").toLowerCase()]}function p(O){var i=O.replace(/^.*\.([^.]+)$/,"$1");return H[i.toLowerCase()||""]}if(!C.parent){return}if(C.name==="script"){if(C.firstChild){m=a.exec(C.firstChild.value)}if(!m){return}o=m[1];K={video:{},params:g.parse(m[2])};A=K.params.width;x=K.params.height}K=K||{video:{},params:{}};M=new b("img",1);M.attr({src:this.editor.theme.url+"/img/trans.gif"});N=C.name;if(N==="video"||N=="audio"){F=C;L=C.getAll("object")[0];k=C.getAll("embed")[0];A=F.attr("width");x=F.attr("height");y=F.attr("id");K.video={attrs:{},sources:[]};z=K.video.attrs;for(N in F.attributes.map){z[N]=F.attributes.map[N]}B=C.attr("src");if(B){K.video.sources.push({src:v.call(n,B,"src",C.name)})}l=F.getAll("source");for(E=0;E<l.length;E++){B=l[E].remove();K.video.sources.push({src:v.call(n,B.attr("src"),"src","source"),type:B.attr("type"),media:B.attr("media")})}if(z.poster){z.poster=v.call(n,z.poster,"poster",C.name)}}if(C.name==="object"){L=C;k=C.getAll("embed")[0]}if(C.name==="embed"){k=C}if(C.name==="iframe"){s=C;o="Iframe"}if(L){A=A||L.attr("width");x=x||L.attr("height");G=G||L.attr("style");y=y||L.attr("id");w=w||L.attr("hspace");r=r||L.attr("vspace");D=D||L.attr("align");j=j||L.attr("bgcolor");K.name=L.attr("name");I=L.getAll("param");for(E=0;E<I.length;E++){q=I[E];N=q.remove().attr("name");if(!h[N]){K.params[N]=q.attr("value")}}K.params.src=K.params.src||L.attr("data")}if(k){A=A||k.attr("width");x=x||k.attr("height");G=G||k.attr("style");y=y||k.attr("id");w=w||k.attr("hspace");r=r||k.attr("vspace");D=D||k.attr("align");j=j||k.attr("bgcolor");for(N in k.attributes.map){if(!h[N]&&!K.params[N]){K.params[N]=k.attributes.map[N]}}}if(s){A=s.attr("width");x=s.attr("height");G=G||s.attr("style");y=s.attr("id");w=s.attr("hspace");r=s.attr("vspace");D=s.attr("align");j=s.attr("bgcolor");tinymce.each(d,function(i){M.attr(i,s.attr(i))});for(N in s.attributes.map){if(!h[N]&&!K.params[N]){K.params[N]=s.attributes.map[N]}}}if(K.params.movie){K.params.src=K.params.src||K.params.movie;delete K.params.movie}if(K.params.src){K.params.src=v.call(n,K.params.src,"src","object")}if(F){if(C.name==="video"){o=H.video.name}else{if(C.name==="audio"){o=H.audio.name}}}if(L&&!o){o=(J(L,"clsid")||J(L,"classid")||J(L,"type")||{}).name}if(k&&!o){o=(J(k,"type")||p(K.params.src)||{}).name}if(k&&o=="EmbeddedAudio"){K.params.type=k.attr("type")}C.replace(M);if(k){k.remove()}if(L){t=u(L.remove());if(t){K.object_html=t}}if(F){t=u(F.remove());if(t){K.video_html=t}}K.hspace=w;K.vspace=r;K.align=D;K.bgcolor=j;M.attr({id:y,"class":"mceItemMedia mceItem"+(o||"Flash"),style:G,width:A||(C.name=="audio"?"300":"320"),height:x||(C.name=="audio"?"32":"240"),hspace:w,vspace:r,align:D,bgcolor:j,"data-mce-json":g.serialize(K,"'")})}});tinymce.PluginManager.add("media",tinymce.plugins.MediaPlugin)})(); \ No newline at end of file +(function(){var b=tinymce.explode("id,name,width,height,style,align,class,hspace,vspace,bgcolor,type"),a=tinymce.makeMap(b.join(",")),f=tinymce.html.Node,d,i,h=tinymce.util.JSON,g;d=[["Flash","d27cdb6e-ae6d-11cf-96b8-444553540000","application/x-shockwave-flash","http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],["ShockWave","166b1bca-3f9c-11cf-8075-444553540000","application/x-director","http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"],["WindowsMedia","6bf52a52-394a-11d3-b153-00c04f79faa6,22d6f312-b0f6-11d0-94ab-0080c74c7e95,05589fa1-c356-11ce-bf01-00aa0055595a","application/x-mplayer2","http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701"],["QuickTime","02bf25d5-8c17-4b23-bc80-d3488abddc6b","video/quicktime","http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"],["RealMedia","cfcdaa03-8be4-11cf-b84b-0020afbbccfa","audio/x-pn-realaudio-plugin","http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"],["Java","8ad9c840-044e-11d1-b3e9-00805f499d93","application/x-java-applet","http://java.sun.com/products/plugin/autodl/jinstall-1_5_0-windows-i586.cab#Version=1,5,0,0"],["Silverlight","dfeaf541-f3e1-4c24-acac-99c30715084a","application/x-silverlight-2"],["Iframe"],["Video"],["EmbeddedAudio"],["Audio"]];function e(j){return typeof(j)=="string"?j.replace(/[^0-9%]/g,""):j}function c(m){var l,j,k;if(m&&!m.splice){j=[];for(k=0;true;k++){if(m[k]){j[k]=m[k]}else{break}}return j}return m}tinymce.create("tinymce.plugins.MediaPlugin",{init:function(n,j){var r=this,l={},m,p,q,k;function o(s){return s&&s.nodeName==="IMG"&&n.dom.hasClass(s,"mceItemMedia")}r.editor=n;r.url=j;i="";for(m=0;m<d.length;m++){k=d[m][0];q={name:k,clsids:tinymce.explode(d[m][1]||""),mimes:tinymce.explode(d[m][2]||""),codebase:d[m][3]};for(p=0;p<q.clsids.length;p++){l["clsid:"+q.clsids[p]]=q}for(p=0;p<q.mimes.length;p++){l[q.mimes[p]]=q}l["mceItem"+k]=q;l[k.toLowerCase()]=q;i+=(i?"|":"")+k}tinymce.each(n.getParam("media_types","video=mp4,m4v,ogv,webm;silverlight=xap;flash=swf,flv;shockwave=dcr;quicktime=mov,qt,mpg,mpeg;shockwave=dcr;windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;realmedia=rm,ra,ram;java=jar;audio=mp3,ogg").split(";"),function(v){var s,u,t;v=v.split(/=/);u=tinymce.explode(v[1].toLowerCase());for(s=0;s<u.length;s++){t=l[v[0].toLowerCase()];if(t){l[u[s]]=t}}});i=new RegExp("write("+i+")\\(([^)]+)\\)");r.lookup=l;n.onPreInit.add(function(){n.schema.addValidElements("object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]");n.parser.addNodeFilter("object,embed,video,audio,script,iframe",function(s){var t=s.length;while(t--){r.objectToImg(s[t])}});n.serializer.addNodeFilter("img",function(s,u,t){var v=s.length,w;while(v--){w=s[v];if((w.attr("class")||"").indexOf("mceItemMedia")!==-1){r.imgToObject(w,t)}}})});n.onInit.add(function(){if(n.theme&&n.theme.onResolveName){n.theme.onResolveName.add(function(s,t){if(t.name==="img"&&n.dom.hasClass(t.node,"mceItemMedia")){t.name="media"}})}if(n&&n.plugins.contextmenu){n.plugins.contextmenu.onContextMenu.add(function(t,u,s){if(s.nodeName==="IMG"&&s.className.indexOf("mceItemMedia")!==-1){u.add({title:"media.edit",icon:"media",cmd:"mceMedia"})}})}});n.addCommand("mceMedia",function(){var t,s;s=n.selection.getNode();if(o(s)){t=n.dom.getAttrib(s,"data-mce-json");if(t){t=h.parse(t);tinymce.each(b,function(u){var v=n.dom.getAttrib(s,u);if(v){t[u]=v}});t.type=r.getType(s.className).name.toLowerCase()}}if(!t){t={type:"flash",video:{sources:[]},params:{}}}n.windowManager.open({file:j+"/media.htm",width:430+parseInt(n.getLang("media.delta_width",0)),height:500+parseInt(n.getLang("media.delta_height",0)),inline:1},{plugin_url:j,data:t})});n.addButton("media",{title:"media.desc",cmd:"mceMedia"});n.onNodeChange.add(function(t,s,u){s.setActive("media",o(u))})},convertUrl:function(l,o){var k=this,n=k.editor,m=n.settings,p=m.url_converter,j=m.url_converter_scope||k;if(!l){return l}if(o){return n.documentBaseURI.toAbsolute(l)}return p.call(j,l,"src","object")},getInfo:function(){return{longname:"Media",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/media",version:tinymce.majorVersion+"."+tinymce.minorVersion}},dataToImg:function(m,k){var r=this,o=r.editor,p=o.documentBaseURI,j,q,n,l;m.params.src=r.convertUrl(m.params.src,k);q=m.video.attrs;if(q){q.src=r.convertUrl(q.src,k)}if(q){q.poster=r.convertUrl(q.poster,k)}j=c(m.video.sources);if(j){for(l=0;l<j.length;l++){j[l].src=r.convertUrl(j[l].src,k)}}n=r.editor.dom.create("img",{id:m.id,style:m.style,align:m.align,hspace:m.hspace,vspace:m.vspace,src:r.editor.theme.url+"/img/trans.gif","class":"mceItemMedia mceItem"+r.getType(m.type).name,"data-mce-json":h.serialize(m,"'")});n.width=m.width=e(m.width||(m.type=="audio"?"300":"320"));n.height=m.height=e(m.height||(m.type=="audio"?"32":"240"));return n},dataToHtml:function(j,k){return this.editor.serializer.serialize(this.dataToImg(j,k),{forced_root_block:"",force_absolute:k})},htmlToData:function(l){var k,j,m;m={type:"flash",video:{sources:[]},params:{}};k=this.editor.parser.parse(l);j=k.getAll("img")[0];if(j){m=h.parse(j.attr("data-mce-json"));m.type=this.getType(j.attr("class")).name.toLowerCase();tinymce.each(b,function(n){var o=j.attr(n);if(o){m[n]=o}})}return m},getType:function(m){var k,j,l;j=tinymce.explode(m," ");for(k=0;k<j.length;k++){l=this.lookup[j[k]];if(l){return l}}},imgToObject:function(z,o){var u=this,p=u.editor,C,H,j,t,I,y,G,w,k,E,s,q,A,D,m,x,l,B,F;function r(n,J){var N,M,O,L,K;K=p.getParam("flash_video_player_url",u.convertUrl(u.url+"/moxieplayer.swf"));if(K){N=p.documentBaseURI;G.params.src=K;if(p.getParam("flash_video_player_absvideourl",true)){n=N.toAbsolute(n||"",true);J=N.toAbsolute(J||"",true)}O="";M=p.getParam("flash_video_player_flashvars",{url:"$url",poster:"$poster"});tinymce.each(M,function(Q,P){Q=Q.replace(/\$url/,n||"");Q=Q.replace(/\$poster/,J||"");if(Q.length>0){O+=(O?"&":"")+P+"="+escape(Q)}});if(O.length){G.params.flashvars=O}L=p.getParam("flash_video_player_params",{allowfullscreen:true,allowscriptaccess:true});tinymce.each(L,function(Q,P){G.params[P]=""+Q})}}G=z.attr("data-mce-json");if(!G){return}G=h.parse(G);q=this.getType(z.attr("class"));B=z.attr("data-mce-style");if(!B){B=z.attr("style");if(B){B=p.dom.serializeStyle(p.dom.parseStyle(B,"img"))}}G.width=z.attr("width")||G.width;G.height=z.attr("height")||G.height;if(q.name==="Iframe"){x=new f("iframe",1);tinymce.each(b,function(n){var J=z.attr(n);if(n=="class"&&J){J=J.replace(/mceItem.+ ?/g,"")}if(J&&J.length>0){x.attr(n,J)}});for(I in G.params){x.attr(I,G.params[I])}x.attr({style:B,src:G.params.src});z.replace(x);return}if(this.editor.settings.media_use_script){x=new f("script",1).attr("type","text/javascript");y=new f("#text",3);y.value="write"+q.name+"("+h.serialize(tinymce.extend(G.params,{width:z.attr("width"),height:z.attr("height")}))+");";x.append(y);z.replace(x);return}if(q.name==="Video"&&G.video.sources[0]){C=new f("video",1).attr(tinymce.extend({id:z.attr("id"),width:e(z.attr("width")),height:e(z.attr("height")),style:B},G.video.attrs));if(G.video.attrs){l=G.video.attrs.poster}k=G.video.sources=c(G.video.sources);for(A=0;A<k.length;A++){if(/\.mp4$/.test(k[A].src)){m=k[A].src}}if(!k[0].type){C.attr("src",k[0].src);k.splice(0,1)}for(A=0;A<k.length;A++){w=new f("source",1).attr(k[A]);w.shortEnded=true;C.append(w)}if(m){r(m,l);q=u.getType("flash")}else{G.params.src=""}}if(q.name==="Audio"&&G.video.sources[0]){F=new f("audio",1).attr(tinymce.extend({id:z.attr("id"),width:e(z.attr("width")),height:e(z.attr("height")),style:B},G.video.attrs));if(G.video.attrs){l=G.video.attrs.poster}k=G.video.sources=c(G.video.sources);if(!k[0].type){F.attr("src",k[0].src);k.splice(0,1)}for(A=0;A<k.length;A++){w=new f("source",1).attr(k[A]);w.shortEnded=true;F.append(w)}G.params.src=""}if(q.name==="EmbeddedAudio"){j=new f("embed",1);j.shortEnded=true;j.attr({id:z.attr("id"),width:e(z.attr("width")),height:e(z.attr("height")),style:B,type:z.attr("type")});for(I in G.params){j.attr(I,G.params[I])}tinymce.each(b,function(n){if(G[n]&&n!="type"){j.attr(n,G[n])}});G.params.src=""}if(G.params.src){if(/\.flv$/i.test(G.params.src)){r(G.params.src,"")}if(o&&o.force_absolute){G.params.src=p.documentBaseURI.toAbsolute(G.params.src)}H=new f("object",1).attr({id:z.attr("id"),width:e(z.attr("width")),height:e(z.attr("height")),style:B});tinymce.each(b,function(n){var J=G[n];if(n=="class"&&J){J=J.replace(/mceItem.+ ?/g,"")}if(J&&n!="type"){H.attr(n,J)}});for(I in G.params){s=new f("param",1);s.shortEnded=true;y=G.params[I];if(I==="src"&&q.name==="WindowsMedia"){I="url"}s.attr({name:I,value:y});H.append(s)}if(this.editor.getParam("media_strict",true)){H.attr({data:G.params.src,type:q.mimes[0]})}else{H.attr({classid:"clsid:"+q.clsids[0],codebase:q.codebase});j=new f("embed",1);j.shortEnded=true;j.attr({id:z.attr("id"),width:e(z.attr("width")),height:e(z.attr("height")),style:B,type:q.mimes[0]});for(I in G.params){j.attr(I,G.params[I])}tinymce.each(b,function(n){if(G[n]&&n!="type"){j.attr(n,G[n])}});H.append(j)}if(G.object_html){y=new f("#text",3);y.raw=true;y.value=G.object_html;H.append(y)}if(C){C.append(H)}}if(C){if(G.video_html){y=new f("#text",3);y.raw=true;y.value=G.video_html;C.append(y)}}if(F){if(G.video_html){y=new f("#text",3);y.raw=true;y.value=G.video_html;F.append(y)}}var v=C||F||H||j;if(v){z.replace(v)}else{z.remove()}},objectToImg:function(C){var L,k,F,s,M,N,y,A,x,G,E,t,q,I,B,l,K,o,H=this.lookup,m,z,v=this.editor.settings.url_converter,n=this.editor.settings.url_converter_scope,w,r,D,j;function u(O){return new tinymce.html.Serializer({inner:true,validate:false}).serialize(O)}function J(P,O){return H[(P.attr(O)||"").toLowerCase()]}function p(P){var O=P.replace(/^.*\.([^.]+)$/,"$1");return H[O.toLowerCase()||""]}if(!C.parent){return}if(C.name==="script"){if(C.firstChild){m=i.exec(C.firstChild.value)}if(!m){return}o=m[1];K={video:{},params:h.parse(m[2])};A=K.params.width;x=K.params.height}K=K||{video:{},params:{}};M=new f("img",1);M.attr({src:this.editor.theme.url+"/img/trans.gif"});N=C.name;if(N==="video"||N=="audio"){F=C;L=C.getAll("object")[0];k=C.getAll("embed")[0];A=F.attr("width");x=F.attr("height");y=F.attr("id");K.video={attrs:{},sources:[]};z=K.video.attrs;for(N in F.attributes.map){z[N]=F.attributes.map[N]}B=C.attr("src");if(B){K.video.sources.push({src:v.call(n,B,"src",C.name)})}l=F.getAll("source");for(E=0;E<l.length;E++){B=l[E].remove();K.video.sources.push({src:v.call(n,B.attr("src"),"src","source"),type:B.attr("type"),media:B.attr("media")})}if(z.poster){z.poster=v.call(n,z.poster,"poster",C.name)}}if(C.name==="object"){L=C;k=C.getAll("embed")[0]}if(C.name==="embed"){k=C}if(C.name==="iframe"){s=C;o="Iframe"}if(L){A=A||L.attr("width");x=x||L.attr("height");G=G||L.attr("style");y=y||L.attr("id");w=w||L.attr("hspace");r=r||L.attr("vspace");D=D||L.attr("align");j=j||L.attr("bgcolor");K.name=L.attr("name");I=L.getAll("param");for(E=0;E<I.length;E++){q=I[E];N=q.remove().attr("name");if(!a[N]){K.params[N]=q.attr("value")}}K.params.src=K.params.src||L.attr("data")}if(k){A=A||k.attr("width");x=x||k.attr("height");G=G||k.attr("style");y=y||k.attr("id");w=w||k.attr("hspace");r=r||k.attr("vspace");D=D||k.attr("align");j=j||k.attr("bgcolor");for(N in k.attributes.map){if(!a[N]&&!K.params[N]){K.params[N]=k.attributes.map[N]}}}if(s){A=e(s.attr("width"));x=e(s.attr("height"));G=G||s.attr("style");y=s.attr("id");w=s.attr("hspace");r=s.attr("vspace");D=s.attr("align");j=s.attr("bgcolor");tinymce.each(b,function(O){M.attr(O,s.attr(O))});for(N in s.attributes.map){if(!a[N]&&!K.params[N]){K.params[N]=s.attributes.map[N]}}}if(K.params.movie){K.params.src=K.params.src||K.params.movie;delete K.params.movie}if(K.params.src){K.params.src=v.call(n,K.params.src,"src","object")}if(F){if(C.name==="video"){o=H.video.name}else{if(C.name==="audio"){o=H.audio.name}}}if(L&&!o){o=(J(L,"clsid")||J(L,"classid")||J(L,"type")||{}).name}if(k&&!o){o=(J(k,"type")||p(K.params.src)||{}).name}if(k&&o=="EmbeddedAudio"){K.params.type=k.attr("type")}C.replace(M);if(k){k.remove()}if(L){t=u(L.remove());if(t){K.object_html=t}}if(F){t=u(F.remove());if(t){K.video_html=t}}K.hspace=w;K.vspace=r;K.align=D;K.bgcolor=j;M.attr({id:y,"class":"mceItemMedia mceItem"+(o||"Flash"),style:G,width:A||(C.name=="audio"?"300":"320"),height:x||(C.name=="audio"?"32":"240"),hspace:w,vspace:r,align:D,bgcolor:j,"data-mce-json":h.serialize(K,"'")})}});tinymce.PluginManager.add("media",tinymce.plugins.MediaPlugin)})(); \ No newline at end of file diff --git a/plugins/media/editor_plugin_src.js b/plugins/media/editor_plugin_src.js index ea79db18a765137be9209c32b95dbaa3aebf8e21..33a58050eac93143222e27abdd72987423ac6ebd 100644 --- a/plugins/media/editor_plugin_src.js +++ b/plugins/media/editor_plugin_src.js @@ -28,6 +28,10 @@ ["Audio"] ]; + function normalizeSize(size) { + return typeof(size) == "string" ? size.replace(/[^0-9%]/g, '') : size; + } + function toArray(obj) { var undef, out, i; @@ -258,8 +262,8 @@ 'data-mce-json' : JSON.serialize(data, "'") }); - img.width = data.width || (data.type == 'audio' ? "300" : "320"); - img.height = data.height || (data.type == 'audio' ? "32" : "240"); + img.width = data.width = normalizeSize(data.width || (data.type == 'audio' ? "300" : "320")); + img.height = data.height = normalizeSize(data.height || (data.type == 'audio' ? "32" : "240")); return img; }, @@ -378,7 +382,7 @@ data = JSON.parse(data); typeItem = this.getType(node.attr('class')); - style = node.attr('data-mce-style') + style = node.attr('data-mce-style'); if (!style) { style = node.attr('style'); @@ -386,6 +390,10 @@ style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img')); } + // Use node width/height to override the data width/height when the placeholder is resized + data.width = node.attr('width') || data.width; + data.height = node.attr('height') || data.height; + // Handle iframe if (typeItem.name === 'Iframe') { replacement = new Node('iframe', 1); @@ -434,8 +442,8 @@ // Create new object element video = new Node('video', 1).attr(tinymce.extend({ id : node.attr('id'), - width: node.attr('width'), - height: node.attr('height'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), style : style }, data.video.attrs)); @@ -473,8 +481,8 @@ // Create new object element audio = new Node('audio', 1).attr(tinymce.extend({ id : node.attr('id'), - width: node.attr('width'), - height: node.attr('height'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), style : style }, data.video.attrs)); @@ -502,8 +510,8 @@ embed.shortEnded = true; embed.attr({ id: node.attr('id'), - width: node.attr('width'), - height: node.attr('height'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), style : style, type: node.attr('type') }); @@ -531,8 +539,8 @@ // Create new object element object = new Node('object', 1).attr({ id : node.attr('id'), - width: node.attr('width'), - height: node.attr('height'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), style : style }); @@ -576,8 +584,8 @@ embed.shortEnded = true; embed.attr({ id: node.attr('id'), - width: node.attr('width'), - height: node.attr('height'), + width: normalizeSize(node.attr('width')), + height: normalizeSize(node.attr('height')), style : style, type: typeItem.mimes[0] }); @@ -793,8 +801,8 @@ if (iframe) { // Get width/height - width = iframe.attr('width'); - height = iframe.attr('height'); + width = normalizeSize(iframe.attr('width')); + height = normalizeSize(iframe.attr('height')); style = style || iframe.attr('style'); id = iframe.attr('id'); hspace = iframe.attr('hspace'); diff --git a/plugins/media/js/media.js b/plugins/media/js/media.js index 733c5f6c284169f979d2e79880128261f0b59718..89cea2a4107ec326b8bc8b3d8e879c869c3780d1 100644 --- a/plugins/media/js/media.js +++ b/plugins/media/js/media.js @@ -78,7 +78,7 @@ get('video_altsource2_filebrowser').innerHTML = getBrowserHTML('video_filebrowser_altsource2','video_altsource2','media','media'); get('audio_altsource1_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource1','audio_altsource1','media','media'); get('audio_altsource2_filebrowser').innerHTML = getBrowserHTML('audio_filebrowser_altsource2','audio_altsource2','media','media'); - get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','media','image'); + get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','image','media'); html = self.getMediaListHTML('medialist', 'src', 'media', 'media'); if (html == "") @@ -295,34 +295,77 @@ } else { src = getVal("src"); - // YouTube *NEW* - if (src.match(/youtu.be\/[a-z1-9.-_]+/)) { + // YouTube Embed + if (src.match(/youtube\.com\/embed\/\w+/)) { data.width = 425; data.height = 350; data.params.frameborder = '0'; data.type = 'iframe'; - src = 'http://www.youtube.com/embed/' + src.match(/youtu.be\/([a-z1-9.-_]+)/)[1]; setVal('src', src); setVal('media_type', data.type); + } else { + // YouTube *NEW* + if (src.match(/youtu\.be\/[a-z1-9.-_]+/)) { + data.width = 425; + data.height = 350; + data.params.frameborder = '0'; + data.type = 'iframe'; + src = 'http://www.youtube.com/embed/' + src.match(/youtu.be\/([a-z1-9.-_]+)/)[1]; + setVal('src', src); + setVal('media_type', data.type); + } + + // YouTube + if (src.match(/youtube\.com(.+)v=([^&]+)/)) { + data.width = 425; + data.height = 350; + data.params.frameborder = '0'; + data.type = 'iframe'; + src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1]; + setVal('src', src); + setVal('media_type', data.type); + } } - // YouTube - if (src.match(/youtube.com(.+)v=([^&]+)/)) { + // Google video + if (src.match(/video\.google\.com(.+)docid=([^&]+)/)) { + data.width = 425; + data.height = 326; + data.type = 'flash'; + src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en'; + setVal('src', src); + setVal('media_type', data.type); + } + + // Vimeo + if (src.match(/vimeo\.com\/([0-9]+)/)) { data.width = 425; data.height = 350; data.params.frameborder = '0'; data.type = 'iframe'; - src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1]; + src = 'http://player.vimeo.com/video/' + src.match(/vimeo.com\/([0-9]+)/)[1]; setVal('src', src); setVal('media_type', data.type); } - - // Google video - if (src.match(/video.google.com(.+)docid=([^&]+)/)) { + + // stream.cz + if (src.match(/stream\.cz\/((?!object).)*\/([0-9]+)/)) { data.width = 425; - data.height = 326; - data.type = 'flash'; - src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en'; + data.height = 350; + data.params.frameborder = '0'; + data.type = 'iframe'; + src = 'http://www.stream.cz/object/' + src.match(/stream.cz\/[^/]+\/([0-9]+)/)[1]; + setVal('src', src); + setVal('media_type', data.type); + } + + // Google maps + if (src.match(/maps\.google\.([a-z]{2,3})\/maps\/(.+)msid=(.+)/)) { + data.width = 425; + data.height = 350; + data.params.frameborder = '0'; + data.type = 'iframe'; + src = 'http://maps.google.com/maps/ms?msid=' + src.match(/msid=(.+)/)[1] + "&output=embed"; setVal('src', src); setVal('media_type', data.type); } diff --git a/plugins/noneditable/editor_plugin.js b/plugins/noneditable/editor_plugin.js index 2d60138eecdea6c6ee1b6ea9f8b77c073695f52b..da411ebc09c66da6e447d0b22109a3b41bb929f9 100644 --- a/plugins/noneditable/editor_plugin.js +++ b/plugins/noneditable/editor_plugin.js @@ -1 +1 @@ -(function(){var a=tinymce.dom.Event;tinymce.create("tinymce.plugins.NonEditablePlugin",{init:function(d,e){var f=this,c,b,g;f.editor=d;c=d.getParam("noneditable_editable_class","mceEditable");b=d.getParam("noneditable_noneditable_class","mceNonEditable");d.onNodeChange.addToTop(function(i,h,l){var k,j;k=i.dom.getParent(i.selection.getStart(),function(m){return i.dom.hasClass(m,b)});j=i.dom.getParent(i.selection.getEnd(),function(m){return i.dom.hasClass(m,b)});if(k||j){g=1;f._setDisabled(1);return false}else{if(g==1){f._setDisabled(0);g=0}}})},getInfo:function(){return{longname:"Non editable elements",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_block:function(c,d){var b=d.keyCode;if((b>32&&b<41)||(b>111&&b<124)){return}return a.cancel(d)},_setDisabled:function(d){var c=this,b=c.editor;tinymce.each(b.controlManager.controls,function(e){e.setDisabled(d)});if(d!==c.disabled){if(d){b.onKeyDown.addToTop(c._block);b.onKeyPress.addToTop(c._block);b.onKeyUp.addToTop(c._block);b.onPaste.addToTop(c._block);b.onContextMenu.addToTop(c._block)}else{b.onKeyDown.remove(c._block);b.onKeyPress.remove(c._block);b.onKeyUp.remove(c._block);b.onPaste.remove(c._block);b.onContextMenu.remove(c._block)}c.disabled=d}}});tinymce.PluginManager.add("noneditable",tinymce.plugins.NonEditablePlugin)})(); \ No newline at end of file +(function(){var c=tinymce.dom.TreeWalker;var a="contenteditable",d="data-mce-"+a;var e=tinymce.VK;function b(n){var j=n.dom,p=n.selection,r,o="mce_noneditablecaret",r="\uFEFF";function m(t){var s;if(t.nodeType===1){s=t.getAttribute(d);if(s&&s!=="inherit"){return s}s=t.contentEditable;if(s!=="inherit"){return s}}return null}function g(s){var t;while(s){t=m(s);if(t){return t==="false"?s:null}s=s.parentNode}}function l(s){while(s){if(s.id===o){return s}s=s.parentNode}}function k(s){var t;if(s){t=new c(s,s);for(s=t.current();s;s=t.next()){if(s.nodeType===3){return s}}}}function f(v,u){var s,t;if(m(v)==="false"){if(j.isBlock(v)){p.select(v);return}}t=j.createRng();if(m(v)==="true"){if(!v.firstChild){v.appendChild(n.getDoc().createTextNode("\u00a0"))}v=v.firstChild;u=true}s=j.create("span",{id:o,"data-mce-bogus":true},r);if(u){v.parentNode.insertBefore(s,v)}else{j.insertAfter(s,v)}t.setStart(s.firstChild,1);t.collapse(true);p.setRng(t);return s}function i(s){var v,t,u;if(s){rng=p.getRng(true);rng.setStartBefore(s);rng.setEndBefore(s);v=k(s);if(v&&v.nodeValue.charAt(0)==r){v=v.deleteData(0,1)}j.remove(s,true);p.setRng(rng)}else{t=l(p.getStart());while((s=j.get(o))&&s!==u){if(t!==s){v=k(s);if(v&&v.nodeValue.charAt(0)==r){v=v.deleteData(0,1)}j.remove(s,true)}u=s}}}function q(){var s,w,u,t,v;function x(B,D){var A,F,E,C,z;A=t.startContainer;F=t.startOffset;if(A.nodeType==3){z=A.nodeValue.length;if((F>0&&F<z)||(D?F==z:F==0)){return}}else{if(F<A.childNodes.length){var G=!D&&F>0?F-1:F;A=A.childNodes[G];if(A.hasChildNodes()){A=A.firstChild}}else{return !D?B:null}}E=new c(A,B);while(C=E[D?"prev":"next"]()){if(C.nodeType===3&&C.nodeValue.length>0){return}else{if(m(C)==="true"){return C}}}return B}i();u=p.isCollapsed();s=g(p.getStart());w=g(p.getEnd());if(s||w){t=p.getRng(true);if(u){s=s||w;var y=p.getStart();if(v=x(s,true)){f(v,true)}else{if(v=x(s,false)){f(v,false)}else{p.select(s)}}}else{t=p.getRng(true);if(s){t.setStartBefore(s)}if(w){t.setEndAfter(w)}p.setRng(t)}}}function h(z,B){var F=B.keyCode,x,C,D,v;function u(H,G){while(H=H[G?"previousSibling":"nextSibling"]){if(H.nodeType!==3||H.nodeValue.length>0){return H}}}function y(G,H){p.select(G);p.collapse(H)}function t(K){var J,I,M,H;function G(O){var N=I;while(N){if(N===O){return}N=N.parentNode}j.remove(O);q()}function L(){var O,P,N=z.schema.getNonEmptyElements();P=new tinymce.dom.TreeWalker(I,z.getBody());while(O=(K?P.prev():P.next())){if(N[O.nodeName.toLowerCase()]){break}if(O.nodeType===3&&tinymce.trim(O.nodeValue).length>0){break}if(m(O)==="false"){G(O);return true}}if(g(O)){return true}return false}if(p.isCollapsed()){J=p.getRng(true);I=J.startContainer;M=J.startOffset;I=l(I)||I;if(H=g(I)){G(H);return false}if(I.nodeType==3&&(K?M>0:M<I.nodeValue.length)){return true}if(I.nodeType==1){I=I.childNodes[M]||I}if(L()){return false}}return true}D=p.getStart();v=p.getEnd();x=g(D)||g(v);if(x&&(F<112||F>124)&&F!=e.DELETE&&F!=e.BACKSPACE){if((tinymce.isMac?B.metaKey:B.ctrlKey)&&(F==67||F==88||F==86)){return}B.preventDefault();if(F==e.LEFT||F==e.RIGHT){var w=F==e.LEFT;if(z.dom.isBlock(x)){var A=w?x.previousSibling:x.nextSibling;var s=new c(A,A);var E=w?s.prev():s.next();y(E,!w)}else{y(x,w)}}}else{if(F==e.LEFT||F==e.RIGHT||F==e.BACKSPACE||F==e.DELETE){C=l(D);if(C){if(F==e.LEFT||F==e.BACKSPACE){x=u(C,true);if(x&&m(x)==="false"){B.preventDefault();if(F==e.LEFT){y(x,true)}else{j.remove(x);return}}else{i(C)}}if(F==e.RIGHT||F==e.DELETE){x=u(C);if(x&&m(x)==="false"){B.preventDefault();if(F==e.RIGHT){y(x,false)}else{j.remove(x);return}}else{i(C)}}}if((F==e.BACKSPACE||F==e.DELETE)&&!t(F==e.BACKSPACE)){B.preventDefault();return false}}}}n.onMouseDown.addToTop(function(s,u){var t=s.selection.getNode();if(m(t)==="false"&&t==u.target){q()}});n.onMouseUp.addToTop(q);n.onKeyDown.addToTop(h);n.onKeyUp.addToTop(q)}tinymce.create("tinymce.plugins.NonEditablePlugin",{init:function(i,k){var h,g,j;function f(m,n){var o=j.length,p=n.content,l=tinymce.trim(g);if(n.format=="raw"){return}while(o--){p=p.replace(j[o],function(s){var r=arguments,q=r[r.length-2];if(q>0&&p.charAt(q-1)=='"'){return s}return'<span class="'+l+'" data-mce-content="'+m.dom.encode(r[0])+'">'+m.dom.encode(typeof(r[1])==="string"?r[1]:r[0])+"</span>"})}n.content=p}h=" "+tinymce.trim(i.getParam("noneditable_editable_class","mceEditable"))+" ";g=" "+tinymce.trim(i.getParam("noneditable_noneditable_class","mceNonEditable"))+" ";j=i.getParam("noneditable_regexp");if(j&&!j.length){j=[j]}i.onPreInit.add(function(){b(i);if(j){i.selection.onBeforeSetContent.add(f);i.onBeforeSetContent.add(f)}i.parser.addAttributeFilter("class",function(l){var m=l.length,n,o;while(m--){o=l[m];n=" "+o.attr("class")+" ";if(n.indexOf(h)!==-1){o.attr(d,"true")}else{if(n.indexOf(g)!==-1){o.attr(d,"false")}}}});i.serializer.addAttributeFilter(d,function(l,m){var n=l.length,o;while(n--){o=l[n];if(j&&o.attr("data-mce-content")){o.name="#text";o.type=3;o.raw=true;o.value=o.attr("data-mce-content")}else{o.attr(a,null);o.attr(d,null)}}});i.parser.addAttributeFilter(a,function(l,m){var n=l.length,o;while(n--){o=l[n];o.attr(d,o.attr(a));o.attr(a,null)}})})},getInfo:function(){return{longname:"Non editable elements",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("noneditable",tinymce.plugins.NonEditablePlugin)})(); \ No newline at end of file diff --git a/plugins/noneditable/editor_plugin_src.js b/plugins/noneditable/editor_plugin_src.js index 916dce29cfc37bd755c724d36cb5f9ffa5fbfd83..a18bcd786acf3b98bc18b52382ef5bef85786b18 100644 --- a/plugins/noneditable/editor_plugin_src.js +++ b/plugins/noneditable/editor_plugin_src.js @@ -9,37 +9,515 @@ */ (function() { - var Event = tinymce.dom.Event; + var TreeWalker = tinymce.dom.TreeWalker; + var externalName = 'contenteditable', internalName = 'data-mce-' + externalName; + var VK = tinymce.VK; + + function handleContentEditableSelection(ed) { + var dom = ed.dom, selection = ed.selection, invisibleChar, caretContainerId = 'mce_noneditablecaret', invisibleChar = '\uFEFF'; + + // Returns the content editable state of a node "true/false" or null + function getContentEditable(node) { + var contentEditable; + + // Ignore non elements + if (node.nodeType === 1) { + // Check for fake content editable + contentEditable = node.getAttribute(internalName); + if (contentEditable && contentEditable !== "inherit") { + return contentEditable; + } + + // Check for real content editable + contentEditable = node.contentEditable; + if (contentEditable !== "inherit") { + return contentEditable; + } + } + + return null; + }; + + // Returns the noneditable parent or null if there is a editable before it or if it wasn't found + function getNonEditableParent(node) { + var state; + + while (node) { + state = getContentEditable(node); + if (state) { + return state === "false" ? node : null; + } + + node = node.parentNode; + } + }; + + // Get caret container parent for the specified node + function getParentCaretContainer(node) { + while (node) { + if (node.id === caretContainerId) { + return node; + } + + node = node.parentNode; + } + }; + + // Finds the first text node in the specified node + function findFirstTextNode(node) { + var walker; + + if (node) { + walker = new TreeWalker(node, node); + + for (node = walker.current(); node; node = walker.next()) { + if (node.nodeType === 3) { + return node; + } + } + } + }; + + // Insert caret container before/after target or expand selection to include block + function insertCaretContainerOrExpandToBlock(target, before) { + var caretContainer, rng; + + // Select block + if (getContentEditable(target) === "false") { + if (dom.isBlock(target)) { + selection.select(target); + return; + } + } + + rng = dom.createRng(); + + if (getContentEditable(target) === "true") { + if (!target.firstChild) { + target.appendChild(ed.getDoc().createTextNode('\u00a0')); + } + + target = target.firstChild; + before = true; + } + + //caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style:'border: 1px solid red'}, invisibleChar); + caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true}, invisibleChar); + + if (before) { + target.parentNode.insertBefore(caretContainer, target); + } else { + dom.insertAfter(caretContainer, target); + } + + rng.setStart(caretContainer.firstChild, 1); + rng.collapse(true); + selection.setRng(rng); + + return caretContainer; + }; + + // Removes any caret container except the one we might be in + function removeCaretContainer(caretContainer) { + var child, currentCaretContainer, lastContainer; + + if (caretContainer) { + rng = selection.getRng(true); + rng.setStartBefore(caretContainer); + rng.setEndBefore(caretContainer); + + child = findFirstTextNode(caretContainer); + if (child && child.nodeValue.charAt(0) == invisibleChar) { + child = child.deleteData(0, 1); + } + + dom.remove(caretContainer, true); + + selection.setRng(rng); + } else { + currentCaretContainer = getParentCaretContainer(selection.getStart()); + while ((caretContainer = dom.get(caretContainerId)) && caretContainer !== lastContainer) { + if (currentCaretContainer !== caretContainer) { + child = findFirstTextNode(caretContainer); + if (child && child.nodeValue.charAt(0) == invisibleChar) { + child = child.deleteData(0, 1); + } + + dom.remove(caretContainer, true); + } + + lastContainer = caretContainer; + } + } + }; + + // Modifies the selection to include contentEditable false elements or insert caret containers + function moveSelection() { + var nonEditableStart, nonEditableEnd, isCollapsed, rng, element; + + // Checks if there is any contents to the left/right side of caret returns the noneditable element or any editable element if it finds one inside + function hasSideContent(element, left) { + var container, offset, walker, node, len; + + container = rng.startContainer; + offset = rng.startOffset; + + // If endpoint is in middle of text node then expand to beginning/end of element + if (container.nodeType == 3) { + len = container.nodeValue.length; + if ((offset > 0 && offset < len) || (left ? offset == len : offset == 0)) { + return; + } + } else { + // Can we resolve the node by index + if (offset < container.childNodes.length) { + // Browser represents caret position as the offset at the start of an element. When moving right + // this is the element we are moving into so we consider our container to be child node at offset-1 + var pos = !left && offset > 0 ? offset-1 : offset; + container = container.childNodes[pos]; + if (container.hasChildNodes()) { + container = container.firstChild; + } + } else { + // If not then the caret is at the last position in it's container and the caret container should be inserted after the noneditable element + return !left ? element : null; + } + } + + // Walk left/right to look for contents + walker = new TreeWalker(container, element); + while (node = walker[left ? 'prev' : 'next']()) { + if (node.nodeType === 3 && node.nodeValue.length > 0) { + return; + } else if (getContentEditable(node) === "true") { + // Found contentEditable=true element return this one to we can move the caret inside it + return node; + } + } + + return element; + }; + + // Remove any existing caret containers + removeCaretContainer(); + + // Get noneditable start/end elements + isCollapsed = selection.isCollapsed(); + nonEditableStart = getNonEditableParent(selection.getStart()); + nonEditableEnd = getNonEditableParent(selection.getEnd()); + + // Is any fo the range endpoints noneditable + if (nonEditableStart || nonEditableEnd) { + rng = selection.getRng(true); + + // If it's a caret selection then look left/right to see if we need to move the caret out side or expand + if (isCollapsed) { + nonEditableStart = nonEditableStart || nonEditableEnd; + var start = selection.getStart(); + if (element = hasSideContent(nonEditableStart, true)) { + // We have no contents to the left of the caret then insert a caret container before the noneditable element + insertCaretContainerOrExpandToBlock(element, true); + } else if (element = hasSideContent(nonEditableStart, false)) { + // We have no contents to the right of the caret then insert a caret container after the noneditable element + insertCaretContainerOrExpandToBlock(element, false); + } else { + // We are in the middle of a noneditable so expand to select it + selection.select(nonEditableStart); + } + } else { + rng = selection.getRng(true); + + // Expand selection to include start non editable element + if (nonEditableStart) { + rng.setStartBefore(nonEditableStart); + } + + // Expand selection to include end non editable element + if (nonEditableEnd) { + rng.setEndAfter(nonEditableEnd); + } + + selection.setRng(rng); + } + } + }; + + function handleKey(ed, e) { + var keyCode = e.keyCode, nonEditableParent, caretContainer, startElement, endElement; + + function getNonEmptyTextNodeSibling(node, prev) { + while (node = node[prev ? 'previousSibling' : 'nextSibling']) { + if (node.nodeType !== 3 || node.nodeValue.length > 0) { + return node; + } + } + }; + + function positionCaretOnElement(element, start) { + selection.select(element); + 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 + if (keyCode == VK.LEFT || keyCode == VK.RIGHT) { + var left = keyCode == VK.LEFT; + // If a block element find previous or next element to position the caret + if (ed.dom.isBlock(nonEditableParent)) { + var targetElement = left ? nonEditableParent.previousSibling : nonEditableParent.nextSibling; + var walker = new TreeWalker(targetElement, targetElement); + var caretElement = left ? walker.prev() : walker.next(); + positionCaretOnElement(caretElement, !left); + } else { + positionCaretOnElement(nonEditableParent, left); + } + } + } else { + // Is arrow left/right, backspace or delete + if (keyCode == VK.LEFT || keyCode == VK.RIGHT || keyCode == VK.BACKSPACE || keyCode == VK.DELETE) { + caretContainer = getParentCaretContainer(startElement); + if (caretContainer) { + // Arrow left or backspace + if (keyCode == VK.LEFT || keyCode == VK.BACKSPACE) { + nonEditableParent = getNonEmptyTextNodeSibling(caretContainer, true); + + if (nonEditableParent && getContentEditable(nonEditableParent) === "false") { + e.preventDefault(); + + if (keyCode == VK.LEFT) { + positionCaretOnElement(nonEditableParent, true); + } else { + dom.remove(nonEditableParent); + return; + } + } else { + removeCaretContainer(caretContainer); + } + } + + // Arrow right or delete + if (keyCode == VK.RIGHT || keyCode == VK.DELETE) { + nonEditableParent = getNonEmptyTextNodeSibling(caretContainer); + + if (nonEditableParent && getContentEditable(nonEditableParent) === "false") { + e.preventDefault(); + + if (keyCode == VK.RIGHT) { + 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) { + var node = ed.selection.getNode(); + + if (getContentEditable(node) === "false" && node == e.target) { + // 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); + }; tinymce.create('tinymce.plugins.NonEditablePlugin', { init : function(ed, url) { - var t = this, editClass, nonEditClass, state; + 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>'; + }); + } - t.editor = ed; - editClass = ed.getParam("noneditable_editable_class", "mceEditable"); - nonEditClass = ed.getParam("noneditable_noneditable_class", "mceNonEditable"); + args.content = content; + }; + + editClass = " " + tinymce.trim(ed.getParam("noneditable_editable_class", "mceEditable")) + " "; + nonEditClass = " " + tinymce.trim(ed.getParam("noneditable_noneditable_class", "mceNonEditable")) + " "; - ed.onNodeChange.addToTop(function(ed, cm, n) { - var sc, ec; + // Setup noneditable regexps array + nonEditableRegExps = ed.getParam("noneditable_regexp"); + if (nonEditableRegExps && !nonEditableRegExps.length) { + nonEditableRegExps = [nonEditableRegExps]; + } - // Block if start or end is inside a non editable element - sc = ed.dom.getParent(ed.selection.getStart(), function(n) { - return ed.dom.hasClass(n, nonEditClass); + ed.onPreInit.add(function() { + handleContentEditableSelection(ed); + + if (nonEditableRegExps) { + 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; + + while (i--) { + node = nodes[i]; + className = " " + node.attr("class") + " "; + + if (className.indexOf(editClass) !== -1) { + node.attr(internalName, "true"); + } else if (className.indexOf(nonEditClass) !== -1) { + node.attr(internalName, "false"); + } + } }); - ec = ed.dom.getParent(ed.selection.getEnd(), function(n) { - return ed.dom.hasClass(n, nonEditClass); + // Remove internal name + ed.serializer.addAttributeFilter(internalName, function(nodes, name) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + + if (nonEditableRegExps && node.attr('data-mce-content')) { + node.name = "#text"; + node.type = 3; + node.raw = true; + node.value = node.attr('data-mce-content'); + } else { + node.attr(externalName, null); + node.attr(internalName, null); + } + } }); - // Block or unblock - if (sc || ec) { - state = 1; - t._setDisabled(1); - return false; - } else if (state == 1) { - t._setDisabled(0); - state = 0; - } + // Convert external name into internal name + ed.parser.addAttributeFilter(externalName, function(nodes, name) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i]; + node.attr(internalName, node.attr(externalName)); + node.attr(externalName, null); + } + }); }); }, @@ -51,42 +529,6 @@ infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/noneditable', version : tinymce.majorVersion + "." + tinymce.minorVersion }; - }, - - _block : function(ed, e) { - var k = e.keyCode; - - // Don't block arrow keys, pg up/down, and F1-F12 - if ((k > 32 && k < 41) || (k > 111 && k < 124)) - return; - - return Event.cancel(e); - }, - - _setDisabled : function(s) { - var t = this, ed = t.editor; - - tinymce.each(ed.controlManager.controls, function(c) { - c.setDisabled(s); - }); - - if (s !== t.disabled) { - if (s) { - ed.onKeyDown.addToTop(t._block); - ed.onKeyPress.addToTop(t._block); - ed.onKeyUp.addToTop(t._block); - ed.onPaste.addToTop(t._block); - ed.onContextMenu.addToTop(t._block); - } else { - ed.onKeyDown.remove(t._block); - ed.onKeyPress.remove(t._block); - ed.onKeyUp.remove(t._block); - ed.onPaste.remove(t._block); - ed.onContextMenu.remove(t._block); - } - - t.disabled = s; - } } }); diff --git a/plugins/paste/editor_plugin.js b/plugins/paste/editor_plugin.js index e47a5c630afdf30eb9e8d0cb1b1ebb0024e09288..0ab05ebbb62733c04a1a4b98838f35b2dbdf00b1 100644 --- a/plugins/paste/editor_plugin.js +++ b/plugins/paste/editor_plugin.js @@ -1 +1 @@ -(function(){var c=tinymce.each,a={paste_auto_cleanup_on_paste:true,paste_enable_default_filters:true,paste_block_drop:false,paste_retain_style_properties:"none",paste_strip_class_attributes:"mso",paste_remove_spans:false,paste_remove_styles:false,paste_remove_styles_if_webkit:true,paste_convert_middot_lists:true,paste_convert_headers_to_strong:false,paste_dialog_width:"450",paste_dialog_height:"400",paste_text_use_dialog:false,paste_text_sticky:false,paste_text_sticky_default:false,paste_text_notifyalways:false,paste_text_linebreaktype:"combined",paste_text_replacements:[[/\u2026/g,"..."],[/[\x93\x94\u201c\u201d]/g,'"'],[/[\x60\x91\x92\u2018\u2019]/g,"'"]]};function b(d,e){return d.getParam(e,a[e])}tinymce.create("tinymce.plugins.PastePlugin",{init:function(d,e){var f=this;f.editor=d;f.url=e;f.onPreProcess=new tinymce.util.Dispatcher(f);f.onPostProcess=new tinymce.util.Dispatcher(f);f.onPreProcess.add(f._preProcess);f.onPostProcess.add(f._postProcess);f.onPreProcess.add(function(i,j){d.execCallback("paste_preprocess",i,j)});f.onPostProcess.add(function(i,j){d.execCallback("paste_postprocess",i,j)});d.onKeyDown.addToTop(function(i,j){if(((tinymce.isMac?j.metaKey:j.ctrlKey)&&j.keyCode==86)||(j.shiftKey&&j.keyCode==45)){return false}});d.pasteAsPlainText=b(d,"paste_text_sticky_default");function h(l,j){var k=d.dom,i;f.onPreProcess.dispatch(f,l);l.node=k.create("div",0,l.content);if(tinymce.isGecko){i=d.selection.getRng(true);if(i.startContainer==i.endContainer&&i.startContainer.nodeType==3){if(l.node.childNodes.length===1&&/^(p|h[1-6]|pre)$/i.test(l.node.firstChild.nodeName)&&l.content.indexOf("__MCE_ITEM__")===-1){k.remove(l.node.firstChild,true)}}}f.onPostProcess.dispatch(f,l);l.content=d.serializer.serialize(l.node,{getInner:1,forced_root_block:""});if((!j)&&(d.pasteAsPlainText)){f._insertPlainText(l.content);if(!b(d,"paste_text_sticky")){d.pasteAsPlainText=false;d.controlManager.setActive("pastetext",false)}}else{f._insert(l.content)}}d.addCommand("mceInsertClipboardContent",function(i,j){h(j,true)});if(!b(d,"paste_text_use_dialog")){d.addCommand("mcePasteText",function(j,i){var k=tinymce.util.Cookie;d.pasteAsPlainText=!d.pasteAsPlainText;d.controlManager.setActive("pastetext",d.pasteAsPlainText);if((d.pasteAsPlainText)&&(!k.get("tinymcePasteText"))){if(b(d,"paste_text_sticky")){d.windowManager.alert(d.translate("paste.plaintext_mode_sticky"))}else{d.windowManager.alert(d.translate("paste.plaintext_mode"))}if(!b(d,"paste_text_notifyalways")){k.set("tinymcePasteText","1",new Date(new Date().getFullYear()+1,12,31))}}})}d.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});d.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"});function g(s){var l,p,j,t,k=d.selection,o=d.dom,q=d.getBody(),i,r;if(s.clipboardData||o.doc.dataTransfer){r=(s.clipboardData||o.doc.dataTransfer).getData("Text");if(d.pasteAsPlainText){s.preventDefault();h({content:o.encode(r).replace(/\r?\n/g,"<br />")});return}}if(o.get("_mcePaste")){return}l=o.add(q,"div",{id:"_mcePaste","class":"mcePaste","data-mce-bogus":"1"},"\uFEFF\uFEFF");if(q!=d.getDoc().body){i=o.getPos(d.selection.getStart(),q).y}else{i=q.scrollTop+o.getViewPort(d.getWin()).y}o.setStyles(l,{position:"absolute",left:tinymce.isGecko?-40:0,top:i-25,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){t=k.getRng();j=o.doc.body.createTextRange();j.moveToElementText(l);j.execCommand("Paste");o.remove(l);if(l.innerHTML==="\uFEFF\uFEFF"){d.execCommand("mcePasteWord");s.preventDefault();return}k.setRng(t);k.setContent("");setTimeout(function(){h({content:l.innerHTML})},0);return tinymce.dom.Event.cancel(s)}else{function m(n){n.preventDefault()}o.bind(d.getDoc(),"mousedown",m);o.bind(d.getDoc(),"keydown",m);p=d.selection.getRng();l=l.firstChild;j=d.getDoc().createRange();j.setStart(l,0);j.setEnd(l,2);k.setRng(j);window.setTimeout(function(){var u="",n;if(!o.select("div.mcePaste > div.mcePaste").length){n=o.select("div.mcePaste");c(n,function(w){var v=w.firstChild;if(v&&v.nodeName=="DIV"&&v.style.marginTop&&v.style.backgroundColor){o.remove(v,1)}c(o.select("span.Apple-style-span",w),function(x){o.remove(x,1)});c(o.select("br[data-mce-bogus]",w),function(x){o.remove(x)});if(w.parentNode.className!="mcePaste"){u+=w.innerHTML}})}else{u="<p>"+o.encode(r).replace(/\r?\n\r?\n/g,"</p><p>").replace(/\r?\n/g,"<br />")+"</p>"}c(o.select("div.mcePaste"),function(v){o.remove(v)});if(p){k.setRng(p)}h({content:u});o.unbind(d.getDoc(),"mousedown",m);o.unbind(d.getDoc(),"keydown",m)},0)}}if(b(d,"paste_auto_cleanup_on_paste")){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){d.onKeyDown.addToTop(function(i,j){if(((tinymce.isMac?j.metaKey:j.ctrlKey)&&j.keyCode==86)||(j.shiftKey&&j.keyCode==45)){g(j)}})}else{d.onPaste.addToTop(function(i,j){return g(j)})}}d.onInit.add(function(){d.controlManager.setActive("pastetext",d.pasteAsPlainText);if(b(d,"paste_block_drop")){d.dom.bind(d.getBody(),["dragend","dragover","draggesture","dragdrop","drop","drag"],function(i){i.preventDefault();i.stopPropagation();return false})}});f._legacySupport()},getInfo:function(){return{longname:"Paste text/word",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_preProcess:function(g,e){var k=this.editor,j=e.content,p=tinymce.grep,n=tinymce.explode,f=tinymce.trim,l,i;function d(h){c(h,function(o){if(o.constructor==RegExp){j=j.replace(o,"")}else{j=j.replace(o[0],o[1])}})}if(k.settings.paste_enable_default_filters==false){return}if(tinymce.isIE&&document.documentMode>=9){d([[/(?:<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"]]);d([[/<br><br>/g,"<BR><BR>"],[/<br>/g," "],[/<BR><BR>/g,"<br>"]])}if(/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(j)||e.wordContent){e.wordContent=true;d([/^\s*( )+/gi,/( |<br[^>]*>)+\s*$/gi]);if(b(k,"paste_convert_headers_to_strong")){j=j.replace(/<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"<p><strong>$1</strong></p>")}if(b(k,"paste_convert_middot_lists")){d([[/<!--\[if !supportLists\]-->/gi,"$&__MCE_ITEM__"],[/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi,"$1__MCE_ITEM__"],[/(<p[^>]+(?:MsoListParagraph)[^>]+>)/gi,"$1__MCE_ITEM__"]])}d([/<!--[\s\S]+?-->/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\u00a0"]]);do{l=j.length;j=j.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi,"$1")}while(l!=j.length);if(b(k,"paste_retain_style_properties").replace(/^none$/i,"").length==0){j=j.replace(/<\/?span[^>]*>/gi,"")}else{d([[/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi,function(o,h){return(h.length>0)?h.replace(/./," ").slice(Math.floor(h.length/2)).split("").join("\u00a0"):""}],[/(<[a-z][^>]*)\sstyle="([^"]*)"/gi,function(t,h,r){var u=[],o=0,q=n(f(r).replace(/"/gi,"'"),";");c(q,function(s){var w,y,z=n(s,":");function x(A){return A+((A!=="0")&&(/\d$/.test(A)))?"px":""}if(z.length==2){w=z[0].toLowerCase();y=z[1].toLowerCase();switch(w){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-table-layout-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":u[o++]=w.replace(/^mso-|-alt$/g,"")+":"+x(y);return;case"horiz-align":u[o++]="text-align:"+y;return;case"vert-align":u[o++]="vertical-align:"+y;return;case"font-color":case"mso-foreground":u[o++]="color:"+y;return;case"mso-background":case"mso-highlight":u[o++]="background:"+y;return;case"mso-default-height":u[o++]="min-height:"+x(y);return;case"mso-default-width":u[o++]="min-width:"+x(y);return;case"mso-padding-between-alt":u[o++]="border-collapse:separate;border-spacing:"+x(y);return;case"text-line-through":if((y=="single")||(y=="double")){u[o++]="text-decoration:line-through"}return;case"mso-zero-height":if(y=="yes"){u[o++]="display:none"}return}if(/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(w)){return}u[o++]=w+":"+z[1]}});if(o>0){return h+' style="'+u.join(";")+'"'}else{return h}}]])}}if(b(k,"paste_convert_headers_to_strong")){d([[/<h[1-6][^>]*>/gi,"<p><strong>"],[/<\/h[1-6][^>]*>/gi,"</strong></p>"]])}d([[/Version:[\d.]+\nStartHTML:\d+\nEndHTML:\d+\nStartFragment:\d+\nEndFragment:\d+/gi,""]]);i=b(k,"paste_strip_class_attributes");if(i!=="none"){function m(q,o){if(i==="all"){return""}var h=p(n(o.replace(/^(["'])(.*)\1$/,"$2")," "),function(r){return(/^(?!mso)/i.test(r))});return h.length?' class="'+h.join(" ")+'"':""}j=j.replace(/ class="([^"]+)"/gi,m);j=j.replace(/ class=([\-\w]+)/gi,m)}if(b(k,"paste_remove_spans")){j=j.replace(/<\/?span[^>]*>/gi,"")}e.content=j},_postProcess:function(g,i){var f=this,e=f.editor,h=e.dom,d;if(e.settings.paste_enable_default_filters==false){return}if(i.wordContent){c(h.select("a",i.node),function(j){if(!j.href||j.href.indexOf("#_Toc")!=-1){h.remove(j,1)}});if(b(e,"paste_convert_middot_lists")){f._convertLists(g,i)}d=b(e,"paste_retain_style_properties");if((tinymce.is(d,"string"))&&(d!=="all")&&(d!=="*")){d=tinymce.explode(d.replace(/^none$/i,""));c(h.select("*",i.node),function(m){var n={},k=0,l,o,j;if(d){for(l=0;l<d.length;l++){o=d[l];j=h.getStyle(m,o);if(j){n[o]=j;k++}}}h.setAttrib(m,"style","");if(d&&k>0){h.setStyles(m,n)}else{if(m.nodeName=="SPAN"&&!m.className){h.remove(m,true)}}})}}if(b(e,"paste_remove_styles")||(b(e,"paste_remove_styles_if_webkit")&&tinymce.isWebKit)){c(h.select("*[style]",i.node),function(j){j.removeAttribute("style");j.removeAttribute("data-mce-style")})}else{if(tinymce.isWebKit){c(h.select("*",i.node),function(j){j.removeAttribute("data-mce-style")})}}},_convertLists:function(g,e){var i=g.editor.dom,h,l,d=-1,f,m=[],k,j;c(i.select("p",e.node),function(t){var q,u="",s,r,n,o;for(q=t.firstChild;q&&q.nodeType==3;q=q.nextSibling){u+=q.nodeValue}u=t.innerHTML.replace(/<\/?\w+[^>]*>/gi,"").replace(/ /g,"\u00a0");if(/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*\u00a0*/.test(u)){s="ul"}if(/^__MCE_ITEM__\s*\w+\.\s*\u00a0+/.test(u)){s="ol"}if(s){f=parseFloat(t.style.marginLeft||0);if(f>d){m.push(f)}if(!h||s!=k){h=i.create(s);i.insertAfter(h,t)}else{if(f>d){h=l.appendChild(i.create(s))}else{if(f<d){n=tinymce.inArray(m,f);o=i.getParents(h.parentNode,s);h=o[o.length-1-n]||h}}}c(i.select("span",t),function(v){var p=v.innerHTML.replace(/<\/?\w+[^>]*>/gi,"");if(s=="ul"&&/^__MCE_ITEM__[\u2022\u00b7\u00a7\u00d8o\u25CF]/.test(p)){i.remove(v)}else{if(/^__MCE_ITEM__[\s\S]*\w+\.( |\u00a0)*\s*/.test(p)){i.remove(v)}}});r=t.innerHTML;if(s=="ul"){r=t.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*( |\u00a0)+\s*/,"")}else{r=t.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.( |\u00a0)+\s*/,"")}l=h.appendChild(i.create("li",0,r));i.remove(t);d=f;k=s}else{h=d=0}});j=e.node.innerHTML;if(j.indexOf("__MCE_ITEM__")!=-1){e.node.innerHTML=j.replace(/__MCE_ITEM__/g,"")}},_insert:function(f,d){var e=this.editor,g=e.selection.getRng();if(!e.selection.isCollapsed()&&g.startContainer!=g.endContainer){e.getDoc().execCommand("Delete",false,null)}e.execCommand("mceInsertContent",false,f,{skip_undo:d})},_insertPlainText:function(g){var d=this.editor,e=b(d,"paste_text_linebreaktype"),i=b(d,"paste_text_replacements"),f=tinymce.is;function h(j){c(j,function(k){if(k.constructor==RegExp){g=g.replace(k,"")}else{g=g.replace(k[0],k[1])}})}if((typeof(g)==="string")&&(g.length>0)){if(/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(g)){h([/[\n\r]+/g])}else{h([/\r+/g])}h([[/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi,"\n\n"],[/<br[^>]*>|<\/tr>/gi,"\n"],[/<\/t[dh]>\s*<t[dh][^>]*>/gi,"\t"],/<[a-z!\/?][^>]*>/gi,[/ /gi," "],[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi,"$1"],[/\n{3,}/g,"\n\n"]]);g=d.dom.decode(tinymce.html.Entities.encodeRaw(g));if(f(i,"array")){h(i)}else{if(f(i,"string")){h(new RegExp(i,"gi"))}}if(e=="none"){h([[/\n+/g," "]])}else{if(e=="br"){h([[/\n/g,"<br />"]])}else{if(e=="p"){h([[/\n+/g,"</p><p>"],[/^(.*<\/p>)(<p>)$/,"<p>$1"]])}else{h([[/\n\n/g,"</p><p>"],[/^(.*<\/p>)(<p>)$/,"<p>$1"],[/\n/g,"<br />"]])}}}d.execCommand("mceInsertContent",false,g)}},_legacySupport:function(){var e=this,d=e.editor;d.addCommand("mcePasteWord",function(){d.windowManager.open({file:e.url+"/pasteword.htm",width:parseInt(b(d,"paste_dialog_width")),height:parseInt(b(d,"paste_dialog_height")),inline:1})});if(b(d,"paste_text_use_dialog")){d.addCommand("mcePasteText",function(){d.windowManager.open({file:e.url+"/pastetext.htm",width:parseInt(b(d,"paste_dialog_width")),height:parseInt(b(d,"paste_dialog_height")),inline:1})})}d.addButton("pasteword",{title:"paste.paste_word_desc",cmd:"mcePasteWord"})}});tinymce.PluginManager.add("paste",tinymce.plugins.PastePlugin)})(); \ No newline at end of file +(function(){var c=tinymce.each,a={paste_auto_cleanup_on_paste:true,paste_enable_default_filters:true,paste_block_drop:false,paste_retain_style_properties:"none",paste_strip_class_attributes:"mso",paste_remove_spans:false,paste_remove_styles:false,paste_remove_styles_if_webkit:true,paste_convert_middot_lists:true,paste_convert_headers_to_strong:false,paste_dialog_width:"450",paste_dialog_height:"400",paste_max_consecutive_linebreaks:2,paste_text_use_dialog:false,paste_text_sticky:false,paste_text_sticky_default:false,paste_text_notifyalways:false,paste_text_linebreaktype:"combined",paste_text_replacements:[[/\u2026/g,"..."],[/[\x93\x94\u201c\u201d]/g,'"'],[/[\x60\x91\x92\u2018\u2019]/g,"'"]]};function b(d,e){return d.getParam(e,a[e])}tinymce.create("tinymce.plugins.PastePlugin",{init:function(d,e){var f=this;f.editor=d;f.url=e;f.onPreProcess=new tinymce.util.Dispatcher(f);f.onPostProcess=new tinymce.util.Dispatcher(f);f.onPreProcess.add(f._preProcess);f.onPostProcess.add(f._postProcess);f.onPreProcess.add(function(i,j){d.execCallback("paste_preprocess",i,j)});f.onPostProcess.add(function(i,j){d.execCallback("paste_postprocess",i,j)});d.onKeyDown.addToTop(function(i,j){if(((tinymce.isMac?j.metaKey:j.ctrlKey)&&j.keyCode==86)||(j.shiftKey&&j.keyCode==45)){return false}});d.pasteAsPlainText=b(d,"paste_text_sticky_default");function h(l,j){var k=d.dom,i;f.onPreProcess.dispatch(f,l);l.node=k.create("div",0,l.content);if(tinymce.isGecko){i=d.selection.getRng(true);if(i.startContainer==i.endContainer&&i.startContainer.nodeType==3){if(l.node.childNodes.length===1&&/^(p|h[1-6]|pre)$/i.test(l.node.firstChild.nodeName)&&l.content.indexOf("__MCE_ITEM__")===-1){k.remove(l.node.firstChild,true)}}}f.onPostProcess.dispatch(f,l);l.content=d.serializer.serialize(l.node,{getInner:1,forced_root_block:""});if((!j)&&(d.pasteAsPlainText)){f._insertPlainText(l.content);if(!b(d,"paste_text_sticky")){d.pasteAsPlainText=false;d.controlManager.setActive("pastetext",false)}}else{f._insert(l.content)}}d.addCommand("mceInsertClipboardContent",function(i,j){h(j,true)});if(!b(d,"paste_text_use_dialog")){d.addCommand("mcePasteText",function(j,i){var k=tinymce.util.Cookie;d.pasteAsPlainText=!d.pasteAsPlainText;d.controlManager.setActive("pastetext",d.pasteAsPlainText);if((d.pasteAsPlainText)&&(!k.get("tinymcePasteText"))){if(b(d,"paste_text_sticky")){d.windowManager.alert(d.translate("paste.plaintext_mode_sticky"))}else{d.windowManager.alert(d.translate("paste.plaintext_mode"))}if(!b(d,"paste_text_notifyalways")){k.set("tinymcePasteText","1",new Date(new Date().getFullYear()+1,12,31))}}})}d.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});d.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"});function g(s){var l,p,j,t,k=d.selection,o=d.dom,q=d.getBody(),i,r;if(s.clipboardData||o.doc.dataTransfer){r=(s.clipboardData||o.doc.dataTransfer).getData("Text");if(d.pasteAsPlainText){s.preventDefault();h({content:o.encode(r).replace(/\r?\n/g,"<br />")});return}}if(o.get("_mcePaste")){return}l=o.add(q,"div",{id:"_mcePaste","class":"mcePaste","data-mce-bogus":"1"},"\uFEFF\uFEFF");if(q!=d.getDoc().body){i=o.getPos(d.selection.getStart(),q).y}else{i=q.scrollTop+o.getViewPort(d.getWin()).y}o.setStyles(l,{position:"absolute",left:tinymce.isGecko?-40:0,top:i-25,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){t=k.getRng();j=o.doc.body.createTextRange();j.moveToElementText(l);j.execCommand("Paste");o.remove(l);if(l.innerHTML==="\uFEFF\uFEFF"){d.execCommand("mcePasteWord");s.preventDefault();return}k.setRng(t);k.setContent("");setTimeout(function(){h({content:l.innerHTML})},0);return tinymce.dom.Event.cancel(s)}else{function m(n){n.preventDefault()}o.bind(d.getDoc(),"mousedown",m);o.bind(d.getDoc(),"keydown",m);p=d.selection.getRng();l=l.firstChild;j=d.getDoc().createRange();j.setStart(l,0);j.setEnd(l,2);k.setRng(j);window.setTimeout(function(){var u="",n;if(!o.select("div.mcePaste > div.mcePaste").length){n=o.select("div.mcePaste");c(n,function(w){var v=w.firstChild;if(v&&v.nodeName=="DIV"&&v.style.marginTop&&v.style.backgroundColor){o.remove(v,1)}c(o.select("span.Apple-style-span",w),function(x){o.remove(x,1)});c(o.select("br[data-mce-bogus]",w),function(x){o.remove(x)});if(w.parentNode.className!="mcePaste"){u+=w.innerHTML}})}else{u="<p>"+o.encode(r).replace(/\r?\n\r?\n/g,"</p><p>").replace(/\r?\n/g,"<br />")+"</p>"}c(o.select("div.mcePaste"),function(v){o.remove(v)});if(p){k.setRng(p)}h({content:u});o.unbind(d.getDoc(),"mousedown",m);o.unbind(d.getDoc(),"keydown",m)},0)}}if(b(d,"paste_auto_cleanup_on_paste")){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){d.onKeyDown.addToTop(function(i,j){if(((tinymce.isMac?j.metaKey:j.ctrlKey)&&j.keyCode==86)||(j.shiftKey&&j.keyCode==45)){g(j)}})}else{d.onPaste.addToTop(function(i,j){return g(j)})}}d.onInit.add(function(){d.controlManager.setActive("pastetext",d.pasteAsPlainText);if(b(d,"paste_block_drop")){d.dom.bind(d.getBody(),["dragend","dragover","draggesture","dragdrop","drop","drag"],function(i){i.preventDefault();i.stopPropagation();return false})}});f._legacySupport()},getInfo:function(){return{longname:"Paste text/word",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/paste",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_preProcess:function(g,e){var k=this.editor,j=e.content,p=tinymce.grep,n=tinymce.explode,f=tinymce.trim,l,i;function d(h){c(h,function(o){if(o.constructor==RegExp){j=j.replace(o,"")}else{j=j.replace(o[0],o[1])}})}if(k.settings.paste_enable_default_filters==false){return}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(e.content)){d([[/(?:<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"]]);d([[/<br><br>/g,"<BR><BR>"],[/<br>/g," "],[/<BR><BR>/g,"<br>"]])}if(/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(j)||e.wordContent){e.wordContent=true;d([/^\s*( )+/gi,/( |<br[^>]*>)+\s*$/gi]);if(b(k,"paste_convert_headers_to_strong")){j=j.replace(/<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"<p><strong>$1</strong></p>")}if(b(k,"paste_convert_middot_lists")){d([[/<!--\[if !supportLists\]-->/gi,"$&__MCE_ITEM__"],[/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi,"$1__MCE_ITEM__"],[/(<p[^>]+(?:MsoListParagraph)[^>]+>)/gi,"$1__MCE_ITEM__"]])}d([/<!--[\s\S]+?-->/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/ /gi,"\u00a0"]]);do{l=j.length;j=j.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi,"$1")}while(l!=j.length);if(b(k,"paste_retain_style_properties").replace(/^none$/i,"").length==0){j=j.replace(/<\/?span[^>]*>/gi,"")}else{d([[/<span\s+style\s*=\s*"\s*mso-spacerun\s*:\s*yes\s*;?\s*"\s*>([\s\u00a0]*)<\/span>/gi,function(o,h){return(h.length>0)?h.replace(/./," ").slice(Math.floor(h.length/2)).split("").join("\u00a0"):""}],[/(<[a-z][^>]*)\sstyle="([^"]*)"/gi,function(t,h,r){var u=[],o=0,q=n(f(r).replace(/"/gi,"'"),";");c(q,function(s){var w,y,z=n(s,":");function x(A){return A+((A!=="0")&&(/\d$/.test(A)))?"px":""}if(z.length==2){w=z[0].toLowerCase();y=z[1].toLowerCase();switch(w){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-table-layout-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":u[o++]=w.replace(/^mso-|-alt$/g,"")+":"+x(y);return;case"horiz-align":u[o++]="text-align:"+y;return;case"vert-align":u[o++]="vertical-align:"+y;return;case"font-color":case"mso-foreground":u[o++]="color:"+y;return;case"mso-background":case"mso-highlight":u[o++]="background:"+y;return;case"mso-default-height":u[o++]="min-height:"+x(y);return;case"mso-default-width":u[o++]="min-width:"+x(y);return;case"mso-padding-between-alt":u[o++]="border-collapse:separate;border-spacing:"+x(y);return;case"text-line-through":if((y=="single")||(y=="double")){u[o++]="text-decoration:line-through"}return;case"mso-zero-height":if(y=="yes"){u[o++]="display:none"}return}if(/^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?!align|decor|indent|trans)|top-bar|version|vnd|word-break)/.test(w)){return}u[o++]=w+":"+z[1]}});if(o>0){return h+' style="'+u.join(";")+'"'}else{return h}}]])}}if(b(k,"paste_convert_headers_to_strong")){d([[/<h[1-6][^>]*>/gi,"<p><strong>"],[/<\/h[1-6][^>]*>/gi,"</strong></p>"]])}d([[/Version:[\d.]+\nStartHTML:\d+\nEndHTML:\d+\nStartFragment:\d+\nEndFragment:\d+/gi,""]]);i=b(k,"paste_strip_class_attributes");if(i!=="none"){function m(q,o){if(i==="all"){return""}var h=p(n(o.replace(/^(["'])(.*)\1$/,"$2")," "),function(r){return(/^(?!mso)/i.test(r))});return h.length?' class="'+h.join(" ")+'"':""}j=j.replace(/ class="([^"]+)"/gi,m);j=j.replace(/ class=([\-\w]+)/gi,m)}if(b(k,"paste_remove_spans")){j=j.replace(/<\/?span[^>]*>/gi,"")}e.content=j},_postProcess:function(g,i){var f=this,e=f.editor,h=e.dom,d;if(e.settings.paste_enable_default_filters==false){return}if(i.wordContent){c(h.select("a",i.node),function(j){if(!j.href||j.href.indexOf("#_Toc")!=-1){h.remove(j,1)}});if(b(e,"paste_convert_middot_lists")){f._convertLists(g,i)}d=b(e,"paste_retain_style_properties");if((tinymce.is(d,"string"))&&(d!=="all")&&(d!=="*")){d=tinymce.explode(d.replace(/^none$/i,""));c(h.select("*",i.node),function(m){var n={},k=0,l,o,j;if(d){for(l=0;l<d.length;l++){o=d[l];j=h.getStyle(m,o);if(j){n[o]=j;k++}}}h.setAttrib(m,"style","");if(d&&k>0){h.setStyles(m,n)}else{if(m.nodeName=="SPAN"&&!m.className){h.remove(m,true)}}})}}if(b(e,"paste_remove_styles")||(b(e,"paste_remove_styles_if_webkit")&&tinymce.isWebKit)){c(h.select("*[style]",i.node),function(j){j.removeAttribute("style");j.removeAttribute("data-mce-style")})}else{if(tinymce.isWebKit){c(h.select("*",i.node),function(j){j.removeAttribute("data-mce-style")})}}},_convertLists:function(g,e){var i=g.editor.dom,h,l,d=-1,f,m=[],k,j;c(i.select("p",e.node),function(t){var q,u="",s,r,n,o;for(q=t.firstChild;q&&q.nodeType==3;q=q.nextSibling){u+=q.nodeValue}u=t.innerHTML.replace(/<\/?\w+[^>]*>/gi,"").replace(/ /g,"\u00a0");if(/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*\u00a0*/.test(u)){s="ul"}if(/^__MCE_ITEM__\s*\w+\.\s*\u00a0+/.test(u)){s="ol"}if(s){f=parseFloat(t.style.marginLeft||0);if(f>d){m.push(f)}if(!h||s!=k){h=i.create(s);i.insertAfter(h,t)}else{if(f>d){h=l.appendChild(i.create(s))}else{if(f<d){n=tinymce.inArray(m,f);o=i.getParents(h.parentNode,s);h=o[o.length-1-n]||h}}}c(i.select("span",t),function(v){var p=v.innerHTML.replace(/<\/?\w+[^>]*>/gi,"");if(s=="ul"&&/^__MCE_ITEM__[\u2022\u00b7\u00a7\u00d8o\u25CF]/.test(p)){i.remove(v)}else{if(/^__MCE_ITEM__[\s\S]*\w+\.( |\u00a0)*\s*/.test(p)){i.remove(v)}}});r=t.innerHTML;if(s=="ul"){r=t.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*( |\u00a0)+\s*/,"")}else{r=t.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.( |\u00a0)+\s*/,"")}l=h.appendChild(i.create("li",0,r));i.remove(t);d=f;k=s}else{h=d=0}});j=e.node.innerHTML;if(j.indexOf("__MCE_ITEM__")!=-1){e.node.innerHTML=j.replace(/__MCE_ITEM__/g,"")}},_insert:function(f,d){var e=this.editor,g=e.selection.getRng();if(!e.selection.isCollapsed()&&g.startContainer!=g.endContainer){e.getDoc().execCommand("Delete",false,null)}e.execCommand("mceInsertContent",false,f,{skip_undo:d})},_insertPlainText:function(j){var h=this.editor,f=b(h,"paste_text_linebreaktype"),k=b(h,"paste_text_replacements"),g=tinymce.is;function e(m){c(m,function(n){if(n.constructor==RegExp){j=j.replace(n,"")}else{j=j.replace(n[0],n[1])}})}if((typeof(j)==="string")&&(j.length>0)){if(/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(j)){e([/[\n\r]+/g])}else{e([/\r+/g])}e([[/<\/(?:p|h[1-6]|ul|ol|dl|table|div|blockquote|fieldset|pre|address|center)>/gi,"\n\n"],[/<br[^>]*>|<\/tr>/gi,"\n"],[/<\/t[dh]>\s*<t[dh][^>]*>/gi,"\t"],/<[a-z!\/?][^>]*>/gi,[/ /gi," "],[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi,"$1"]]);var d=Number(b(h,"paste_max_consecutive_linebreaks"));if(d>-1){var l=new RegExp("\n{"+(d+1)+",}","g");var i="";while(i.length<d){i+="\n"}e([[l,i]])}j=h.dom.decode(tinymce.html.Entities.encodeRaw(j));if(g(k,"array")){e(k)}else{if(g(k,"string")){e(new RegExp(k,"gi"))}}if(f=="none"){e([[/\n+/g," "]])}else{if(f=="br"){e([[/\n/g,"<br />"]])}else{if(f=="p"){e([[/\n+/g,"</p><p>"],[/^(.*<\/p>)(<p>)$/,"<p>$1"]])}else{e([[/\n\n/g,"</p><p>"],[/^(.*<\/p>)(<p>)$/,"<p>$1"],[/\n/g,"<br />"]])}}}h.execCommand("mceInsertContent",false,j)}},_legacySupport:function(){var e=this,d=e.editor;d.addCommand("mcePasteWord",function(){d.windowManager.open({file:e.url+"/pasteword.htm",width:parseInt(b(d,"paste_dialog_width")),height:parseInt(b(d,"paste_dialog_height")),inline:1})});if(b(d,"paste_text_use_dialog")){d.addCommand("mcePasteText",function(){d.windowManager.open({file:e.url+"/pastetext.htm",width:parseInt(b(d,"paste_dialog_width")),height:parseInt(b(d,"paste_dialog_height")),inline:1})})}d.addButton("pasteword",{title:"paste.paste_word_desc",cmd:"mcePasteWord"})}});tinymce.PluginManager.add("paste",tinymce.plugins.PastePlugin)})(); \ No newline at end of file diff --git a/plugins/paste/editor_plugin_src.js b/plugins/paste/editor_plugin_src.js index 73fe7fe9a40abe31e9ec11bcc61525ddf144735a..0154eceb58c0f87f00cd5e613c3d8de2e14f62a1 100644 --- a/plugins/paste/editor_plugin_src.js +++ b/plugins/paste/editor_plugin_src.js @@ -23,6 +23,7 @@ paste_convert_headers_to_strong : false, paste_dialog_width : "450", paste_dialog_height : "400", + paste_max_consecutive_linebreaks: 2, paste_text_use_dialog : false, paste_text_sticky : false, paste_text_sticky_default : false, @@ -359,7 +360,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']]); @@ -790,10 +791,23 @@ [/<\/t[dh]>\s*<t[dh][^>]*>/gi, "\t"], // Table cells get tabs betweem them /<[a-z!\/?][^>]*>/gi, // Delete all remaining tags [/ /gi, " "], // Convert non-break spaces to regular spaces (remember, *plain text*) - [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"],// Cool little RegExp deletes whitespace around linebreak chars. - [/\n{3,}/g, "\n\n"] // Max. 2 consecutive linebreaks + [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"] // Cool little RegExp deletes whitespace around linebreak chars. ]); + var maxLinebreaks = Number(getParam(ed, "paste_max_consecutive_linebreaks")); + if (maxLinebreaks > -1) { + var maxLinebreaksRegex = new RegExp("\n{" + (maxLinebreaks + 1) + ",}", "g"); + var linebreakReplacement = ""; + + while (linebreakReplacement.length < maxLinebreaks) { + linebreakReplacement += "\n"; + } + + process([ + [maxLinebreaksRegex, linebreakReplacement] // Limit max consecutive linebreaks + ]); + } + content = ed.dom.decode(tinymce.html.Entities.encodeRaw(content)); // Perform default or custom replacements diff --git a/plugins/searchreplace/searchreplace.htm b/plugins/searchreplace/searchreplace.htm index 5a22d8aa4dcc977e547e07a93f20df0ea84524a0..2443a9184b199ac8f7ba27cde4cff4cf52621210 100644 --- a/plugins/searchreplace/searchreplace.htm +++ b/plugins/searchreplace/searchreplace.htm @@ -93,7 +93,7 @@ <input type="submit" id="insert" name="insert" value="{#searchreplace_dlg.findnext}" /> <input type="button" class="button" id="replaceBtn" name="replaceBtn" value="{#searchreplace_dlg.replace}" onclick="SearchReplaceDialog.searchNext('current');" /> <input type="button" class="button" id="replaceAllBtn" name="replaceAllBtn" value="{#searchreplace_dlg.replaceall}" onclick="SearchReplaceDialog.searchNext('all');" /> - <input type="button" id="cancel" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" /> + <input type="button" id="cancel" name="close" value="{#close}" onclick="tinyMCEPopup.close();" /> </div> </form> </body> diff --git a/plugins/spellchecker/editor_plugin.js b/plugins/spellchecker/editor_plugin.js index 71fbb68a644154a18bd6cd0fc3099e751f6cf42f..48549c9239294c2588705e5b3a649e729c5de9ca 100644 --- a/plugins/spellchecker/editor_plugin.js +++ b/plugins/spellchecker/editor_plugin.js @@ -1 +1 @@ -(function(){var a=tinymce.util.JSONRequest,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.SpellcheckerPlugin",{getInfo:function(){return{longname:"Spellchecker",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker",version:tinymce.majorVersion+"."+tinymce.minorVersion}},init:function(e,f){var g=this,d;g.url=f;g.editor=e;g.rpcUrl=e.getParam("spellchecker_rpc_url","{backend}");if(g.rpcUrl=="{backend}"){if(tinymce.isIE){return}g.hasSupport=true;e.onContextMenu.addToTop(function(h,i){if(g.active){return false}})}e.addCommand("mceSpellCheck",function(){if(g.rpcUrl=="{backend}"){g.editor.getBody().spellcheck=g.active=!g.active;return}if(!g.active){e.setProgressState(1);g._sendRPC("checkWords",[g.selectedLang,g._getWords()],function(h){if(h.length>0){g.active=1;g._markWords(h);e.setProgressState(0);e.nodeChanged()}else{e.setProgressState(0);if(e.getParam("spellchecker_report_no_misspellings",true)){e.windowManager.alert("spellchecker.no_mpell")}}})}else{g._done()}});if(e.settings.content_css!==false){e.contentCSS.push(f+"/css/content.css")}e.onClick.add(g._showMenu,g);e.onContextMenu.add(g._showMenu,g);e.onBeforeGetContent.add(function(){if(g.active){g._removeWords()}});e.onNodeChange.add(function(i,h){h.setActive("spellchecker",g.active)});e.onSetContent.add(function(){g._done()});e.onBeforeGetContent.add(function(){g._done()});e.onBeforeExecCommand.add(function(h,i){if(i=="mceFullScreen"){g._done()}});g.languages={};c(e.getParam("spellchecker_languages","+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv","hash"),function(i,h){if(h.indexOf("+")===0){h=h.substring(1);g.selectedLang=i}g.languages[h]=i})},createControl:function(h,d){var f=this,g,e=f.editor;if(h=="spellchecker"){if(f.rpcUrl=="{backend}"){if(f.hasSupport){g=d.createButton(h,{title:"spellchecker.desc",cmd:"mceSpellCheck",scope:f})}return g}g=d.createSplitButton(h,{title:"spellchecker.desc",cmd:"mceSpellCheck",scope:f});g.onRenderMenu.add(function(j,i){i.add({title:"spellchecker.langs","class":"mceMenuItemTitle"}).setDisabled(1);c(f.languages,function(n,m){var p={icon:1},l;p.onclick=function(){if(n==f.selectedLang){return}l.setSelected(1);f.selectedItem.setSelected(0);f.selectedItem=l;f.selectedLang=n};p.title=m;l=i.add(p);l.setSelected(n==f.selectedLang);if(n==f.selectedLang){f.selectedItem=l}})});return g}},_walk:function(i,g){var h=this.editor.getDoc(),e;if(h.createTreeWalker){e=h.createTreeWalker(i,NodeFilter.SHOW_TEXT,null,false);while((i=e.nextNode())!=null){g.call(this,i)}}else{tinymce.walk(i,g,"childNodes")}},_getSeparators:function(){var e="",d,f=this.editor.getParam("spellchecker_word_separator_chars",'\\s!"#$%&()*+,-./:;<=>?@[]^_{|}����������������\u201d\u201c');for(d=0;d<f.length;d++){e+="\\"+f.charAt(d)}return e},_getWords:function(){var e=this.editor,g=[],d="",f={},h=[];this._walk(e.getBody(),function(i){if(i.nodeType==3){d+=i.nodeValue+" "}});if(e.getParam("spellchecker_word_pattern")){h=d.match("("+e.getParam("spellchecker_word_pattern")+")","gi")}else{d=d.replace(new RegExp("([0-9]|["+this._getSeparators()+"])","g")," ");d=tinymce.trim(d.replace(/(\s+)/g," "));h=d.split(" ")}c(h,function(i){if(!f[i]){g.push(i);f[i]=1}});return g},_removeWords:function(e){var f=this.editor,h=f.dom,g=f.selection,d=g.getBookmark();c(h.select("span").reverse(),function(i){if(i&&(h.hasClass(i,"mceItemHiddenSpellWord")||h.hasClass(i,"mceItemHidden"))){if(!e||h.decode(i.innerHTML)==e){h.remove(i,1)}}});g.moveToBookmark(d)},_markWords:function(l){var g=this.editor,f=g.dom,j=g.getDoc(),h=g.selection,i=h.getBookmark(),d=[],k=l.join("|"),m=this._getSeparators(),e=new RegExp("(^|["+m+"])("+k+")(?=["+m+"]|$)","g");this._walk(g.getBody(),function(o){if(o.nodeType==3){d.push(o)}});c(d,function(t){var r,q,o,s,p=t.nodeValue;if(e.test(p)){p=f.encode(p);q=f.create("span",{"class":"mceItemHidden"});if(tinymce.isIE){p=p.replace(e,"$1<mcespell>$2</mcespell>");while((s=p.indexOf("<mcespell>"))!=-1){o=p.substring(0,s);if(o.length){r=j.createTextNode(f.decode(o));q.appendChild(r)}p=p.substring(s+10);s=p.indexOf("</mcespell>");o=p.substring(0,s);p=p.substring(s+11);q.appendChild(f.create("span",{"class":"mceItemHiddenSpellWord"},o))}if(p.length){r=j.createTextNode(f.decode(p));q.appendChild(r)}}else{q.innerHTML=p.replace(e,'$1<span class="mceItemHiddenSpellWord">$2</span>')}f.replace(q,t)}});h.moveToBookmark(i)},_showMenu:function(h,j){var i=this,h=i.editor,d=i._menu,l,k=h.dom,g=k.getViewPort(h.getWin()),f=j.target;j=0;if(!d){d=h.controlManager.createDropMenu("spellcheckermenu",{"class":"mceNoIcons"});i._menu=d}if(k.hasClass(f,"mceItemHiddenSpellWord")){d.removeAll();d.add({title:"spellchecker.wait","class":"mceMenuItemTitle"}).setDisabled(1);i._sendRPC("getSuggestions",[i.selectedLang,k.decode(f.innerHTML)],function(m){var e;d.removeAll();if(m.length>0){d.add({title:"spellchecker.sug","class":"mceMenuItemTitle"}).setDisabled(1);c(m,function(n){d.add({title:n,onclick:function(){k.replace(h.getDoc().createTextNode(n),f);i._checkDone()}})});d.addSeparator()}else{d.add({title:"spellchecker.no_sug","class":"mceMenuItemTitle"}).setDisabled(1)}if(h.getParam("show_ignore_words",true)){e=i.editor.getParam("spellchecker_enable_ignore_rpc","");d.add({title:"spellchecker.ignore_word",onclick:function(){var n=f.innerHTML;k.remove(f,1);i._checkDone();if(e){h.setProgressState(1);i._sendRPC("ignoreWord",[i.selectedLang,n],function(o){h.setProgressState(0)})}}});d.add({title:"spellchecker.ignore_words",onclick:function(){var n=f.innerHTML;i._removeWords(k.decode(n));i._checkDone();if(e){h.setProgressState(1);i._sendRPC("ignoreWords",[i.selectedLang,n],function(o){h.setProgressState(0)})}}})}if(i.editor.getParam("spellchecker_enable_learn_rpc")){d.add({title:"spellchecker.learn_word",onclick:function(){var n=f.innerHTML;k.remove(f,1);i._checkDone();h.setProgressState(1);i._sendRPC("learnWord",[i.selectedLang,n],function(o){h.setProgressState(0)})}})}d.update()});l=b.getPos(h.getContentAreaContainer());d.settings.offset_x=l.x;d.settings.offset_y=l.y;h.selection.select(f);l=k.getPos(f);d.showMenu(l.x,l.y+f.offsetHeight-g.y);return tinymce.dom.Event.cancel(j)}else{d.hideMenu()}},_checkDone:function(){var e=this,d=e.editor,g=d.dom,f;c(g.select("span"),function(h){if(h&&g.hasClass(h,"mceItemHiddenSpellWord")){f=true;return false}});if(!f){e._done()}},_done:function(){var d=this,e=d.active;if(d.active){d.active=0;d._removeWords();if(d._menu){d._menu.hideMenu()}if(e){d.editor.nodeChanged()}}},_sendRPC:function(e,g,d){var f=this;a.sendRPC({url:f.rpcUrl,method:e,params:g,success:d,error:function(i,h){f.editor.setProgressState(0);f.editor.windowManager.alert(i.errstr||("Error response: "+h.responseText))}})}});tinymce.PluginManager.add("spellchecker",tinymce.plugins.SpellcheckerPlugin)})(); \ No newline at end of file +(function(){var a=tinymce.util.JSONRequest,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.SpellcheckerPlugin",{getInfo:function(){return{longname:"Spellchecker",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/spellchecker",version:tinymce.majorVersion+"."+tinymce.minorVersion}},init:function(e,f){var g=this,d;g.url=f;g.editor=e;g.rpcUrl=e.getParam("spellchecker_rpc_url","{backend}");if(g.rpcUrl=="{backend}"){if(tinymce.isIE){return}g.hasSupport=true;e.onContextMenu.addToTop(function(h,i){if(g.active){return false}})}e.addCommand("mceSpellCheck",function(){if(g.rpcUrl=="{backend}"){g.editor.getBody().spellcheck=g.active=!g.active;return}if(!g.active){e.setProgressState(1);g._sendRPC("checkWords",[g.selectedLang,g._getWords()],function(h){if(h.length>0){g.active=1;g._markWords(h);e.setProgressState(0);e.nodeChanged()}else{e.setProgressState(0);if(e.getParam("spellchecker_report_no_misspellings",true)){e.windowManager.alert("spellchecker.no_mpell")}}})}else{g._done()}});if(e.settings.content_css!==false){e.contentCSS.push(f+"/css/content.css")}e.onClick.add(g._showMenu,g);e.onContextMenu.add(g._showMenu,g);e.onBeforeGetContent.add(function(){if(g.active){g._removeWords()}});e.onNodeChange.add(function(i,h){h.setActive("spellchecker",g.active)});e.onSetContent.add(function(){g._done()});e.onBeforeGetContent.add(function(){g._done()});e.onBeforeExecCommand.add(function(h,i){if(i=="mceFullScreen"){g._done()}});g.languages={};c(e.getParam("spellchecker_languages","+English=en,Danish=da,Dutch=nl,Finnish=fi,French=fr,German=de,Italian=it,Polish=pl,Portuguese=pt,Spanish=es,Swedish=sv","hash"),function(i,h){if(h.indexOf("+")===0){h=h.substring(1);g.selectedLang=i}g.languages[h]=i})},createControl:function(h,d){var f=this,g,e=f.editor;if(h=="spellchecker"){if(f.rpcUrl=="{backend}"){if(f.hasSupport){g=d.createButton(h,{title:"spellchecker.desc",cmd:"mceSpellCheck",scope:f})}return g}g=d.createSplitButton(h,{title:"spellchecker.desc",cmd:"mceSpellCheck",scope:f});g.onRenderMenu.add(function(j,i){i.add({title:"spellchecker.langs","class":"mceMenuItemTitle"}).setDisabled(1);c(f.languages,function(n,m){var p={icon:1},l;p.onclick=function(){if(n==f.selectedLang){return}l.setSelected(1);f.selectedItem.setSelected(0);f.selectedItem=l;f.selectedLang=n};p.title=m;l=i.add(p);l.setSelected(n==f.selectedLang);if(n==f.selectedLang){f.selectedItem=l}})});return g}},_walk:function(i,g){var h=this.editor.getDoc(),e;if(h.createTreeWalker){e=h.createTreeWalker(i,NodeFilter.SHOW_TEXT,null,false);while((i=e.nextNode())!=null){g.call(this,i)}}else{tinymce.walk(i,g,"childNodes")}},_getSeparators:function(){var e="",d,f=this.editor.getParam("spellchecker_word_separator_chars",'\\s!"#$%&()*+,-./:;<=>?@[]^_{|}����������������\u201d\u201c');for(d=0;d<f.length;d++){e+="\\"+f.charAt(d)}return e},_getWords:function(){var e=this.editor,g=[],d="",f={},h=[];this._walk(e.getBody(),function(i){if(i.nodeType==3){d+=i.nodeValue+" "}});if(e.getParam("spellchecker_word_pattern")){h=d.match("("+e.getParam("spellchecker_word_pattern")+")","gi")}else{d=d.replace(new RegExp("([0-9]|["+this._getSeparators()+"])","g")," ");d=tinymce.trim(d.replace(/(\s+)/g," "));h=d.split(" ")}c(h,function(i){if(!f[i]){g.push(i);f[i]=1}});return g},_removeWords:function(d){var e=this.editor,h=e.dom,g=e.selection,f=g.getRng(true);c(h.select("span").reverse(),function(i){if(i&&(h.hasClass(i,"mceItemHiddenSpellWord")||h.hasClass(i,"mceItemHidden"))){if(!d||h.decode(i.innerHTML)==d){h.remove(i,1)}}});g.setRng(f)},_markWords:function(l){var h=this.editor,g=h.dom,j=h.getDoc(),i=h.selection,d=i.getRng(true),e=[],k=l.join("|"),m=this._getSeparators(),f=new RegExp("(^|["+m+"])("+k+")(?=["+m+"]|$)","g");this._walk(h.getBody(),function(o){if(o.nodeType==3){e.push(o)}});c(e,function(t){var r,q,o,s,p=t.nodeValue;if(f.test(p)){p=g.encode(p);q=g.create("span",{"class":"mceItemHidden"});if(tinymce.isIE){p=p.replace(f,"$1<mcespell>$2</mcespell>");while((s=p.indexOf("<mcespell>"))!=-1){o=p.substring(0,s);if(o.length){r=j.createTextNode(g.decode(o));q.appendChild(r)}p=p.substring(s+10);s=p.indexOf("</mcespell>");o=p.substring(0,s);p=p.substring(s+11);q.appendChild(g.create("span",{"class":"mceItemHiddenSpellWord"},o))}if(p.length){r=j.createTextNode(g.decode(p));q.appendChild(r)}}else{q.innerHTML=p.replace(f,'$1<span class="mceItemHiddenSpellWord">$2</span>')}g.replace(q,t)}});i.setRng(d)},_showMenu:function(h,j){var i=this,h=i.editor,d=i._menu,l,k=h.dom,g=k.getViewPort(h.getWin()),f=j.target;j=0;if(!d){d=h.controlManager.createDropMenu("spellcheckermenu",{"class":"mceNoIcons"});i._menu=d}if(k.hasClass(f,"mceItemHiddenSpellWord")){d.removeAll();d.add({title:"spellchecker.wait","class":"mceMenuItemTitle"}).setDisabled(1);i._sendRPC("getSuggestions",[i.selectedLang,k.decode(f.innerHTML)],function(m){var e;d.removeAll();if(m.length>0){d.add({title:"spellchecker.sug","class":"mceMenuItemTitle"}).setDisabled(1);c(m,function(n){d.add({title:n,onclick:function(){k.replace(h.getDoc().createTextNode(n),f);i._checkDone()}})});d.addSeparator()}else{d.add({title:"spellchecker.no_sug","class":"mceMenuItemTitle"}).setDisabled(1)}if(h.getParam("show_ignore_words",true)){e=i.editor.getParam("spellchecker_enable_ignore_rpc","");d.add({title:"spellchecker.ignore_word",onclick:function(){var n=f.innerHTML;k.remove(f,1);i._checkDone();if(e){h.setProgressState(1);i._sendRPC("ignoreWord",[i.selectedLang,n],function(o){h.setProgressState(0)})}}});d.add({title:"spellchecker.ignore_words",onclick:function(){var n=f.innerHTML;i._removeWords(k.decode(n));i._checkDone();if(e){h.setProgressState(1);i._sendRPC("ignoreWords",[i.selectedLang,n],function(o){h.setProgressState(0)})}}})}if(i.editor.getParam("spellchecker_enable_learn_rpc")){d.add({title:"spellchecker.learn_word",onclick:function(){var n=f.innerHTML;k.remove(f,1);i._checkDone();h.setProgressState(1);i._sendRPC("learnWord",[i.selectedLang,n],function(o){h.setProgressState(0)})}})}d.update()});l=b.getPos(h.getContentAreaContainer());d.settings.offset_x=l.x;d.settings.offset_y=l.y;h.selection.select(f);l=k.getPos(f);d.showMenu(l.x,l.y+f.offsetHeight-g.y);return tinymce.dom.Event.cancel(j)}else{d.hideMenu()}},_checkDone:function(){var e=this,d=e.editor,g=d.dom,f;c(g.select("span"),function(h){if(h&&g.hasClass(h,"mceItemHiddenSpellWord")){f=true;return false}});if(!f){e._done()}},_done:function(){var d=this,e=d.active;if(d.active){d.active=0;d._removeWords();if(d._menu){d._menu.hideMenu()}if(e){d.editor.nodeChanged()}}},_sendRPC:function(e,g,d){var f=this;a.sendRPC({url:f.rpcUrl,method:e,params:g,success:d,error:function(i,h){f.editor.setProgressState(0);f.editor.windowManager.alert(i.errstr||("Error response: "+h.responseText))}})}});tinymce.PluginManager.add("spellchecker",tinymce.plugins.SpellcheckerPlugin)})(); \ No newline at end of file diff --git a/plugins/spellchecker/editor_plugin_src.js b/plugins/spellchecker/editor_plugin_src.js index fb32af43420c5245d88e6f469d3495d52ce30218..86fdfceb409ed46342668cc63e78e6d6d8350735 100644 --- a/plugins/spellchecker/editor_plugin_src.js +++ b/plugins/spellchecker/editor_plugin_src.js @@ -208,7 +208,7 @@ }, _removeWords : function(w) { - var ed = this.editor, dom = ed.dom, se = ed.selection, b = se.getBookmark(); + var ed = this.editor, dom = ed.dom, se = ed.selection, r = se.getRng(true); each(dom.select('span').reverse(), function(n) { if (n && (dom.hasClass(n, 'mceItemHiddenSpellWord') || dom.hasClass(n, 'mceItemHidden'))) { @@ -217,11 +217,11 @@ } }); - se.moveToBookmark(b); + se.setRng(r); }, _markWords : function(wl) { - var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, b = se.getBookmark(), nl = [], + var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, r = se.getRng(true), nl = [], w = wl.join('|'), re = this._getSeparators(), rx = new RegExp('(^|[' + re + '])(' + w + ')(?=[' + re + ']|$)', 'g'); // Collect all text nodes @@ -279,7 +279,7 @@ } }); - se.moveToBookmark(b); + se.setRng(r); }, _showMenu : function(ed, e) { diff --git a/plugins/style/css/props.css b/plugins/style/css/props.css index eb1f2649605d6815e176186d78ce6fda3414e15f..3b8f0ee777b4a5126887b959fff3655ee0240f70 100644 --- a/plugins/style/css/props.css +++ b/plugins/style/css/props.css @@ -5,6 +5,7 @@ select, #block_text_indent, #box_width, #box_height, #box_padding_top, #box_padd #box_margin_top, #box_margin_right, #box_margin_bottom, #box_margin_left, #positioning_width, #positioning_height, #positioning_zindex {width:70px;} #positioning_placement_top, #positioning_placement_right, #positioning_placement_bottom, #positioning_placement_left {width:70px;} #positioning_clip_top, #positioning_clip_right, #positioning_clip_bottom, #positioning_clip_left {width:70px;} +.panel_toggle_insert_span {padding-top:10px;} .panel_wrapper div.current {padding-top:10px;height:230px;} .delim {border-left:1px solid gray;} .tdelim {border-bottom:1px solid gray;} diff --git a/plugins/style/editor_plugin.js b/plugins/style/editor_plugin.js index cab2153c40f1402f0fc9d36ff688174463d7fe3d..dda9f928b9573f64f541f9c204fd21ac0890fc2c 100644 --- a/plugins/style/editor_plugin.js +++ b/plugins/style/editor_plugin.js @@ -1 +1 @@ -(function(){tinymce.create("tinymce.plugins.StylePlugin",{init:function(a,b){a.addCommand("mceStyleProps",function(){a.windowManager.open({file:b+"/props.htm",width:480+parseInt(a.getLang("style.delta_width",0)),height:320+parseInt(a.getLang("style.delta_height",0)),inline:1},{plugin_url:b,style_text:a.selection.getNode().style.cssText})});a.addCommand("mceSetElementStyle",function(d,c){if(e=a.selection.getNode()){a.dom.setAttrib(e,"style",c);a.execCommand("mceRepaint")}});a.onNodeChange.add(function(d,c,f){c.setDisabled("styleprops",f.nodeName==="BODY")});a.addButton("styleprops",{title:"style.desc",cmd:"mceStyleProps"})},getInfo:function(){return{longname:"Style",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/style",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("style",tinymce.plugins.StylePlugin)})(); \ No newline at end of file +(function(){tinymce.create("tinymce.plugins.StylePlugin",{init:function(a,b){a.addCommand("mceStyleProps",function(){var c=false;var f=a.selection.getSelectedBlocks();var d=[];if(f.length===1){d.push(a.selection.getNode().style.cssText)}else{tinymce.each(f,function(g){d.push(a.dom.getAttrib(g,"style"))});c=true}a.windowManager.open({file:b+"/props.htm",width:480+parseInt(a.getLang("style.delta_width",0)),height:340+parseInt(a.getLang("style.delta_height",0)),inline:1},{applyStyleToBlocks:c,plugin_url:b,styles:d})});a.addCommand("mceSetElementStyle",function(d,c){if(e=a.selection.getNode()){a.dom.setAttrib(e,"style",c);a.execCommand("mceRepaint")}});a.onNodeChange.add(function(d,c,f){c.setDisabled("styleprops",f.nodeName==="BODY")});a.addButton("styleprops",{title:"style.desc",cmd:"mceStyleProps"})},getInfo:function(){return{longname:"Style",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/style",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("style",tinymce.plugins.StylePlugin)})(); \ No newline at end of file diff --git a/plugins/style/editor_plugin_src.js b/plugins/style/editor_plugin_src.js index 5f7755f1840afafe0170d115335c567c2a5ecaa4..eaa7c7713adaf4a1f85c620c00cbafc10e85fd6e 100644 --- a/plugins/style/editor_plugin_src.js +++ b/plugins/style/editor_plugin_src.js @@ -13,14 +13,30 @@ init : function(ed, url) { // Register commands ed.addCommand('mceStyleProps', function() { + + var applyStyleToBlocks = false; + var blocks = ed.selection.getSelectedBlocks(); + var styles = []; + + if (blocks.length === 1) { + styles.push(ed.selection.getNode().style.cssText); + } + else { + tinymce.each(blocks, function(block) { + styles.push(ed.dom.getAttrib(block, 'style')); + }); + applyStyleToBlocks = true; + } + ed.windowManager.open({ file : url + '/props.htm', width : 480 + parseInt(ed.getLang('style.delta_width', 0)), - height : 320 + parseInt(ed.getLang('style.delta_height', 0)), + height : 340 + parseInt(ed.getLang('style.delta_height', 0)), inline : 1 }, { + applyStyleToBlocks : applyStyleToBlocks, plugin_url : url, - style_text : ed.selection.getNode().style.cssText + styles : styles }); }); @@ -52,4 +68,4 @@ // Register plugin tinymce.PluginManager.add('style', tinymce.plugins.StylePlugin); -})(); \ No newline at end of file +})(); diff --git a/plugins/style/js/props.js b/plugins/style/js/props.js index 07a4c3ef4e832626f8b5905b6a01a9f7f8c8cab1..0a8a8ec3ef5841a3f1ae970e813707d111986508 100644 --- a/plugins/style/js/props.js +++ b/plugins/style/js/props.js @@ -27,10 +27,41 @@ var defaultBorderStyle = "none;solid;dashed;dotted;double;groove;ridge;inset;out var defaultBorderWidth = "thin;medium;thick"; var defaultListType = "disc;circle;square;decimal;lower-roman;upper-roman;lower-alpha;upper-alpha;none"; -function init() { +function aggregateStyles(allStyles) { + var mergedStyles = {}; + + tinymce.each(allStyles, function(style) { + if (style !== '') { + var parsedStyles = tinyMCEPopup.editor.dom.parseStyle(style); + for (var name in parsedStyles) { + if (parsedStyles.hasOwnProperty(name)) { + if (mergedStyles[name] === undefined) { + mergedStyles[name] = parsedStyles[name]; + } + else if (name === 'text-decoration') { + if (mergedStyles[name].indexOf(parsedStyles[name]) === -1) { + mergedStyles[name] = mergedStyles[name] +' '+ parsedStyles[name]; + } + } + } + } + } + }); + + return mergedStyles; +} + +var applyActionIsInsert; +var existingStyles; + +function init(ed) { var ce = document.getElementById('container'), h; - ce.style.cssText = tinyMCEPopup.getWindowArg('style_text'); + existingStyles = aggregateStyles(tinyMCEPopup.getWindowArg('styles')); + ce.style.cssText = tinyMCEPopup.editor.dom.serializeStyle(existingStyles); + + applyActionIsInsert = ed.getParam("edit_css_style_insert_span", false); + document.getElementById('toggle_insert_span').checked = applyActionIsInsert; h = getBrowserHTML('background_image_browser','background_image','image','advimage'); document.getElementById("background_image_browser").innerHTML = h; @@ -368,13 +399,41 @@ function hasEqualValues(a) { return true; } +function toggleApplyAction() { + applyActionIsInsert = ! applyActionIsInsert; +} + function applyAction() { var ce = document.getElementById('container'), ed = tinyMCEPopup.editor; generateCSS(); tinyMCEPopup.restoreSelection(); - ed.dom.setAttrib(ed.selection.getSelectedBlocks(), 'style', tinyMCEPopup.editor.dom.serializeStyle(tinyMCEPopup.editor.dom.parseStyle(ce.style.cssText))); + + var newStyles = tinyMCEPopup.editor.dom.parseStyle(ce.style.cssText); + + if (applyActionIsInsert) { + ed.formatter.register('plugin_style', { + inline: 'span', styles: existingStyles + }); + ed.formatter.remove('plugin_style'); + + ed.formatter.register('plugin_style', { + inline: 'span', styles: newStyles + }); + ed.formatter.apply('plugin_style'); + } else { + var nodes; + + if (tinyMCEPopup.getWindowArg('applyStyleToBlocks')) { + nodes = ed.selection.getSelectedBlocks(); + } + else { + nodes = ed.selection.getNode(); + } + + ed.dom.setAttrib(nodes, 'style', tinyMCEPopup.editor.dom.serializeStyle(newStyles)); + } } function updateAction() { diff --git a/plugins/style/langs/en_dlg.js b/plugins/style/langs/en_dlg.js index 9a1d4a22303f0c207c7edf4f14869168cfe7b803..35881b3aca00f3558b61a22f7f554921c8483cc5 100644 --- a/plugins/style/langs/en_dlg.js +++ b/plugins/style/langs/en_dlg.js @@ -1 +1 @@ -tinyMCE.addI18n('en.style_dlg',{"text_lineheight":"Line Height","text_variant":"Variant","text_style":"Style","text_weight":"Weight","text_size":"Size","text_font":"Font","text_props":"Text","positioning_tab":"Positioning","list_tab":"List","border_tab":"Border","box_tab":"Box","block_tab":"Block","background_tab":"Background","text_tab":"Text",apply:"Apply",title:"Edit CSS Style",clip:"Clip",placement:"Placement",overflow:"Overflow",zindex:"Z-index",visibility:"Visibility","positioning_type":"Type",position:"Position","bullet_image":"Bullet Image","list_type":"Type",color:"Color",height:"Height",width:"Width",style:"Style",margin:"Margin",left:"Left",bottom:"Bottom",right:"Right",top:"Top",same:"Same for All",padding:"Padding","box_clear":"Clear","box_float":"Float","box_height":"Height","box_width":"Width","block_display":"Display","block_whitespace":"Whitespace","block_text_indent":"Text Indent","block_text_align":"Text Align","block_vertical_alignment":"Vertical Alignment","block_letterspacing":"Letter Spacing","block_wordspacing":"Word Spacing","background_vpos":"Vertical Position","background_hpos":"Horizontal Position","background_attachment":"Attachment","background_repeat":"Repeat","background_image":"Background Image","background_color":"Background Color","text_none":"None","text_blink":"Blink","text_case":"Case","text_striketrough":"Strikethrough","text_underline":"Underline","text_overline":"Overline","text_decoration":"Decoration","text_color":"Color",text:"Text",background:"Background",block:"Block",box:"Box",border:"Border",list:"List"}); \ No newline at end of file +tinyMCE.addI18n('en.style_dlg',{"text_lineheight":"Line Height","text_variant":"Variant","text_style":"Style","text_weight":"Weight","text_size":"Size","text_font":"Font","text_props":"Text","positioning_tab":"Positioning","list_tab":"List","border_tab":"Border","box_tab":"Box","block_tab":"Block","background_tab":"Background","text_tab":"Text",apply:"Apply",toggle_insert_span:"Insert span at selection",title:"Edit CSS Style",clip:"Clip",placement:"Placement",overflow:"Overflow",zindex:"Z-index",visibility:"Visibility","positioning_type":"Type",position:"Position","bullet_image":"Bullet Image","list_type":"Type",color:"Color",height:"Height",width:"Width",style:"Style",margin:"Margin",left:"Left",bottom:"Bottom",right:"Right",top:"Top",same:"Same for All",padding:"Padding","box_clear":"Clear","box_float":"Float","box_height":"Height","box_width":"Width","block_display":"Display","block_whitespace":"Whitespace","block_text_indent":"Text Indent","block_text_align":"Text Align","block_vertical_alignment":"Vertical Alignment","block_letterspacing":"Letter Spacing","block_wordspacing":"Word Spacing","background_vpos":"Vertical Position","background_hpos":"Horizontal Position","background_attachment":"Attachment","background_repeat":"Repeat","background_image":"Background Image","background_color":"Background Color","text_none":"None","text_blink":"Blink","text_case":"Case","text_striketrough":"Strikethrough","text_underline":"Underline","text_overline":"Overline","text_decoration":"Decoration","text_color":"Color",text:"Text",background:"Background",block:"Block",box:"Box",border:"Border",list:"List"}); diff --git a/plugins/style/props.htm b/plugins/style/props.htm index 3e3de85d0a5767cdd22b5aa1a56081c4fcb80997..7dc087a307386394205338bfe8c417809840d471 100644 --- a/plugins/style/props.htm +++ b/plugins/style/props.htm @@ -825,6 +825,11 @@ </div> </div> +<div class="panel_toggle_insert_span"> + <input type="checkbox" class="checkbox" id="toggle_insert_span" name="toggle_insert_span" onClick="toggleApplyAction();" /> + <label for="toggle_insert_span">{#style_dlg.toggle_insert_span}</label> +</div> + <div class="mceActionPanel"> <input type="submit" id="insert" name="insert" value="{#update}" /> <input type="button" class="button" id="apply" name="apply" value="{#style_dlg.apply}" onClick="applyAction();" /> diff --git a/plugins/style/readme.txt b/plugins/style/readme.txt new file mode 100644 index 0000000000000000000000000000000000000000..5bac30202e443d3adc69e7b758543b09a047a117 --- /dev/null +++ b/plugins/style/readme.txt @@ -0,0 +1,19 @@ +Edit CSS Style plug-in notes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Unlike WYSIWYG editor functionality that operates only on the selected text, +typically by inserting new HTML elements with the specified styles. +This plug-in operates on the HTML blocks surrounding the selected text. +No new HTML elements are created. + +This plug-in only operates on the surrounding blocks and not the nearest +parent node. This means that if a block encapsulates a node, +e.g <p><span>text</span></p>, then only the styles in the block are +recognized, not those in the span. + +When selecting text that includes multiple blocks at the same level (peers), +this plug-in accumulates the specified styles in all of the surrounding blocks +and populates the dialogue checkboxes accordingly. There is no differentiation +between styles set in all the blocks versus styles set in some of the blocks. + +When the [Update] or [Apply] buttons are pressed, the styles selected in the +checkboxes are applied to all blocks that surround the selected text. diff --git a/plugins/tabfocus/editor_plugin.js b/plugins/tabfocus/editor_plugin.js index 42a82d112c5d568031498bb94d978777225ab35f..2c51291615f5c1e3d957904d5751d9fcb52616ca 100644 --- a/plugins/tabfocus/editor_plugin.js +++ b/plugins/tabfocus/editor_plugin.js @@ -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)})(); \ No newline at end of file +(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)})(); \ No newline at end of file diff --git a/plugins/tabfocus/editor_plugin_src.js b/plugins/tabfocus/editor_plugin_src.js index a1579c85f22760df55dc01ffa04c2a00aca7917a..94f45320d600fcf930c693ce39fa83b0d02518cc 100644 --- a/plugins/tabfocus/editor_plugin_src.js +++ b/plugins/tabfocus/editor_plugin_src.js @@ -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' && diff --git a/plugins/table/editor_plugin.js b/plugins/table/editor_plugin.js index 9acc09bcae6c44eddc75e78ba7d0ee355e70a908..4a35a5ef93106b46ee628110931cf522cc27f8d7 100644 --- a/plugins/table/editor_plugin.js +++ b/plugins/table/editor_plugin.js @@ -1 +1 @@ -(function(d){var e=d.each;function c(g,h){var j=h.ownerDocument,f=j.createRange(),k;f.setStartBefore(h);f.setEnd(g.endContainer,g.endOffset);k=j.createElement("body");k.appendChild(f.cloneContents());return k.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length==0}function a(g,f){return parseInt(g.getAttribute(f)||1)}function b(H,G,K){var g,L,D,o;t();o=G.getParent(K.getStart(),"th,td");if(o){L=F(o);D=I();o=z(L.x,L.y)}function A(N,M){N=N.cloneNode(M);N.removeAttribute("id");return N}function t(){var M=0;g=[];e(["thead","tbody","tfoot"],function(N){var O=G.select("> "+N+" tr",H);e(O,function(P,Q){Q+=M;e(G.select("> td, > th",P),function(W,R){var S,T,U,V;if(g[Q]){while(g[Q][R]){R++}}U=a(W,"rowspan");V=a(W,"colspan");for(T=Q;T<Q+U;T++){if(!g[T]){g[T]=[]}for(S=R;S<R+V;S++){g[T][S]={part:N,real:T==Q&&S==R,elm:W,rowspan:U,colspan:V}}}})});M+=O.length})}function z(M,O){var N;N=g[O];if(N){return N[M]}}function s(O,M,N){if(O){N=parseInt(N);if(N===1){O.removeAttribute(M,1)}else{O.setAttribute(M,N,1)}}}function j(M){return M&&(G.hasClass(M.elm,"mceSelected")||M==o)}function k(){var M=[];e(H.rows,function(N){e(N.cells,function(O){if(G.hasClass(O,"mceSelected")||O==o.elm){M.push(N);return false}})});return M}function r(){var M=G.createRng();M.setStartAfter(H);M.setEndAfter(H);K.setRng(M);G.remove(H)}function f(M){var N;d.walk(M,function(P){var O;if(P.nodeType==3){e(G.getParents(P.parentNode,null,M).reverse(),function(Q){Q=A(Q,false);if(!N){N=O=Q}else{if(O){O.appendChild(Q)}}O=Q});if(O){O.innerHTML=d.isIE?" ":'<br data-mce-bogus="1" />'}return false}},"childNodes");M=A(M,false);s(M,"rowSpan",1);s(M,"colSpan",1);if(N){M.appendChild(N)}else{if(!d.isIE){M.innerHTML='<br data-mce-bogus="1" />'}}return M}function q(){var M=G.createRng();e(G.select("tr",H),function(N){if(N.cells.length==0){G.remove(N)}});if(G.select("tr",H).length==0){M.setStartAfter(H);M.setEndAfter(H);K.setRng(M);G.remove(H);return}e(G.select("thead,tbody,tfoot",H),function(N){if(N.rows.length==0){G.remove(N)}});t();row=g[Math.min(g.length-1,L.y)];if(row){K.select(row[Math.min(row.length-1,L.x)].elm,true);K.collapse(true)}}function u(S,Q,U,R){var P,N,M,O,T;P=g[Q][S].elm.parentNode;for(M=1;M<=U;M++){P=G.getNext(P,"tr");if(P){for(N=S;N>=0;N--){T=g[Q+M][N].elm;if(T.parentNode==P){for(O=1;O<=R;O++){G.insertAfter(f(T),T)}break}}if(N==-1){for(O=1;O<=R;O++){P.insertBefore(f(P.cells[0]),P.cells[0])}}}}}function C(){e(g,function(M,N){e(M,function(P,O){var S,R,T,Q;if(j(P)){P=P.elm;S=a(P,"colspan");R=a(P,"rowspan");if(S>1||R>1){s(P,"rowSpan",1);s(P,"colSpan",1);for(Q=0;Q<S-1;Q++){G.insertAfter(f(P),P)}u(O,N,R-1,S)}}})})}function p(V,S,Y){var P,O,X,W,U,R,T,M,V,N,Q;if(V){pos=F(V);P=pos.x;O=pos.y;X=P+(S-1);W=O+(Y-1)}else{P=L.x;O=L.y;X=D.x;W=D.y}T=z(P,O);M=z(X,W);if(T&&M&&T.part==M.part){C();t();T=z(P,O).elm;s(T,"colSpan",(X-P)+1);s(T,"rowSpan",(W-O)+1);for(R=O;R<=W;R++){for(U=P;U<=X;U++){if(!g[R]||!g[R][U]){continue}V=g[R][U].elm;if(V!=T){N=d.grep(V.childNodes);e(N,function(Z){T.appendChild(Z)});if(N.length){N=d.grep(T.childNodes);Q=0;e(N,function(Z){if(Z.nodeName=="BR"&&G.getAttrib(Z,"data-mce-bogus")&&Q++<N.length-1){T.removeChild(Z)}})}G.remove(V)}}}q()}}function l(Q){var M,S,P,R,T,U,N,V,O;e(g,function(W,X){e(W,function(Z,Y){if(j(Z)){Z=Z.elm;T=Z.parentNode;U=A(T,false);M=X;if(Q){return false}}});if(Q){return !M}});for(R=0;R<g[0].length;R++){if(!g[M][R]){continue}S=g[M][R].elm;if(S!=P){if(!Q){O=a(S,"rowspan");if(O>1){s(S,"rowSpan",O+1);continue}}else{if(M>0&&g[M-1][R]){V=g[M-1][R].elm;O=a(V,"rowSpan");if(O>1){s(V,"rowSpan",O+1);continue}}}N=f(S);s(N,"colSpan",S.colSpan);U.appendChild(N);P=S}}if(U.hasChildNodes()){if(!Q){G.insertAfter(U,T)}else{T.parentNode.insertBefore(U,T)}}}function h(N){var O,M;e(g,function(P,Q){e(P,function(S,R){if(j(S)){O=R;if(N){return false}}});if(N){return !O}});e(g,function(S,T){var P,Q,R;if(!S[O]){return}P=S[O].elm;if(P!=M){R=a(P,"colspan");Q=a(P,"rowspan");if(R==1){if(!N){G.insertAfter(f(P),P);u(O,T,Q-1,R)}else{P.parentNode.insertBefore(f(P),P);u(O,T,Q-1,R)}}else{s(P,"colSpan",P.colSpan+1)}M=P}})}function n(){var M=[];e(g,function(N,O){e(N,function(Q,P){if(j(Q)&&d.inArray(M,P)===-1){e(g,function(T){var R=T[P].elm,S;S=a(R,"colSpan");if(S>1){s(R,"colSpan",S-1)}else{G.remove(R)}});M.push(P)}})});q()}function m(){var N;function M(Q){var P,R,O;P=G.getNext(Q,"tr");e(Q.cells,function(S){var T=a(S,"rowSpan");if(T>1){s(S,"rowSpan",T-1);R=F(S);u(R.x,R.y,1,1)}});R=F(Q.cells[0]);e(g[R.y],function(S){var T;S=S.elm;if(S!=O){T=a(S,"rowSpan");if(T<=1){G.remove(S)}else{s(S,"rowSpan",T-1)}O=S}})}N=k();e(N.reverse(),function(O){M(O)});q()}function E(){var M=k();G.remove(M);q();return M}function J(){var M=k();e(M,function(O,N){M[N]=A(O,true)});return M}function B(O,N){var P=k(),M=P[N?0:P.length-1],Q=M.cells.length;e(g,function(S){var R;Q=0;e(S,function(U,T){if(U.real){Q+=U.colspan}if(U.elm.parentNode==M){R=1}});if(R){return false}});if(!N){O.reverse()}e(O,function(T){var S=T.cells.length,R;for(i=0;i<S;i++){R=T.cells[i];s(R,"colSpan",1);s(R,"rowSpan",1)}for(i=S;i<Q;i++){T.appendChild(f(T.cells[S-1]))}for(i=Q;i<S;i++){G.remove(T.cells[i])}if(N){M.parentNode.insertBefore(T,M)}else{G.insertAfter(T,M)}})}function F(M){var N;e(g,function(O,P){e(O,function(R,Q){if(R.elm==M){N={x:Q,y:P};return false}});return !N});return N}function w(M){L=F(M)}function I(){var O,N,M;N=M=0;e(g,function(P,Q){e(P,function(S,R){var U,T;if(j(S)){S=g[Q][R];if(R>N){N=R}if(Q>M){M=Q}if(S.real){U=S.colspan-1;T=S.rowspan-1;if(U){if(R+U>N){N=R+U}}if(T){if(Q+T>M){M=Q+T}}}}})});return{x:N,y:M}}function v(S){var P,O,U,T,N,M,Q,R;D=F(S);if(L&&D){P=Math.min(L.x,D.x);O=Math.min(L.y,D.y);U=Math.max(L.x,D.x);T=Math.max(L.y,D.y);N=U;M=T;for(y=O;y<=M;y++){S=g[y][P];if(!S.real){if(P-(S.colspan-1)<P){P-=S.colspan-1}}}for(x=P;x<=N;x++){S=g[O][x];if(!S.real){if(O-(S.rowspan-1)<O){O-=S.rowspan-1}}}for(y=O;y<=T;y++){for(x=P;x<=U;x++){S=g[y][x];if(S.real){Q=S.colspan-1;R=S.rowspan-1;if(Q){if(x+Q>N){N=x+Q}}if(R){if(y+R>M){M=y+R}}}}}G.removeClass(G.select("td.mceSelected,th.mceSelected"),"mceSelected");for(y=O;y<=M;y++){for(x=P;x<=N;x++){if(g[y][x]){G.addClass(g[y][x].elm,"mceSelected")}}}}}d.extend(this,{deleteTable:r,split:C,merge:p,insertRow:l,insertCol:h,deleteCols:n,deleteRows:m,cutRows:E,copyRows:J,pasteRows:B,getPos:F,setStartCell:w,setEndCell:v})}d.create("tinymce.plugins.TablePlugin",{init:function(g,h){var f,m,j=true;function l(p){var o=g.selection,n=g.dom.getParent(p||o.getNode(),"table");if(n){return new b(n,g.dom,o)}}function k(){g.getBody().style.webkitUserSelect="";if(j){g.dom.removeClass(g.dom.select("td.mceSelected,th.mceSelected"),"mceSelected");j=false}}e([["table","table.desc","mceInsertTable",true],["delete_table","table.del","mceTableDelete"],["delete_col","table.delete_col_desc","mceTableDeleteCol"],["delete_row","table.delete_row_desc","mceTableDeleteRow"],["col_after","table.col_after_desc","mceTableInsertColAfter"],["col_before","table.col_before_desc","mceTableInsertColBefore"],["row_after","table.row_after_desc","mceTableInsertRowAfter"],["row_before","table.row_before_desc","mceTableInsertRowBefore"],["row_props","table.row_desc","mceTableRowProps",true],["cell_props","table.cell_desc","mceTableCellProps",true],["split_cells","table.split_cells_desc","mceTableSplitCells",true],["merge_cells","table.merge_cells_desc","mceTableMergeCells",true]],function(n){g.addButton(n[0],{title:n[1],cmd:n[2],ui:n[3]})});if(!d.isIE){g.onClick.add(function(n,o){o=o.target;if(o.nodeName==="TABLE"){n.selection.select(o);n.nodeChanged()}})}g.onPreProcess.add(function(o,p){var n,q,r,t=o.dom,s;n=t.select("table",p.node);q=n.length;while(q--){r=n[q];t.setAttrib(r,"data-mce-style","");if((s=t.getAttrib(r,"width"))){t.setStyle(r,"width",s);t.setAttrib(r,"width","")}if((s=t.getAttrib(r,"height"))){t.setStyle(r,"height",s);t.setAttrib(r,"height","")}}});g.onNodeChange.add(function(q,o,s){var r;s=q.selection.getStart();r=q.dom.getParent(s,"td,th,caption");o.setActive("table",s.nodeName==="TABLE"||!!r);if(r&&r.nodeName==="CAPTION"){r=0}o.setDisabled("delete_table",!r);o.setDisabled("delete_col",!r);o.setDisabled("delete_table",!r);o.setDisabled("delete_row",!r);o.setDisabled("col_after",!r);o.setDisabled("col_before",!r);o.setDisabled("row_after",!r);o.setDisabled("row_before",!r);o.setDisabled("row_props",!r);o.setDisabled("cell_props",!r);o.setDisabled("split_cells",!r);o.setDisabled("merge_cells",!r)});g.onInit.add(function(r){var p,t,q=r.dom,u;f=r.windowManager;r.onMouseDown.add(function(w,z){if(z.button!=2){k();t=q.getParent(z.target,"td,th");p=q.getParent(t,"table")}});q.bind(r.getDoc(),"mouseover",function(C){var A,z,B=C.target;if(t&&(u||B!=t)&&(B.nodeName=="TD"||B.nodeName=="TH")){z=q.getParent(B,"table");if(z==p){if(!u){u=l(z);u.setStartCell(t);r.getBody().style.webkitUserSelect="none"}u.setEndCell(B);j=true}A=r.selection.getSel();try{if(A.removeAllRanges){A.removeAllRanges()}else{A.empty()}}catch(w){}C.preventDefault()}});r.onMouseUp.add(function(F,G){var z,B=F.selection,H,I=B.getSel(),w,C,A,E;if(t){if(u){F.getBody().style.webkitUserSelect=""}function D(J,L){var K=new d.dom.TreeWalker(J,J);do{if(J.nodeType==3&&d.trim(J.nodeValue).length!=0){if(L){z.setStart(J,0)}else{z.setEnd(J,J.nodeValue.length)}return}if(J.nodeName=="BR"){if(L){z.setStartBefore(J)}else{z.setEndBefore(J)}return}}while(J=(L?K.next():K.prev()))}H=q.select("td.mceSelected,th.mceSelected");if(H.length>0){z=q.createRng();C=H[0];E=H[H.length-1];z.setStartBefore(C);z.setEndAfter(C);D(C,1);w=new d.dom.TreeWalker(C,q.getParent(H[0],"table"));do{if(C.nodeName=="TD"||C.nodeName=="TH"){if(!q.hasClass(C,"mceSelected")){break}A=C}}while(C=w.next());D(A);B.setRng(z)}F.nodeChanged();t=u=p=null}});r.onKeyUp.add(function(w,z){k()});r.onKeyDown.add(function(w,z){n(w)});r.onMouseDown.add(function(w,z){if(z.button!=2){n(w)}});function o(D,z,A,F){var B=3,G=D.dom.getParent(z.startContainer,"TABLE"),C,w,E;if(G){C=G.parentNode}w=z.startContainer.nodeType==B&&z.startOffset==0&&z.endOffset==0&&F&&(A.nodeName=="TR"||A==C);E=(A.nodeName=="TD"||A.nodeName=="TH")&&!F;return w||E}function n(A){if(!d.isWebKit){return}var z=A.selection.getRng();var C=A.selection.getNode();var B=A.dom.getParent(z.startContainer,"TD,TH");if(!o(A,z,C,B)){return}if(!B){B=C}var w=B.lastChild;while(w.lastChild){w=w.lastChild}z.setEnd(w,w.nodeValue.length);A.selection.setRng(z)}r.plugins.table.fixTableCellSelection=n;if(r&&r.plugins.contextmenu){r.plugins.contextmenu.onContextMenu.add(function(A,w,C){var D,B=r.selection,z=B.getNode()||r.getBody();if(r.dom.getParent(C,"td")||r.dom.getParent(C,"th")||r.dom.select("td.mceSelected,th.mceSelected").length){w.removeAll();if(z.nodeName=="A"&&!r.dom.getAttrib(z,"name")){w.add({title:"advanced.link_desc",icon:"link",cmd:r.plugins.advlink?"mceAdvLink":"mceLink",ui:true});w.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});w.addSeparator()}if(z.nodeName=="IMG"&&z.className.indexOf("mceItem")==-1){w.add({title:"advanced.image_desc",icon:"image",cmd:r.plugins.advimage?"mceAdvImage":"mceImage",ui:true});w.addSeparator()}w.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",value:{action:"insert"}});w.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable"});w.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete"});w.addSeparator();D=w.addMenu({title:"table.cell"});D.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps"});D.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells"});D.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells"});D=w.addMenu({title:"table.row"});D.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps"});D.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});D.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});D.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});D.addSeparator();D.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});D.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});D.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"}).setDisabled(!m);D.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"}).setDisabled(!m);D=w.addMenu({title:"table.col"});D.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});D.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});D.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{w.add({title:"table.desc",icon:"table",cmd:"mceInsertTable"})}})}if(d.isWebKit){function v(C,N){var L=d.VK;var Q=N.keyCode;function O(Y,U,S){var T=Y?"previousSibling":"nextSibling";var Z=C.dom.getParent(U,"tr");var X=Z[T];if(X){z(C,U,X,Y);d.dom.Event.cancel(S);return true}else{var aa=C.dom.getParent(Z,"table");var W=Z.parentNode;var R=W.nodeName.toLowerCase();if(R==="tbody"||R===(Y?"tfoot":"thead")){var V=w(Y,aa,W,"tbody");if(V!==null){return K(Y,V,U,S)}}return M(Y,Z,T,aa,S)}}function w(V,T,U,X){var S=C.dom.select(">"+X,T);var R=S.indexOf(U);if(V&&R===0||!V&&R===S.length-1){return B(V,T)}else{if(R===-1){var W=U.tagName.toLowerCase()==="thead"?0:S.length-1;return S[W]}else{return S[R+(V?-1:1)]}}}function B(U,T){var S=U?"thead":"tfoot";var R=C.dom.select(">"+S,T);return R.length!==0?R[0]:null}function K(V,T,S,U){var R=J(T,V);R&&z(C,S,R,V);d.dom.Event.cancel(U);return true}function M(Y,U,R,X,W){var S=X[R];if(S){F(S);return true}else{var V=C.dom.getParent(X,"td,th");if(V){return O(Y,V,W)}else{var T=J(U,!Y);F(T);return d.dom.Event.cancel(W)}}}function J(S,R){return S&&S[R?"lastChild":"firstChild"]}function F(R){C.selection.setCursorLocation(R,0)}function A(){return Q==L.UP||Q==L.DOWN}function D(R){var T=R.selection.getNode();var S=R.dom.getParent(T,"tr");return S!==null}function P(S){var R=0;var T=S;while(T.previousSibling){T=T.previousSibling;R=R+a(T,"colspan")}return R}function E(T,R){var U=0;var S=0;e(T.children,function(V,W){U=U+a(V,"colspan");S=W;if(U>R){return false}});return S}function z(T,W,Y,V){var X=P(T.dom.getParent(W,"td,th"));var S=E(Y,X);var R=Y.childNodes[S];var U=J(R,V);F(U||R)}function H(R){var T=C.selection.getNode();var U=C.dom.getParent(T,"td,th");var S=C.dom.getParent(R,"td,th");return U&&U!==S&&I(U,S)}function I(S,R){return C.dom.getParent(S,"TABLE")===C.dom.getParent(R,"TABLE")}if(A()&&D(C)){var G=C.selection.getNode();setTimeout(function(){if(H(G)){O(!N.shiftKey&&Q===L.UP,G,N)}},0)}}r.onKeyDown.add(v)}if(!d.isIE){function s(){var w;for(w=r.getBody().lastChild;w&&w.nodeType==3&&!w.nodeValue.length;w=w.previousSibling){}if(w&&w.nodeName=="TABLE"){r.dom.add(r.getBody(),"p",null,'<br mce_bogus="1" />')}}if(d.isGecko){r.onKeyDown.add(function(z,B){var w,A,C=z.dom;if(B.keyCode==37||B.keyCode==38){w=z.selection.getRng();A=C.getParent(w.startContainer,"table");if(A&&z.getBody().firstChild==A){if(c(w,A)){w=C.createRng();w.setStartBefore(A);w.setEndBefore(A);z.selection.setRng(w);B.preventDefault()}}}})}r.onKeyUp.add(s);r.onSetContent.add(s);r.onVisualAid.add(s);r.onPreProcess.add(function(w,A){var z=A.node.lastChild;if(z&&z.childNodes.length==1&&z.firstChild.nodeName=="BR"){w.dom.remove(z)}});if(d.isGecko){r.onKeyDown.add(function(z,B){if(B.keyCode===d.VK.ENTER&&B.shiftKey){var A=z.selection.getRng().startContainer;var C=q.getParent(A,"td,th");if(C){var w=z.getDoc().createTextNode("\uFEFF");q.insertAfter(w,A)}}})}s();r.startContent=r.getContent({format:"raw"})}});e({mceTableSplitCells:function(n){n.split()},mceTableMergeCells:function(o){var p,q,n;n=g.dom.getParent(g.selection.getNode(),"th,td");if(n){p=n.rowSpan;q=n.colSpan}if(!g.dom.select("td.mceSelected,th.mceSelected").length){f.open({url:h+"/merge_cells.htm",width:240+parseInt(g.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(g.getLang("table.merge_cells_delta_height",0)),inline:1},{rows:p,cols:q,onaction:function(r){o.merge(n,r.cols,r.rows)},plugin_url:h})}else{o.merge()}},mceTableInsertRowBefore:function(n){n.insertRow(true)},mceTableInsertRowAfter:function(n){n.insertRow()},mceTableInsertColBefore:function(n){n.insertCol(true)},mceTableInsertColAfter:function(n){n.insertCol()},mceTableDeleteCol:function(n){n.deleteCols()},mceTableDeleteRow:function(n){n.deleteRows()},mceTableCutRow:function(n){m=n.cutRows()},mceTableCopyRow:function(n){m=n.copyRows()},mceTablePasteRowBefore:function(n){n.pasteRows(m,true)},mceTablePasteRowAfter:function(n){n.pasteRows(m)},mceTableDelete:function(n){n.deleteTable()}},function(o,n){g.addCommand(n,function(){var p=l();if(p){o(p);g.execCommand("mceRepaint");k()}})});e({mceInsertTable:function(n){f.open({url:h+"/table.htm",width:400+parseInt(g.getLang("table.table_delta_width",0)),height:320+parseInt(g.getLang("table.table_delta_height",0)),inline:1},{plugin_url:h,action:n?n.action:0})},mceTableRowProps:function(){f.open({url:h+"/row.htm",width:400+parseInt(g.getLang("table.rowprops_delta_width",0)),height:295+parseInt(g.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:h})},mceTableCellProps:function(){f.open({url:h+"/cell.htm",width:400+parseInt(g.getLang("table.cellprops_delta_width",0)),height:295+parseInt(g.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:h})}},function(o,n){g.addCommand(n,function(p,q){o(q)})})}});d.PluginManager.add("table",d.plugins.TablePlugin)})(tinymce); \ No newline at end of file +(function(d){var e=d.each;function c(g,h){var j=h.ownerDocument,f=j.createRange(),k;f.setStartBefore(h);f.setEnd(g.endContainer,g.endOffset);k=j.createElement("body");k.appendChild(f.cloneContents());return k.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length==0}function a(g,f){return parseInt(g.getAttribute(f)||1)}function b(H,G,K){var g,L,D,o;t();o=G.getParent(K.getStart(),"th,td");if(o){L=F(o);D=I();o=z(L.x,L.y)}function A(N,M){N=N.cloneNode(M);N.removeAttribute("id");return N}function t(){var M=0;g=[];e(["thead","tbody","tfoot"],function(N){var O=G.select("> "+N+" tr",H);e(O,function(P,Q){Q+=M;e(G.select("> td, > th",P),function(W,R){var S,T,U,V;if(g[Q]){while(g[Q][R]){R++}}U=a(W,"rowspan");V=a(W,"colspan");for(T=Q;T<Q+U;T++){if(!g[T]){g[T]=[]}for(S=R;S<R+V;S++){g[T][S]={part:N,real:T==Q&&S==R,elm:W,rowspan:U,colspan:V}}}})});M+=O.length})}function z(M,O){var N;N=g[O];if(N){return N[M]}}function s(O,M,N){if(O){N=parseInt(N);if(N===1){O.removeAttribute(M,1)}else{O.setAttribute(M,N,1)}}}function j(M){return M&&(G.hasClass(M.elm,"mceSelected")||M==o)}function k(){var M=[];e(H.rows,function(N){e(N.cells,function(O){if(G.hasClass(O,"mceSelected")||O==o.elm){M.push(N);return false}})});return M}function r(){var M=G.createRng();M.setStartAfter(H);M.setEndAfter(H);K.setRng(M);G.remove(H)}function f(M){var N;d.walk(M,function(P){var O;if(P.nodeType==3){e(G.getParents(P.parentNode,null,M).reverse(),function(Q){Q=A(Q,false);if(!N){N=O=Q}else{if(O){O.appendChild(Q)}}O=Q});if(O){O.innerHTML=d.isIE?" ":'<br data-mce-bogus="1" />'}return false}},"childNodes");M=A(M,false);s(M,"rowSpan",1);s(M,"colSpan",1);if(N){M.appendChild(N)}else{if(!d.isIE){M.innerHTML='<br data-mce-bogus="1" />'}}return M}function q(){var M=G.createRng();e(G.select("tr",H),function(N){if(N.cells.length==0){G.remove(N)}});if(G.select("tr",H).length==0){M.setStartAfter(H);M.setEndAfter(H);K.setRng(M);G.remove(H);return}e(G.select("thead,tbody,tfoot",H),function(N){if(N.rows.length==0){G.remove(N)}});t();row=g[Math.min(g.length-1,L.y)];if(row){K.select(row[Math.min(row.length-1,L.x)].elm,true);K.collapse(true)}}function u(S,Q,U,R){var P,N,M,O,T;P=g[Q][S].elm.parentNode;for(M=1;M<=U;M++){P=G.getNext(P,"tr");if(P){for(N=S;N>=0;N--){T=g[Q+M][N].elm;if(T.parentNode==P){for(O=1;O<=R;O++){G.insertAfter(f(T),T)}break}}if(N==-1){for(O=1;O<=R;O++){P.insertBefore(f(P.cells[0]),P.cells[0])}}}}}function C(){e(g,function(M,N){e(M,function(P,O){var S,R,T,Q;if(j(P)){P=P.elm;S=a(P,"colspan");R=a(P,"rowspan");if(S>1||R>1){s(P,"rowSpan",1);s(P,"colSpan",1);for(Q=0;Q<S-1;Q++){G.insertAfter(f(P),P)}u(O,N,R-1,S)}}})})}function p(V,S,Y){var P,O,X,W,U,R,T,M,V,N,Q;if(V){pos=F(V);P=pos.x;O=pos.y;X=P+(S-1);W=O+(Y-1)}else{L=D=null;e(g,function(Z,aa){e(Z,function(ac,ab){if(j(ac)){if(!L){L={x:ab,y:aa}}D={x:ab,y:aa}}})});P=L.x;O=L.y;X=D.x;W=D.y}T=z(P,O);M=z(X,W);if(T&&M&&T.part==M.part){C();t();T=z(P,O).elm;s(T,"colSpan",(X-P)+1);s(T,"rowSpan",(W-O)+1);for(R=O;R<=W;R++){for(U=P;U<=X;U++){if(!g[R]||!g[R][U]){continue}V=g[R][U].elm;if(V!=T){N=d.grep(V.childNodes);e(N,function(Z){T.appendChild(Z)});if(N.length){N=d.grep(T.childNodes);Q=0;e(N,function(Z){if(Z.nodeName=="BR"&&G.getAttrib(Z,"data-mce-bogus")&&Q++<N.length-1){T.removeChild(Z)}})}G.remove(V)}}}q()}}function l(Q){var M,S,P,R,T,U,N,V,O;e(g,function(W,X){e(W,function(Z,Y){if(j(Z)){Z=Z.elm;T=Z.parentNode;U=A(T,false);M=X;if(Q){return false}}});if(Q){return !M}});for(R=0;R<g[0].length;R++){if(!g[M][R]){continue}S=g[M][R].elm;if(S!=P){if(!Q){O=a(S,"rowspan");if(O>1){s(S,"rowSpan",O+1);continue}}else{if(M>0&&g[M-1][R]){V=g[M-1][R].elm;O=a(V,"rowSpan");if(O>1){s(V,"rowSpan",O+1);continue}}}N=f(S);s(N,"colSpan",S.colSpan);U.appendChild(N);P=S}}if(U.hasChildNodes()){if(!Q){G.insertAfter(U,T)}else{T.parentNode.insertBefore(U,T)}}}function h(N){var O,M;e(g,function(P,Q){e(P,function(S,R){if(j(S)){O=R;if(N){return false}}});if(N){return !O}});e(g,function(S,T){var P,Q,R;if(!S[O]){return}P=S[O].elm;if(P!=M){R=a(P,"colspan");Q=a(P,"rowspan");if(R==1){if(!N){G.insertAfter(f(P),P);u(O,T,Q-1,R)}else{P.parentNode.insertBefore(f(P),P);u(O,T,Q-1,R)}}else{s(P,"colSpan",P.colSpan+1)}M=P}})}function n(){var M=[];e(g,function(N,O){e(N,function(Q,P){if(j(Q)&&d.inArray(M,P)===-1){e(g,function(T){var R=T[P].elm,S;S=a(R,"colSpan");if(S>1){s(R,"colSpan",S-1)}else{G.remove(R)}});M.push(P)}})});q()}function m(){var N;function M(Q){var P,R,O;P=G.getNext(Q,"tr");e(Q.cells,function(S){var T=a(S,"rowSpan");if(T>1){s(S,"rowSpan",T-1);R=F(S);u(R.x,R.y,1,1)}});R=F(Q.cells[0]);e(g[R.y],function(S){var T;S=S.elm;if(S!=O){T=a(S,"rowSpan");if(T<=1){G.remove(S)}else{s(S,"rowSpan",T-1)}O=S}})}N=k();e(N.reverse(),function(O){M(O)});q()}function E(){var M=k();G.remove(M);q();return M}function J(){var M=k();e(M,function(O,N){M[N]=A(O,true)});return M}function B(O,N){if(!O){return}var P=k(),M=P[N?0:P.length-1],Q=M.cells.length;e(g,function(S){var R;Q=0;e(S,function(U,T){if(U.real){Q+=U.colspan}if(U.elm.parentNode==M){R=1}});if(R){return false}});if(!N){O.reverse()}e(O,function(T){var S=T.cells.length,R;for(i=0;i<S;i++){R=T.cells[i];s(R,"colSpan",1);s(R,"rowSpan",1)}for(i=S;i<Q;i++){T.appendChild(f(T.cells[S-1]))}for(i=Q;i<S;i++){G.remove(T.cells[i])}if(N){M.parentNode.insertBefore(T,M)}else{G.insertAfter(T,M)}});G.removeClass(G.select("td.mceSelected,th.mceSelected"),"mceSelected")}function F(M){var N;e(g,function(O,P){e(O,function(R,Q){if(R.elm==M){N={x:Q,y:P};return false}});return !N});return N}function w(M){L=F(M)}function I(){var O,N,M;N=M=0;e(g,function(P,Q){e(P,function(S,R){var U,T;if(j(S)){S=g[Q][R];if(R>N){N=R}if(Q>M){M=Q}if(S.real){U=S.colspan-1;T=S.rowspan-1;if(U){if(R+U>N){N=R+U}}if(T){if(Q+T>M){M=Q+T}}}}})});return{x:N,y:M}}function v(S){var P,O,U,T,N,M,Q,R;D=F(S);if(L&&D){P=Math.min(L.x,D.x);O=Math.min(L.y,D.y);U=Math.max(L.x,D.x);T=Math.max(L.y,D.y);N=U;M=T;for(y=O;y<=M;y++){S=g[y][P];if(!S.real){if(P-(S.colspan-1)<P){P-=S.colspan-1}}}for(x=P;x<=N;x++){S=g[O][x];if(!S.real){if(O-(S.rowspan-1)<O){O-=S.rowspan-1}}}for(y=O;y<=T;y++){for(x=P;x<=U;x++){S=g[y][x];if(S.real){Q=S.colspan-1;R=S.rowspan-1;if(Q){if(x+Q>N){N=x+Q}}if(R){if(y+R>M){M=y+R}}}}}G.removeClass(G.select("td.mceSelected,th.mceSelected"),"mceSelected");for(y=O;y<=M;y++){for(x=P;x<=N;x++){if(g[y][x]){G.addClass(g[y][x].elm,"mceSelected")}}}}}d.extend(this,{deleteTable:r,split:C,merge:p,insertRow:l,insertCol:h,deleteCols:n,deleteRows:m,cutRows:E,copyRows:J,pasteRows:B,getPos:F,setStartCell:w,setEndCell:v})}d.create("tinymce.plugins.TablePlugin",{init:function(g,h){var f,m,j=true;function l(p){var o=g.selection,n=g.dom.getParent(p||o.getNode(),"table");if(n){return new b(n,g.dom,o)}}function k(){g.getBody().style.webkitUserSelect="";if(j){g.dom.removeClass(g.dom.select("td.mceSelected,th.mceSelected"),"mceSelected");j=false}}e([["table","table.desc","mceInsertTable",true],["delete_table","table.del","mceTableDelete"],["delete_col","table.delete_col_desc","mceTableDeleteCol"],["delete_row","table.delete_row_desc","mceTableDeleteRow"],["col_after","table.col_after_desc","mceTableInsertColAfter"],["col_before","table.col_before_desc","mceTableInsertColBefore"],["row_after","table.row_after_desc","mceTableInsertRowAfter"],["row_before","table.row_before_desc","mceTableInsertRowBefore"],["row_props","table.row_desc","mceTableRowProps",true],["cell_props","table.cell_desc","mceTableCellProps",true],["split_cells","table.split_cells_desc","mceTableSplitCells",true],["merge_cells","table.merge_cells_desc","mceTableMergeCells",true]],function(n){g.addButton(n[0],{title:n[1],cmd:n[2],ui:n[3]})});if(!d.isIE){g.onClick.add(function(n,o){o=o.target;if(o.nodeName==="TABLE"){n.selection.select(o);n.nodeChanged()}})}g.onPreProcess.add(function(o,p){var n,q,r,t=o.dom,s;n=t.select("table",p.node);q=n.length;while(q--){r=n[q];t.setAttrib(r,"data-mce-style","");if((s=t.getAttrib(r,"width"))){t.setStyle(r,"width",s);t.setAttrib(r,"width","")}if((s=t.getAttrib(r,"height"))){t.setStyle(r,"height",s);t.setAttrib(r,"height","")}}});g.onNodeChange.add(function(q,o,s){var r;s=q.selection.getStart();r=q.dom.getParent(s,"td,th,caption");o.setActive("table",s.nodeName==="TABLE"||!!r);if(r&&r.nodeName==="CAPTION"){r=0}o.setDisabled("delete_table",!r);o.setDisabled("delete_col",!r);o.setDisabled("delete_table",!r);o.setDisabled("delete_row",!r);o.setDisabled("col_after",!r);o.setDisabled("col_before",!r);o.setDisabled("row_after",!r);o.setDisabled("row_before",!r);o.setDisabled("row_props",!r);o.setDisabled("cell_props",!r);o.setDisabled("split_cells",!r);o.setDisabled("merge_cells",!r)});g.onInit.add(function(r){var p,t,q=r.dom,u;f=r.windowManager;r.onMouseDown.add(function(w,z){if(z.button!=2){k();t=q.getParent(z.target,"td,th");p=q.getParent(t,"table")}});q.bind(r.getDoc(),"mouseover",function(C){var A,z,B=C.target;if(t&&(u||B!=t)&&(B.nodeName=="TD"||B.nodeName=="TH")){z=q.getParent(B,"table");if(z==p){if(!u){u=l(z);u.setStartCell(t);r.getBody().style.webkitUserSelect="none"}u.setEndCell(B);j=true}A=r.selection.getSel();try{if(A.removeAllRanges){A.removeAllRanges()}else{A.empty()}}catch(w){}C.preventDefault()}});r.onMouseUp.add(function(F,G){var z,B=F.selection,H,I=B.getSel(),w,C,A,E;if(t){if(u){F.getBody().style.webkitUserSelect=""}function D(J,L){var K=new d.dom.TreeWalker(J,J);do{if(J.nodeType==3&&d.trim(J.nodeValue).length!=0){if(L){z.setStart(J,0)}else{z.setEnd(J,J.nodeValue.length)}return}if(J.nodeName=="BR"){if(L){z.setStartBefore(J)}else{z.setEndBefore(J)}return}}while(J=(L?K.next():K.prev()))}H=q.select("td.mceSelected,th.mceSelected");if(H.length>0){z=q.createRng();C=H[0];E=H[H.length-1];z.setStartBefore(C);z.setEndAfter(C);D(C,1);w=new d.dom.TreeWalker(C,q.getParent(H[0],"table"));do{if(C.nodeName=="TD"||C.nodeName=="TH"){if(!q.hasClass(C,"mceSelected")){break}A=C}}while(C=w.next());D(A);B.setRng(z)}F.nodeChanged();t=u=p=null}});r.onKeyUp.add(function(w,z){k()});r.onKeyDown.add(function(w,z){n(w)});r.onMouseDown.add(function(w,z){if(z.button!=2){n(w)}});function o(D,z,A,F){var B=3,G=D.dom.getParent(z.startContainer,"TABLE"),C,w,E;if(G){C=G.parentNode}w=z.startContainer.nodeType==B&&z.startOffset==0&&z.endOffset==0&&F&&(A.nodeName=="TR"||A==C);E=(A.nodeName=="TD"||A.nodeName=="TH")&&!F;return w||E}function n(A){if(!d.isWebKit){return}var z=A.selection.getRng();var C=A.selection.getNode();var B=A.dom.getParent(z.startContainer,"TD,TH");if(!o(A,z,C,B)){return}if(!B){B=C}var w=B.lastChild;while(w.lastChild){w=w.lastChild}z.setEnd(w,w.nodeValue.length);A.selection.setRng(z)}r.plugins.table.fixTableCellSelection=n;if(r&&r.plugins.contextmenu){r.plugins.contextmenu.onContextMenu.add(function(A,w,C){var D,B=r.selection,z=B.getNode()||r.getBody();if(r.dom.getParent(C,"td")||r.dom.getParent(C,"th")||r.dom.select("td.mceSelected,th.mceSelected").length){w.removeAll();if(z.nodeName=="A"&&!r.dom.getAttrib(z,"name")){w.add({title:"advanced.link_desc",icon:"link",cmd:r.plugins.advlink?"mceAdvLink":"mceLink",ui:true});w.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});w.addSeparator()}if(z.nodeName=="IMG"&&z.className.indexOf("mceItem")==-1){w.add({title:"advanced.image_desc",icon:"image",cmd:r.plugins.advimage?"mceAdvImage":"mceImage",ui:true});w.addSeparator()}w.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",value:{action:"insert"}});w.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable"});w.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete"});w.addSeparator();D=w.addMenu({title:"table.cell"});D.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps"});D.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells"});D.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells"});D=w.addMenu({title:"table.row"});D.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps"});D.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});D.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});D.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});D.addSeparator();D.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});D.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});D.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"}).setDisabled(!m);D.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"}).setDisabled(!m);D=w.addMenu({title:"table.col"});D.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});D.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});D.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{w.add({title:"table.desc",icon:"table",cmd:"mceInsertTable"})}})}if(d.isWebKit){function v(C,N){var L=d.VK;var Q=N.keyCode;function O(Y,U,S){var T=Y?"previousSibling":"nextSibling";var Z=C.dom.getParent(U,"tr");var X=Z[T];if(X){z(C,U,X,Y);d.dom.Event.cancel(S);return true}else{var aa=C.dom.getParent(Z,"table");var W=Z.parentNode;var R=W.nodeName.toLowerCase();if(R==="tbody"||R===(Y?"tfoot":"thead")){var V=w(Y,aa,W,"tbody");if(V!==null){return K(Y,V,U,S)}}return M(Y,Z,T,aa,S)}}function w(V,T,U,X){var S=C.dom.select(">"+X,T);var R=S.indexOf(U);if(V&&R===0||!V&&R===S.length-1){return B(V,T)}else{if(R===-1){var W=U.tagName.toLowerCase()==="thead"?0:S.length-1;return S[W]}else{return S[R+(V?-1:1)]}}}function B(U,T){var S=U?"thead":"tfoot";var R=C.dom.select(">"+S,T);return R.length!==0?R[0]:null}function K(V,T,S,U){var R=J(T,V);R&&z(C,S,R,V);d.dom.Event.cancel(U);return true}function M(Y,U,R,X,W){var S=X[R];if(S){F(S);return true}else{var V=C.dom.getParent(X,"td,th");if(V){return O(Y,V,W)}else{var T=J(U,!Y);F(T);return d.dom.Event.cancel(W)}}}function J(S,R){var T=S&&S[R?"lastChild":"firstChild"];return T&&T.nodeName==="BR"?C.dom.getParent(T,"td,th"):T}function F(R){C.selection.setCursorLocation(R,0)}function A(){return Q==L.UP||Q==L.DOWN}function D(R){var T=R.selection.getNode();var S=R.dom.getParent(T,"tr");return S!==null}function P(S){var R=0;var T=S;while(T.previousSibling){T=T.previousSibling;R=R+a(T,"colspan")}return R}function E(T,R){var U=0;var S=0;e(T.children,function(V,W){U=U+a(V,"colspan");S=W;if(U>R){return false}});return S}function z(T,W,Y,V){var X=P(T.dom.getParent(W,"td,th"));var S=E(Y,X);var R=Y.childNodes[S];var U=J(R,V);F(U||R)}function H(R){var T=C.selection.getNode();var U=C.dom.getParent(T,"td,th");var S=C.dom.getParent(R,"td,th");return U&&U!==S&&I(U,S)}function I(S,R){return C.dom.getParent(S,"TABLE")===C.dom.getParent(R,"TABLE")}if(A()&&D(C)){var G=C.selection.getNode();setTimeout(function(){if(H(G)){O(!N.shiftKey&&Q===L.UP,G,N)}},0)}}r.onKeyDown.add(v)}function s(){var w;for(w=r.getBody().lastChild;w&&w.nodeType==3&&!w.nodeValue.length;w=w.previousSibling){}if(w&&w.nodeName=="TABLE"){if(r.settings.forced_root_block){r.dom.add(r.getBody(),r.settings.forced_root_block,null,d.isIE?" ":'<br data-mce-bogus="1" />')}else{r.dom.add(r.getBody(),"br",{"data-mce-bogus":"1"})}}}if(d.isGecko){r.onKeyDown.add(function(z,B){var w,A,C=z.dom;if(B.keyCode==37||B.keyCode==38){w=z.selection.getRng();A=C.getParent(w.startContainer,"table");if(A&&z.getBody().firstChild==A){if(c(w,A)){w=C.createRng();w.setStartBefore(A);w.setEndBefore(A);z.selection.setRng(w);B.preventDefault()}}}})}r.onKeyUp.add(s);r.onSetContent.add(s);r.onVisualAid.add(s);r.onPreProcess.add(function(w,A){var z=A.node.lastChild;if(z&&(z.nodeName=="BR"||(z.childNodes.length==1&&(z.firstChild.nodeName=="BR"||z.firstChild.nodeValue=="\u00a0")))&&z.previousSibling&&z.previousSibling.nodeName=="TABLE"){w.dom.remove(z)}});s();r.startContent=r.getContent({format:"raw"})});e({mceTableSplitCells:function(n){n.split()},mceTableMergeCells:function(o){var p,q,n;n=g.dom.getParent(g.selection.getNode(),"th,td");if(n){p=n.rowSpan;q=n.colSpan}if(!g.dom.select("td.mceSelected,th.mceSelected").length){f.open({url:h+"/merge_cells.htm",width:240+parseInt(g.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(g.getLang("table.merge_cells_delta_height",0)),inline:1},{rows:p,cols:q,onaction:function(r){o.merge(n,r.cols,r.rows)},plugin_url:h})}else{o.merge()}},mceTableInsertRowBefore:function(n){n.insertRow(true)},mceTableInsertRowAfter:function(n){n.insertRow()},mceTableInsertColBefore:function(n){n.insertCol(true)},mceTableInsertColAfter:function(n){n.insertCol()},mceTableDeleteCol:function(n){n.deleteCols()},mceTableDeleteRow:function(n){n.deleteRows()},mceTableCutRow:function(n){m=n.cutRows()},mceTableCopyRow:function(n){m=n.copyRows()},mceTablePasteRowBefore:function(n){n.pasteRows(m,true)},mceTablePasteRowAfter:function(n){n.pasteRows(m)},mceTableDelete:function(n){n.deleteTable()}},function(o,n){g.addCommand(n,function(){var p=l();if(p){o(p);g.execCommand("mceRepaint");k()}})});e({mceInsertTable:function(n){f.open({url:h+"/table.htm",width:400+parseInt(g.getLang("table.table_delta_width",0)),height:320+parseInt(g.getLang("table.table_delta_height",0)),inline:1},{plugin_url:h,action:n?n.action:0})},mceTableRowProps:function(){f.open({url:h+"/row.htm",width:400+parseInt(g.getLang("table.rowprops_delta_width",0)),height:295+parseInt(g.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:h})},mceTableCellProps:function(){f.open({url:h+"/cell.htm",width:400+parseInt(g.getLang("table.cellprops_delta_width",0)),height:295+parseInt(g.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:h})}},function(o,n){g.addCommand(n,function(p,q){o(q)})})}});d.PluginManager.add("table",d.plugins.TablePlugin)})(tinymce); \ No newline at end of file diff --git a/plugins/table/editor_plugin_src.js b/plugins/table/editor_plugin_src.js index ed70f3d3ee54ff3d6575b24aa2c6ee861a9e8399..532b79c6faa2410dbdece76d9181736547d6ace4 100644 --- a/plugins/table/editor_plugin_src.js +++ b/plugins/table/editor_plugin_src.js @@ -287,6 +287,21 @@ endX = startX + (cols - 1); endY = startY + (rows - 1); } else { + startPos = endPos = null; + + // Calculate start/end pos by checking for selected cells in grid works better with context menu + each(grid, function(row, y) { + each(row, function(cell, x) { + if (isCellSelected(cell)) { + if (!startPos) { + startPos = {x: x, y: y}; + } + + endPos = {x: x, y: y}; + } + }); + }); + // Use selection startX = startPos.x; startY = startPos.y; @@ -551,6 +566,10 @@ }; function pasteRows(rows, before) { + // If we don't have any rows in the clipboard, return immediately + if(!rows) + return; + var selectedRows = getSelectedRows(), targetRow = selectedRows[before ? 0 : selectedRows.length - 1], targetCellCount = targetRow.cells.length; @@ -599,6 +618,9 @@ else dom.insertAfter(row, targetRow); }); + + // Remove current selection + dom.removeClass(dom.select('td.mceSelected,th.mceSelected'), 'mceSelected'); }; function getPos(target) { @@ -1144,7 +1166,9 @@ } function getChildForDirection(parent, up) { - return parent && parent[up ? 'lastChild' : 'firstChild']; + var child = parent && parent[up ? 'lastChild' : 'firstChild']; + // BR is not a valid table child to return in this case we return the table cell + return child && child.nodeName === 'BR' ? ed.dom.getParent(child, 'td,th') : child; } function moveCursorToStartOfElement(n) { @@ -1214,80 +1238,86 @@ ed.onKeyDown.add(moveSelection); } - + // Fixes an issue on Gecko where it's impossible to place the caret behind a table // This fix will force a paragraph element after the table but only when the forced_root_block setting is enabled - if (!tinymce.isIE) { - function fixTableCaretPos() { - var last; + function fixTableCaretPos() { + var last; - // Skip empty text nodes form the end - for (last = ed.getBody().lastChild; last && last.nodeType == 3 && !last.nodeValue.length; last = last.previousSibling) ; + // Skip empty text nodes form the end + for (last = ed.getBody().lastChild; last && last.nodeType == 3 && !last.nodeValue.length; last = last.previousSibling) ; - if (last && last.nodeName == 'TABLE') - ed.dom.add(ed.getBody(), 'p', null, '<br mce_bogus="1" />'); - }; + if (last && last.nodeName == 'TABLE') { + if (ed.settings.forced_root_block) + ed.dom.add(ed.getBody(), ed.settings.forced_root_block, null, tinymce.isIE ? ' ' : '<br data-mce-bogus="1" />'); + else + ed.dom.add(ed.getBody(), 'br', {'data-mce-bogus': '1'}); + } + }; - // Fixes an bug where it's impossible to place the caret before a table in Gecko - // this fix solves it by detecting when the caret is at the beginning of such a table - // and then manually moves the caret infront of the table - if (tinymce.isGecko) { - ed.onKeyDown.add(function(ed, e) { - var rng, table, dom = ed.dom; + // Fixes an bug where it's impossible to place the caret before a table in Gecko + // this fix solves it by detecting when the caret is at the beginning of such a table + // and then manually moves the caret infront of the table + if (tinymce.isGecko) { + ed.onKeyDown.add(function(ed, e) { + var rng, table, dom = ed.dom; - // On gecko it's not possible to place the caret before a table - if (e.keyCode == 37 || e.keyCode == 38) { - rng = ed.selection.getRng(); - table = dom.getParent(rng.startContainer, 'table'); + // On gecko it's not possible to place the caret before a table + if (e.keyCode == 37 || e.keyCode == 38) { + rng = ed.selection.getRng(); + table = dom.getParent(rng.startContainer, 'table'); - if (table && ed.getBody().firstChild == table) { - if (isAtStart(rng, table)) { - rng = dom.createRng(); + if (table && ed.getBody().firstChild == table) { + if (isAtStart(rng, table)) { + rng = dom.createRng(); - rng.setStartBefore(table); - rng.setEndBefore(table); + rng.setStartBefore(table); + rng.setEndBefore(table); - ed.selection.setRng(rng); + ed.selection.setRng(rng); - e.preventDefault(); - } + e.preventDefault(); } } - }); - } - - ed.onKeyUp.add(fixTableCaretPos); - ed.onSetContent.add(fixTableCaretPos); - ed.onVisualAid.add(fixTableCaretPos); - - ed.onPreProcess.add(function(ed, o) { - var last = o.node.lastChild; - - if (last && last.childNodes.length == 1 && last.firstChild.nodeName == 'BR') - ed.dom.remove(last); + } }); + } + ed.onKeyUp.add(fixTableCaretPos); + ed.onSetContent.add(fixTableCaretPos); + ed.onVisualAid.add(fixTableCaretPos); - /** - * Fixes bug in Gecko where shift-enter in table cell does not place caret on new line - */ - if (tinymce.isGecko) { - ed.onKeyDown.add(function(ed, e) { - if (e.keyCode === tinymce.VK.ENTER && e.shiftKey) { - var node = ed.selection.getRng().startContainer; - var tableCell = dom.getParent(node, 'td,th'); - if (tableCell) { - var zeroSizedNbsp = ed.getDoc().createTextNode("\uFEFF"); - dom.insertAfter(zeroSizedNbsp, node); - } - } - }); + ed.onPreProcess.add(function(ed, o) { + var last = o.node.lastChild; + + if (last && (last.nodeName == "BR" || (last.childNodes.length == 1 && (last.firstChild.nodeName == 'BR' || last.firstChild.nodeValue == '\u00a0'))) && last.previousSibling && last.previousSibling.nodeName == "TABLE") { + ed.dom.remove(last); } + }); - fixTableCaretPos(); - ed.startContent = ed.getContent({format : 'raw'}); + /** + * Fixes bug in Gecko where shift-enter in table cell does not place caret on new line + * + * Removed: Since the new enter logic seems to fix this one. + */ + /* + if (tinymce.isGecko) { + ed.onKeyDown.add(function(ed, e) { + if (e.keyCode === tinymce.VK.ENTER && e.shiftKey) { + var node = ed.selection.getRng().startContainer; + var tableCell = dom.getParent(node, 'td,th'); + if (tableCell) { + var zeroSizedNbsp = ed.getDoc().createTextNode("\uFEFF"); + dom.insertAfter(zeroSizedNbsp, node); + } + } + }); } + */ + + fixTableCaretPos(); + ed.startContent = ed.getContent({format : 'raw'}); }); // Register action commands diff --git a/plugins/table/js/cell.js b/plugins/table/js/cell.js index d6f32905997164364d956f9cb34350249ef26f21..02ecf22c8aff0ea9d41ebff5b8abb9fa84e715cb 100644 --- a/plugins/table/js/cell.js +++ b/plugins/table/js/cell.js @@ -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); } diff --git a/plugins/table/js/row.js b/plugins/table/js/row.js index a13d69592d5af7467eee68259b930ab110975ed8..0c678de4630a42ce5f5c1ddbdd523612421487a6 100644 --- a/plugins/table/js/row.js +++ b/plugins/table/js/row.js @@ -25,6 +25,7 @@ function init() { var dir = dom.getAttrib(trElm, 'dir'); selectByValue(formObj, 'rowtype', rowtype); + setActionforRowType(formObj, rowtype); // Any cells selected if (dom.select('td.mceSelected,th.mceSelected', trElm).length == 0) { @@ -234,4 +235,20 @@ function changedColor() { formObj.style.value = dom.serializeStyle(st); } +function changedRowType() { + var formObj = document.forms[0]; + var rowtype = getSelectValue(formObj, 'rowtype'); + + setActionforRowType(formObj, rowtype); + +} + +function setActionforRowType(formObj, rowtype) { + if (rowtype === "tbody") { + formObj.action.disabled = false; + } else { + selectByValue(formObj, 'action', "row"); + formObj.action.disabled = true; + } +} tinyMCEPopup.onInit.add(init); diff --git a/plugins/table/js/table.js b/plugins/table/js/table.js index 0242506a454a40c4be07ea802b2758a0b310860a..1db243b63a69a7c4d442703c08bd673efe85e62b 100644 --- a/plugins/table/js/table.js +++ b/plugins/table/js/table.js @@ -242,13 +242,17 @@ function insertTable() { } else inst.execCommand('mceInsertContent', false, html); - tinymce.each(dom.select('table[data-mce-new]'), function(node) { + tinymce.each(dom.select('table[data-mce-new]'), function(node) { + var tdorth = dom.select('td,th', node); + // Fixes a bug in IE where the caret cannot be placed after the table if the table is at the end of the document if (tinymce.isIE && node.nextSibling == null) { - dom.insertAfter(dom.create('p'), node); - } + if (inst.settings.forced_root_block) + dom.insertAfter(dom.create(inst.settings.forced_root_block), node); + else + dom.insertAfter(dom.create('br', {'data-mce-bogus': '1'}), node); + } - var tdorth = dom.select('td,th', node); try { // IE9 might fail to do this selection inst.selection.setCursorLocation(tdorth[0], 0); @@ -303,6 +307,15 @@ function init() { var formObj = document.forms[0]; var elm = dom.getParent(inst.selection.getNode(), "table"); + // Hide advanced fields that isn't available in the schema + tinymce.each("summary id rules dir style frame".split(" "), function(name) { + var tr = tinyMCEPopup.dom.getParent(name, "tr") || tinyMCEPopup.dom.getParent("t" + name, "tr"); + + if (tr && !tinyMCEPopup.editor.schema.isValid("table", name)) { + tr.style.display = 'none'; + } + }); + action = tinyMCEPopup.getWindowArg('action'); if (!action) diff --git a/plugins/table/row.htm b/plugins/table/row.htm index 1885401f6bc00dbcbf77d7beeedd82c77f06fa7f..6ebef28427a958f6232de8007a6952ecc9ed3462 100644 --- a/plugins/table/row.htm +++ b/plugins/table/row.htm @@ -28,7 +28,7 @@ <tr> <td><label for="rowtype">{#table_dlg.rowtype}</label></td> <td class="col2"> - <select id="rowtype" name="rowtype" class="mceFocus"> + <select id="rowtype" name="rowtype" class="mceFocus" onChange="changedRowType();"> <option value="thead">{#table_dlg.thead}</option> <option value="tbody">{#table_dlg.tbody}</option> <option value="tfoot">{#table_dlg.tfoot}</option> @@ -83,8 +83,8 @@ <table role="presentation" border="0" cellpadding="0" cellspacing="4"> <tr> - <td class="column1"><label for="id">{#table_dlg.id}</label></td> - <td><input id="id" name="id" type="text" value="" style="width: 200px" /></td> + <td class="column1"><label for="id">{#table_dlg.id}</label></td> + <td><input id="id" name="id" type="text" value="" style="width: 200px" /></td> </tr> <tr> @@ -93,25 +93,25 @@ </tr> <tr> - <td class="column1"><label for="dir">{#table_dlg.langdir}</label></td> + <td class="column1"><label for="dir">{#table_dlg.langdir}</label></td> <td> - <select id="dir" name="dir" style="width: 200px"> - <option value="">{#not_set}</option> - <option value="ltr">{#table_dlg.ltr}</option> - <option value="rtl">{#table_dlg.rtl}</option> + <select id="dir" name="dir" style="width: 200px"> + <option value="">{#not_set}</option> + <option value="ltr">{#table_dlg.ltr}</option> + <option value="rtl">{#table_dlg.rtl}</option> </select> - </td> + </td> </tr> <tr> - <td class="column1"><label for="lang">{#table_dlg.langcode}</label></td> + <td class="column1"><label for="lang">{#table_dlg.langcode}</label></td> <td> <input id="lang" name="lang" type="text" value="" style="width: 200px" /> - </td> + </td> </tr> <tr> - <td class="column1"><label for="backgroundimage">{#table_dlg.bgimage}</label></td> + <td class="column1"><label for="backgroundimage">{#table_dlg.bgimage}</label></td> <td> <table role="presentation" border="0" cellpadding="0" cellspacing="0"> <tr> @@ -119,11 +119,11 @@ <td id="backgroundimagebrowsercontainer"> </td> </tr> </table> - </td> + </td> </tr> <tr> - <td class="column1"><label for="bgcolor" id="bgcolor_label">{#table_dlg.bgcolor}</label></td> + <td class="column1"><label for="bgcolor" id="bgcolor_label">{#table_dlg.bgcolor}</label></td> <td> <span role="group" aria-labelledby="bgcolor_label"> <table role="presentation" border="0" cellpadding="0" cellspacing="0"> @@ -133,7 +133,7 @@ </tr> </table> </span> - </td> + </td> </tr> </table> </fieldset> diff --git a/plugins/visualblocks/css/visualblocks.css b/plugins/visualblocks/css/visualblocks.css new file mode 100644 index 0000000000000000000000000000000000000000..76bc92b50c0c1172862719df46ae8c181cf97e7d --- /dev/null +++ b/plugins/visualblocks/css/visualblocks.css @@ -0,0 +1,21 @@ +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==)} +h2 {background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8Hybbx4oOuqgTynJd6bGlWg3DkJzoaUAAAOw==)} +h3 {background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIZjI8Hybbx4oOuqgTynJf2Ln2NOHpQpmhAAQA7)} +h4 {background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxInR0zqeAdhtJlXwV1oCll2HaWgAAOw==)} +h5 {background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjane4iq5GlW05GgIkIZUAAAOw==)} +h6 {background-image: url(data:image/gif;base64,R0lGODlhDgAKAIABALu7u////yH5BAEAAAEALAAAAAAOAAoAAAIajI8HybbxIoiuwjan04jep1iZ1XRlAo5bVgAAOw==)} +div {background-image: url(data:image/gif;base64,R0lGODlhEgAKAIABALu7u////yH5BAEAAAEALAAAAAASAAoAAAIfjI9poI0cgDywrhuxfbrzDEbQM2Ei5aRjmoySW4pAAQA7)} +section {background-image: url(data:image/gif;base64,R0lGODlhKAAKAIABALu7u////yH5BAEAAAEALAAAAAAoAAoAAAI5jI+pywcNY3sBWHdNrplytD2ellDeSVbp+GmWqaDqDMepc8t17Y4vBsK5hDyJMcI6KkuYU+jpjLoKADs=)} +article {background-image: url(data:image/gif;base64,R0lGODlhKgAKAIABALu7u////yH5BAEAAAEALAAAAAAqAAoAAAI6jI+pywkNY3wG0GBvrsd2tXGYSGnfiF7ikpXemTpOiJScasYoDJJrjsG9gkCJ0ag6KhmaIe3pjDYBBQA7)} +blockquote {background-image: url(data:image/gif;base64,R0lGODlhPgAKAIABALu7u////yH5BAEAAAEALAAAAAA+AAoAAAJPjI+py+0Knpz0xQDyuUhvfoGgIX5iSKZYgq5uNL5q69asZ8s5rrf0yZmpNkJZzFesBTu8TOlDVAabUyatguVhWduud3EyiUk45xhTTgMBBQA7)} +address {background-image: url(data:image/gif;base64,R0lGODlhLQAKAIABALu7u////yH5BAEAAAEALAAAAAAtAAoAAAI/jI+pywwNozSP1gDyyZcjb3UaRpXkWaXmZW4OqKLhBmLs+K263DkJK7OJeifh7FicKD9A1/IpGdKkyFpNmCkAADs=)} +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} diff --git a/plugins/visualblocks/editor_plugin.js b/plugins/visualblocks/editor_plugin.js new file mode 100644 index 0000000000000000000000000000000000000000..c65eaf2b4c681aa65aa12b5d156a75b0e04b7503 --- /dev/null +++ b/plugins/visualblocks/editor_plugin.js @@ -0,0 +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",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)})(); \ No newline at end of file diff --git a/plugins/visualblocks/editor_plugin_src.js b/plugins/visualblocks/editor_plugin_src.js new file mode 100644 index 0000000000000000000000000000000000000000..b9d2ab2e15f6873e13f44596ec1b5e771fdc9039 --- /dev/null +++ b/plugins/visualblocks/editor_plugin_src.js @@ -0,0 +1,63 @@ +/** + * editor_plugin_src.js + * + * Copyright 2012, Moxiecode Systems AB + * Released under LGPL License. + * + * License: http://tinymce.moxiecode.com/license + * Contributing: http://tinymce.moxiecode.com/contributing + */ + +(function() { + tinymce.create('tinymce.plugins.VisualBlocks', { + init : function(ed, url) { + var cssId; + + // We don't support older browsers like IE6/7 and they don't provide prototypes for DOM objects + if (!window.NodeList) { + return; + } + + ed.addCommand('mceVisualBlocks', function() { + var dom = ed.dom, linkElm; + + if (!cssId) { + cssId = dom.uniqueId(); + linkElm = dom.create('link', { + id: cssId, + rel : 'stylesheet', + href : url + '/css/visualblocks.css' + }); + + ed.getDoc().getElementsByTagName('head')[0].appendChild(linkElm); + } else { + linkElm = dom.get(cssId); + linkElm.disabled = !linkElm.disabled; + } + + ed.controlManager.setActive('visualblocks', !linkElm.disabled); + }); + + ed.addButton('visualblocks', {title : 'visualblocks.desc', cmd : 'mceVisualBlocks'}); + + ed.onInit.add(function() { + if (ed.settings.visualblocks_default_state) { + ed.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 + }; + } + }); + + // Register plugin + tinymce.PluginManager.add('visualblocks', tinymce.plugins.VisualBlocks); +})(); \ No newline at end of file diff --git a/themes/advanced/color_picker.htm b/themes/advanced/color_picker.htm index ad1bb0f6ccfaee3762641f44044e39d2fbae4d8a..b625531a6a8e70b5eef7f084193444fa81379640 100644 --- a/themes/advanced/color_picker.htm +++ b/themes/advanced/color_picker.htm @@ -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> diff --git a/themes/advanced/editor_template.js b/themes/advanced/editor_template.js index d85b4952ed2db712dd70ab899dbc461396ea369d..4b8d563757108b88cf121e4d72894b33cb12da50 100644 --- a/themes/advanced/editor_template.js +++ b/themes/advanced/editor_template.js @@ -1 +1 @@ -(function(e){var d=e.DOM,b=e.dom.Event,h=e.extend,f=e.each,a=e.util.Cookie,g,c=e.explode;e.ThemeManager.requireLangPack("advanced");e.create("tinymce.themes.AdvancedTheme",{sizes:[8,10,12,14,18,24,36],controls:{bold:["bold_desc","Bold"],italic:["italic_desc","Italic"],underline:["underline_desc","Underline"],strikethrough:["striketrough_desc","Strikethrough"],justifyleft:["justifyleft_desc","JustifyLeft"],justifycenter:["justifycenter_desc","JustifyCenter"],justifyright:["justifyright_desc","JustifyRight"],justifyfull:["justifyfull_desc","JustifyFull"],bullist:["bullist_desc","InsertUnorderedList"],numlist:["numlist_desc","InsertOrderedList"],outdent:["outdent_desc","Outdent"],indent:["indent_desc","Indent"],cut:["cut_desc","Cut"],copy:["copy_desc","Copy"],paste:["paste_desc","Paste"],undo:["undo_desc","Undo"],redo:["redo_desc","Redo"],link:["link_desc","mceLink"],unlink:["unlink_desc","unlink"],image:["image_desc","mceImage"],cleanup:["cleanup_desc","mceCleanup"],help:["help_desc","mceHelp"],code:["code_desc","mceCodeEditor"],hr:["hr_desc","InsertHorizontalRule"],removeformat:["removeformat_desc","RemoveFormat"],sub:["sub_desc","subscript"],sup:["sup_desc","superscript"],forecolor:["forecolor_desc","ForeColor"],forecolorpicker:["forecolor_desc","mceForeColor"],backcolor:["backcolor_desc","HiliteColor"],backcolorpicker:["backcolor_desc","mceBackColor"],charmap:["charmap_desc","mceCharMap"],visualaid:["visualaid_desc","mceToggleVisualAid"],anchor:["anchor_desc","mceInsertAnchor"],newdocument:["newdocument_desc","mceNewDocument"],blockquote:["blockquote_desc","mceBlockQuote"]},stateControls:["bold","italic","underline","strikethrough","bullist","numlist","justifyleft","justifycenter","justifyright","justifyfull","sub","sup","blockquote"],init:function(j,k){var l=this,m,i,n;l.editor=j;l.url=k;l.onResolveName=new e.util.Dispatcher(this);j.forcedHighContrastMode=j.settings.detect_highcontrast&&l._isHighContrast();j.settings.skin=j.forcedHighContrastMode?"highcontrast":j.settings.skin;l.settings=m=h({theme_advanced_path:true,theme_advanced_toolbar_location:"bottom",theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,|,sub,sup,|,charmap",theme_advanced_blockformats:"p,address,pre,h1,h2,h3,h4,h5,h6",theme_advanced_toolbar_align:"center",theme_advanced_fonts:"Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1,theme_advanced_font_sizes:"1,2,3,4,5,6,7",theme_advanced_font_selector:"span",theme_advanced_show_current_color:0,readonly:j.settings.readonly},j.settings);if(!m.font_size_style_values){m.font_size_style_values="8pt,10pt,12pt,14pt,18pt,24pt,36pt"}if(e.is(m.theme_advanced_font_sizes,"string")){m.font_size_style_values=e.explode(m.font_size_style_values);m.font_size_classes=e.explode(m.font_size_classes||"");n={};j.settings.theme_advanced_font_sizes=m.theme_advanced_font_sizes;f(j.getParam("theme_advanced_font_sizes","","hash"),function(q,p){var o;if(p==q&&q>=1&&q<=7){p=q+" ("+l.sizes[q-1]+"pt)";o=m.font_size_classes[q-1];q=m.font_size_style_values[q-1]||(l.sizes[q-1]+"pt")}if(/^\s*\./.test(q)){o=q.replace(/\./g,"")}n[p]=o?{"class":o}:{fontSize:q}});m.theme_advanced_font_sizes=n}if((i=m.theme_advanced_path_location)&&i!="none"){m.theme_advanced_statusbar_location=m.theme_advanced_path_location}if(m.theme_advanced_statusbar_location=="none"){m.theme_advanced_statusbar_location=0}if(j.settings.content_css!==false){j.contentCSS.push(j.baseURI.toAbsolute(k+"/skins/"+j.settings.skin+"/content.css"))}j.onInit.add(function(){if(!j.settings.readonly){j.onNodeChange.add(l._nodeChanged,l);j.onKeyUp.add(l._updateUndoStatus,l);j.onMouseUp.add(l._updateUndoStatus,l);j.dom.bind(j.dom.getRoot(),"dragend",function(){l._updateUndoStatus(j)})}});j.onSetProgressState.add(function(q,o,r){var s,t=q.id,p;if(o){l.progressTimer=setTimeout(function(){s=q.getContainer();s=s.insertBefore(d.create("DIV",{style:"position:relative"}),s.firstChild);p=d.get(q.id+"_tbl");d.add(s,"div",{id:t+"_blocker","class":"mceBlocker",style:{width:p.clientWidth+2,height:p.clientHeight+2}});d.add(s,"div",{id:t+"_progress","class":"mceProgress",style:{left:p.clientWidth/2,top:p.clientHeight/2}})},r||0)}else{d.remove(t+"_blocker");d.remove(t+"_progress");clearTimeout(l.progressTimer)}});d.loadCSS(m.editor_css?j.documentBaseURI.toAbsolute(m.editor_css):k+"/skins/"+j.settings.skin+"/ui.css");if(m.skin_variant){d.loadCSS(k+"/skins/"+j.settings.skin+"/ui_"+m.skin_variant+".css")}},_isHighContrast:function(){var i,j=d.add(d.getRoot(),"div",{style:"background-color: rgb(171,239,86);"});i=(d.getStyle(j,"background-color",true)+"").toLowerCase().replace(/ /g,"");d.remove(j);return i!="rgb(171,239,86)"&&i!="#abef56"},createControl:function(l,i){var j,k;if(k=i.createControl(l)){return k}switch(l){case"styleselect":return this._createStyleSelect();case"formatselect":return this._createBlockFormats();case"fontselect":return this._createFontSelect();case"fontsizeselect":return this._createFontSizeSelect();case"forecolor":return this._createForeColorMenu();case"backcolor":return this._createBackColorMenu()}if((j=this.controls[l])){return i.createButton(l,{title:"advanced."+j[0],cmd:j[1],ui:j[2],value:j[3]})}},execCommand:function(k,j,l){var i=this["_"+k];if(i){i.call(this,j,l);return true}return false},_importClasses:function(k){var i=this.editor,j=i.controlManager.get("styleselect");if(j.getLength()==0){f(i.dom.getClasses(),function(n,l){var m="style_"+l;i.formatter.register(m,{inline:"span",attributes:{"class":n["class"]},selector:"*"});j.add(n["class"],m)})}},_createStyleSelect:function(m){var k=this,i=k.editor,j=i.controlManager,l;l=j.createListBox("styleselect",{title:"advanced.style_select",onselect:function(o){var p,n=[];f(l.items,function(q){n.push(q.value)});i.focus();i.undoManager.add();p=i.formatter.matchAll(n);if(!o||p[0]==o){if(p[0]){i.formatter.remove(p[0])}}else{i.formatter.apply(o)}i.undoManager.add();i.nodeChanged();return false}});i.onInit.add(function(){var o=0,n=i.getParam("style_formats");if(n){f(n,function(p){var q,r=0;f(p,function(){r++});if(r>1){q=p.name=p.name||"style_"+(o++);i.formatter.register(q,p);l.add(p.title,q)}else{l.add(p.title)}})}else{f(i.getParam("theme_advanced_styles","","hash"),function(r,q){var p;if(r){p="style_"+(o++);i.formatter.register(p,{inline:"span",classes:r,selector:"*"});l.add(k.editor.translate(q),p)}})}});if(l.getLength()==0){l.onPostRender.add(function(o,p){if(!l.NativeListBox){b.add(p.id+"_text","focus",k._importClasses,k);b.add(p.id+"_text","mousedown",k._importClasses,k);b.add(p.id+"_open","focus",k._importClasses,k);b.add(p.id+"_open","mousedown",k._importClasses,k)}else{b.add(p.id,"focus",k._importClasses,k)}})}return l},_createFontSelect:function(){var k,j=this,i=j.editor;k=i.controlManager.createListBox("fontselect",{title:"advanced.fontdefault",onselect:function(l){var m=k.items[k.selectedIndex];if(!l&&m){i.execCommand("FontName",false,m.value);return}i.execCommand("FontName",false,l);k.select(function(n){return l==n});if(m&&m.value==l){k.select(null)}return false}});if(k){f(i.getParam("theme_advanced_fonts",j.settings.theme_advanced_fonts,"hash"),function(m,l){k.add(i.translate(l),m,{style:m.indexOf("dings")==-1?"font-family:"+m:""})})}return k},_createFontSizeSelect:function(){var m=this,k=m.editor,n,l=0,j=[];n=k.controlManager.createListBox("fontsizeselect",{title:"advanced.font_size",onselect:function(i){var o=n.items[n.selectedIndex];if(!i&&o){o=o.value;if(o["class"]){k.formatter.toggle("fontsize_class",{value:o["class"]});k.undoManager.add();k.nodeChanged()}else{k.execCommand("FontSize",false,o.fontSize)}return}if(i["class"]){k.focus();k.undoManager.add();k.formatter.toggle("fontsize_class",{value:i["class"]});k.undoManager.add();k.nodeChanged()}else{k.execCommand("FontSize",false,i.fontSize)}n.select(function(p){return i==p});if(o&&(o.value.fontSize==i.fontSize||o.value["class"]&&o.value["class"]==i["class"])){n.select(null)}return false}});if(n){f(m.settings.theme_advanced_font_sizes,function(o,i){var p=o.fontSize;if(p>=1&&p<=7){p=m.sizes[parseInt(p)-1]+"pt"}n.add(i,o,{style:"font-size:"+p,"class":"mceFontSize"+(l++)+(" "+(o["class"]||""))})})}return n},_createBlockFormats:function(){var k,i={p:"advanced.paragraph",address:"advanced.address",pre:"advanced.pre",h1:"advanced.h1",h2:"advanced.h2",h3:"advanced.h3",h4:"advanced.h4",h5:"advanced.h5",h6:"advanced.h6",div:"advanced.div",blockquote:"advanced.blockquote",code:"advanced.code",dt:"advanced.dt",dd:"advanced.dd",samp:"advanced.samp"},j=this;k=j.editor.controlManager.createListBox("formatselect",{title:"advanced.block",onselect:function(l){j.editor.execCommand("FormatBlock",false,l);return false}});if(k){f(j.editor.getParam("theme_advanced_blockformats",j.settings.theme_advanced_blockformats,"hash"),function(m,l){k.add(j.editor.translate(l!=m?l:i[m]),m,{"class":"mce_formatPreview mce_"+m})})}return k},_createForeColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_text_colors){l.colors=i}if(k.theme_advanced_default_foreground_color){l.default_color=k.theme_advanced_default_foreground_color}l.title="advanced.forecolor_desc";l.cmd="ForeColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("forecolor",l);return m},_createBackColorMenu:function(){var m,j=this,k=j.settings,l={},i;if(k.theme_advanced_more_colors){l.more_colors_func=function(){j._mceColorPicker(0,{color:m.value,func:function(n){m.setColor(n)}})}}if(i=k.theme_advanced_background_colors){l.colors=i}if(k.theme_advanced_default_background_color){l.default_color=k.theme_advanced_default_background_color}l.title="advanced.backcolor_desc";l.cmd="HiliteColor";l.scope=this;m=j.editor.controlManager.createColorSplitButton("backcolor",l);return m},renderUI:function(k){var m,l,q,v=this,r=v.editor,w=v.settings,u,j,i;if(r.settings){r.settings.aria_label=w.aria_label+r.getLang("advanced.help_shortcut")}m=j=d.create("span",{role:"application","aria-labelledby":r.id+"_voice",id:r.id+"_parent","class":"mceEditor "+r.settings.skin+"Skin"+(w.skin_variant?" "+r.settings.skin+"Skin"+v._ufirst(w.skin_variant):"")});d.add(m,"span",{"class":"mceVoiceLabel",style:"display:none;",id:r.id+"_voice"},w.aria_label);if(!d.boxModel){m=d.add(m,"div",{"class":"mceOldBoxModel"})}m=u=d.add(m,"table",{role:"presentation",id:r.id+"_tbl","class":"mceLayout",cellSpacing:0,cellPadding:0});m=q=d.add(m,"tbody");switch((w.theme_advanced_layout_manager||"").toLowerCase()){case"rowlayout":l=v._rowLayout(w,q,k);break;case"customlayout":l=r.execCallback("theme_advanced_custom_layout",w,q,k,j);break;default:l=v._simpleLayout(w,q,k,j)}m=k.targetNode;i=u.rows;d.addClass(i[0],"mceFirst");d.addClass(i[i.length-1],"mceLast");f(d.select("tr",q),function(o){d.addClass(o.firstChild,"mceFirst");d.addClass(o.childNodes[o.childNodes.length-1],"mceLast")});if(d.get(w.theme_advanced_toolbar_container)){d.get(w.theme_advanced_toolbar_container).appendChild(j)}else{d.insertAfter(j,m)}b.add(r.id+"_path_row","click",function(n){n=n.target;if(n.nodeName=="A"){v._sel(n.className.replace(/^.*mcePath_([0-9]+).*$/,"$1"));return b.cancel(n)}});if(!r.getParam("accessibility_focus")){b.add(d.add(j,"a",{href:"#"},"<!-- IE -->"),"focus",function(){tinyMCE.get(r.id).focus()})}if(w.theme_advanced_toolbar_location=="external"){k.deltaHeight=0}v.deltaHeight=k.deltaHeight;k.targetNode=null;r.onKeyDown.add(function(p,n){var s=121,o=122;if(n.altKey){if(n.keyCode===s){if(e.isWebKit){window.focus()}v.toolbarGroup.focus();return b.cancel(n)}else{if(n.keyCode===o){d.get(p.id+"_path_row").focus();return b.cancel(n)}}}});r.addShortcut("alt+0","","mceShortcuts",v);return{iframeContainer:l,editorContainer:r.id+"_parent",sizeContainer:u,deltaHeight:k.deltaHeight}},getInfo:function(){return{longname:"Advanced theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:e.majorVersion+"."+e.minorVersion}},resizeBy:function(i,j){var k=d.get(this.editor.id+"_ifr");this.resizeTo(k.clientWidth+i,k.clientHeight+j)},resizeTo:function(i,m,k){var j=this.editor,l=this.settings,n=d.get(j.id+"_tbl"),o=d.get(j.id+"_ifr");i=Math.max(l.theme_advanced_resizing_min_width||100,i);m=Math.max(l.theme_advanced_resizing_min_height||100,m);i=Math.min(l.theme_advanced_resizing_max_width||65535,i);m=Math.min(l.theme_advanced_resizing_max_height||65535,m);d.setStyle(n,"height","");d.setStyle(o,"height",m);if(l.theme_advanced_resize_horizontal){d.setStyle(n,"width","");d.setStyle(o,"width",i);if(i<n.clientWidth){i=n.clientWidth;d.setStyle(o,"width",n.clientWidth)}}if(k&&l.theme_advanced_resizing_use_cookie){a.setHash("TinyMCE_"+j.id+"_size",{cw:i,ch:m})}},destroy:function(){var i=this.editor.id;b.clear(i+"_resize");b.clear(i+"_path_row");b.clear(i+"_external_close")},_simpleLayout:function(y,r,k,i){var x=this,u=x.editor,v=y.theme_advanced_toolbar_location,m=y.theme_advanced_statusbar_location,l,j,q,w;if(y.readonly){l=d.add(r,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"});return j}if(v=="top"){x._addToolbars(r,k)}if(v=="external"){l=w=d.create("div",{style:"position:relative"});l=d.add(l,"div",{id:u.id+"_external","class":"mceExternalToolbar"});d.add(l,"a",{id:u.id+"_external_close",href:"javascript:;","class":"mceExternalClose"});l=d.add(l,"table",{id:u.id+"_tblext",cellSpacing:0,cellPadding:0});q=d.add(l,"tbody");if(i.firstChild.className=="mceOldBoxModel"){i.firstChild.appendChild(w)}else{i.insertBefore(w,i.firstChild)}x._addToolbars(q,k);u.onMouseUp.add(function(){var o=d.get(u.id+"_external");d.show(o);d.hide(g);var n=b.add(u.id+"_external_close","click",function(){d.hide(u.id+"_external");b.remove(u.id+"_external_close","click",n)});d.show(o);d.setStyle(o,"top",0-d.getRect(u.id+"_tblext").h-1);d.hide(o);d.show(o);o.style.filter="";g=u.id+"_external";o=null})}if(m=="top"){x._addStatusBar(r,k)}if(!y.theme_advanced_toolbar_container){l=d.add(r,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"})}if(v=="bottom"){x._addToolbars(r,k)}if(m=="bottom"){x._addStatusBar(r,k)}return j},_rowLayout:function(w,m,k){var v=this,p=v.editor,u,x,i=p.controlManager,l,j,r,q;u=w.theme_advanced_containers_default_class||"";x=w.theme_advanced_containers_default_align||"center";f(c(w.theme_advanced_containers||""),function(s,o){var n=w["theme_advanced_container_"+s]||"";switch(s.toLowerCase()){case"mceeditor":l=d.add(m,"tr");l=j=d.add(l,"td",{"class":"mceIframeContainer"});break;case"mceelementpath":v._addStatusBar(m,k);break;default:q=(w["theme_advanced_container_"+s+"_align"]||x).toLowerCase();q="mce"+v._ufirst(q);l=d.add(d.add(m,"tr"),"td",{"class":"mceToolbar "+(w["theme_advanced_container_"+s+"_class"]||u)+" "+q||x});r=i.createToolbar("toolbar"+o);v._addControls(n,r);d.setHTML(l,r.renderHTML());k.deltaHeight-=w.theme_advanced_row_height}});return j},_addControls:function(j,i){var k=this,l=k.settings,m,n=k.editor.controlManager;if(l.theme_advanced_disable&&!k._disabled){m={};f(c(l.theme_advanced_disable),function(o){m[o]=1});k._disabled=m}else{m=k._disabled}f(c(j),function(p){var o;if(m&&m[p]){return}if(p=="tablecontrols"){f(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"],function(q){q=k.createControl(q,n);if(q){i.add(q)}});return}o=k.createControl(p,n);if(o){i.add(o)}})},_addToolbars:function(x,k){var A=this,p,m,r=A.editor,B=A.settings,z,j=r.controlManager,u,l,q=[],y,w;w=j.createToolbarGroup("toolbargroup",{name:r.getLang("advanced.toolbar"),tab_focus_toolbar:r.getParam("theme_advanced_tab_focus_toolbar")});A.toolbarGroup=w;y=B.theme_advanced_toolbar_align.toLowerCase();y="mce"+A._ufirst(y);l=d.add(d.add(x,"tr",{role:"presentation"}),"td",{"class":"mceToolbar "+y,role:"presentation"});for(p=1;(z=B["theme_advanced_buttons"+p]);p++){m=j.createToolbar("toolbar"+p,{"class":"mceToolbarRow"+p});if(B["theme_advanced_buttons"+p+"_add"]){z+=","+B["theme_advanced_buttons"+p+"_add"]}if(B["theme_advanced_buttons"+p+"_add_before"]){z=B["theme_advanced_buttons"+p+"_add_before"]+","+z}A._addControls(z,m);w.add(m);k.deltaHeight-=B.theme_advanced_row_height}q.push(w.renderHTML());q.push(d.createHTML("a",{href:"#",accesskey:"z",title:r.getLang("advanced.toolbar_focus"),onfocus:"tinyMCE.getInstanceById('"+r.id+"').focus();"},"<!-- IE -->"));d.setHTML(l,q.join(""))},_addStatusBar:function(m,j){var k,v=this,p=v.editor,w=v.settings,i,q,u,l;k=d.add(m,"tr");k=l=d.add(k,"td",{"class":"mceStatusbar"});k=d.add(k,"div",{id:p.id+"_path_row",role:"group","aria-labelledby":p.id+"_path_voice"});if(w.theme_advanced_path){d.add(k,"span",{id:p.id+"_path_voice"},p.translate("advanced.path"));d.add(k,"span",{},": ")}else{d.add(k,"span",{}," ")}if(w.theme_advanced_resizing){d.add(l,"a",{id:p.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize",tabIndex:"-1"});if(w.theme_advanced_resizing_use_cookie){p.onPostRender.add(function(){var n=a.getHash("TinyMCE_"+p.id+"_size"),r=d.get(p.id+"_tbl");if(!n){return}v.resizeTo(n.cw,n.ch)})}p.onPostRender.add(function(){b.add(p.id+"_resize","click",function(n){n.preventDefault()});b.add(p.id+"_resize","mousedown",function(D){var t,r,s,o,C,z,A,F,n,E,x;function y(G){G.preventDefault();n=A+(G.screenX-C);E=F+(G.screenY-z);v.resizeTo(n,E)}function B(G){b.remove(d.doc,"mousemove",t);b.remove(p.getDoc(),"mousemove",r);b.remove(d.doc,"mouseup",s);b.remove(p.getDoc(),"mouseup",o);n=A+(G.screenX-C);E=F+(G.screenY-z);v.resizeTo(n,E,true)}D.preventDefault();C=D.screenX;z=D.screenY;x=d.get(v.editor.id+"_ifr");A=n=x.clientWidth;F=E=x.clientHeight;t=b.add(d.doc,"mousemove",y);r=b.add(p.getDoc(),"mousemove",y);s=b.add(d.doc,"mouseup",B);o=b.add(p.getDoc(),"mouseup",B)})})}j.deltaHeight-=21;k=m=null},_updateUndoStatus:function(j){var i=j.controlManager,k=j.undoManager;i.setDisabled("undo",!k.hasUndo()&&!k.typing);i.setDisabled("redo",!k.hasRedo())},_nodeChanged:function(m,r,D,q,E){var y=this,C,F=0,x,G,z=y.settings,w,k,u,B,l,j,i;e.each(y.stateControls,function(n){r.setActive(n,m.queryCommandState(y.controls[n][1]))});function o(p){var s,n=E.parents,t=p;if(typeof(p)=="string"){t=function(v){return v.nodeName==p}}for(s=0;s<n.length;s++){if(t(n[s])){return n[s]}}}r.setActive("visualaid",m.hasVisual);y._updateUndoStatus(m);r.setDisabled("outdent",!m.queryCommandState("Outdent"));C=o("A");if(G=r.get("link")){if(!C||!C.name){G.setDisabled(!C&&q);G.setActive(!!C)}}if(G=r.get("unlink")){G.setDisabled(!C&&q);G.setActive(!!C&&!C.name)}if(G=r.get("anchor")){G.setActive(!q&&!!C&&C.name)}C=o("IMG");if(G=r.get("image")){G.setActive(!q&&!!C&&D.className.indexOf("mceItem")==-1)}if(G=r.get("styleselect")){y._importClasses();j=[];f(G.items,function(n){j.push(n.value)});i=m.formatter.matchAll(j);G.select(i[0])}if(G=r.get("formatselect")){C=o(d.isBlock);if(C){G.select(C.nodeName.toLowerCase())}}o(function(p){if(p.nodeName==="SPAN"){if(!w&&p.className){w=p.className}}if(m.dom.is(p,z.theme_advanced_font_selector)){if(!k&&p.style.fontSize){k=p.style.fontSize}if(!u&&p.style.fontFamily){u=p.style.fontFamily.replace(/[\"\']+/g,"").replace(/^([^,]+).*/,"$1").toLowerCase()}if(!B&&p.style.color){B=p.style.color}if(!l&&p.style.backgroundColor){l=p.style.backgroundColor}}return false});if(G=r.get("fontselect")){G.select(function(n){return n.replace(/^([^,]+).*/,"$1").toLowerCase()==u})}if(G=r.get("fontsizeselect")){if(z.theme_advanced_runtime_fontsize&&!k&&!w){k=m.dom.getStyle(D,"fontSize",true)}G.select(function(n){if(n.fontSize&&n.fontSize===k){return true}if(n["class"]&&n["class"]===w){return true}})}if(z.theme_advanced_show_current_color){function A(p,n){if(G=r.get(p)){if(!n){n=G.settings.default_color}if(n!==G.value){G.displayColor(n)}}}A("forecolor",B);A("backcolor",l)}if(z.theme_advanced_show_current_color){function A(p,n){if(G=r.get(p)){if(!n){n=G.settings.default_color}if(n!==G.value){G.displayColor(n)}}}A("forecolor",B);A("backcolor",l)}if(z.theme_advanced_path&&z.theme_advanced_statusbar_location){C=d.get(m.id+"_path")||d.add(m.id+"_path_row","span",{id:m.id+"_path"});if(y.statusKeyboardNavigation){y.statusKeyboardNavigation.destroy();y.statusKeyboardNavigation=null}d.setHTML(C,"");o(function(H){var p=H.nodeName.toLowerCase(),s,v,t="";if(H.nodeType!=1||p==="br"||H.getAttribute("data-mce-bogus")||d.hasClass(H,"mceItemHidden")||d.hasClass(H,"mceItemRemoved")){return}if(e.isIE&&H.scopeName!=="HTML"){p=H.scopeName+":"+p}p=p.replace(/mce\:/g,"");switch(p){case"b":p="strong";break;case"i":p="em";break;case"img":if(x=d.getAttrib(H,"src")){t+="src: "+x+" "}break;case"a":if(x=d.getAttrib(H,"name")){t+="name: "+x+" ";p+="#"+x}if(x=d.getAttrib(H,"href")){t+="href: "+x+" "}break;case"font":if(x=d.getAttrib(H,"face")){t+="font: "+x+" "}if(x=d.getAttrib(H,"size")){t+="size: "+x+" "}if(x=d.getAttrib(H,"color")){t+="color: "+x+" "}break;case"span":if(x=d.getAttrib(H,"style")){t+="style: "+x+" "}break}if(x=d.getAttrib(H,"id")){t+="id: "+x+" "}if(x=H.className){x=x.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g,"");if(x){t+="class: "+x+" ";if(d.isBlock(H)||p=="img"||p=="span"){p+="."+x}}}p=p.replace(/(html:)/g,"");p={name:p,node:H,title:t};y.onResolveName.dispatch(y,p);t=p.title;p=p.name;v=d.create("a",{href:"javascript:;",role:"button",onmousedown:"return false;",title:t,"class":"mcePath_"+(F++)},p);if(C.hasChildNodes()){C.insertBefore(d.create("span",{"aria-hidden":"true"},"\u00a0\u00bb "),C.firstChild);C.insertBefore(v,C.firstChild)}else{C.appendChild(v)}},m.getBody());if(d.select("a",C).length>0){y.statusKeyboardNavigation=new e.ui.KeyboardNavigation({root:m.id+"_path_row",items:d.select("a",C),excludeFromTabOrder:true,onCancel:function(){m.focus()}},d)}}},_sel:function(i){this.editor.execCommand("mceSelectNodeDepth",false,i)},_mceInsertAnchor:function(k,j){var i=this.editor;i.windowManager.open({url:this.url+"/anchor.htm",width:320+parseInt(i.getLang("advanced.anchor_delta_width",0)),height:90+parseInt(i.getLang("advanced.anchor_delta_height",0)),inline:true},{theme_url:this.url})},_mceCharMap:function(){var i=this.editor;i.windowManager.open({url:this.url+"/charmap.htm",width:550+parseInt(i.getLang("advanced.charmap_delta_width",0)),height:265+parseInt(i.getLang("advanced.charmap_delta_height",0)),inline:true},{theme_url:this.url})},_mceHelp:function(){var i=this.editor;i.windowManager.open({url:this.url+"/about.htm",width:480,height:380,inline:true},{theme_url:this.url})},_mceShortcuts:function(){var i=this.editor;i.windowManager.open({url:this.url+"/shortcuts.htm",width:480,height:380,inline:true},{theme_url:this.url})},_mceColorPicker:function(k,j){var i=this.editor;j=j||{};i.windowManager.open({url:this.url+"/color_picker.htm",width:375+parseInt(i.getLang("advanced.colorpicker_delta_width",0)),height:250+parseInt(i.getLang("advanced.colorpicker_delta_height",0)),close_previous:false,inline:true},{input_color:j.color,func:j.func,theme_url:this.url})},_mceCodeEditor:function(j,k){var i=this.editor;i.windowManager.open({url:this.url+"/source_editor.htm",width:parseInt(i.getParam("theme_advanced_source_editor_width",720)),height:parseInt(i.getParam("theme_advanced_source_editor_height",580)),inline:true,resizable:true,maximizable:true},{theme_url:this.url})},_mceImage:function(j,k){var i=this.editor;if(i.dom.getAttrib(i.selection.getNode(),"class").indexOf("mceItem")!=-1){return}i.windowManager.open({url:this.url+"/image.htm",width:355+parseInt(i.getLang("advanced.image_delta_width",0)),height:275+parseInt(i.getLang("advanced.image_delta_height",0)),inline:true},{theme_url:this.url})},_mceLink:function(j,k){var i=this.editor;i.windowManager.open({url:this.url+"/link.htm",width:310+parseInt(i.getLang("advanced.link_delta_width",0)),height:200+parseInt(i.getLang("advanced.link_delta_height",0)),inline:true},{theme_url:this.url})},_mceNewDocument:function(){var i=this.editor;i.windowManager.confirm("advanced.newdocument",function(j){if(j){i.execCommand("mceSetContent",false,"")}})},_mceForeColor:function(){var i=this;this._mceColorPicker(0,{color:i.fgColor,func:function(j){i.fgColor=j;i.editor.execCommand("ForeColor",false,j)}})},_mceBackColor:function(){var i=this;this._mceColorPicker(0,{color:i.bgColor,func:function(j){i.bgColor=j;i.editor.execCommand("HiliteColor",false,j)}})},_ufirst:function(i){return i.substring(0,1).toUpperCase()+i.substring(1)}});e.ThemeManager.add("advanced",e.themes.AdvancedTheme)}(tinymce)); \ No newline at end of file +(function(h){var i=h.DOM,g=h.dom.Event,c=h.extend,f=h.each,a=h.util.Cookie,e,d=h.explode;function b(p,m){var k,l,o=p.dom,j="",n,r;previewStyles=p.settings.preview_styles;if(previewStyles===false){return""}if(!previewStyles){previewStyles="font-family font-size font-weight text-decoration text-transform color background-color"}function q(s){return s.replace(/%(\w+)/g,"")}k=m.block||m.inline||"span";l=o.create(k);f(m.styles,function(t,s){t=q(t);if(t){o.setStyle(l,s,t)}});f(m.attributes,function(t,s){t=q(t);if(t){o.setAttrib(l,s,t)}});f(m.classes,function(s){s=q(s);if(!o.hasClass(l,s)){o.addClass(l,s)}});o.setStyles(l,{position:"absolute",left:-65535});p.getBody().appendChild(l);n=o.getStyle(p.getBody(),"fontSize",true);n=/px$/.test(n)?parseInt(n,10):0;f(previewStyles.split(" "),function(s){var t=o.getStyle(l,s,true);if(s=="background-color"&&/transparent|rgba\s*\([^)]+,\s*0\)/.test(t)){t=o.getStyle(p.getBody(),s,true);if(o.toHex(t).toLowerCase()=="#ffffff"){return}}if(s=="font-size"){if(/em|%$/.test(t)){if(n===0){return}t=parseFloat(t,10)/(/%$/.test(t)?100:1);t=(t*n)+"px"}}j+=s+":"+t+";"});o.remove(l);return j}h.ThemeManager.requireLangPack("advanced");h.create("tinymce.themes.AdvancedTheme",{sizes:[8,10,12,14,18,24,36],controls:{bold:["bold_desc","Bold"],italic:["italic_desc","Italic"],underline:["underline_desc","Underline"],strikethrough:["striketrough_desc","Strikethrough"],justifyleft:["justifyleft_desc","JustifyLeft"],justifycenter:["justifycenter_desc","JustifyCenter"],justifyright:["justifyright_desc","JustifyRight"],justifyfull:["justifyfull_desc","JustifyFull"],bullist:["bullist_desc","InsertUnorderedList"],numlist:["numlist_desc","InsertOrderedList"],outdent:["outdent_desc","Outdent"],indent:["indent_desc","Indent"],cut:["cut_desc","Cut"],copy:["copy_desc","Copy"],paste:["paste_desc","Paste"],undo:["undo_desc","Undo"],redo:["redo_desc","Redo"],link:["link_desc","mceLink"],unlink:["unlink_desc","unlink"],image:["image_desc","mceImage"],cleanup:["cleanup_desc","mceCleanup"],help:["help_desc","mceHelp"],code:["code_desc","mceCodeEditor"],hr:["hr_desc","InsertHorizontalRule"],removeformat:["removeformat_desc","RemoveFormat"],sub:["sub_desc","subscript"],sup:["sup_desc","superscript"],forecolor:["forecolor_desc","ForeColor"],forecolorpicker:["forecolor_desc","mceForeColor"],backcolor:["backcolor_desc","HiliteColor"],backcolorpicker:["backcolor_desc","mceBackColor"],charmap:["charmap_desc","mceCharMap"],visualaid:["visualaid_desc","mceToggleVisualAid"],anchor:["anchor_desc","mceInsertAnchor"],newdocument:["newdocument_desc","mceNewDocument"],blockquote:["blockquote_desc","mceBlockQuote"]},stateControls:["bold","italic","underline","strikethrough","bullist","numlist","justifyleft","justifycenter","justifyright","justifyfull","sub","sup","blockquote"],init:function(k,l){var m=this,n,j,p;m.editor=k;m.url=l;m.onResolveName=new h.util.Dispatcher(this);n=k.settings;k.forcedHighContrastMode=k.settings.detect_highcontrast&&m._isHighContrast();k.settings.skin=k.forcedHighContrastMode?"highcontrast":k.settings.skin;if(!n.theme_advanced_buttons1){n=c({theme_advanced_buttons1:"bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect",theme_advanced_buttons2:"bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code",theme_advanced_buttons3:"hr,removeformat,visualaid,|,sub,sup,|,charmap"},n)}m.settings=n=c({theme_advanced_path:true,theme_advanced_toolbar_location:"top",theme_advanced_blockformats:"p,address,pre,h1,h2,h3,h4,h5,h6",theme_advanced_toolbar_align:"left",theme_advanced_statusbar_location:"bottom",theme_advanced_fonts:"Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats",theme_advanced_more_colors:1,theme_advanced_row_height:23,theme_advanced_resize_horizontal:1,theme_advanced_resizing_use_cookie:1,theme_advanced_font_sizes:"1,2,3,4,5,6,7",theme_advanced_font_selector:"span",theme_advanced_show_current_color:0,readonly:k.settings.readonly},n);if(!n.font_size_style_values){n.font_size_style_values="8pt,10pt,12pt,14pt,18pt,24pt,36pt"}if(h.is(n.theme_advanced_font_sizes,"string")){n.font_size_style_values=h.explode(n.font_size_style_values);n.font_size_classes=h.explode(n.font_size_classes||"");p={};k.settings.theme_advanced_font_sizes=n.theme_advanced_font_sizes;f(k.getParam("theme_advanced_font_sizes","","hash"),function(r,q){var o;if(q==r&&r>=1&&r<=7){q=r+" ("+m.sizes[r-1]+"pt)";o=n.font_size_classes[r-1];r=n.font_size_style_values[r-1]||(m.sizes[r-1]+"pt")}if(/^\s*\./.test(r)){o=r.replace(/\./g,"")}p[q]=o?{"class":o}:{fontSize:r}});n.theme_advanced_font_sizes=p}if((j=n.theme_advanced_path_location)&&j!="none"){n.theme_advanced_statusbar_location=n.theme_advanced_path_location}if(n.theme_advanced_statusbar_location=="none"){n.theme_advanced_statusbar_location=0}if(k.settings.content_css!==false){k.contentCSS.push(k.baseURI.toAbsolute(l+"/skins/"+k.settings.skin+"/content.css"))}k.onInit.add(function(){if(!k.settings.readonly){k.onNodeChange.add(m._nodeChanged,m);k.onKeyUp.add(m._updateUndoStatus,m);k.onMouseUp.add(m._updateUndoStatus,m);k.dom.bind(k.dom.getRoot(),"dragend",function(){m._updateUndoStatus(k)})}});k.onSetProgressState.add(function(r,o,s){var t,u=r.id,q;if(o){m.progressTimer=setTimeout(function(){t=r.getContainer();t=t.insertBefore(i.create("DIV",{style:"position:relative"}),t.firstChild);q=i.get(r.id+"_tbl");i.add(t,"div",{id:u+"_blocker","class":"mceBlocker",style:{width:q.clientWidth+2,height:q.clientHeight+2}});i.add(t,"div",{id:u+"_progress","class":"mceProgress",style:{left:q.clientWidth/2,top:q.clientHeight/2}})},s||0)}else{i.remove(u+"_blocker");i.remove(u+"_progress");clearTimeout(m.progressTimer)}});i.loadCSS(n.editor_css?k.documentBaseURI.toAbsolute(n.editor_css):l+"/skins/"+k.settings.skin+"/ui.css");if(n.skin_variant){i.loadCSS(l+"/skins/"+k.settings.skin+"/ui_"+n.skin_variant+".css")}},_isHighContrast:function(){var j,k=i.add(i.getRoot(),"div",{style:"background-color: rgb(171,239,86);"});j=(i.getStyle(k,"background-color",true)+"").toLowerCase().replace(/ /g,"");i.remove(k);return j!="rgb(171,239,86)"&&j!="#abef56"},createControl:function(m,j){var k,l;if(l=j.createControl(m)){return l}switch(m){case"styleselect":return this._createStyleSelect();case"formatselect":return this._createBlockFormats();case"fontselect":return this._createFontSelect();case"fontsizeselect":return this._createFontSizeSelect();case"forecolor":return this._createForeColorMenu();case"backcolor":return this._createBackColorMenu()}if((k=this.controls[m])){return j.createButton(m,{title:"advanced."+k[0],cmd:k[1],ui:k[2],value:k[3]})}},execCommand:function(l,k,m){var j=this["_"+l];if(j){j.call(this,k,m);return true}return false},_importClasses:function(l){var j=this.editor,k=j.controlManager.get("styleselect");if(k.getLength()==0){f(j.dom.getClasses(),function(q,m){var p="style_"+m,n;n={inline:"span",attributes:{"class":q["class"]},selector:"*"};j.formatter.register(p,n);k.add(q["class"],p,{style:function(){return b(j,n)}})})}},_createStyleSelect:function(o){var l=this,j=l.editor,k=j.controlManager,m;m=k.createListBox("styleselect",{title:"advanced.style_select",onselect:function(q){var r,n=[],p;f(m.items,function(s){n.push(s.value)});j.focus();j.undoManager.add();r=j.formatter.matchAll(n);h.each(r,function(s){if(!q||s==q){if(s){j.formatter.remove(s)}p=true}});if(!p){j.formatter.apply(q)}j.undoManager.add();j.nodeChanged();return false}});j.onPreInit.add(function(){var p=0,n=j.getParam("style_formats");if(n){f(n,function(q){var r,s=0;f(q,function(){s++});if(s>1){r=q.name=q.name||"style_"+(p++);j.formatter.register(r,q);m.add(q.title,r,{style:function(){return b(j,q)}})}else{m.add(q.title)}})}else{f(j.getParam("theme_advanced_styles","","hash"),function(t,s){var r,q;if(t){r="style_"+(p++);q={inline:"span",classes:t,selector:"*"};j.formatter.register(r,q);m.add(l.editor.translate(s),r,{style:function(){return b(j,q)}})}})}});if(m.getLength()==0){m.onPostRender.add(function(p,q){if(!m.NativeListBox){g.add(q.id+"_text","focus",l._importClasses,l);g.add(q.id+"_text","mousedown",l._importClasses,l);g.add(q.id+"_open","focus",l._importClasses,l);g.add(q.id+"_open","mousedown",l._importClasses,l)}else{g.add(q.id,"focus",l._importClasses,l)}})}return m},_createFontSelect:function(){var l,k=this,j=k.editor;l=j.controlManager.createListBox("fontselect",{title:"advanced.fontdefault",onselect:function(m){var n=l.items[l.selectedIndex];if(!m&&n){j.execCommand("FontName",false,n.value);return}j.execCommand("FontName",false,m);l.select(function(o){return m==o});if(n&&n.value==m){l.select(null)}return false}});if(l){f(j.getParam("theme_advanced_fonts",k.settings.theme_advanced_fonts,"hash"),function(n,m){l.add(j.translate(m),n,{style:n.indexOf("dings")==-1?"font-family:"+n:""})})}return l},_createFontSizeSelect:function(){var m=this,k=m.editor,n,l=0,j=[];n=k.controlManager.createListBox("fontsizeselect",{title:"advanced.font_size",onselect:function(o){var p=n.items[n.selectedIndex];if(!o&&p){p=p.value;if(p["class"]){k.formatter.toggle("fontsize_class",{value:p["class"]});k.undoManager.add();k.nodeChanged()}else{k.execCommand("FontSize",false,p.fontSize)}return}if(o["class"]){k.focus();k.undoManager.add();k.formatter.toggle("fontsize_class",{value:o["class"]});k.undoManager.add();k.nodeChanged()}else{k.execCommand("FontSize",false,o.fontSize)}n.select(function(q){return o==q});if(p&&(p.value.fontSize==o.fontSize||p.value["class"]&&p.value["class"]==o["class"])){n.select(null)}return false}});if(n){f(m.settings.theme_advanced_font_sizes,function(p,o){var q=p.fontSize;if(q>=1&&q<=7){q=m.sizes[parseInt(q)-1]+"pt"}n.add(o,p,{style:"font-size:"+q,"class":"mceFontSize"+(l++)+(" "+(p["class"]||""))})})}return n},_createBlockFormats:function(){var l,j={p:"advanced.paragraph",address:"advanced.address",pre:"advanced.pre",h1:"advanced.h1",h2:"advanced.h2",h3:"advanced.h3",h4:"advanced.h4",h5:"advanced.h5",h6:"advanced.h6",div:"advanced.div",blockquote:"advanced.blockquote",code:"advanced.code",dt:"advanced.dt",dd:"advanced.dd",samp:"advanced.samp"},k=this;l=k.editor.controlManager.createListBox("formatselect",{title:"advanced.block",onselect:function(m){k.editor.execCommand("FormatBlock",false,m);return false}});if(l){f(k.editor.getParam("theme_advanced_blockformats",k.settings.theme_advanced_blockformats,"hash"),function(n,m){l.add(k.editor.translate(m!=n?m:j[n]),n,{"class":"mce_formatPreview mce_"+n,style:function(){return b(k.editor,{block:n})}})})}return l},_createForeColorMenu:function(){var n,k=this,l=k.settings,m={},j;if(l.theme_advanced_more_colors){m.more_colors_func=function(){k._mceColorPicker(0,{color:n.value,func:function(o){n.setColor(o)}})}}if(j=l.theme_advanced_text_colors){m.colors=j}if(l.theme_advanced_default_foreground_color){m.default_color=l.theme_advanced_default_foreground_color}m.title="advanced.forecolor_desc";m.cmd="ForeColor";m.scope=this;n=k.editor.controlManager.createColorSplitButton("forecolor",m);return n},_createBackColorMenu:function(){var n,k=this,l=k.settings,m={},j;if(l.theme_advanced_more_colors){m.more_colors_func=function(){k._mceColorPicker(0,{color:n.value,func:function(o){n.setColor(o)}})}}if(j=l.theme_advanced_background_colors){m.colors=j}if(l.theme_advanced_default_background_color){m.default_color=l.theme_advanced_default_background_color}m.title="advanced.backcolor_desc";m.cmd="HiliteColor";m.scope=this;n=k.editor.controlManager.createColorSplitButton("backcolor",m);return n},renderUI:function(l){var q,m,r,w=this,u=w.editor,x=w.settings,v,k,j;if(u.settings){u.settings.aria_label=x.aria_label+u.getLang("advanced.help_shortcut")}q=k=i.create("span",{role:"application","aria-labelledby":u.id+"_voice",id:u.id+"_parent","class":"mceEditor "+u.settings.skin+"Skin"+(x.skin_variant?" "+u.settings.skin+"Skin"+w._ufirst(x.skin_variant):"")+(u.settings.directionality=="rtl"?" mceRtl":"")});i.add(q,"span",{"class":"mceVoiceLabel",style:"display:none;",id:u.id+"_voice"},x.aria_label);if(!i.boxModel){q=i.add(q,"div",{"class":"mceOldBoxModel"})}q=v=i.add(q,"table",{role:"presentation",id:u.id+"_tbl","class":"mceLayout",cellSpacing:0,cellPadding:0});q=r=i.add(q,"tbody");switch((x.theme_advanced_layout_manager||"").toLowerCase()){case"rowlayout":m=w._rowLayout(x,r,l);break;case"customlayout":m=u.execCallback("theme_advanced_custom_layout",x,r,l,k);break;default:m=w._simpleLayout(x,r,l,k)}q=l.targetNode;j=v.rows;i.addClass(j[0],"mceFirst");i.addClass(j[j.length-1],"mceLast");f(i.select("tr",r),function(o){i.addClass(o.firstChild,"mceFirst");i.addClass(o.childNodes[o.childNodes.length-1],"mceLast")});if(i.get(x.theme_advanced_toolbar_container)){i.get(x.theme_advanced_toolbar_container).appendChild(k)}else{i.insertAfter(k,q)}g.add(u.id+"_path_row","click",function(n){n=n.target;if(n.nodeName=="A"){w._sel(n.className.replace(/^.*mcePath_([0-9]+).*$/,"$1"));return false}});if(!u.getParam("accessibility_focus")){g.add(i.add(k,"a",{href:"#"},"<!-- IE -->"),"focus",function(){tinyMCE.get(u.id).focus()})}if(x.theme_advanced_toolbar_location=="external"){l.deltaHeight=0}w.deltaHeight=l.deltaHeight;l.targetNode=null;u.onKeyDown.add(function(p,n){var s=121,o=122;if(n.altKey){if(n.keyCode===s){if(h.isWebKit){window.focus()}w.toolbarGroup.focus();return g.cancel(n)}else{if(n.keyCode===o){i.get(p.id+"_path_row").focus();return g.cancel(n)}}}});u.addShortcut("alt+0","","mceShortcuts",w);return{iframeContainer:m,editorContainer:u.id+"_parent",sizeContainer:v,deltaHeight:l.deltaHeight}},getInfo:function(){return{longname:"Advanced theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:h.majorVersion+"."+h.minorVersion}},resizeBy:function(j,k){var l=i.get(this.editor.id+"_ifr");this.resizeTo(l.clientWidth+j,l.clientHeight+k)},resizeTo:function(j,n,l){var k=this.editor,m=this.settings,o=i.get(k.id+"_tbl"),p=i.get(k.id+"_ifr");j=Math.max(m.theme_advanced_resizing_min_width||100,j);n=Math.max(m.theme_advanced_resizing_min_height||100,n);j=Math.min(m.theme_advanced_resizing_max_width||65535,j);n=Math.min(m.theme_advanced_resizing_max_height||65535,n);i.setStyle(o,"height","");i.setStyle(p,"height",n);if(m.theme_advanced_resize_horizontal){i.setStyle(o,"width","");i.setStyle(p,"width",j);if(j<o.clientWidth){j=o.clientWidth;i.setStyle(p,"width",o.clientWidth)}}if(l&&m.theme_advanced_resizing_use_cookie){a.setHash("TinyMCE_"+k.id+"_size",{cw:j,ch:n})}},destroy:function(){var j=this.editor.id;g.clear(j+"_resize");g.clear(j+"_path_row");g.clear(j+"_external_close")},_simpleLayout:function(z,u,l,j){var y=this,v=y.editor,w=z.theme_advanced_toolbar_location,q=z.theme_advanced_statusbar_location,m,k,r,x;if(z.readonly){m=i.add(u,"tr");m=k=i.add(m,"td",{"class":"mceIframeContainer"});return k}if(w=="top"){y._addToolbars(u,l)}if(w=="external"){m=x=i.create("div",{style:"position:relative"});m=i.add(m,"div",{id:v.id+"_external","class":"mceExternalToolbar"});i.add(m,"a",{id:v.id+"_external_close",href:"javascript:;","class":"mceExternalClose"});m=i.add(m,"table",{id:v.id+"_tblext",cellSpacing:0,cellPadding:0});r=i.add(m,"tbody");if(j.firstChild.className=="mceOldBoxModel"){j.firstChild.appendChild(x)}else{j.insertBefore(x,j.firstChild)}y._addToolbars(r,l);v.onMouseUp.add(function(){var o=i.get(v.id+"_external");i.show(o);i.hide(e);var n=g.add(v.id+"_external_close","click",function(){i.hide(v.id+"_external");g.remove(v.id+"_external_close","click",n);return false});i.show(o);i.setStyle(o,"top",0-i.getRect(v.id+"_tblext").h-1);i.hide(o);i.show(o);o.style.filter="";e=v.id+"_external";o=null})}if(q=="top"){y._addStatusBar(u,l)}if(!z.theme_advanced_toolbar_container){m=i.add(u,"tr");m=k=i.add(m,"td",{"class":"mceIframeContainer"})}if(w=="bottom"){y._addToolbars(u,l)}if(q=="bottom"){y._addStatusBar(u,l)}return k},_rowLayout:function(x,p,l){var w=this,q=w.editor,v,y,j=q.controlManager,m,k,u,r;v=x.theme_advanced_containers_default_class||"";y=x.theme_advanced_containers_default_align||"center";f(d(x.theme_advanced_containers||""),function(s,o){var n=x["theme_advanced_container_"+s]||"";switch(s.toLowerCase()){case"mceeditor":m=i.add(p,"tr");m=k=i.add(m,"td",{"class":"mceIframeContainer"});break;case"mceelementpath":w._addStatusBar(p,l);break;default:r=(x["theme_advanced_container_"+s+"_align"]||y).toLowerCase();r="mce"+w._ufirst(r);m=i.add(i.add(p,"tr"),"td",{"class":"mceToolbar "+(x["theme_advanced_container_"+s+"_class"]||v)+" "+r||y});u=j.createToolbar("toolbar"+o);w._addControls(n,u);i.setHTML(m,u.renderHTML());l.deltaHeight-=x.theme_advanced_row_height}});return k},_addControls:function(k,j){var l=this,m=l.settings,n,o=l.editor.controlManager;if(m.theme_advanced_disable&&!l._disabled){n={};f(d(m.theme_advanced_disable),function(p){n[p]=1});l._disabled=n}else{n=l._disabled}f(d(k),function(q){var p;if(n&&n[q]){return}if(q=="tablecontrols"){f(["table","|","row_props","cell_props","|","row_before","row_after","delete_row","|","col_before","col_after","delete_col","|","split_cells","merge_cells"],function(r){r=l.createControl(r,o);if(r){j.add(r)}});return}p=l.createControl(q,o);if(p){j.add(p)}})},_addToolbars:function(y,k){var B=this,q,p,u=B.editor,C=B.settings,A,j=u.controlManager,w,l,r=[],z,x,m=false;x=j.createToolbarGroup("toolbargroup",{name:u.getLang("advanced.toolbar"),tab_focus_toolbar:u.getParam("theme_advanced_tab_focus_toolbar")});B.toolbarGroup=x;z=C.theme_advanced_toolbar_align.toLowerCase();z="mce"+B._ufirst(z);l=i.add(i.add(y,"tr",{role:"presentation"}),"td",{"class":"mceToolbar "+z,role:"toolbar"});for(q=1;(A=C["theme_advanced_buttons"+q]);q++){m=true;p=j.createToolbar("toolbar"+q,{"class":"mceToolbarRow"+q});if(C["theme_advanced_buttons"+q+"_add"]){A+=","+C["theme_advanced_buttons"+q+"_add"]}if(C["theme_advanced_buttons"+q+"_add_before"]){A=C["theme_advanced_buttons"+q+"_add_before"]+","+A}B._addControls(A,p);x.add(p);k.deltaHeight-=C.theme_advanced_row_height}if(!m){k.deltaHeight-=C.theme_advanced_row_height}r.push(x.renderHTML());r.push(i.createHTML("a",{href:"#",accesskey:"z",title:u.getLang("advanced.toolbar_focus"),onfocus:"tinyMCE.getInstanceById('"+u.id+"').focus();"},"<!-- IE -->"));i.setHTML(l,r.join(""))},_addStatusBar:function(p,k){var l,w=this,q=w.editor,x=w.settings,j,u,v,m;l=i.add(p,"tr");l=m=i.add(l,"td",{"class":"mceStatusbar"});l=i.add(l,"div",{id:q.id+"_path_row",role:"group","aria-labelledby":q.id+"_path_voice"});if(x.theme_advanced_path){i.add(l,"span",{id:q.id+"_path_voice"},q.translate("advanced.path"));i.add(l,"span",{},": ")}else{i.add(l,"span",{}," ")}if(x.theme_advanced_resizing){i.add(m,"a",{id:q.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize",tabIndex:"-1"});if(x.theme_advanced_resizing_use_cookie){q.onPostRender.add(function(){var n=a.getHash("TinyMCE_"+q.id+"_size"),r=i.get(q.id+"_tbl");if(!n){return}w.resizeTo(n.cw,n.ch)})}q.onPostRender.add(function(){g.add(q.id+"_resize","click",function(n){n.preventDefault()});g.add(q.id+"_resize","mousedown",function(E){var t,r,s,o,D,A,B,G,n,F,y;function z(H){H.preventDefault();n=B+(H.screenX-D);F=G+(H.screenY-A);w.resizeTo(n,F)}function C(H){g.remove(i.doc,"mousemove",t);g.remove(q.getDoc(),"mousemove",r);g.remove(i.doc,"mouseup",s);g.remove(q.getDoc(),"mouseup",o);n=B+(H.screenX-D);F=G+(H.screenY-A);w.resizeTo(n,F,true);q.nodeChanged()}E.preventDefault();D=E.screenX;A=E.screenY;y=i.get(w.editor.id+"_ifr");B=n=y.clientWidth;G=F=y.clientHeight;t=g.add(i.doc,"mousemove",z);r=g.add(q.getDoc(),"mousemove",z);s=g.add(i.doc,"mouseup",C);o=g.add(q.getDoc(),"mouseup",C)})})}k.deltaHeight-=21;l=p=null},_updateUndoStatus:function(k){var j=k.controlManager,l=k.undoManager;j.setDisabled("undo",!l.hasUndo()&&!l.typing);j.setDisabled("redo",!l.hasRedo())},_nodeChanged:function(o,u,E,r,F){var z=this,D,G=0,y,H,A=z.settings,x,l,w,C,m,k,j;h.each(z.stateControls,function(n){u.setActive(n,o.queryCommandState(z.controls[n][1]))});function q(p){var s,n=F.parents,t=p;if(typeof(p)=="string"){t=function(v){return v.nodeName==p}}for(s=0;s<n.length;s++){if(t(n[s])){return n[s]}}}u.setActive("visualaid",o.hasVisual);z._updateUndoStatus(o);u.setDisabled("outdent",!o.queryCommandState("Outdent"));D=q("A");if(H=u.get("link")){H.setDisabled((!D&&r)||(D&&!D.href));H.setActive(!!D&&(!D.name&&!D.id))}if(H=u.get("unlink")){H.setDisabled(!D&&r);H.setActive(!!D&&!D.name&&!D.id)}if(H=u.get("anchor")){H.setActive(!r&&!!D&&(D.name||(D.id&&!D.href)))}D=q("IMG");if(H=u.get("image")){H.setActive(!r&&!!D&&E.className.indexOf("mceItem")==-1)}if(H=u.get("styleselect")){z._importClasses();k=[];f(H.items,function(n){k.push(n.value)});j=o.formatter.matchAll(k);H.select(j[0]);h.each(j,function(p,n){if(n>0){H.mark(p)}})}if(H=u.get("formatselect")){D=q(o.dom.isBlock);if(D){H.select(D.nodeName.toLowerCase())}}q(function(p){if(p.nodeName==="SPAN"){if(!x&&p.className){x=p.className}}if(o.dom.is(p,A.theme_advanced_font_selector)){if(!l&&p.style.fontSize){l=p.style.fontSize}if(!w&&p.style.fontFamily){w=p.style.fontFamily.replace(/[\"\']+/g,"").replace(/^([^,]+).*/,"$1").toLowerCase()}if(!C&&p.style.color){C=p.style.color}if(!m&&p.style.backgroundColor){m=p.style.backgroundColor}}return false});if(H=u.get("fontselect")){H.select(function(n){return n.replace(/^([^,]+).*/,"$1").toLowerCase()==w})}if(H=u.get("fontsizeselect")){if(A.theme_advanced_runtime_fontsize&&!l&&!x){l=o.dom.getStyle(E,"fontSize",true)}H.select(function(n){if(n.fontSize&&n.fontSize===l){return true}if(n["class"]&&n["class"]===x){return true}})}if(A.theme_advanced_show_current_color){function B(p,n){if(H=u.get(p)){if(!n){n=H.settings.default_color}if(n!==H.value){H.displayColor(n)}}}B("forecolor",C);B("backcolor",m)}if(A.theme_advanced_show_current_color){function B(p,n){if(H=u.get(p)){if(!n){n=H.settings.default_color}if(n!==H.value){H.displayColor(n)}}}B("forecolor",C);B("backcolor",m)}if(A.theme_advanced_path&&A.theme_advanced_statusbar_location){D=i.get(o.id+"_path")||i.add(o.id+"_path_row","span",{id:o.id+"_path"});if(z.statusKeyboardNavigation){z.statusKeyboardNavigation.destroy();z.statusKeyboardNavigation=null}i.setHTML(D,"");q(function(I){var p=I.nodeName.toLowerCase(),s,v,t="";if(I.nodeType!=1||p==="br"||I.getAttribute("data-mce-bogus")||i.hasClass(I,"mceItemHidden")||i.hasClass(I,"mceItemRemoved")){return}if(h.isIE&&I.scopeName!=="HTML"&&I.scopeName){p=I.scopeName+":"+p}p=p.replace(/mce\:/g,"");switch(p){case"b":p="strong";break;case"i":p="em";break;case"img":if(y=i.getAttrib(I,"src")){t+="src: "+y+" "}break;case"a":if(y=i.getAttrib(I,"name")){t+="name: "+y+" ";p+="#"+y}if(y=i.getAttrib(I,"href")){t+="href: "+y+" "}break;case"font":if(y=i.getAttrib(I,"face")){t+="font: "+y+" "}if(y=i.getAttrib(I,"size")){t+="size: "+y+" "}if(y=i.getAttrib(I,"color")){t+="color: "+y+" "}break;case"span":if(y=i.getAttrib(I,"style")){t+="style: "+y+" "}break}if(y=i.getAttrib(I,"id")){t+="id: "+y+" "}if(y=I.className){y=y.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g,"");if(y){t+="class: "+y+" ";if(o.dom.isBlock(I)||p=="img"||p=="span"){p+="."+y}}}p=p.replace(/(html:)/g,"");p={name:p,node:I,title:t};z.onResolveName.dispatch(z,p);t=p.title;p=p.name;v=i.create("a",{href:"javascript:;",role:"button",onmousedown:"return false;",title:t,"class":"mcePath_"+(G++)},p);if(D.hasChildNodes()){D.insertBefore(i.create("span",{"aria-hidden":"true"},"\u00a0\u00bb "),D.firstChild);D.insertBefore(v,D.firstChild)}else{D.appendChild(v)}},o.getBody());if(i.select("a",D).length>0){z.statusKeyboardNavigation=new h.ui.KeyboardNavigation({root:o.id+"_path_row",items:i.select("a",D),excludeFromTabOrder:true,onCancel:function(){o.focus()}},i)}}},_sel:function(j){this.editor.execCommand("mceSelectNodeDepth",false,j)},_mceInsertAnchor:function(l,k){var j=this.editor;j.windowManager.open({url:this.url+"/anchor.htm",width:320+parseInt(j.getLang("advanced.anchor_delta_width",0)),height:90+parseInt(j.getLang("advanced.anchor_delta_height",0)),inline:true},{theme_url:this.url})},_mceCharMap:function(){var j=this.editor;j.windowManager.open({url:this.url+"/charmap.htm",width:550+parseInt(j.getLang("advanced.charmap_delta_width",0)),height:265+parseInt(j.getLang("advanced.charmap_delta_height",0)),inline:true},{theme_url:this.url})},_mceHelp:function(){var j=this.editor;j.windowManager.open({url:this.url+"/about.htm",width:480,height:380,inline:true},{theme_url:this.url})},_mceShortcuts:function(){var j=this.editor;j.windowManager.open({url:this.url+"/shortcuts.htm",width:480,height:380,inline:true},{theme_url:this.url})},_mceColorPicker:function(l,k){var j=this.editor;k=k||{};j.windowManager.open({url:this.url+"/color_picker.htm",width:375+parseInt(j.getLang("advanced.colorpicker_delta_width",0)),height:250+parseInt(j.getLang("advanced.colorpicker_delta_height",0)),close_previous:false,inline:true},{input_color:k.color,func:k.func,theme_url:this.url})},_mceCodeEditor:function(k,l){var j=this.editor;j.windowManager.open({url:this.url+"/source_editor.htm",width:parseInt(j.getParam("theme_advanced_source_editor_width",720)),height:parseInt(j.getParam("theme_advanced_source_editor_height",580)),inline:true,resizable:true,maximizable:true},{theme_url:this.url})},_mceImage:function(k,l){var j=this.editor;if(j.dom.getAttrib(j.selection.getNode(),"class","").indexOf("mceItem")!=-1){return}j.windowManager.open({url:this.url+"/image.htm",width:355+parseInt(j.getLang("advanced.image_delta_width",0)),height:275+parseInt(j.getLang("advanced.image_delta_height",0)),inline:true},{theme_url:this.url})},_mceLink:function(k,l){var j=this.editor;j.windowManager.open({url:this.url+"/link.htm",width:310+parseInt(j.getLang("advanced.link_delta_width",0)),height:200+parseInt(j.getLang("advanced.link_delta_height",0)),inline:true},{theme_url:this.url})},_mceNewDocument:function(){var j=this.editor;j.windowManager.confirm("advanced.newdocument",function(k){if(k){j.execCommand("mceSetContent",false,"")}})},_mceForeColor:function(){var j=this;this._mceColorPicker(0,{color:j.fgColor,func:function(k){j.fgColor=k;j.editor.execCommand("ForeColor",false,k)}})},_mceBackColor:function(){var j=this;this._mceColorPicker(0,{color:j.bgColor,func:function(k){j.bgColor=k;j.editor.execCommand("HiliteColor",false,k)}})},_ufirst:function(j){return j.substring(0,1).toUpperCase()+j.substring(1)}});h.ThemeManager.add("advanced",h.themes.AdvancedTheme)}(tinymce)); \ No newline at end of file diff --git a/themes/advanced/editor_template_src.js b/themes/advanced/editor_template_src.js index 324e11d0453a69a45f9a0a23a89e0c636f737157..82166dcb68692c5f4127a116c0dd7542df39d964 100644 --- a/themes/advanced/editor_template_src.js +++ b/themes/advanced/editor_template_src.js @@ -11,6 +11,95 @@ (function(tinymce) { var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend, each = tinymce.each, Cookie = tinymce.util.Cookie, lastExtID, explode = tinymce.explode; + // Generates a preview for a format + function getPreviewCss(ed, fmt) { + var name, previewElm, dom = ed.dom, previewCss = '', parentFontSize, previewStylesName; + + previewStyles = ed.settings.preview_styles; + + // No preview forced + if (previewStyles === false) + return ''; + + // Default preview + if (!previewStyles) + previewStyles = 'font-family font-size font-weight text-decoration text-transform color background-color'; + + // Removes any variables since these can't be previewed + function removeVars(val) { + return val.replace(/%(\w+)/g, ''); + }; + + // Create block/inline element to use for preview + name = fmt.block || fmt.inline || 'span'; + previewElm = dom.create(name); + + // Add format styles to preview element + each(fmt.styles, function(value, name) { + value = removeVars(value); + + if (value) + dom.setStyle(previewElm, name, value); + }); + + // Add attributes to preview element + each(fmt.attributes, function(value, name) { + value = removeVars(value); + + if (value) + dom.setAttrib(previewElm, name, value); + }); + + // Add classes to preview element + each(fmt.classes, function(value) { + value = removeVars(value); + + if (!dom.hasClass(previewElm, value)) + dom.addClass(previewElm, value); + }); + + // Add the previewElm outside the visual area + dom.setStyles(previewElm, {position: 'absolute', left: -0xFFFF}); + ed.getBody().appendChild(previewElm); + + // Get parent container font size so we can compute px values out of em/% for older IE:s + parentFontSize = dom.getStyle(ed.getBody(), 'fontSize', true); + parentFontSize = /px$/.test(parentFontSize) ? parseInt(parentFontSize, 10) : 0; + + 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)) { + if (parentFontSize === 0) { + return; + } + + // Convert font size from em/% to px + value = parseFloat(value, 10) / (/%$/.test(value) ? 100 : 1); + value = (value * parentFontSize) + 'px'; + } + } + + previewCss += name + ':' + value + ';'; + }); + + dom.remove(previewElm); + + return previewCss; + }; + // Tell it to load theme specific language pack(s) tinymce.ThemeManager.requireLangPack('advanced'); @@ -61,23 +150,31 @@ init : function(ed, url) { var t = this, s, v, o; - + t.editor = ed; t.url = url; t.onResolveName = new tinymce.util.Dispatcher(this); + s = ed.settings; ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast(); ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin; + // Setup default buttons + if (!s.theme_advanced_buttons1) { + s = extend({ + theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", + theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", + theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap" + }, s); + } + // Default settings t.settings = s = extend({ theme_advanced_path : true, - theme_advanced_toolbar_location : 'bottom', - theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect", - theme_advanced_buttons2 : "bullist,numlist,|,outdent,indent,|,undo,redo,|,link,unlink,anchor,image,cleanup,help,code", - theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap", + theme_advanced_toolbar_location : 'top', theme_advanced_blockformats : "p,address,pre,h1,h2,h3,h4,h5,h6", - theme_advanced_toolbar_align : "center", + theme_advanced_toolbar_align : "left", + theme_advanced_statusbar_location : "bottom", theme_advanced_fonts : "Andale Mono=andale mono,times;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Trebuchet MS=trebuchet ms,geneva;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats", theme_advanced_more_colors : 1, theme_advanced_row_height : 23, @@ -87,7 +184,7 @@ theme_advanced_font_selector : "span", theme_advanced_show_current_color: 0, readonly : ed.settings.readonly - }, ed.settings); + }, s); // Setup default font_size_style_values if (!s.font_size_style_values) @@ -219,15 +316,21 @@ if (ctrl.getLength() == 0) { each(ed.dom.getClasses(), function(o, idx) { - var name = 'style_' + idx; + var name = 'style_' + idx, fmt; - ed.formatter.register(name, { + fmt = { inline : 'span', attributes : {'class' : o['class']}, selector : '*' - }); + }; + + ed.formatter.register(name, fmt); - ctrl.add(o['class'], name); + ctrl.add(o['class'], name, { + style: function() { + return getPreviewCss(ed, fmt); + } + }); }); } }, @@ -239,7 +342,7 @@ ctrl = ctrlMan.createListBox('styleselect', { title : 'advanced.style_select', onselect : function(name) { - var matches, formatNames = []; + var matches, formatNames = [], removedFormat; each(ctrl.items, function(item) { formatNames.push(item.value); @@ -248,12 +351,18 @@ ed.focus(); ed.undoManager.add(); - // Toggle off the current format + // Toggle off the current format(s) matches = ed.formatter.matchAll(formatNames); - if (!name || matches[0] == name) { - if (matches[0]) - ed.formatter.remove(matches[0]); - } else + tinymce.each(matches, function(match) { + if (!name || match == name) { + if (match) + ed.formatter.remove(match); + + removedFormat = true; + } + }); + + if (!removedFormat) ed.formatter.apply(name); ed.undoManager.add(); @@ -264,7 +373,7 @@ }); // Handle specified format - ed.onInit.add(function() { + ed.onPreInit.add(function() { var counter = 0, formats = ed.getParam('style_formats'); if (formats) { @@ -276,24 +385,32 @@ if (keys > 1) { name = fmt.name = fmt.name || 'style_' + (counter++); ed.formatter.register(name, fmt); - ctrl.add(fmt.title, name); + ctrl.add(fmt.title, name, { + style: function() { + return getPreviewCss(ed, fmt); + } + }); } else ctrl.add(fmt.title); }); } else { each(ed.getParam('theme_advanced_styles', '', 'hash'), function(val, key) { - var name; + var name, fmt; if (val) { name = 'style_' + (counter++); - - ed.formatter.register(name, { + fmt = { inline : 'span', classes : val, selector : '*' - }); + }; - ctrl.add(t.editor.translate(key), name); + ed.formatter.register(name, fmt); + ctrl.add(t.editor.translate(key), name, { + style: function() { + return getPreviewCss(ed, fmt); + } + }); } }); } @@ -433,7 +550,9 @@ if (c) { each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) { - c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v}); + c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v, style: function() { + return getPreviewCss(t.editor, {block: v}); + }}); }); } @@ -507,7 +626,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) @@ -552,15 +671,14 @@ if (e.nodeName == 'A') { t._sel(e.className.replace(/^.*mcePath_([0-9]+).*$/, '$1')); - - return Event.cancel(e); + return false; } }); /* if (DOM.get(ed.id + '_path_row')) { Event.add(ed.id + '_tbl', 'mouseover', function(e) { var re; - + e = e.target; if (e.nodeName == 'SPAN' && DOM.hasClass(e.parentNode, 'mceButton')) { @@ -713,6 +831,7 @@ var f = Event.add(ed.id + '_external_close', 'click', function() { DOM.hide(ed.id + '_external'); Event.remove(ed.id + '_external_close', 'click', f); + return false; }); DOM.show(e); @@ -825,7 +944,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'), @@ -837,10 +956,11 @@ a = s.theme_advanced_toolbar_align.toLowerCase(); a = 'mce' + t._ufirst(a); - n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"}); + n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"toolbar"}); // 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']) @@ -854,6 +974,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('')); @@ -863,7 +986,7 @@ var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td; n = DOM.add(tb, 'tr'); - n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); + n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'}); if (s.theme_advanced_path) { DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path')); @@ -871,7 +994,7 @@ } else { DOM.add(n, 'span', {}, ' '); } - + if (s.theme_advanced_resizing) { DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize', tabIndex:"-1"}); @@ -916,6 +1039,8 @@ width = startWidth + (e.screenX - startX); height = startHeight + (e.screenY - startY); t.resizeTo(width, height, true); + + ed.nodeChanged(); }; e.preventDefault(); @@ -975,19 +1100,17 @@ p = getParent('A'); if (c = cm.get('link')) { - if (!p || !p.name) { - c.setDisabled(!p && co); - c.setActive(!!p); - } + c.setDisabled((!p && co) || (p && !p.href)); + c.setActive(!!p && (!p.name && !p.id)); } if (c = cm.get('unlink')) { c.setDisabled(!p && co); - c.setActive(!!p && !p.name); + c.setActive(!!p && !p.name && !p.id); } if (c = cm.get('anchor')) { - c.setActive(!co && !!p && p.name); + c.setActive(!co && !!p && (p.name || (p.id && !p.href))); } p = getParent('IMG'); @@ -1004,10 +1127,15 @@ matches = ed.formatter.matchAll(formatNames); c.select(matches[0]); + tinymce.each(matches, function(match, index) { + if (index > 0) { + c.mark(match); + } + }); } if (c = cm.get('formatselect')) { - p = getParent(DOM.isBlock); + p = getParent(ed.dom.isBlock); if (p) c.select(p.nodeName.toLowerCase()); @@ -1026,7 +1154,7 @@ if (!fn && n.style.fontFamily) fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase(); - + if (!fc && n.style.color) fc = n.style.color; @@ -1057,7 +1185,7 @@ return true; }); } - + if (s.theme_advanced_show_current_color) { function updateColor(controlId, color) { if (c = cm.get(controlId)) { @@ -1105,7 +1233,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 @@ -1161,12 +1289,12 @@ ti += 'id: ' + v + ' '; if (v = n.className) { - v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, '') + v = v.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g, ''); if (v) { ti += 'class: ' + v + ' '; - if (DOM.isBlock(n) || na == 'img' || na == 'span') + if (ed.dom.isBlock(n) || na == 'img' || na == 'span') na += '.' + v; } } @@ -1294,7 +1422,7 @@ var ed = this.editor; // Internal image object like a flash placeholder - if (ed.dom.getAttrib(ed.selection.getNode(), 'class').indexOf('mceItem') != -1) + if (ed.dom.getAttrib(ed.selection.getNode(), 'class', '').indexOf('mceItem') != -1) return; ed.windowManager.open({ diff --git a/themes/advanced/img/icons.gif b/themes/advanced/img/icons.gif index 641a9e3d314f4ea051692a2274aeb281456f5df9..ca222490188b939d695f5ff8823c42c0394c65f7 100644 Binary files a/themes/advanced/img/icons.gif and b/themes/advanced/img/icons.gif differ diff --git a/themes/advanced/js/anchor.js b/themes/advanced/js/anchor.js index 04f41e0cac076e5fde4c0820e99ab01f1a48bffc..2909a3a4d738640f44eb57a327372d9e0efb2f25 100644 --- a/themes/advanced/js/anchor.js +++ b/themes/advanced/js/anchor.js @@ -6,7 +6,7 @@ var AnchorDialog = { this.editor = ed; elm = ed.dom.getParent(ed.selection.getNode(), 'A'); - v = ed.dom.getAttrib(elm, 'name'); + v = ed.dom.getAttrib(elm, 'name') || ed.dom.getAttrib(elm, 'id'); if (v) { this.action = 'update'; @@ -17,7 +17,7 @@ var AnchorDialog = { }, update : function() { - var ed = this.editor, elm, name = document.forms[0].anchorName.value; + var ed = this.editor, elm, name = document.forms[0].anchorName.value, attribName; if (!name || !/^[a-z][a-z0-9\-\_:\.]*$/i.test(name)) { tinyMCEPopup.alert('advanced_dlg.anchor_invalid'); @@ -29,12 +29,25 @@ var AnchorDialog = { if (this.action != 'update') ed.selection.collapse(1); + var aRule = ed.schema.getElementRule('a'); + if (!aRule || aRule.attributes.name) { + attribName = 'name'; + } else { + attribName = 'id'; + } + elm = ed.dom.getParent(ed.selection.getNode(), 'A'); if (elm) { - elm.setAttribute('name', name); - elm.name = name; - } else - ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', {name : name, 'class' : 'mceItemAnchor'}, '')); + elm.setAttribute(attribName, name); + elm[attribName] = name; + ed.undoManager.add(); + } else { + // create with zero-sized nbsp so that in Webkit where anchor is on last line by itself caret cannot be placed after it + var attrs = {'class' : 'mceItemAnchor'}; + attrs[attribName] = name; + ed.execCommand('mceInsertContent', 0, ed.dom.createHTML('a', attrs, '\uFEFF')); + ed.nodeChanged(); + } tinyMCEPopup.close(); } diff --git a/themes/advanced/js/color_picker.js b/themes/advanced/js/color_picker.js index f51e703b0af8215a4ef3056e495b43510651c8bd..cc891c17118d80462a1bb18a8db37cdb13535b04 100644 --- a/themes/advanced/js/color_picker.js +++ b/themes/advanced/js/color_picker.js @@ -1,329 +1,345 @@ -tinyMCEPopup.requireLangPack(); - -var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false; - -var colors = [ - "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033", - "#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", - "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff", - "#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", - "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399", - "#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", - "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333", - "#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", - "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff", - "#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", - "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699", - "#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", - "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633", - "#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", - "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff", - "#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", - "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999", - "#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", - "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33", - "#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", - "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff", - "#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", - "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99", - "#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", - "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33", - "#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", - "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff" -]; - -var named = { - '#F0F8FF':'Alice Blue','#FAEBD7':'Antique White','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige', - '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'Blanched Almond','#0000FF':'Blue','#8A2BE2':'Blue Violet','#A52A2A':'Brown', - '#DEB887':'Burly Wood','#5F9EA0':'Cadet Blue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'Cornflower Blue', - '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'Dark Blue','#008B8B':'Dark Cyan','#B8860B':'Dark Golden Rod', - '#A9A9A9':'Dark Gray','#A9A9A9':'Dark Grey','#006400':'Dark Green','#BDB76B':'Dark Khaki','#8B008B':'Dark Magenta','#556B2F':'Dark Olive Green', - '#FF8C00':'Darkorange','#9932CC':'Dark Orchid','#8B0000':'Dark Red','#E9967A':'Dark Salmon','#8FBC8F':'Dark Sea Green','#483D8B':'Dark Slate Blue', - '#2F4F4F':'Dark Slate Gray','#2F4F4F':'Dark Slate Grey','#00CED1':'Dark Turquoise','#9400D3':'Dark Violet','#FF1493':'Deep Pink','#00BFFF':'Deep Sky Blue', - '#696969':'Dim Gray','#696969':'Dim Grey','#1E90FF':'Dodger Blue','#B22222':'Fire Brick','#FFFAF0':'Floral White','#228B22':'Forest Green', - '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'Ghost White','#FFD700':'Gold','#DAA520':'Golden Rod','#808080':'Gray','#808080':'Grey', - '#008000':'Green','#ADFF2F':'Green Yellow','#F0FFF0':'Honey Dew','#FF69B4':'Hot Pink','#CD5C5C':'Indian Red','#4B0082':'Indigo','#FFFFF0':'Ivory', - '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'Lavender Blush','#7CFC00':'Lawn Green','#FFFACD':'Lemon Chiffon','#ADD8E6':'Light Blue', - '#F08080':'Light Coral','#E0FFFF':'Light Cyan','#FAFAD2':'Light Golden Rod Yellow','#D3D3D3':'Light Gray','#D3D3D3':'Light Grey','#90EE90':'Light Green', - '#FFB6C1':'Light Pink','#FFA07A':'Light Salmon','#20B2AA':'Light Sea Green','#87CEFA':'Light Sky Blue','#778899':'Light Slate Gray','#778899':'Light Slate Grey', - '#B0C4DE':'Light Steel Blue','#FFFFE0':'Light Yellow','#00FF00':'Lime','#32CD32':'Lime Green','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon', - '#66CDAA':'Medium Aqua Marine','#0000CD':'Medium Blue','#BA55D3':'Medium Orchid','#9370D8':'Medium Purple','#3CB371':'Medium Sea Green','#7B68EE':'Medium Slate Blue', - '#00FA9A':'Medium Spring Green','#48D1CC':'Medium Turquoise','#C71585':'Medium Violet Red','#191970':'Midnight Blue','#F5FFFA':'Mint Cream','#FFE4E1':'Misty Rose','#FFE4B5':'Moccasin', - '#FFDEAD':'Navajo White','#000080':'Navy','#FDF5E6':'Old Lace','#808000':'Olive','#6B8E23':'Olive Drab','#FFA500':'Orange','#FF4500':'Orange Red','#DA70D6':'Orchid', - '#EEE8AA':'Pale Golden Rod','#98FB98':'Pale Green','#AFEEEE':'Pale Turquoise','#D87093':'Pale Violet Red','#FFEFD5':'Papaya Whip','#FFDAB9':'Peach Puff', - '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'Powder Blue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'Rosy Brown','#4169E1':'Royal Blue', - '#8B4513':'Saddle Brown','#FA8072':'Salmon','#F4A460':'Sandy Brown','#2E8B57':'Sea Green','#FFF5EE':'Sea Shell','#A0522D':'Sienna','#C0C0C0':'Silver', - '#87CEEB':'Sky Blue','#6A5ACD':'Slate Blue','#708090':'Slate Gray','#708090':'Slate Grey','#FFFAFA':'Snow','#00FF7F':'Spring Green', - '#4682B4':'Steel Blue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet', - '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'White Smoke','#FFFF00':'Yellow','#9ACD32':'Yellow Green' -}; - -var namedLookup = {}; - -function init() { - var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color')), key, value; - - tinyMCEPopup.resizeToInnerSize(); - - generatePicker(); - generateWebColors(); - generateNamedColors(); - - if (inputColor) { - changeFinalColor(inputColor); - - col = convertHexToRGB(inputColor); - - if (col) - updateLight(col.r, col.g, col.b); - } - - for (key in named) { - value = named[key]; - namedLookup[value.replace(/\s+/, '').toLowerCase()] = key.replace(/#/, '').toLowerCase(); - } -} - -function toHexColor(color) { - var matches, red, green, blue, toInt = parseInt; - - function hex(value) { - value = parseInt(value).toString(16); - - return value.length > 1 ? value : '0' + value; // Padd with leading zero - }; - - color = color.replace(/[\s#]+/g, '').toLowerCase(); - color = namedLookup[color] || color; - matches = /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)|([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})|([a-f0-9])([a-f0-9])([a-f0-9])$/.exec(color); - - if (matches) { - if (matches[1]) { - red = toInt(matches[1]); - green = toInt(matches[2]); - blue = toInt(matches[3]); - } else if (matches[4]) { - red = toInt(matches[4], 16); - green = toInt(matches[5], 16); - blue = toInt(matches[6], 16); - } else if (matches[7]) { - red = toInt(matches[7] + matches[7], 16); - green = toInt(matches[8] + matches[8], 16); - blue = toInt(matches[9] + matches[9], 16); - } - - return '#' + hex(red) + hex(green) + hex(blue); - } - - return ''; -} - -function insertAction() { - var color = document.getElementById("color").value, f = tinyMCEPopup.getWindowArg('func'); - - tinyMCEPopup.restoreSelection(); - - if (f) - f(toHexColor(color)); - - tinyMCEPopup.close(); -} - -function showColor(color, name) { - if (name) - document.getElementById("colorname").innerHTML = name; - - document.getElementById("preview").style.backgroundColor = color; - document.getElementById("color").value = color.toUpperCase(); -} - -function convertRGBToHex(col) { - var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); - - if (!col) - return col; - - var rgb = col.replace(re, "$1,$2,$3").split(','); - if (rgb.length == 3) { - r = parseInt(rgb[0]).toString(16); - g = parseInt(rgb[1]).toString(16); - b = parseInt(rgb[2]).toString(16); - - r = r.length == 1 ? '0' + r : r; - g = g.length == 1 ? '0' + g : g; - b = b.length == 1 ? '0' + b : b; - - return "#" + r + g + b; - } - - return col; -} - -function convertHexToRGB(col) { - if (col.indexOf('#') != -1) { - col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); - - r = parseInt(col.substring(0, 2), 16); - g = parseInt(col.substring(2, 4), 16); - b = parseInt(col.substring(4, 6), 16); - - return {r : r, g : g, b : b}; - } - - return null; -} - -function generatePicker() { - var el = document.getElementById('light'), h = '', i; - - for (i = 0; i < detail; i++){ - h += '<div id="gs'+i+'" style="background-color:#000000; width:15px; height:3px; border-style:none; border-width:0px;"' - + ' onclick="changeFinalColor(this.style.backgroundColor)"' - + ' onmousedown="isMouseDown = true; return false;"' - + ' onmouseup="isMouseDown = false;"' - + ' onmousemove="if (isMouseDown && isMouseOver) changeFinalColor(this.style.backgroundColor); return false;"' - + ' onmouseover="isMouseOver = true;"' - + ' onmouseout="isMouseOver = false;"' - + '></div>'; - } - - el.innerHTML = h; -} - -function generateWebColors() { - var el = document.getElementById('webcolors'), h = '', i; - - if (el.className == 'generated') - return; - - // TODO: VoiceOver doesn't seem to support legend as a label referenced by labelledby. - h += '<div role="listbox" aria-labelledby="webcolors_title" tabindex="0"><table role="presentation" border="0" cellspacing="1" cellpadding="0">' - + '<tr>'; - - for (i=0; i<colors.length; i++) { - h += '<td bgcolor="' + colors[i] + '" width="10" height="10">' - + '<a href="javascript:insertAction();" role="option" tabindex="-1" aria-labelledby="web_colors_' + i + '" onfocus="showColor(\'' + colors[i] + '\');" onmouseover="showColor(\'' + colors[i] + '\');" style="display:block;width:10px;height:10px;overflow:hidden;">'; - if (tinyMCEPopup.editor.forcedHighContrastMode) { - h += '<canvas class="mceColorSwatch" height="10" width="10" data-color="' + colors[i] + '"></canvas>'; - } - h += '<span class="mceVoiceLabel" style="display:none;" id="web_colors_' + i + '">' + colors[i].toUpperCase() + '</span>'; - h += '</a></td>'; - if ((i+1) % 18 == 0) - h += '</tr><tr>'; - } - - h += '</table></div>'; - - el.innerHTML = h; - el.className = 'generated'; - - paintCanvas(el); - enableKeyboardNavigation(el.firstChild); -} - -function paintCanvas(el) { - tinyMCEPopup.getWin().tinymce.each(tinyMCEPopup.dom.select('canvas.mceColorSwatch', el), function(canvas) { - var context; - if (canvas.getContext && (context = canvas.getContext("2d"))) { - context.fillStyle = canvas.getAttribute('data-color'); - context.fillRect(0, 0, 10, 10); - } - }); -} -function generateNamedColors() { - var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; - - if (el.className == 'generated') - return; - - for (n in named) { - v = named[n]; - h += '<a href="javascript:insertAction();" role="option" tabindex="-1" aria-labelledby="named_colors_' + i + '" onfocus="showColor(\'' + n + '\',\'' + v + '\');" onmouseover="showColor(\'' + n + '\',\'' + v + '\');" style="background-color: ' + n + '">'; - if (tinyMCEPopup.editor.forcedHighContrastMode) { - h += '<canvas class="mceColorSwatch" height="10" width="10" data-color="' + colors[i] + '"></canvas>'; - } - h += '<span class="mceVoiceLabel" style="display:none;" id="named_colors_' + i + '">' + v + '</span>'; - h += '</a>'; - i++; - } - - el.innerHTML = h; - el.className = 'generated'; - - paintCanvas(el); - enableKeyboardNavigation(el); -} - -function enableKeyboardNavigation(el) { - tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', { - root: el, - items: tinyMCEPopup.dom.select('a', el) - }, tinyMCEPopup.dom); -} - -function dechex(n) { - return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); -} - -function computeColor(e) { - var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB, pos = tinyMCEPopup.dom.getPos(e.target); - - x = e.offsetX ? e.offsetX : (e.target ? e.clientX - pos.x : 0); - y = e.offsetY ? e.offsetY : (e.target ? e.clientY - pos.y : 0); - - partWidth = document.getElementById('colors').width / 6; - partDetail = detail / 2; - imHeight = document.getElementById('colors').height; - - r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; - g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); - b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); - - coef = (imHeight - y) / imHeight; - r = 128 + (r - 128) * coef; - g = 128 + (g - 128) * coef; - b = 128 + (b - 128) * coef; - - changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); - updateLight(r, g, b); -} - -function updateLight(r, g, b) { - var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; - - for (i=0; i<detail; i++) { - if ((i>=0) && (i<partDetail)) { - finalCoef = i / partDetail; - finalR = dechex(255 - (255 - r) * finalCoef); - finalG = dechex(255 - (255 - g) * finalCoef); - finalB = dechex(255 - (255 - b) * finalCoef); - } else { - finalCoef = 2 - i / partDetail; - finalR = dechex(r * finalCoef); - finalG = dechex(g * finalCoef); - finalB = dechex(b * finalCoef); - } - - color = finalR + finalG + finalB; - - setCol('gs' + i, '#'+color); - } -} - -function changeFinalColor(color) { - if (color.indexOf('#') == -1) - color = convertRGBToHex(color); - - setCol('preview', color); - document.getElementById('color').value = color; -} - -function setCol(e, c) { - try { - document.getElementById(e).style.backgroundColor = c; - } catch (ex) { - // Ignore IE warning - } -} - -tinyMCEPopup.onInit.add(init); +tinyMCEPopup.requireLangPack(); + +var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false; + +var colors = [ + "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033", + "#330066","#330099","#3300cc","#3300ff","#660000","#660033","#660066","#660099", + "#6600cc","#6600ff","#990000","#990033","#990066","#990099","#9900cc","#9900ff", + "#cc0000","#cc0033","#cc0066","#cc0099","#cc00cc","#cc00ff","#ff0000","#ff0033", + "#ff0066","#ff0099","#ff00cc","#ff00ff","#003300","#003333","#003366","#003399", + "#0033cc","#0033ff","#333300","#333333","#333366","#333399","#3333cc","#3333ff", + "#663300","#663333","#663366","#663399","#6633cc","#6633ff","#993300","#993333", + "#993366","#993399","#9933cc","#9933ff","#cc3300","#cc3333","#cc3366","#cc3399", + "#cc33cc","#cc33ff","#ff3300","#ff3333","#ff3366","#ff3399","#ff33cc","#ff33ff", + "#006600","#006633","#006666","#006699","#0066cc","#0066ff","#336600","#336633", + "#336666","#336699","#3366cc","#3366ff","#666600","#666633","#666666","#666699", + "#6666cc","#6666ff","#996600","#996633","#996666","#996699","#9966cc","#9966ff", + "#cc6600","#cc6633","#cc6666","#cc6699","#cc66cc","#cc66ff","#ff6600","#ff6633", + "#ff6666","#ff6699","#ff66cc","#ff66ff","#009900","#009933","#009966","#009999", + "#0099cc","#0099ff","#339900","#339933","#339966","#339999","#3399cc","#3399ff", + "#669900","#669933","#669966","#669999","#6699cc","#6699ff","#999900","#999933", + "#999966","#999999","#9999cc","#9999ff","#cc9900","#cc9933","#cc9966","#cc9999", + "#cc99cc","#cc99ff","#ff9900","#ff9933","#ff9966","#ff9999","#ff99cc","#ff99ff", + "#00cc00","#00cc33","#00cc66","#00cc99","#00cccc","#00ccff","#33cc00","#33cc33", + "#33cc66","#33cc99","#33cccc","#33ccff","#66cc00","#66cc33","#66cc66","#66cc99", + "#66cccc","#66ccff","#99cc00","#99cc33","#99cc66","#99cc99","#99cccc","#99ccff", + "#cccc00","#cccc33","#cccc66","#cccc99","#cccccc","#ccccff","#ffcc00","#ffcc33", + "#ffcc66","#ffcc99","#ffcccc","#ffccff","#00ff00","#00ff33","#00ff66","#00ff99", + "#00ffcc","#00ffff","#33ff00","#33ff33","#33ff66","#33ff99","#33ffcc","#33ffff", + "#66ff00","#66ff33","#66ff66","#66ff99","#66ffcc","#66ffff","#99ff00","#99ff33", + "#99ff66","#99ff99","#99ffcc","#99ffff","#ccff00","#ccff33","#ccff66","#ccff99", + "#ccffcc","#ccffff","#ffff00","#ffff33","#ffff66","#ffff99","#ffffcc","#ffffff" +]; + +var named = { + '#F0F8FF':'Alice Blue','#FAEBD7':'Antique White','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige', + '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'Blanched Almond','#0000FF':'Blue','#8A2BE2':'Blue Violet','#A52A2A':'Brown', + '#DEB887':'Burly Wood','#5F9EA0':'Cadet Blue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'Cornflower Blue', + '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'Dark Blue','#008B8B':'Dark Cyan','#B8860B':'Dark Golden Rod', + '#A9A9A9':'Dark Gray','#A9A9A9':'Dark Grey','#006400':'Dark Green','#BDB76B':'Dark Khaki','#8B008B':'Dark Magenta','#556B2F':'Dark Olive Green', + '#FF8C00':'Darkorange','#9932CC':'Dark Orchid','#8B0000':'Dark Red','#E9967A':'Dark Salmon','#8FBC8F':'Dark Sea Green','#483D8B':'Dark Slate Blue', + '#2F4F4F':'Dark Slate Gray','#2F4F4F':'Dark Slate Grey','#00CED1':'Dark Turquoise','#9400D3':'Dark Violet','#FF1493':'Deep Pink','#00BFFF':'Deep Sky Blue', + '#696969':'Dim Gray','#696969':'Dim Grey','#1E90FF':'Dodger Blue','#B22222':'Fire Brick','#FFFAF0':'Floral White','#228B22':'Forest Green', + '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'Ghost White','#FFD700':'Gold','#DAA520':'Golden Rod','#808080':'Gray','#808080':'Grey', + '#008000':'Green','#ADFF2F':'Green Yellow','#F0FFF0':'Honey Dew','#FF69B4':'Hot Pink','#CD5C5C':'Indian Red','#4B0082':'Indigo','#FFFFF0':'Ivory', + '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'Lavender Blush','#7CFC00':'Lawn Green','#FFFACD':'Lemon Chiffon','#ADD8E6':'Light Blue', + '#F08080':'Light Coral','#E0FFFF':'Light Cyan','#FAFAD2':'Light Golden Rod Yellow','#D3D3D3':'Light Gray','#D3D3D3':'Light Grey','#90EE90':'Light Green', + '#FFB6C1':'Light Pink','#FFA07A':'Light Salmon','#20B2AA':'Light Sea Green','#87CEFA':'Light Sky Blue','#778899':'Light Slate Gray','#778899':'Light Slate Grey', + '#B0C4DE':'Light Steel Blue','#FFFFE0':'Light Yellow','#00FF00':'Lime','#32CD32':'Lime Green','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon', + '#66CDAA':'Medium Aqua Marine','#0000CD':'Medium Blue','#BA55D3':'Medium Orchid','#9370D8':'Medium Purple','#3CB371':'Medium Sea Green','#7B68EE':'Medium Slate Blue', + '#00FA9A':'Medium Spring Green','#48D1CC':'Medium Turquoise','#C71585':'Medium Violet Red','#191970':'Midnight Blue','#F5FFFA':'Mint Cream','#FFE4E1':'Misty Rose','#FFE4B5':'Moccasin', + '#FFDEAD':'Navajo White','#000080':'Navy','#FDF5E6':'Old Lace','#808000':'Olive','#6B8E23':'Olive Drab','#FFA500':'Orange','#FF4500':'Orange Red','#DA70D6':'Orchid', + '#EEE8AA':'Pale Golden Rod','#98FB98':'Pale Green','#AFEEEE':'Pale Turquoise','#D87093':'Pale Violet Red','#FFEFD5':'Papaya Whip','#FFDAB9':'Peach Puff', + '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'Powder Blue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'Rosy Brown','#4169E1':'Royal Blue', + '#8B4513':'Saddle Brown','#FA8072':'Salmon','#F4A460':'Sandy Brown','#2E8B57':'Sea Green','#FFF5EE':'Sea Shell','#A0522D':'Sienna','#C0C0C0':'Silver', + '#87CEEB':'Sky Blue','#6A5ACD':'Slate Blue','#708090':'Slate Gray','#708090':'Slate Grey','#FFFAFA':'Snow','#00FF7F':'Spring Green', + '#4682B4':'Steel Blue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet', + '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'White Smoke','#FFFF00':'Yellow','#9ACD32':'Yellow Green' +}; + +var namedLookup = {}; + +function init() { + var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color')), key, value; + + tinyMCEPopup.resizeToInnerSize(); + + generatePicker(); + generateWebColors(); + generateNamedColors(); + + if (inputColor) { + changeFinalColor(inputColor); + + col = convertHexToRGB(inputColor); + + if (col) + updateLight(col.r, col.g, col.b); + } + + for (key in named) { + value = named[key]; + namedLookup[value.replace(/\s+/, '').toLowerCase()] = key.replace(/#/, '').toLowerCase(); + } +} + +function toHexColor(color) { + var matches, red, green, blue, toInt = parseInt; + + function hex(value) { + value = parseInt(value).toString(16); + + return value.length > 1 ? value : '0' + value; // Padd with leading zero + }; + + color = tinymce.trim(color); + color = color.replace(/^[#]/, '').toLowerCase(); // remove leading '#' + color = namedLookup[color] || color; + + matches = /^rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)$/.exec(color); + + if (matches) { + red = toInt(matches[1]); + green = toInt(matches[2]); + blue = toInt(matches[3]); + } else { + matches = /^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/.exec(color); + + if (matches) { + red = toInt(matches[1], 16); + green = toInt(matches[2], 16); + blue = toInt(matches[3], 16); + } else { + matches = /^([0-9a-f])([0-9a-f])([0-9a-f])$/.exec(color); + + if (matches) { + red = toInt(matches[1] + matches[1], 16); + green = toInt(matches[2] + matches[2], 16); + blue = toInt(matches[3] + matches[3], 16); + } else { + return ''; + } + } + } + + return '#' + hex(red) + hex(green) + hex(blue); +} + +function insertAction() { + var color = document.getElementById("color").value, f = tinyMCEPopup.getWindowArg('func'); + + var hexColor = toHexColor(color); + + if (hexColor === '') { + var text = tinyMCEPopup.editor.getLang('advanced_dlg.invalid_color_value'); + tinyMCEPopup.alert(text + ': ' + color); + } + else { + tinyMCEPopup.restoreSelection(); + + if (f) + f(hexColor); + + tinyMCEPopup.close(); + } +} + +function showColor(color, name) { + if (name) + document.getElementById("colorname").innerHTML = name; + + document.getElementById("preview").style.backgroundColor = color; + document.getElementById("color").value = color.toUpperCase(); +} + +function convertRGBToHex(col) { + var re = new RegExp("rgb\\s*\\(\\s*([0-9]+).*,\\s*([0-9]+).*,\\s*([0-9]+).*\\)", "gi"); + + if (!col) + return col; + + var rgb = col.replace(re, "$1,$2,$3").split(','); + if (rgb.length == 3) { + r = parseInt(rgb[0]).toString(16); + g = parseInt(rgb[1]).toString(16); + b = parseInt(rgb[2]).toString(16); + + r = r.length == 1 ? '0' + r : r; + g = g.length == 1 ? '0' + g : g; + b = b.length == 1 ? '0' + b : b; + + return "#" + r + g + b; + } + + return col; +} + +function convertHexToRGB(col) { + if (col.indexOf('#') != -1) { + col = col.replace(new RegExp('[^0-9A-F]', 'gi'), ''); + + r = parseInt(col.substring(0, 2), 16); + g = parseInt(col.substring(2, 4), 16); + b = parseInt(col.substring(4, 6), 16); + + return {r : r, g : g, b : b}; + } + + return null; +} + +function generatePicker() { + var el = document.getElementById('light'), h = '', i; + + for (i = 0; i < detail; i++){ + h += '<div id="gs'+i+'" style="background-color:#000000; width:15px; height:3px; border-style:none; border-width:0px;"' + + ' onclick="changeFinalColor(this.style.backgroundColor)"' + + ' onmousedown="isMouseDown = true; return false;"' + + ' onmouseup="isMouseDown = false;"' + + ' onmousemove="if (isMouseDown && isMouseOver) changeFinalColor(this.style.backgroundColor); return false;"' + + ' onmouseover="isMouseOver = true;"' + + ' onmouseout="isMouseOver = false;"' + + '></div>'; + } + + el.innerHTML = h; +} + +function generateWebColors() { + var el = document.getElementById('webcolors'), h = '', i; + + if (el.className == 'generated') + return; + + // TODO: VoiceOver doesn't seem to support legend as a label referenced by labelledby. + h += '<div role="listbox" aria-labelledby="webcolors_title" tabindex="0"><table role="presentation" border="0" cellspacing="1" cellpadding="0">' + + '<tr>'; + + for (i=0; i<colors.length; i++) { + h += '<td bgcolor="' + colors[i] + '" width="10" height="10">' + + '<a href="javascript:insertAction();" role="option" tabindex="-1" aria-labelledby="web_colors_' + i + '" onfocus="showColor(\'' + colors[i] + '\');" onmouseover="showColor(\'' + colors[i] + '\');" style="display:block;width:10px;height:10px;overflow:hidden;">'; + if (tinyMCEPopup.editor.forcedHighContrastMode) { + h += '<canvas class="mceColorSwatch" height="10" width="10" data-color="' + colors[i] + '"></canvas>'; + } + h += '<span class="mceVoiceLabel" style="display:none;" id="web_colors_' + i + '">' + colors[i].toUpperCase() + '</span>'; + h += '</a></td>'; + if ((i+1) % 18 == 0) + h += '</tr><tr>'; + } + + h += '</table></div>'; + + el.innerHTML = h; + el.className = 'generated'; + + paintCanvas(el); + enableKeyboardNavigation(el.firstChild); +} + +function paintCanvas(el) { + tinyMCEPopup.getWin().tinymce.each(tinyMCEPopup.dom.select('canvas.mceColorSwatch', el), function(canvas) { + var context; + if (canvas.getContext && (context = canvas.getContext("2d"))) { + context.fillStyle = canvas.getAttribute('data-color'); + context.fillRect(0, 0, 10, 10); + } + }); +} +function generateNamedColors() { + var el = document.getElementById('namedcolors'), h = '', n, v, i = 0; + + if (el.className == 'generated') + return; + + for (n in named) { + v = named[n]; + h += '<a href="javascript:insertAction();" role="option" tabindex="-1" aria-labelledby="named_colors_' + i + '" onfocus="showColor(\'' + n + '\',\'' + v + '\');" onmouseover="showColor(\'' + n + '\',\'' + v + '\');" style="background-color: ' + n + '">'; + if (tinyMCEPopup.editor.forcedHighContrastMode) { + h += '<canvas class="mceColorSwatch" height="10" width="10" data-color="' + colors[i] + '"></canvas>'; + } + h += '<span class="mceVoiceLabel" style="display:none;" id="named_colors_' + i + '">' + v + '</span>'; + h += '</a>'; + i++; + } + + el.innerHTML = h; + el.className = 'generated'; + + paintCanvas(el); + enableKeyboardNavigation(el); +} + +function enableKeyboardNavigation(el) { + tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', { + root: el, + items: tinyMCEPopup.dom.select('a', el) + }, tinyMCEPopup.dom); +} + +function dechex(n) { + return strhex.charAt(Math.floor(n / 16)) + strhex.charAt(n % 16); +} + +function computeColor(e) { + var x, y, partWidth, partDetail, imHeight, r, g, b, coef, i, finalCoef, finalR, finalG, finalB, pos = tinyMCEPopup.dom.getPos(e.target); + + x = e.offsetX ? e.offsetX : (e.target ? e.clientX - pos.x : 0); + y = e.offsetY ? e.offsetY : (e.target ? e.clientY - pos.y : 0); + + partWidth = document.getElementById('colors').width / 6; + partDetail = detail / 2; + imHeight = document.getElementById('colors').height; + + r = (x >= 0)*(x < partWidth)*255 + (x >= partWidth)*(x < 2*partWidth)*(2*255 - x * 255 / partWidth) + (x >= 4*partWidth)*(x < 5*partWidth)*(-4*255 + x * 255 / partWidth) + (x >= 5*partWidth)*(x < 6*partWidth)*255; + g = (x >= 0)*(x < partWidth)*(x * 255 / partWidth) + (x >= partWidth)*(x < 3*partWidth)*255 + (x >= 3*partWidth)*(x < 4*partWidth)*(4*255 - x * 255 / partWidth); + b = (x >= 2*partWidth)*(x < 3*partWidth)*(-2*255 + x * 255 / partWidth) + (x >= 3*partWidth)*(x < 5*partWidth)*255 + (x >= 5*partWidth)*(x < 6*partWidth)*(6*255 - x * 255 / partWidth); + + coef = (imHeight - y) / imHeight; + r = 128 + (r - 128) * coef; + g = 128 + (g - 128) * coef; + b = 128 + (b - 128) * coef; + + changeFinalColor('#' + dechex(r) + dechex(g) + dechex(b)); + updateLight(r, g, b); +} + +function updateLight(r, g, b) { + var i, partDetail = detail / 2, finalCoef, finalR, finalG, finalB, color; + + for (i=0; i<detail; i++) { + if ((i>=0) && (i<partDetail)) { + finalCoef = i / partDetail; + finalR = dechex(255 - (255 - r) * finalCoef); + finalG = dechex(255 - (255 - g) * finalCoef); + finalB = dechex(255 - (255 - b) * finalCoef); + } else { + finalCoef = 2 - i / partDetail; + finalR = dechex(r * finalCoef); + finalG = dechex(g * finalCoef); + finalB = dechex(b * finalCoef); + } + + color = finalR + finalG + finalB; + + setCol('gs' + i, '#'+color); + } +} + +function changeFinalColor(color) { + if (color.indexOf('#') == -1) + color = convertRGBToHex(color); + + setCol('preview', color); + document.getElementById('color').value = color; +} + +function setCol(e, c) { + try { + document.getElementById(e).style.backgroundColor = c; + } catch (ex) { + // Ignore IE warning + } +} + +tinyMCEPopup.onInit.add(init); diff --git a/themes/advanced/js/image.js b/themes/advanced/js/image.js index bd72e5044d7b960b60501e21f5202c3c8cb02b60..bb09e75bf5970001ac43c2988580f1526715808f 100644 --- a/themes/advanced/js/image.js +++ b/themes/advanced/js/image.js @@ -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'); @@ -229,12 +231,7 @@ var ImageDialog = { updateImageData : function() { var f = document.forms[0], t = ImageDialog; - - // Start UNL Change! - // By default, we don't want width and height specified. - return; - // End UNL Change! - + if (f.width.value == "") f.width.value = t.preloadImg.width; diff --git a/themes/advanced/js/link.js b/themes/advanced/js/link.js index 53ff409e7962f0d4f2d686922e33eff2ae53714b..8c1d73c502fbb37134946625381cbb9767d9076d 100644 --- a/themes/advanced/js/link.js +++ b/themes/advanced/js/link.js @@ -68,10 +68,16 @@ var LinkDialog = { } else { ed.dom.setAttribs(e, { href : href, - title : f.linktitle.value, - target : f.target_list ? getSelectValue(f, "target_list") : null, - 'class' : f.class_list ? getSelectValue(f, "class_list") : null + title : f.linktitle.value }); + + if (f.target_list) { + ed.dom.setAttrib(e, 'target', getSelectValue(f, "target_list")); + } + + if (f.class_list) { + ed.dom.setAttrib(e, 'class', getSelectValue(f, "class_list")); + } } // Don't move caret if selection was image diff --git a/themes/advanced/js/source_editor.js b/themes/advanced/js/source_editor.js index 84546ad52ebc461ccdebb02e1762e8c9ea760744..dd5e366fa9daf9f7556586b0756dc8cc5a74cc4a 100644 --- a/themes/advanced/js/source_editor.js +++ b/themes/advanced/js/source_editor.js @@ -16,7 +16,7 @@ function onLoadInit() { document.getElementById('htmlSource').value = tinyMCEPopup.editor.getContent({source_view : true}); if (tinyMCEPopup.editor.getParam("theme_advanced_source_editor_wrap", true)) { - setWrap('soft'); + turnWrapOn(); document.getElementById('wraped').checked = true; } @@ -37,11 +37,33 @@ function setWrap(val) { } } -function toggleWordWrap(elm) { - if (elm.checked) - setWrap('soft'); - else +function setWhiteSpaceCss(value) { + var el = document.getElementById('htmlSource'); + tinymce.DOM.setStyle(el, 'white-space', value); +} + +function turnWrapOff() { + if (tinymce.isWebKit) { + setWhiteSpaceCss('pre'); + } else { setWrap('off'); + } +} + +function turnWrapOn() { + if (tinymce.isWebKit) { + setWhiteSpaceCss('pre-wrap'); + } else { + setWrap('soft'); + } +} + +function toggleWordWrap(elm) { + if (elm.checked) { + turnWrapOn(); + } else { + turnWrapOff(); + } } function resizeInputs() { diff --git a/themes/advanced/langs/en_dlg.js b/themes/advanced/langs/en_dlg.js index 42c9a13c8524382c3891614b078e80de58af32fd..50cd87e3d0decc6a30b7791ff424d4d9152f35f3 100644 --- a/themes/advanced/langs/en_dlg.js +++ b/themes/advanced/langs/en_dlg.js @@ -1 +1 @@ -tinyMCE.addI18n('en.advanced_dlg', {"link_list":"Link List","link_is_external":"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?","link_is_email":"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?","link_titlefield":"Title","link_target_blank":"Open Link in a New Window","link_target_same":"Open Link in the Same Window","link_target":"Target","link_url":"Link URL","link_title":"Insert/Edit Link","image_align_right":"Right","image_align_left":"Left","image_align_textbottom":"Text Bottom","image_align_texttop":"Text Top","image_align_bottom":"Bottom","image_align_middle":"Middle","image_align_top":"Top","image_align_baseline":"Baseline","image_align":"Alignment","image_hspace":"Horizontal Space","image_vspace":"Vertical Space","image_dimensions":"Dimensions","image_alt":"Image Description","image_list":"Image List","image_border":"Border","image_src":"Image URL","image_title":"Insert/Edit Image","charmap_title":"Select Special Character", "charmap_usage":"Use left and right arrows to navigate.","colorpicker_name":"Name:","colorpicker_color":"Color:","colorpicker_named_title":"Named Colors","colorpicker_named_tab":"Named","colorpicker_palette_title":"Palette Colors","colorpicker_palette_tab":"Palette","colorpicker_picker_title":"Color Picker","colorpicker_picker_tab":"Picker","colorpicker_title":"Select a Color","code_wordwrap":"Word Wrap","code_title":"HTML Source Editor","anchor_name":"Anchor Name","anchor_title":"Insert/Edit Anchor","about_loaded":"Loaded Plugins","about_version":"Version","about_author":"Author","about_plugin":"Plugin","about_plugins":"Plugins","about_license":"License","about_help":"Help","about_general":"About","about_title":"About TinyMCE","anchor_invalid":"Please specify a valid anchor name.","accessibility_help":"Accessibility Help","accessibility_usage_title":"General Usage","":""}); +tinyMCE.addI18n('en.advanced_dlg', {"link_list":"Link List","link_is_external":"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?","link_is_email":"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?","link_titlefield":"Title","link_target_blank":"Open Link in a New Window","link_target_same":"Open Link in the Same Window","link_target":"Target","link_url":"Link URL","link_title":"Insert/Edit Link","image_align_right":"Right","image_align_left":"Left","image_align_textbottom":"Text Bottom","image_align_texttop":"Text Top","image_align_bottom":"Bottom","image_align_middle":"Middle","image_align_top":"Top","image_align_baseline":"Baseline","image_align":"Alignment","image_hspace":"Horizontal Space","image_vspace":"Vertical Space","image_dimensions":"Dimensions","image_alt":"Image Description","image_list":"Image List","image_border":"Border","image_src":"Image URL","image_title":"Insert/Edit Image","charmap_title":"Select Special Character", "charmap_usage":"Use left and right arrows to navigate.","colorpicker_name":"Name:","colorpicker_color":"Color:","colorpicker_named_title":"Named Colors","colorpicker_named_tab":"Named","colorpicker_palette_title":"Palette Colors","colorpicker_palette_tab":"Palette","colorpicker_picker_title":"Color Picker","colorpicker_picker_tab":"Picker","colorpicker_title":"Select a Color","code_wordwrap":"Word Wrap","code_title":"HTML Source Editor","anchor_name":"Anchor Name","anchor_title":"Insert/Edit Anchor","about_loaded":"Loaded Plugins","about_version":"Version","about_author":"Author","about_plugin":"Plugin","about_plugins":"Plugins","about_license":"License","about_help":"Help","about_general":"About","about_title":"About TinyMCE","anchor_invalid":"Please specify a valid anchor name.","accessibility_help":"Accessibility Help","accessibility_usage_title":"General Usage","invalid_color_value":"Invalid color value","":""}); diff --git a/themes/advanced/skins/default/dialog.css b/themes/advanced/skins/default/dialog.css index f01222650e03a53bac7d07907127cf5b1bdd27f6..879786fc15cbb534320d21426a839443fe84eade 100644 --- a/themes/advanced/skins/default/dialog.css +++ b/themes/advanced/skins/default/dialog.css @@ -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;} diff --git a/themes/advanced/skins/default/ui.css b/themes/advanced/skins/default/ui.css index 2b7c2a59a90aef8ed64f461f5e0fc95ae3e282a2..77083f311d0c9a6706cbebf878ad6fbbe7a4de04 100644 --- a/themes/advanced/skins/default/ui.css +++ b/themes/advanced/skins/default/ui.css @@ -83,7 +83,7 @@ .defaultSkin .mce_forecolor span.mceAction, .defaultSkin .mce_backcolor span.mceAction {overflow:hidden; height:16px} /* Menu */ -.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8} +.defaultSkin .mceMenu {position:absolute; left:0; top:0; z-index:1000; border:1px solid #D4D0C8; direction:ltr} .defaultSkin .mceNoIcons span.mceIcon {width:0;} .defaultSkin .mceNoIcons a .mceText {padding-left:10px} .defaultSkin .mceMenu table {background:#FFF} @@ -109,6 +109,10 @@ .defaultSkin .mceBlocker {position:absolute; left:0; top:0; z-index:1000; opacity:0.5; -ms-filter:'alpha(opacity=50)'; filter:alpha(opacity=50); background:#FFF} .defaultSkin .mceProgress {position:absolute; left:0; top:0; z-index:1001; background:url(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 */ .defaultSkin .mce_formatPreview a {font-size:10px} .defaultSkin .mce_p span.mceText {} @@ -212,3 +216,4 @@ .defaultSkin span.mce_pagebreak {background-position:0 -40px} .defaultSkin span.mce_restoredraft {background-position:-20px -40px} .defaultSkin span.mce_spellchecker {background-position:-540px -20px} +.defaultSkin span.mce_visualblocks {background-position: -40px -40px} diff --git a/themes/advanced/skins/highcontrast/dialog.css b/themes/advanced/skins/highcontrast/dialog.css index b2ed097cd08ddaa47d791e23b7945fd9af6e9d62..6d9fc8dd65cb18b7fdc85513fe3e7546fe3c78c4 100644 --- a/themes/advanced/skins/highcontrast/dialog.css +++ b/themes/advanced/skins/highcontrast/dialog.css @@ -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;} diff --git a/themes/advanced/skins/highcontrast/ui.css b/themes/advanced/skins/highcontrast/ui.css index a2cfcc393c08d51c29365c22e7ab4c916ddbea2f..effbbe1583678a6c2163b47eef662f731995b113 100644 --- a/themes/advanced/skins/highcontrast/ui.css +++ b/themes/advanced/skins/highcontrast/ui.css @@ -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} diff --git a/themes/advanced/skins/o2k7/dialog.css b/themes/advanced/skins/o2k7/dialog.css index ec087722481db858c53b6cf7a637988e254a76b5..a54db98df1a0b11df10d5108a06aab8ee558ad47 100644 --- a/themes/advanced/skins/o2k7/dialog.css +++ b/themes/advanced/skins/o2k7/dialog.css @@ -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;} diff --git a/themes/advanced/skins/o2k7/ui.css b/themes/advanced/skins/o2k7/ui.css index 0916c34e8339a3ac2e8eb837d073b47f66c62159..a310223719a3a8c660c82a7984c0e7b9bfe801d9 100644 --- a/themes/advanced/skins/o2k7/ui.css +++ b/themes/advanced/skins/o2k7/ui.css @@ -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 {} @@ -215,3 +219,4 @@ .o2k7Skin span.mce_pagebreak {background-position:0 -40px} .o2k7Skin span.mce_restoredraft {background-position:-20px -40px} .o2k7Skin span.mce_spellchecker {background-position:-540px -20px} +.o2k7Skin span.mce_visualblocks {background-position: -40px -40px} diff --git a/themes/advanced/source_editor.htm b/themes/advanced/source_editor.htm index 3c6d65808a854b73e184ba7ec9a67a0790e501ff..dd973fcc0517b2f6e92914c9a8da2211d356f4c4 100644 --- a/themes/advanced/source_editor.htm +++ b/themes/advanced/source_editor.htm @@ -4,7 +4,7 @@ <script type="text/javascript" src="../../tiny_mce_popup.js"></script> <script type="text/javascript" src="js/source_editor.js"></script> </head> -<body onresize="resizeInputs();" style="display:none; overflow:hidden;"> +<body onresize="resizeInputs();" style="display:none; overflow:hidden;" spellcheck="false"> <form name="source" onsubmit="saveContent();return false;" action="#"> <div style="float: left" class="title"><label for="htmlSource">{#advanced_dlg.code_title}</label></div> diff --git a/tiny_mce.js b/tiny_mce.js index 573e669636564a8d8cd63e1732166e08164da5e4..4387febff9dc7014646071052cc0fda02745ac63 100644 --- a/tiny_mce.js +++ b/tiny_mce.js @@ -1 +1 @@ -(function(d){var a=/^\s*|\s*$/g,e,c="B".replace(/A(.)|B/,"$1")==="$1";var b={majorVersion:"3",minorVersion:"4.9",releaseDate:"2012-02-23",_init:function(){var s=this,q=document,o=navigator,g=o.userAgent,m,f,l,k,j,r;s.isOpera=d.opera&&opera.buildNumber;s.isWebKit=/WebKit/.test(g);s.isIE=!s.isWebKit&&!s.isOpera&&(/MSIE/gi).test(g)&&(/Explorer/gi).test(o.appName);s.isIE6=s.isIE&&/MSIE [56]/.test(g);s.isIE7=s.isIE&&/MSIE [7]/.test(g);s.isIE8=s.isIE&&/MSIE [8]/.test(g);s.isIE9=s.isIE&&/MSIE [9]/.test(g);s.isGecko=!s.isWebKit&&/Gecko/.test(g);s.isMac=g.indexOf("Mac")!=-1;s.isAir=/adobeair/i.test(g);s.isIDevice=/(iPad|iPhone)/.test(g);s.isIOS5=s.isIDevice&&g.match(/AppleWebKit\/(\d*)/)[1]>=534;if(d.tinyMCEPreInit){s.suffix=tinyMCEPreInit.suffix;s.baseURL=tinyMCEPreInit.base;s.query=tinyMCEPreInit.query;return}s.suffix="";f=q.getElementsByTagName("base");for(m=0;m<f.length;m++){if(r=f[m].href){if(/^https?:\/\/[^\/]+$/.test(r)){r+="/"}k=r?r.match(/.*\//)[0]:""}}function h(i){if(i.src&&/tiny_mce(|_gzip|_jquery|_prototype|_full)(_dev|_src)?.js/.test(i.src)){if(/_(src|dev)\.js/g.test(i.src)){s.suffix="_src"}if((j=i.src.indexOf("?"))!=-1){s.query=i.src.substring(j+1)}s.baseURL=i.src.substring(0,i.src.lastIndexOf("/"));if(k&&s.baseURL.indexOf("://")==-1&&s.baseURL.indexOf("/")!==0){s.baseURL=k+s.baseURL}return s.baseURL}return null}f=q.getElementsByTagName("script");for(m=0;m<f.length;m++){if(h(f[m])){return}}l=q.getElementsByTagName("head")[0];if(l){f=l.getElementsByTagName("script");for(m=0;m<f.length;m++){if(h(f[m])){return}}}return},is:function(g,f){if(!f){return g!==e}if(f=="array"&&(g.hasOwnProperty&&g instanceof Array)){return true}return typeof(g)==f},makeMap:function(f,j,h){var g;f=f||[];j=j||",";if(typeof(f)=="string"){f=f.split(j)}h=h||{};g=f.length;while(g--){h[f[g]]={}}return h},each:function(i,f,h){var j,g;if(!i){return 0}h=h||i;if(i.length!==e){for(j=0,g=i.length;j<g;j++){if(f.call(h,i[j],j,i)===false){return 0}}}else{for(j in i){if(i.hasOwnProperty(j)){if(f.call(h,i[j],j,i)===false){return 0}}}}return 1},map:function(g,h){var i=[];b.each(g,function(f){i.push(h(f))});return i},grep:function(g,h){var i=[];b.each(g,function(f){if(!h||h(f)){i.push(f)}});return i},inArray:function(g,h){var j,f;if(g){for(j=0,f=g.length;j<f;j++){if(g[j]===h){return j}}}return -1},extend:function(k,j){var h,g,f=arguments;for(h=1,g=f.length;h<g;h++){j=f[h];b.each(j,function(i,l){if(i!==e){k[l]=i}})}return k},trim:function(f){return(f?""+f:"").replace(a,"")},create:function(o,f,j){var n=this,g,i,k,l,h,m=0;o=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(o);k=o[3].match(/(^|\.)(\w+)$/i)[2];i=n.createNS(o[3].replace(/\.\w+$/,""),j);if(i[k]){return}if(o[2]=="static"){i[k]=f;if(this.onCreate){this.onCreate(o[2],o[3],i[k])}return}if(!f[k]){f[k]=function(){};m=1}i[k]=f[k];n.extend(i[k].prototype,f);if(o[5]){g=n.resolve(o[5]).prototype;l=o[5].match(/\.(\w+)$/i)[1];h=i[k];if(m){i[k]=function(){return g[l].apply(this,arguments)}}else{i[k]=function(){this.parent=g[l];return h.apply(this,arguments)}}i[k].prototype[k]=i[k];n.each(g,function(p,q){i[k].prototype[q]=g[q]});n.each(f,function(p,q){if(g[q]){i[k].prototype[q]=function(){this.parent=g[q];return p.apply(this,arguments)}}else{if(q!=k){i[k].prototype[q]=p}}})}n.each(f["static"],function(p,q){i[k][q]=p});if(this.onCreate){this.onCreate(o[2],o[3],i[k].prototype)}},walk:function(i,h,j,g){g=g||this;if(i){if(j){i=i[j]}b.each(i,function(k,f){if(h.call(g,k,f,j)===false){return false}b.walk(k,h,j,g)})}},createNS:function(j,h){var g,f;h=h||d;j=j.split(".");for(g=0;g<j.length;g++){f=j[g];if(!h[f]){h[f]={}}h=h[f]}return h},resolve:function(j,h){var g,f;h=h||d;j=j.split(".");for(g=0,f=j.length;g<f;g++){h=h[j[g]];if(!h){break}}return h},addUnload:function(j,i){var h=this;j={func:j,scope:i||this};if(!h.unloads){function g(){var f=h.unloads,l,m;if(f){for(m in f){l=f[m];if(l&&l.func){l.func.call(l.scope,1)}}if(d.detachEvent){d.detachEvent("onbeforeunload",k);d.detachEvent("onunload",g)}else{if(d.removeEventListener){d.removeEventListener("unload",g,false)}}h.unloads=l=f=w=g=0;if(d.CollectGarbage){CollectGarbage()}}}function k(){var l=document;if(l.readyState=="interactive"){function f(){l.detachEvent("onstop",f);if(g){g()}l=0}if(l){l.attachEvent("onstop",f)}d.setTimeout(function(){if(l){l.detachEvent("onstop",f)}},0)}}if(d.attachEvent){d.attachEvent("onunload",g);d.attachEvent("onbeforeunload",k)}else{if(d.addEventListener){d.addEventListener("unload",g,false)}}h.unloads=[j]}else{h.unloads.push(j)}return j},removeUnload:function(i){var g=this.unloads,h=null;b.each(g,function(j,f){if(j&&j.func==i){g.splice(f,1);h=i;return false}});return h},explode:function(f,g){return f?b.map(f.split(g||","),b.trim):f},_addVer:function(g){var f;if(!this.query){return g}f=(g.indexOf("?")==-1?"?":"&")+this.query;if(g.indexOf("#")==-1){return g+f}return g.replace("#",f+"#")},_replace:function(h,f,g){if(c){return g.replace(h,function(){var l=f,j=arguments,k;for(k=0;k<j.length-2;k++){if(j[k]===e){l=l.replace(new RegExp("\\$"+k,"g"),"")}else{l=l.replace(new RegExp("\\$"+k,"g"),j[k])}}return l})}return g.replace(h,f)}};b._init();d.tinymce=d.tinyMCE=b})(window);tinymce.create("tinymce.util.Dispatcher",{scope:null,listeners:null,Dispatcher:function(a){this.scope=a||this;this.listeners=[]},add:function(a,b){this.listeners.push({cb:a,scope:b||this.scope});return a},addToTop:function(a,b){this.listeners.unshift({cb:a,scope:b||this.scope});return a},remove:function(a){var b=this.listeners,c=null;tinymce.each(b,function(e,d){if(a==e.cb){c=a;b.splice(d,1);return false}});return c},dispatch:function(){var f,d=arguments,e,b=this.listeners,g;for(e=0;e<b.length;e++){g=b[e];f=g.cb.apply(g.scope,d.length>0?d:[g.scope]);if(f===false){break}}return f}});(function(){var a=tinymce.each;tinymce.create("tinymce.util.URI",{URI:function(e,g){var f=this,i,d,c,h;e=tinymce.trim(e);g=f.settings=g||{};if(/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e)){f.source=e;return}if(e.indexOf("/")===0&&e.indexOf("//")!==0){e=(g.base_uri?g.base_uri.protocol||"http":"http")+"://mce_host"+e}if(!/^[\w-]*:?\/\//.test(e)){h=g.base_uri?g.base_uri.path:new tinymce.util.URI(location.href).directory;e=((g.base_uri&&g.base_uri.protocol)||"http")+"://mce_host"+f.toAbsPath(h,e)}e=e.replace(/@@/g,"(mce_at)");e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e);a(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(b,j){var k=e[j];if(k){k=k.replace(/\(mce_at\)/g,"@@")}f[b]=k});if(c=g.base_uri){if(!f.protocol){f.protocol=c.protocol}if(!f.userInfo){f.userInfo=c.userInfo}if(!f.port&&f.host=="mce_host"){f.port=c.port}if(!f.host||f.host=="mce_host"){f.host=c.host}f.source=""}},setPath:function(c){var b=this;c=/^(.*?)\/?(\w+)?$/.exec(c);b.path=c[0];b.directory=c[1];b.file=c[2];b.source="";b.getURI()},toRelative:function(b){var c=this,d;if(b==="./"){return b}b=new tinymce.util.URI(b,{base_uri:c});if((b.host!="mce_host"&&c.host!=b.host&&b.host)||c.port!=b.port||c.protocol!=b.protocol){return b.getURI()}d=c.toRelPath(c.path,b.path);if(b.query){d+="?"+b.query}if(b.anchor){d+="#"+b.anchor}return d},toAbsolute:function(b,c){var b=new tinymce.util.URI(b,{base_uri:this});return b.getURI(this.host==b.host&&this.protocol==b.protocol?c:0)},toRelPath:function(g,h){var c,f=0,d="",e,b;g=g.substring(0,g.lastIndexOf("/"));g=g.split("/");c=h.split("/");if(g.length>=c.length){for(e=0,b=g.length;e<b;e++){if(e>=c.length||g[e]!=c[e]){f=e+1;break}}}if(g.length<c.length){for(e=0,b=c.length;e<b;e++){if(e>=g.length||g[e]!=c[e]){f=e+1;break}}}if(f==1){return h}for(e=0,b=g.length-(f-1);e<b;e++){d+="../"}for(e=f-1,b=c.length;e<b;e++){if(e!=f-1){d+="/"+c[e]}else{d+=c[e]}}return d},toAbsPath:function(e,f){var c,b=0,h=[],d,g;d=/\/$/.test(f)?"/":"";e=e.split("/");f=f.split("/");a(e,function(i){if(i){h.push(i)}});e=h;for(c=f.length-1,h=[];c>=0;c--){if(f[c].length==0||f[c]=="."){continue}if(f[c]==".."){b++;continue}if(b>0){b--;continue}h.push(f[c])}c=e.length-b;if(c<=0){g=h.reverse().join("/")}else{g=e.slice(0,c).join("/")+"/"+h.reverse().join("/")}if(g.indexOf("/")!==0){g="/"+g}if(d&&g.lastIndexOf("/")!==g.length-1){g+=d}return g},getURI:function(d){var c,b=this;if(!b.source||d){c="";if(!d){if(b.protocol){c+=b.protocol+"://"}if(b.userInfo){c+=b.userInfo+"@"}if(b.host){c+=b.host}if(b.port){c+=":"+b.port}}if(b.path){c+=b.path}if(b.query){c+="?"+b.query}if(b.anchor){c+="#"+b.anchor}b.source=c}return b.source}})})();(function(){var a=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(d){var b=this.get(d),c;if(b){a(b.split("&"),function(e){e=e.split("=");c=c||{};c[unescape(e[0])]=unescape(e[1])})}return c},setHash:function(j,b,g,f,i,c){var h="";a(b,function(e,d){h+=(!h?"":"&")+escape(d)+"="+escape(e)});this.set(j,h,g,f,i,c)},get:function(i){var h=document.cookie,g,f=i+"=",d;if(!h){return}d=h.indexOf("; "+f);if(d==-1){d=h.indexOf(f);if(d!=0){return null}}else{d+=2}g=h.indexOf(";",d);if(g==-1){g=h.length}return unescape(h.substring(d+f.length,g))},set:function(i,b,g,f,h,c){document.cookie=i+"="+escape(b)+((g)?"; expires="+g.toGMTString():"")+((f)?"; path="+escape(f):"")+((h)?"; domain="+h:"")+((c)?"; secure":"")},remove:function(e,b){var c=new Date();c.setTime(c.getTime()-1000);this.set(e,"",c,b,c)}})})();(function(){function serialize(o,quote){var i,v,t;quote=quote||'"';if(o==null){return"null"}t=typeof o;if(t=="string"){v="\bb\tt\nn\ff\rr\"\"''\\\\";return quote+o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(a,b){if(quote==='"'&&a==="'"){return a}i=v.indexOf(b);if(i+1){return"\\"+v.charAt(i+1)}a=b.charCodeAt().toString(16);return"\\u"+"0000".substring(a.length)+a})+quote}if(t=="object"){if(o.hasOwnProperty&&o instanceof Array){for(i=0,v="[";i<o.length;i++){v+=(i>0?",":"")+serialize(o[i],quote)}return v+"]"}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):""}}return v+"}"}return""+o}tinymce.util.JSON={serialize:serialize,parse:function(s){try{return eval("("+s+")")}catch(ex){}}}})();tinymce.create("static tinymce.util.XHR",{send:function(g){var a,e,b=window,h=0;g.scope=g.scope||this;g.success_scope=g.success_scope||g.scope;g.error_scope=g.error_scope||g.scope;g.async=g.async===false?false:true;g.data=g.data||"";function d(i){a=0;try{a=new ActiveXObject(i)}catch(c){}return a}a=b.XMLHttpRequest?new XMLHttpRequest():d("Microsoft.XMLHTTP")||d("Msxml2.XMLHTTP");if(a){if(a.overrideMimeType){a.overrideMimeType(g.content_type)}a.open(g.type||(g.data?"POST":"GET"),g.url,g.async);if(g.content_type){a.setRequestHeader("Content-Type",g.content_type)}a.setRequestHeader("X-Requested-With","XMLHttpRequest");a.send(g.data);function f(){if(!g.async||a.readyState==4||h++>10000){if(g.success&&h<10000&&a.status==200){g.success.call(g.success_scope,""+a.responseText,a,g)}else{if(g.error){g.error.call(g.error_scope,h>10000?"TIMED_OUT":"GENERAL",a,g)}}a=null}else{b.setTimeout(f,10)}}if(!g.async){return f()}e=b.setTimeout(f,10)}}});(function(){var c=tinymce.extend,b=tinymce.util.JSON,a=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(d){this.settings=c({},d);this.count=0},send:function(f){var e=f.error,d=f.success;f=c(this.settings,f);f.success=function(h,g){h=b.parse(h);if(typeof(h)=="undefined"){h={error:"JSON Parse error."}}if(h.error){e.call(f.error_scope||f.scope,h.error,g)}else{d.call(f.success_scope||f.scope,h.result)}};f.error=function(h,g){if(e){e.call(f.error_scope||f.scope,h,g)}};f.data=b.serialize({id:f.id||"c"+(this.count++),method:f.method,params:f.params});f.content_type="application/json";a.send(f)},"static":{sendRPC:function(d){return new tinymce.util.JSONRequest().send(d)}}})}());(function(a){a.VK={DELETE:46,BACKSPACE:8,ENTER:13,TAB:9,SPACEBAR:32,UP:38,DOWN:40,modifierPressed:function(b){return b.shiftKey||b.ctrlKey||b.altKey}}})(tinymce);(function(l){var j=l.VK,k=j.BACKSPACE,h=j.DELETE;function c(n){var p=n.dom,o=n.selection;n.onKeyDown.add(function(r,v){var q,x,t,u,s;s=v.keyCode==h;if((s||v.keyCode==k)&&!j.modifierPressed(v)){v.preventDefault();q=o.getRng();x=p.getParent(q.startContainer,p.isBlock);if(s){x=p.getNext(x,p.isBlock)}if(x){t=x.firstChild;while(t&&t.nodeType==3&&t.nodeValue.length==0){t=t.nextSibling}if(t&&t.nodeName==="SPAN"){u=t.cloneNode(false)}}r.getDoc().execCommand(s?"ForwardDelete":"Delete",false,null);x=p.getParent(q.startContainer,p.isBlock);l.each(p.select("span.Apple-style-span,font.Apple-style-span",x),function(y){var z=o.getBookmark();if(u){p.replace(u.cloneNode(false),y,true)}else{p.remove(y,true)}o.moveToBookmark(z)})}})}function d(n){function o(r){var q=n.dom.create("body");var s=r.cloneContents();q.appendChild(s);return n.selection.serializer.serialize(q,{format:"html"})}function p(q){var s=o(q);var t=n.dom.createRng();t.selectNode(n.getBody());var r=o(t);return s===r}n.onKeyDown.addToTop(function(r,t){var s=t.keyCode;if(s==h||s==k){var q=r.selection.getRng(true);if(!q.collapsed&&p(q)){r.setContent("",{format:"raw"});r.nodeChanged();t.preventDefault()}}})}function b(n){n.dom.bind(n.getDoc(),"focusin",function(){n.selection.setRng(n.selection.getRng())})}function e(n){n.onKeyDown.add(function(o,r){if(r.keyCode===k){if(o.selection.isCollapsed()&&o.selection.getRng(true).startOffset===0){var q=o.selection.getNode();var p=q.previousSibling;if(p&&p.nodeName&&p.nodeName.toLowerCase()==="hr"){o.dom.remove(p);l.dom.Event.cancel(r)}}}})}function g(n){if(!Range.prototype.getClientRects){n.onMouseDown.add(function(p,q){if(q.target.nodeName==="HTML"){var o=p.getBody();o.blur();setTimeout(function(){o.focus()},0)}})}}function f(n){n.onClick.add(function(o,p){p=p.target;if(/^(IMG|HR)$/.test(p.nodeName)){o.selection.getSel().setBaseAndExtent(p,0,p,1)}if(p.nodeName=="A"&&o.dom.hasClass(p,"mceItemAnchor")){o.selection.select(p)}o.nodeChanged()})}function i(n){n.onKeyDown.add(function(o,p){function q(r){var s=r.selection.getNode();var t="h1,h2,h3,h4,h5,h6";return r.dom.is(s,t)||r.dom.getParent(s,t)!==null}if(p.keyCode===j.ENTER&&!j.modifierPressed(p)&&q(o)){setTimeout(function(){var r=o.selection.getNode();if(o.dom.is(r,"p")){o.dom.setAttrib(r,"style",null);o.execCommand("mceCleanup")}},0)}})}function m(n){var p,o;n.dom.bind(n.getDoc(),"selectionchange",function(){if(o){clearTimeout(o);o=0}o=window.setTimeout(function(){var q=n.selection.getRng();if(!p||!l.dom.RangeUtils.compareRanges(q,p)){n.nodeChanged();p=q}},50)})}function a(n){document.body.setAttribute("role","application")}l.create("tinymce.util.Quirks",{Quirks:function(n){if(l.isWebKit){c(n);d(n);b(n);f(n);if(l.isIDevice){m(n)}}if(l.isIE){e(n);d(n);a(n);i(n)}if(l.isGecko){e(n);g(n)}}})})(tinymce);(function(j){var a,g,d,k=/[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,b=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,f=/[<>&\"\']/g,c=/&(#x|#)?([\w]+);/g,i={128:"\u20AC",130:"\u201A",131:"\u0192",132:"\u201E",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02C6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017D",145:"\u2018",146:"\u2019",147:"\u201C",148:"\u201D",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02DC",153:"\u2122",154:"\u0161",155:"\u203A",156:"\u0153",158:"\u017E",159:"\u0178"};g={'"':""","'":"'","<":"<",">":">","&":"&"};d={"<":"<",">":">","&":"&",""":'"',"'":"'"};function h(l){var m;m=document.createElement("div");m.innerHTML=l;return m.textContent||m.innerText||l}function e(m,p){var n,o,l,q={};if(m){m=m.split(",");p=p||10;for(n=0;n<m.length;n+=2){o=String.fromCharCode(parseInt(m[n],p));if(!g[o]){l="&"+m[n+1]+";";q[o]=l;q[l]=o}}return q}}a=e("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,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);j.html=j.html||{};j.html.Entities={encodeRaw:function(m,l){return m.replace(l?k:b,function(n){return g[n]||n})},encodeAllRaw:function(l){return(""+l).replace(f,function(m){return g[m]||m})},encodeNumeric:function(m,l){return m.replace(l?k:b,function(n){if(n.length>1){return"&#"+(((n.charCodeAt(0)-55296)*1024)+(n.charCodeAt(1)-56320)+65536)+";"}return g[n]||"&#"+n.charCodeAt(0)+";"})},encodeNamed:function(n,l,m){m=m||a;return n.replace(l?k:b,function(o){return g[o]||m[o]||o})},getEncodeFunc:function(l,o){var p=j.html.Entities;o=e(o)||a;function m(r,q){return r.replace(q?k:b,function(s){return g[s]||o[s]||"&#"+s.charCodeAt(0)+";"||s})}function n(r,q){return p.encodeNamed(r,q,o)}l=j.makeMap(l.replace(/\+/g,","));if(l.named&&l.numeric){return m}if(l.named){if(o){return n}return p.encodeNamed}if(l.numeric){return p.encodeNumeric}return p.encodeRaw},decode:function(l){return l.replace(c,function(n,m,o){if(m){o=parseInt(o,m.length===2?16:10);if(o>65535){o-=65536;return String.fromCharCode(55296+(o>>10),56320+(o&1023))}else{return i[o]||String.fromCharCode(o)}}return d[n]||a[n]||h(n)})}}})(tinymce);tinymce.html.Styles=function(d,f){var k=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,h=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,b=/\s*([^:]+):\s*([^;]+);?/g,l=/\s+$/,m=/rgb/,e,g,a={},j;d=d||{};j="\\\" \\' \\; \\: ; : \uFEFF".split(" ");for(g=0;g<j.length;g++){a[j[g]]="\uFEFF"+g;a["\uFEFF"+g]=j[g]}function c(n,q,p,i){function o(r){r=parseInt(r).toString(16);return r.length>1?r:"0"+r}return"#"+o(q)+o(p)+o(i)}return{toHex:function(i){return i.replace(k,c)},parse:function(r){var y={},p,n,v,q,u=d.url_converter,x=d.url_converter_scope||this;function o(C,F){var E,B,A,D;E=y[C+"-top"+F];if(!E){return}B=y[C+"-right"+F];if(E!=B){return}A=y[C+"-bottom"+F];if(B!=A){return}D=y[C+"-left"+F];if(A!=D){return}y[C+F]=D;delete y[C+"-top"+F];delete y[C+"-right"+F];delete y[C+"-bottom"+F];delete y[C+"-left"+F]}function t(B){var C=y[B],A;if(!C||C.indexOf(" ")<0){return}C=C.split(" ");A=C.length;while(A--){if(C[A]!==C[0]){return false}}y[B]=C[0];return true}function z(C,B,A,D){if(!t(B)){return}if(!t(A)){return}if(!t(D)){return}y[C]=y[B]+" "+y[A]+" "+y[D];delete y[B];delete y[A];delete y[D]}function s(A){q=true;return a[A]}function i(B,A){if(q){B=B.replace(/\uFEFF[0-9]/g,function(C){return a[C]})}if(!A){B=B.replace(/\\([\'\";:])/g,"$1")}return B}if(r){r=r.replace(/\\[\"\';:\uFEFF]/g,s).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(A){return A.replace(/[;:]/g,s)});while(p=b.exec(r)){n=p[1].replace(l,"").toLowerCase();v=p[2].replace(l,"");if(n&&v.length>0){if(n==="font-weight"&&v==="700"){v="bold"}else{if(n==="color"||n==="background-color"){v=v.toLowerCase()}}v=v.replace(k,c);v=v.replace(h,function(B,A,E,D,F,C){F=F||C;if(F){F=i(F);return"'"+F.replace(/\'/g,"\\'")+"'"}A=i(A||E||D);if(u){A=u.call(x,A,"style")}return"url('"+A.replace(/\'/g,"\\'")+"')"});y[n]=q?i(v,true):v}b.lastIndex=p.index+p[0].length}o("border","");o("border","-width");o("border","-color");o("border","-style");o("padding","");o("margin","");z("border","border-width","border-style","border-color");if(y.border==="medium none"){delete y.border}}return y},serialize:function(p,r){var o="",n,q;function i(t){var x,u,s,v;x=f.styles[t];if(x){for(u=0,s=x.length;u<s;u++){t=x[u];v=p[t];if(v!==e&&v.length>0){o+=(o.length>0?" ":"")+t+": "+v+";"}}}}if(r&&f&&f.styles){i("*");i(r)}else{for(n in p){q=p[n];if(q!==e&&q.length>0){o+=(o.length>0?" ":"")+n+": "+q+";"}}}return o}}};(function(m){var h={},j,l,g,f,c={},b,e,d=m.makeMap,k=m.each;function i(o,n){return o.split(n||",")}function a(r,q){var o,p={};function n(s){return s.replace(/[A-Z]+/g,function(t){return n(r[t])})}for(o in r){if(r.hasOwnProperty(o)){r[o]=n(r[o])}}n(q).replace(/#/g,"#text").replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g,function(v,t,s,u){s=i(s,"|");p[t]={attributes:d(s),attributesOrder:s,children:d(u,"|",{"#comment":{}})}});return p}l="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";l=d(l,",",d(l.toUpperCase()));h=a({Z:"H|K|N|O|P",Y:"X|form|R|Q",ZG:"E|span|width|align|char|charoff|valign",X:"p|T|div|U|W|isindex|fieldset|table",ZF:"E|align|char|charoff|valign",W:"pre|hr|blockquote|address|center|noframes",ZE:"abbr|axis|headers|scope|rowspan|colspan|align|char|charoff|valign|nowrap|bgcolor|width|height",ZD:"[E][S]",U:"ul|ol|dl|menu|dir",ZC:"p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q",T:"h1|h2|h3|h4|h5|h6",ZB:"X|S|Q",S:"R|P",ZA:"a|G|J|M|O|P",R:"a|H|K|N|O",Q:"noscript|P",P:"ins|del|script",O:"input|select|textarea|label|button",N:"M|L",M:"em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym",L:"sub|sup",K:"J|I",J:"tt|i|b|u|s|strike",I:"big|small|font|basefont",H:"G|F",G:"br|span|bdo",F:"object|applet|img|map|iframe",E:"A|B|C",D:"accesskey|tabindex|onfocus|onblur",C:"onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup",B:"lang|xml:lang|dir",A:"id|class|style|title"},"script[id|charset|type|language|src|defer|xml:space][]style[B|id|type|media|title|xml:space][]object[E|declare|classid|codebase|data|type|codetype|archive|standby|width|height|usemap|name|tabindex|align|border|hspace|vspace][#|param|Y]param[id|name|value|valuetype|type][]p[E|align][#|S]a[E|D|charset|type|name|href|hreflang|rel|rev|shape|coords|target][#|Z]br[A|clear][]span[E][#|S]bdo[A|C|B][#|S]applet[A|codebase|archive|code|object|alt|name|width|height|align|hspace|vspace][#|param|Y]h1[E|align][#|S]img[E|src|alt|name|longdesc|width|height|usemap|ismap|align|border|hspace|vspace][]map[B|C|A|name][X|form|Q|area]h2[E|align][#|S]iframe[A|longdesc|name|src|frameborder|marginwidth|marginheight|scrolling|align|width|height][#|Y]h3[E|align][#|S]tt[E][#|S]i[E][#|S]b[E][#|S]u[E][#|S]s[E][#|S]strike[E][#|S]big[E][#|S]small[E][#|S]font[A|B|size|color|face][#|S]basefont[id|size|color|face][]em[E][#|S]strong[E][#|S]dfn[E][#|S]code[E][#|S]q[E|cite][#|S]samp[E][#|S]kbd[E][#|S]var[E][#|S]cite[E][#|S]abbr[E][#|S]acronym[E][#|S]sub[E][#|S]sup[E][#|S]input[E|D|type|name|value|checked|disabled|readonly|size|maxlength|src|alt|usemap|onselect|onchange|accept|align][]select[E|name|size|multiple|disabled|tabindex|onfocus|onblur|onchange][optgroup|option]optgroup[E|disabled|label][option]option[E|selected|disabled|label|value][]textarea[E|D|name|rows|cols|disabled|readonly|onselect|onchange][]label[E|for|accesskey|onfocus|onblur][#|S]button[E|D|name|value|type|disabled][#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]h4[E|align][#|S]ins[E|cite|datetime][#|Y]h5[E|align][#|S]del[E|cite|datetime][#|Y]h6[E|align][#|S]div[E|align][#|Y]ul[E|type|compact][li]li[E|type|value][#|Y]ol[E|type|compact|start][li]dl[E|compact][dt|dd]dt[E][#|S]dd[E][#|Y]menu[E|compact][li]dir[E|compact][li]pre[E|width|xml:space][#|ZA]hr[E|align|noshade|size|width][]blockquote[E|cite][#|Y]address[E][#|S|p]center[E][#|Y]noframes[E][#|Y]isindex[A|B|prompt][]fieldset[E][#|legend|Y]legend[E|accesskey|align][#|S]table[E|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor][caption|col|colgroup|thead|tfoot|tbody|tr]caption[E|align][#|S]col[ZG][]colgroup[ZG][col]thead[ZF][tr]tr[ZF|bgcolor][th|td]th[E|ZE][#|Y]form[E|action|method|name|enctype|onsubmit|onreset|accept|accept-charset|target][#|X|R|Q]noscript[E][#|Y]td[E|ZE][#|Y]tfoot[ZF][tr]tbody[ZF][tr]area[E|D|shape|coords|href|nohref|alt|target][]base[id|href|target][]body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]");j=d("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,autoplay,loop,controls");g=d("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source");f=m.extend(d("td,th,iframe,video,audio,object"),g);b=d("pre,script,style,textarea");e=d("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");m.html.Schema=function(r){var A=this,n={},o={},y=[],q,p;r=r||{};if(r.verify_html===false){r.valid_elements="*[*]"}if(r.valid_styles){q={};k(r.valid_styles,function(C,B){q[B]=m.explode(C)})}p=r.whitespace_elements?d(r.whitespace_elements):b;function z(B){return new RegExp("^"+B.replace(/([?+*])/g,".$1")+"$")}function t(I){var H,D,W,S,X,C,F,R,U,N,V,Z,L,G,T,B,P,E,Y,aa,M,Q,K=/^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,O=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,J=/[*?+]/;if(I){I=i(I);if(n["@"]){P=n["@"].attributes;E=n["@"].attributesOrder}for(H=0,D=I.length;H<D;H++){C=K.exec(I[H]);if(C){T=C[1];N=C[2];B=C[3];U=C[4];L={};G=[];F={attributes:L,attributesOrder:G};if(T==="#"){F.paddEmpty=true}if(T==="-"){F.removeEmpty=true}if(P){for(aa in P){L[aa]=P[aa]}G.push.apply(G,E)}if(U){U=i(U,"|");for(W=0,S=U.length;W<S;W++){C=O.exec(U[W]);if(C){R={};Z=C[1];V=C[2].replace(/::/g,":");T=C[3];Q=C[4];if(Z==="!"){F.attributesRequired=F.attributesRequired||[];F.attributesRequired.push(V);R.required=true}if(Z==="-"){delete L[V];G.splice(m.inArray(G,V),1);continue}if(T){if(T==="="){F.attributesDefault=F.attributesDefault||[];F.attributesDefault.push({name:V,value:Q});R.defaultValue=Q}if(T===":"){F.attributesForced=F.attributesForced||[];F.attributesForced.push({name:V,value:Q});R.forcedValue=Q}if(T==="<"){R.validValues=d(Q,"?")}}if(J.test(V)){F.attributePatterns=F.attributePatterns||[];R.pattern=z(V);F.attributePatterns.push(R)}else{if(!L[V]){G.push(V)}L[V]=R}}}}if(!P&&N=="@"){P=L;E=G}if(B){F.outputName=N;n[B]=F}if(J.test(N)){F.pattern=z(N);y.push(F)}else{n[N]=F}}}}}function v(B){n={};y=[];t(B);k(h,function(D,C){o[C]=D.children})}function s(C){var B=/^(~)?(.+)$/;if(C){k(i(C),function(G){var E=B.exec(G),F=E[1]==="~",H=F?"span":"div",D=E[2];o[D]=o[H];c[D]=H;if(!F){l[D]={}}k(o,function(I,J){if(I[H]){I[D]=I[H]}})})}}function u(C){var B=/^([+\-]?)(\w+)\[([^\]]+)\]$/;if(C){k(i(C),function(G){var F=B.exec(G),D,E;if(F){E=F[1];if(E){D=o[F[2]]}else{D=o[F[2]]={"#comment":{}}}D=o[F[2]];k(i(F[3],"|"),function(H){if(E==="-"){delete D[H]}else{D[H]={}}})}})}}function x(B){var D=n[B],C;if(D){return D}C=y.length;while(C--){D=y[C];if(D.pattern.test(B)){return D}}}if(!r.valid_elements){k(h,function(C,B){n[B]={attributes:C.attributes,attributesOrder:C.attributesOrder};o[B]=C.children});k(i("strong/b,em/i"),function(B){B=i(B,"/");n[B[1]].outputName=B[0]});n.img.attributesDefault=[{name:"alt",value:""}];k(i("ol,ul,sub,sup,blockquote,span,font,a,table,tbody,tr"),function(B){n[B].removeEmpty=true});k(i("p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption"),function(B){n[B].paddEmpty=true})}else{v(r.valid_elements)}s(r.custom_elements);u(r.valid_children);t(r.extended_valid_elements);u("+ol[ul|ol],+ul[ul|ol]");if(!x("span")){t("span[!data-mce-type|*]")}if(r.invalid_elements){m.each(m.explode(r.invalid_elements),function(B){if(n[B]){delete n[B]}})}A.children=o;A.styles=q;A.getBoolAttrs=function(){return j};A.getBlockElements=function(){return l};A.getShortEndedElements=function(){return g};A.getSelfClosingElements=function(){return e};A.getNonEmptyElements=function(){return f};A.getWhiteSpaceElements=function(){return p};A.isValidChild=function(B,D){var C=o[B];return !!(C&&C[D])};A.getElementRule=x;A.getCustomElements=function(){return c};A.addValidElements=t;A.setValidElements=v;A.addCustomElements=s;A.addValidChildren=u};m.html.Schema.boolAttrMap=j;m.html.Schema.blockElementsMap=l})(tinymce);(function(a){a.html.SaxParser=function(c,e){var b=this,d=function(){};c=c||{};b.schema=e=e||new a.html.Schema();if(c.fix_self_closing!==false){c.fix_self_closing=true}a.each("comment cdata text start end pi doctype".split(" "),function(f){if(f){b[f]=c[f]||d}});b.parse=function(D){var n=this,g,F=0,H,A,z=[],M,P,B,q,y,r,L,G,N,u,m,k,s,Q,o,O,E,R,K,f,I,l,C,J,h,v=0,j=a.html.Entities.decode,x,p;function t(S){var U,T;U=z.length;while(U--){if(z[U].name===S){break}}if(U>=0){for(T=z.length-1;T>=U;T--){S=z[T];if(S.valid){n.end(S.name)}}z.length=U}}l=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([^\\s\\/<>]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/)>))","g");C=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;J={script:/<\/script[^>]*>/gi,style:/<\/style[^>]*>/gi,noscript:/<\/noscript[^>]*>/gi};L=e.getShortEndedElements();I=e.getSelfClosingElements();G=e.getBoolAttrs();u=c.validate;r=c.remove_internals;x=c.fix_self_closing;p=a.isIE;o=/^:/;while(g=l.exec(D)){if(F<g.index){n.text(j(D.substr(F,g.index-F)))}if(H=g[6]){H=H.toLowerCase();if(p&&o.test(H)){H=H.substr(1)}t(H)}else{if(H=g[7]){H=H.toLowerCase();if(p&&o.test(H)){H=H.substr(1)}N=H in L;if(x&&I[H]&&z.length>0&&z[z.length-1].name===H){t(H)}if(!u||(m=e.getElementRule(H))){k=true;if(u){O=m.attributes;E=m.attributePatterns}if(Q=g[8]){y=Q.indexOf("data-mce-type")!==-1;if(y&&r){k=false}M=[];M.map={};Q.replace(C,function(T,S,X,W,V){var Y,U;S=S.toLowerCase();X=S in G?S:j(X||W||V||"");if(u&&!y&&S.indexOf("data-")!==0){Y=O[S];if(!Y&&E){U=E.length;while(U--){Y=E[U];if(Y.pattern.test(S)){break}}if(U===-1){Y=null}}if(!Y){return}if(Y.validValues&&!(X in Y.validValues)){return}}M.map[S]=X;M.push({name:S,value:X})})}else{M=[];M.map={}}if(u&&!y){R=m.attributesRequired;K=m.attributesDefault;f=m.attributesForced;if(f){P=f.length;while(P--){s=f[P];q=s.name;h=s.value;if(h==="{$uid}"){h="mce_"+v++}M.map[q]=h;M.push({name:q,value:h})}}if(K){P=K.length;while(P--){s=K[P];q=s.name;if(!(q in M.map)){h=s.value;if(h==="{$uid}"){h="mce_"+v++}M.map[q]=h;M.push({name:q,value:h})}}}if(R){P=R.length;while(P--){if(R[P] in M.map){break}}if(P===-1){k=false}}if(M.map["data-mce-bogus"]){k=false}}if(k){n.start(H,M,N)}}else{k=false}if(A=J[H]){A.lastIndex=F=g.index+g[0].length;if(g=A.exec(D)){if(k){B=D.substr(F,g.index-F)}F=g.index+g[0].length}else{B=D.substr(F);F=D.length}if(k&&B.length>0){n.text(B,true)}if(k){n.end(H)}l.lastIndex=F;continue}if(!N){if(!Q||Q.indexOf("/")!=Q.length-1){z.push({name:H,valid:k})}else{if(k){n.end(H)}}}}else{if(H=g[1]){n.comment(H)}else{if(H=g[2]){n.cdata(H)}else{if(H=g[3]){n.doctype(H)}else{if(H=g[4]){n.pi(H,g[5])}}}}}}F=g.index+g[0].length}if(F<D.length){n.text(j(D.substr(F)))}for(P=z.length-1;P>=0;P--){H=z[P];if(H.valid){n.end(H.name)}}}}})(tinymce);(function(d){var c=/^[ \t\r\n]*$/,e={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};function a(k,l,j){var i,h,f=j?"lastChild":"firstChild",g=j?"prev":"next";if(k[f]){return k[f]}if(k!==l){i=k[g];if(i){return i}for(h=k.parent;h&&h!==l;h=h.parent){i=h[g];if(i){return i}}}}function b(f,g){this.name=f;this.type=g;if(g===1){this.attributes=[];this.attributes.map={}}}d.extend(b.prototype,{replace:function(g){var f=this;if(g.parent){g.remove()}f.insert(g,f);f.remove();return f},attr:function(h,l){var f=this,g,j,k;if(typeof h!=="string"){for(j in h){f.attr(j,h[j])}return f}if(g=f.attributes){if(l!==k){if(l===null){if(h in g.map){delete g.map[h];j=g.length;while(j--){if(g[j].name===h){g=g.splice(j,1);return f}}}return f}if(h in g.map){j=g.length;while(j--){if(g[j].name===h){g[j].value=l;break}}}else{g.push({name:h,value:l})}g.map[h]=l;return f}else{return g.map[h]}}},clone:function(){var g=this,n=new b(g.name,g.type),h,f,m,j,k;if(m=g.attributes){k=[];k.map={};for(h=0,f=m.length;h<f;h++){j=m[h];if(j.name!=="id"){k[k.length]={name:j.name,value:j.value};k.map[j.name]=j.value}}n.attributes=k}n.value=g.value;n.shortEnded=g.shortEnded;return n},wrap:function(g){var f=this;f.parent.insert(g,f);g.append(f);return f},unwrap:function(){var f=this,h,g;for(h=f.firstChild;h;){g=h.next;f.insert(h,f,true);h=g}f.remove()},remove:function(){var f=this,h=f.parent,g=f.next,i=f.prev;if(h){if(h.firstChild===f){h.firstChild=g;if(g){g.prev=null}}else{i.next=g}if(h.lastChild===f){h.lastChild=i;if(i){i.next=null}}else{g.prev=i}f.parent=f.next=f.prev=null}return f},append:function(h){var f=this,g;if(h.parent){h.remove()}g=f.lastChild;if(g){g.next=h;h.prev=g;f.lastChild=h}else{f.lastChild=f.firstChild=h}h.parent=f;return h},insert:function(h,f,i){var g;if(h.parent){h.remove()}g=f.parent||this;if(i){if(f===g.firstChild){g.firstChild=h}else{f.prev.next=h}h.prev=f.prev;h.next=f;f.prev=h}else{if(f===g.lastChild){g.lastChild=h}else{f.next.prev=h}h.next=f.next;h.prev=f;f.next=h}h.parent=g;return h},getAll:function(g){var f=this,h,i=[];for(h=f.firstChild;h;h=a(h,f)){if(h.name===g){i.push(h)}}return i},empty:function(){var g=this,f,h,j;if(g.firstChild){f=[];for(j=g.firstChild;j;j=a(j,g)){f.push(j)}h=f.length;while(h--){j=f[h];j.parent=j.firstChild=j.lastChild=j.next=j.prev=null}}g.firstChild=g.lastChild=null;return g},isEmpty:function(k){var f=this,j=f.firstChild,h,g;if(j){do{if(j.type===1){if(j.attributes.map["data-mce-bogus"]){continue}if(k[j.name]){return false}h=j.attributes.length;while(h--){g=j.attributes[h].name;if(g==="name"||g.indexOf("data-")===0){return false}}}if(j.type===8){return false}if((j.type===3&&!c.test(j.value))){return false}}while(j=a(j,f))}return true},walk:function(f){return a(this,null,f)}});d.extend(b,{create:function(g,f){var i,h;i=new b(g,e[g]||1);if(f){for(h in f){i.attr(h,f[h])}}return i}});d.html.Node=b})(tinymce);(function(b){var a=b.html.Node;b.html.DomParser=function(g,h){var f=this,e={},d=[],i={},c={};g=g||{};g.validate="validate" in g?g.validate:true;g.root_name=g.root_name||"body";f.schema=h=h||new b.html.Schema();function j(m){var o,p,x,v,z,n,q,l,t,u,k,s,y,r;s=b.makeMap("tr,td,th,tbody,thead,tfoot,table");k=h.getNonEmptyElements();for(o=0;o<m.length;o++){p=m[o];if(!p.parent){continue}v=[p];for(x=p.parent;x&&!h.isValidChild(x.name,p.name)&&!s[x.name];x=x.parent){v.push(x)}if(x&&v.length>1){v.reverse();z=n=f.filterNode(v[0].clone());for(t=0;t<v.length-1;t++){if(h.isValidChild(n.name,v[t].name)){q=f.filterNode(v[t].clone());n.append(q)}else{q=n}for(l=v[t].firstChild;l&&l!=v[t+1];){r=l.next;q.append(l);l=r}n=q}if(!z.isEmpty(k)){x.insert(z,v[0],true);x.insert(p,z)}else{x.insert(p,v[0],true)}x=v[0];if(x.isEmpty(k)||x.firstChild===x.lastChild&&x.firstChild.name==="br"){x.empty().remove()}}else{if(p.parent){if(p.name==="li"){y=p.prev;if(y&&(y.name==="ul"||y.name==="ul")){y.append(p);continue}y=p.next;if(y&&(y.name==="ul"||y.name==="ul")){y.insert(p,y.firstChild,true);continue}p.wrap(f.filterNode(new a("ul",1)));continue}if(h.isValidChild(p.parent.name,"div")&&h.isValidChild("div",p.name)){p.wrap(f.filterNode(new a("div",1)))}else{if(p.name==="style"||p.name==="script"){p.empty().remove()}else{p.unwrap()}}}}}}f.filterNode=function(m){var l,k,n;if(k in e){n=i[k];if(n){n.push(m)}else{i[k]=[m]}}l=d.length;while(l--){k=d[l].name;if(k in m.attributes.map){n=c[k];if(n){n.push(m)}else{c[k]=[m]}}}return m};f.addNodeFilter=function(k,l){b.each(b.explode(k),function(m){var n=e[m];if(!n){e[m]=n=[]}n.push(l)})};f.addAttributeFilter=function(k,l){b.each(b.explode(k),function(m){var n;for(n=0;n<d.length;n++){if(d[n].name===m){d[n].callbacks.push(l);return}}d.push({name:m,callbacks:[l]})})};f.parse=function(v,m){var n,H,A,z,C,B,x,r,E,K,y,o,D,J=[],t,k,s,p,u,q;m=m||{};i={};c={};o=b.extend(b.makeMap("script,style,head,html,body,title,meta,param"),h.getBlockElements());u=h.getNonEmptyElements();p=h.children;y=g.validate;q="forced_root_block" in m?m.forced_root_block:g.forced_root_block;s=h.getWhiteSpaceElements();D=/^[ \t\r\n]+/;t=/[ \t\r\n]+$/;k=/[ \t\r\n]+/g;function F(){var L=H.firstChild,l,M;while(L){l=L.next;if(L.type==3||(L.type==1&&L.name!=="p"&&!o[L.name]&&!L.attr("data-mce-type"))){if(!M){M=I(q,1);H.insert(M,L);M.append(L)}else{M.append(L)}}else{M=null}L=l}}function I(l,L){var M=new a(l,L),N;if(l in e){N=i[l];if(N){N.push(M)}else{i[l]=[M]}}return M}function G(M){var N,l,L;for(N=M.prev;N&&N.type===3;){l=N.value.replace(t,"");if(l.length>0){N.value=l;N=N.prev}else{L=N.prev;N.remove();N=L}}}n=new b.html.SaxParser({validate:y,fix_self_closing:!y,cdata:function(l){A.append(I("#cdata",4)).value=l},text:function(M,l){var L;if(!s[A.name]){M=M.replace(k," ");if(A.lastChild&&o[A.lastChild.name]){M=M.replace(D,"")}}if(M.length!==0){L=I("#text",3);L.raw=!!l;A.append(L).value=M}},comment:function(l){A.append(I("#comment",8)).value=l},pi:function(l,L){A.append(I(l,7)).value=L;G(A)},doctype:function(L){var l;l=A.append(I("#doctype",10));l.value=L;G(A)},start:function(l,T,M){var R,O,N,L,P,U,S,Q;N=y?h.getElementRule(l):{};if(N){R=I(N.outputName||l,1);R.attributes=T;R.shortEnded=M;A.append(R);Q=p[A.name];if(Q&&p[R.name]&&!Q[R.name]){J.push(R)}O=d.length;while(O--){P=d[O].name;if(P in T.map){E=c[P];if(E){E.push(R)}else{c[P]=[R]}}}if(o[l]){G(R)}if(!M){A=R}}},end:function(l){var P,M,O,L,N;M=y?h.getElementRule(l):{};if(M){if(o[l]){if(!s[A.name]){for(P=A.firstChild;P&&P.type===3;){O=P.value.replace(D,"");if(O.length>0){P.value=O;P=P.next}else{L=P.next;P.remove();P=L}}for(P=A.lastChild;P&&P.type===3;){O=P.value.replace(t,"");if(O.length>0){P.value=O;P=P.prev}else{L=P.prev;P.remove();P=L}}}P=A.prev;if(P&&P.type===3){O=P.value.replace(D,"");if(O.length>0){P.value=O}else{P.remove()}}}if(M.removeEmpty||M.paddEmpty){if(A.isEmpty(u)){if(M.paddEmpty){A.empty().append(new a("#text","3")).value="\u00a0"}else{if(!A.attributes.map.name){N=A.parent;A.empty().remove();A=N;return}}}}A=A.parent}}},h);H=A=new a(m.context||g.root_name,11);n.parse(v);if(y&&J.length){if(!m.context){j(J)}else{m.invalid=true}}if(q&&H.name=="body"){F()}if(!m.invalid){for(K in i){E=e[K];z=i[K];x=z.length;while(x--){if(!z[x].parent){z.splice(x,1)}}for(C=0,B=E.length;C<B;C++){E[C](z,K,m)}}for(C=0,B=d.length;C<B;C++){E=d[C];if(E.name in c){z=c[E.name];x=z.length;while(x--){if(!z[x].parent){z.splice(x,1)}}for(x=0,r=E.callbacks.length;x<r;x++){E.callbacks[x](z,E.name,m)}}}}return H};if(g.remove_trailing_brs){f.addNodeFilter("br",function(n,m){var r,q=n.length,o,u=h.getBlockElements(),k=h.getNonEmptyElements(),s,p,t;u.body=1;for(r=0;r<q;r++){o=n[r];s=o.parent;if(u[o.parent.name]&&o===s.lastChild){p=o.prev;while(p){t=p.name;if(t!=="span"||p.attr("data-mce-type")!=="bookmark"){if(t!=="br"){break}if(t==="br"){o=null;break}}p=p.prev}if(o){o.remove();if(s.isEmpty(k)){elementRule=h.getElementRule(s.name);if(elementRule){if(elementRule.removeEmpty){s.remove()}else{if(elementRule.paddEmpty){s.empty().append(new b.html.Node("#text",3)).value="\u00a0"}}}}}}}})}}})(tinymce);tinymce.html.Writer=function(e){var c=[],a,b,d,f,g;e=e||{};a=e.indent;b=tinymce.makeMap(e.indent_before||"");d=tinymce.makeMap(e.indent_after||"");f=tinymce.html.Entities.getEncodeFunc(e.entity_encoding||"raw",e.entities);g=e.element_format=="html";return{start:function(m,k,p){var n,j,h,o;if(a&&b[m]&&c.length>0){o=c[c.length-1];if(o.length>0&&o!=="\n"){c.push("\n")}}c.push("<",m);if(k){for(n=0,j=k.length;n<j;n++){h=k[n];c.push(" ",h.name,'="',f(h.value,true),'"')}}if(!p||g){c[c.length]=">"}else{c[c.length]=" />"}if(p&&a&&d[m]&&c.length>0){o=c[c.length-1];if(o.length>0&&o!=="\n"){c.push("\n")}}},end:function(h){var i;c.push("</",h,">");if(a&&d[h]&&c.length>0){i=c[c.length-1];if(i.length>0&&i!=="\n"){c.push("\n")}}},text:function(i,h){if(i.length>0){c[c.length]=h?i:f(i)}},cdata:function(h){c.push("<![CDATA[",h,"]]>")},comment:function(h){c.push("<!--",h,"-->")},pi:function(h,i){if(i){c.push("<?",h," ",i,"?>")}else{c.push("<?",h,"?>")}if(a){c.push("\n")}},doctype:function(h){c.push("<!DOCTYPE",h,">",a?"\n":"")},reset:function(){c.length=0},getContent:function(){return c.join("").replace(/\n$/,"")}}};(function(a){a.html.Serializer=function(c,d){var b=this,e=new a.html.Writer(c);c=c||{};c.validate="validate" in c?c.validate:true;b.schema=d=d||new a.html.Schema();b.writer=e;b.serialize=function(h){var g,i;i=c.validate;g={3:function(k,j){e.text(k.value,k.raw)},8:function(j){e.comment(j.value)},7:function(j){e.pi(j.name,j.value)},10:function(j){e.doctype(j.value)},4:function(j){e.cdata(j.value)},11:function(j){if((j=j.firstChild)){do{f(j)}while(j=j.next)}}};e.reset();function f(k){var t=g[k.type],j,o,s,r,p,u,n,m,q;if(!t){j=k.name;o=k.shortEnded;s=k.attributes;if(i&&s&&s.length>1){u=[];u.map={};q=d.getElementRule(k.name);for(n=0,m=q.attributesOrder.length;n<m;n++){r=q.attributesOrder[n];if(r in s.map){p=s.map[r];u.map[r]=p;u.push({name:r,value:p})}}for(n=0,m=s.length;n<m;n++){r=s[n].name;if(!(r in u.map)){p=s.map[r];u.map[r]=p;u.push({name:r,value:p})}}s=u}e.start(k.name,s,o);if(!o){if((k=k.firstChild)){do{f(k)}while(k=k.next)}e.end(j)}}else{t(k)}}if(h.type==1&&!c.inner){f(h)}else{g[11](h)}return e.getContent()}}})(tinymce);(function(h){var f=h.each,e=h.is,d=h.isWebKit,b=h.isIE,c=h.html.Entities,a=/^([a-z0-9],?)+$/i,g=h.html.Schema.blockElementsMap,i=/^[ \t\r\n]*$/;h.create("tinymce.dom.DOMUtils",{doc:null,root:null,files:null,pixelStyles:/^(top|left|bottom|right|width|height|borderWidth)$/,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},DOMUtils:function(o,m){var l=this,j,k;l.doc=o;l.win=window;l.files={};l.cssFlicker=false;l.counter=0;l.stdMode=!h.isIE||o.documentMode>=8;l.boxModel=!h.isIE||o.compatMode=="CSS1Compat"||l.stdMode;l.hasOuterHTML="outerHTML" in o.createElement("a");l.settings=m=h.extend({keep_values:false,hex_colors:1},m);l.schema=m.schema;l.styles=new h.html.Styles({url_converter:m.url_converter,url_converter_scope:m.url_converter_scope},m.schema);if(h.isIE6){try{o.execCommand("BackgroundImageCache",false,true)}catch(n){l.cssFlicker=true}}if(b&&m.schema){("abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video").replace(/\w+/g,function(p){o.createElement(p)});for(k in m.schema.getCustomElements()){o.createElement(k)}}h.addUnload(l.destroy,l)},getRoot:function(){var j=this,k=j.settings;return(k&&j.get(k.root_element))||j.doc.body},getViewPort:function(k){var l,j;k=!k?this.win:k;l=k.document;j=this.boxModel?l.documentElement:l.body;return{x:k.pageXOffset||j.scrollLeft,y:k.pageYOffset||j.scrollTop,w:k.innerWidth||j.clientWidth,h:k.innerHeight||j.clientHeight}},getRect:function(m){var l,j=this,k;m=j.get(m);l=j.getPos(m);k=j.getSize(m);return{x:l.x,y:l.y,w:k.w,h:k.h}},getSize:function(m){var k=this,j,l;m=k.get(m);j=k.getStyle(m,"width");l=k.getStyle(m,"height");if(j.indexOf("px")===-1){j=0}if(l.indexOf("px")===-1){l=0}return{w:parseInt(j)||m.offsetWidth||m.clientWidth,h:parseInt(l)||m.offsetHeight||m.clientHeight}},getParent:function(l,k,j){return this.getParents(l,k,j,false)},getParents:function(u,p,l,s){var k=this,j,m=k.settings,q=[];u=k.get(u);s=s===undefined;if(m.strict_root){l=l||k.getRoot()}if(e(p,"string")){j=p;if(p==="*"){p=function(o){return o.nodeType==1}}else{p=function(o){return k.is(o,j)}}}while(u){if(u==l||!u.nodeType||u.nodeType===9){break}if(!p||p(u)){if(s){q.push(u)}else{return u}}u=u.parentNode}return s?q:null},get:function(j){var k;if(j&&this.doc&&typeof(j)=="string"){k=j;j=this.doc.getElementById(j);if(j&&j.id!==k){return this.doc.getElementsByName(k)[1]}}return j},getNext:function(k,j){return this._findSib(k,j,"nextSibling")},getPrev:function(k,j){return this._findSib(k,j,"previousSibling")},select:function(l,k){var j=this;return h.dom.Sizzle(l,j.get(k)||j.get(j.settings.root_element)||j.doc,[])},is:function(l,j){var k;if(l.length===undefined){if(j==="*"){return l.nodeType==1}if(a.test(j)){j=j.toLowerCase().split(/,/);l=l.nodeName.toLowerCase();for(k=j.length-1;k>=0;k--){if(j[k]==l){return true}}return false}}return h.dom.Sizzle.matches(j,l.nodeType?[l]:l).length>0},add:function(m,q,j,l,o){var k=this;return this.run(m,function(s){var r,n;r=e(q,"string")?k.doc.createElement(q):q;k.setAttribs(r,j);if(l){if(l.nodeType){r.appendChild(l)}else{k.setHTML(r,l)}}return !o?s.appendChild(r):r})},create:function(l,j,k){return this.add(this.doc.createElement(l),l,j,k,1)},createHTML:function(r,j,p){var q="",m=this,l;q+="<"+r;for(l in j){if(j.hasOwnProperty(l)){q+=" "+l+'="'+m.encode(j[l])+'"'}}if(typeof(p)!="undefined"){return q+">"+p+"</"+r+">"}return q+" />"},remove:function(j,k){return this.run(j,function(m){var n,l=m.parentNode;if(!l){return null}if(k){while(n=m.firstChild){if(!h.isIE||n.nodeType!==3||n.nodeValue){l.insertBefore(n,m)}else{m.removeChild(n)}}}return l.removeChild(m)})},setStyle:function(m,j,k){var l=this;return l.run(m,function(p){var o,n;o=p.style;j=j.replace(/-(\D)/g,function(r,q){return q.toUpperCase()});if(l.pixelStyles.test(j)&&(h.is(k,"number")||/^[\-0-9\.]+$/.test(k))){k+="px"}switch(j){case"opacity":if(b){o.filter=k===""?"":"alpha(opacity="+(k*100)+")";if(!m.currentStyle||!m.currentStyle.hasLayout){o.display="inline-block"}}o[j]=o["-moz-opacity"]=o["-khtml-opacity"]=k||"";break;case"float":b?o.styleFloat=k:o.cssFloat=k;break;default:o[j]=k||""}if(l.settings.update_styles){l.setAttrib(p,"data-mce-style")}})},getStyle:function(m,j,l){m=this.get(m);if(!m){return}if(this.doc.defaultView&&l){j=j.replace(/[A-Z]/g,function(n){return"-"+n});try{return this.doc.defaultView.getComputedStyle(m,null).getPropertyValue(j)}catch(k){return null}}j=j.replace(/-(\D)/g,function(o,n){return n.toUpperCase()});if(j=="float"){j=b?"styleFloat":"cssFloat"}if(m.currentStyle&&l){return m.currentStyle[j]}return m.style?m.style[j]:undefined},setStyles:function(m,n){var k=this,l=k.settings,j;j=l.update_styles;l.update_styles=0;f(n,function(o,p){k.setStyle(m,p,o)});l.update_styles=j;if(l.update_styles){k.setAttrib(m,l.cssText)}},removeAllAttribs:function(j){return this.run(j,function(m){var l,k=m.attributes;for(l=k.length-1;l>=0;l--){m.removeAttributeNode(k.item(l))}})},setAttrib:function(l,m,j){var k=this;if(!l||!m){return}if(k.settings.strict){m=m.toLowerCase()}return this.run(l,function(q){var p=k.settings;var n=q.getAttribute(m);if(j!==null){switch(m){case"style":if(!e(j,"string")){f(j,function(r,s){k.setStyle(q,s,r)});return}if(p.keep_values){if(j&&!k._isRes(j)){q.setAttribute("data-mce-style",j,2)}else{q.removeAttribute("data-mce-style",2)}}q.style.cssText=j;break;case"class":q.className=j||"";break;case"src":case"href":if(p.keep_values){if(p.url_converter){j=p.url_converter.call(p.url_converter_scope||k,j,m,q)}k.setAttrib(q,"data-mce-"+m,j,2)}break;case"shape":q.setAttribute("data-mce-style",j);break}}if(e(j)&&j!==null&&j.length!==0){q.setAttribute(m,""+j,2)}else{q.removeAttribute(m,2)}if(tinyMCE.activeEditor&&n!=j){var o=tinyMCE.activeEditor;o.onSetAttrib.dispatch(o,q,m,j)}})},setAttribs:function(k,l){var j=this;return this.run(k,function(m){f(l,function(o,p){j.setAttrib(m,p,o)})})},getAttrib:function(o,p,l){var j,k=this,m;o=k.get(o);if(!o||o.nodeType!==1){return l===m?false:l}if(!e(l)){l=""}if(/^(src|href|style|coords|shape)$/.test(p)){j=o.getAttribute("data-mce-"+p);if(j){return j}}if(b&&k.props[p]){j=o[k.props[p]];j=j&&j.nodeValue?j.nodeValue:j}if(!j){j=o.getAttribute(p,2)}if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(p)){if(o[k.props[p]]===true&&j===""){return p}return j?p:""}if(o.nodeName==="FORM"&&o.getAttributeNode(p)){return o.getAttributeNode(p).nodeValue}if(p==="style"){j=j||o.style.cssText;if(j){j=k.serializeStyle(k.parseStyle(j),o.nodeName);if(k.settings.keep_values&&!k._isRes(j)){o.setAttribute("data-mce-style",j)}}}if(d&&p==="class"&&j){j=j.replace(/(apple|webkit)\-[a-z\-]+/gi,"")}if(b){switch(p){case"rowspan":case"colspan":if(j===1){j=""}break;case"size":if(j==="+0"||j===20||j===0){j=""}break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":if(j===0){j=""}break;case"hspace":if(j===-1){j=""}break;case"maxlength":case"tabindex":if(j===32768||j===2147483647||j==="32768"){j=""}break;case"multiple":case"compact":case"noshade":case"nowrap":if(j===65535){return p}return l;case"shape":j=j.toLowerCase();break;default:if(p.indexOf("on")===0&&j){j=h._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1",""+j)}}}return(j!==m&&j!==null&&j!=="")?""+j:l},getPos:function(s,m){var k=this,j=0,q=0,o,p=k.doc,l;s=k.get(s);m=m||p.body;if(s){if(s.getBoundingClientRect){s=s.getBoundingClientRect();o=k.boxModel?p.documentElement:p.body;j=s.left+(p.documentElement.scrollLeft||p.body.scrollLeft)-o.clientTop;q=s.top+(p.documentElement.scrollTop||p.body.scrollTop)-o.clientLeft;return{x:j,y:q}}l=s;while(l&&l!=m&&l.nodeType){j+=l.offsetLeft||0;q+=l.offsetTop||0;l=l.offsetParent}l=s.parentNode;while(l&&l!=m&&l.nodeType){j-=l.scrollLeft||0;q-=l.scrollTop||0;l=l.parentNode}}return{x:j,y:q}},parseStyle:function(j){return this.styles.parse(j)},serializeStyle:function(k,j){return this.styles.serialize(k,j)},loadCSS:function(j){var l=this,m=l.doc,k;if(!j){j=""}k=l.select("head")[0];f(j.split(","),function(n){var o;if(l.files[n]){return}l.files[n]=true;o=l.create("link",{rel:"stylesheet",href:h._addVer(n)});if(b&&m.documentMode&&m.recalc){o.onload=function(){if(m.recalc){m.recalc()}o.onload=null}}k.appendChild(o)})},addClass:function(j,k){return this.run(j,function(l){var m;if(!k){return 0}if(this.hasClass(l,k)){return l.className}m=this.removeClass(l,k);return l.className=(m!=""?(m+" "):"")+k})},removeClass:function(l,m){var j=this,k;return j.run(l,function(o){var n;if(j.hasClass(o,m)){if(!k){k=new RegExp("(^|\\s+)"+m+"(\\s+|$)","g")}n=o.className.replace(k," ");n=h.trim(n!=" "?n:"");o.className=n;if(!n){o.removeAttribute("class");o.removeAttribute("className")}return n}return o.className})},hasClass:function(k,j){k=this.get(k);if(!k||!j){return false}return(" "+k.className+" ").indexOf(" "+j+" ")!==-1},show:function(j){return this.setStyle(j,"display","block")},hide:function(j){return this.setStyle(j,"display","none")},isHidden:function(j){j=this.get(j);return !j||j.style.display=="none"||this.getStyle(j,"display")=="none"},uniqueId:function(j){return(!j?"mce_":j)+(this.counter++)},setHTML:function(l,k){var j=this;return j.run(l,function(n){if(b){while(n.firstChild){n.removeChild(n.firstChild)}try{n.innerHTML="<br />"+k;n.removeChild(n.firstChild)}catch(m){n=j.create("div");n.innerHTML="<br />"+k;f(n.childNodes,function(p,o){if(o){n.appendChild(p)}})}}else{n.innerHTML=k}return k})},getOuterHTML:function(l){var k,j=this;l=j.get(l);if(!l){return null}if(l.nodeType===1&&j.hasOuterHTML){return l.outerHTML}k=(l.ownerDocument||j.doc).createElement("body");k.appendChild(l.cloneNode(true));return k.innerHTML},setOuterHTML:function(m,k,n){var j=this;function l(p,o,r){var s,q;q=r.createElement("body");q.innerHTML=o;s=q.lastChild;while(s){j.insertAfter(s.cloneNode(true),p);s=s.previousSibling}j.remove(p)}return this.run(m,function(p){p=j.get(p);if(p.nodeType==1){n=n||p.ownerDocument||j.doc;if(b){try{if(b&&p.nodeType==1){p.outerHTML=k}else{l(p,k,n)}}catch(o){l(p,k,n)}}else{l(p,k,n)}}})},decode:c.decode,encode:c.encodeAllRaw,insertAfter:function(j,k){k=this.get(k);return this.run(j,function(m){var l,n;l=k.parentNode;n=k.nextSibling;if(n){l.insertBefore(m,n)}else{l.appendChild(m)}return m})},isBlock:function(k){var j=k.nodeType;if(j){return !!(j===1&&g[k.nodeName])}return !!g[k]},replace:function(p,m,j){var l=this;if(e(m,"array")){p=p.cloneNode(true)}return l.run(m,function(k){if(j){f(h.grep(k.childNodes),function(n){p.appendChild(n)})}return k.parentNode.replaceChild(p,k)})},rename:function(m,j){var l=this,k;if(m.nodeName!=j.toUpperCase()){k=l.create(j);f(l.getAttribs(m),function(n){l.setAttrib(k,n.nodeName,l.getAttrib(m,n.nodeName))});l.replace(k,m,1)}return k||m},findCommonAncestor:function(l,j){var m=l,k;while(m){k=j;while(k&&m!=k){k=k.parentNode}if(m==k){break}m=m.parentNode}if(!m&&l.ownerDocument){return l.ownerDocument.documentElement}return m},toHex:function(j){var l=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(j);function k(m){m=parseInt(m).toString(16);return m.length>1?m:"0"+m}if(l){j="#"+k(l[1])+k(l[2])+k(l[3]);return j}return j},getClasses:function(){var n=this,j=[],m,o={},p=n.settings.class_filter,l;if(n.classes){return n.classes}function q(r){f(r.imports,function(s){q(s)});f(r.cssRules||r.rules,function(s){switch(s.type||1){case 1:if(s.selectorText){f(s.selectorText.split(","),function(t){t=t.replace(/^\s*|\s*$|^\s\./g,"");if(/\.mce/.test(t)||!/\.[\w\-]+$/.test(t)){return}l=t;t=h._replace(/.*\.([a-z0-9_\-]+).*/i,"$1",t);if(p&&!(t=p(t,l))){return}if(!o[t]){j.push({"class":t});o[t]=1}})}break;case 3:q(s.styleSheet);break}})}try{f(n.doc.styleSheets,q)}catch(k){}if(j.length>0){n.classes=j}return j},run:function(m,l,k){var j=this,n;if(j.doc&&typeof(m)==="string"){m=j.get(m)}if(!m){return false}k=k||this;if(!m.nodeType&&(m.length||m.length===0)){n=[];f(m,function(p,o){if(p){if(typeof(p)=="string"){p=j.doc.getElementById(p)}n.push(l.call(k,p,o))}});return n}return l.call(k,m)},getAttribs:function(k){var j;k=this.get(k);if(!k){return[]}if(b){j=[];if(k.nodeName=="OBJECT"){return k.attributes}if(k.nodeName==="OPTION"&&this.getAttrib(k,"selected")){j.push({specified:1,nodeName:"selected"})}k.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi,"").replace(/[\w:\-]+/gi,function(l){j.push({specified:1,nodeName:l})});return j}return k.attributes},isEmpty:function(m,k){var r=this,o,n,q,j,l,p;m=m.firstChild;if(m){j=new h.dom.TreeWalker(m);k=k||r.schema?r.schema.getNonEmptyElements():null;do{q=m.nodeType;if(q===1){if(m.getAttribute("data-mce-bogus")){continue}l=m.nodeName.toLowerCase();if(k&&k[l]){p=m.parentNode;if(l==="br"&&r.isBlock(p)&&p.firstChild===m&&p.lastChild===m){continue}return false}n=r.getAttribs(m);o=m.attributes.length;while(o--){l=m.attributes[o].nodeName;if(l==="name"||l==="data-mce-bookmark"){return false}}}if(q==8){return false}if((q===3&&!i.test(m.nodeValue))){return false}}while(m=j.next())}return true},destroy:function(k){var j=this;if(j.events){j.events.destroy()}j.win=j.doc=j.root=j.events=null;if(!k){h.removeUnload(j.destroy)}},createRng:function(){var j=this.doc;return j.createRange?j.createRange():new h.dom.Range(this)},nodeIndex:function(n,o){var j=0,l,m,k;if(n){for(l=n.nodeType,n=n.previousSibling,m=n;n;n=n.previousSibling){k=n.nodeType;if(o&&k==3){if(k==l||!n.nodeValue.length){continue}}j++;l=k}}return j},split:function(n,m,q){var s=this,j=s.createRng(),o,l,p;function k(x){var u,t=x.childNodes,v=x.nodeType;function y(B){var A=B.previousSibling&&B.previousSibling.nodeName=="SPAN";var z=B.nextSibling&&B.nextSibling.nodeName=="SPAN";return A&&z}if(v==1&&x.getAttribute("data-mce-type")=="bookmark"){return}for(u=t.length-1;u>=0;u--){k(t[u])}if(v!=9){if(v==3&&x.nodeValue.length>0){var r=h.trim(x.nodeValue).length;if(!s.isBlock(x.parentNode)||r>0||r==0&&y(x)){return}}else{if(v==1){t=x.childNodes;if(t.length==1&&t[0]&&t[0].nodeType==1&&t[0].getAttribute("data-mce-type")=="bookmark"){x.parentNode.insertBefore(t[0],x)}if(t.length||/^(br|hr|input|img)$/i.test(x.nodeName)){return}}}s.remove(x)}return x}if(n&&m){j.setStart(n.parentNode,s.nodeIndex(n));j.setEnd(m.parentNode,s.nodeIndex(m));o=j.extractContents();j=s.createRng();j.setStart(m.parentNode,s.nodeIndex(m)+1);j.setEnd(n.parentNode,s.nodeIndex(n)+1);l=j.extractContents();p=n.parentNode;p.insertBefore(k(o),n);if(q){p.replaceChild(q,m)}else{p.insertBefore(m,n)}p.insertBefore(k(l),n);s.remove(n);return q||m}},bind:function(n,j,m,l){var k=this;if(!k.events){k.events=new h.dom.EventUtils()}return k.events.add(n,j,m,l||this)},unbind:function(m,j,l){var k=this;if(!k.events){k.events=new h.dom.EventUtils()}return k.events.remove(m,j,l)},_findSib:function(m,j,k){var l=this,n=j;if(m){if(e(n,"string")){n=function(o){return l.is(o,j)}}for(m=m[k];m;m=m[k]){if(n(m)){return m}}}return null},_isRes:function(j){return/^(top|left|bottom|right|width|height)/i.test(j)||/;\s*(top|left|bottom|right|width|height)/i.test(j)}});h.DOM=new h.dom.DOMUtils(document,{process_html:0})})(tinymce);(function(a){function b(c){var N=this,e=c.doc,S=0,E=1,j=2,D=true,R=false,U="startOffset",h="startContainer",P="endContainer",z="endOffset",k=tinymce.extend,n=c.nodeIndex;k(N,{startContainer:e,startOffset:0,endContainer:e,endOffset:0,collapsed:D,commonAncestorContainer:e,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:q,setEnd:s,setStartBefore:g,setStartAfter:I,setEndBefore:J,setEndAfter:u,collapse:A,selectNode:x,selectNodeContents:F,compareBoundaryPoints:v,deleteContents:p,extractContents:H,cloneContents:d,insertNode:C,surroundContents:M,cloneRange:K});function q(V,t){B(D,V,t)}function s(V,t){B(R,V,t)}function g(t){q(t.parentNode,n(t))}function I(t){q(t.parentNode,n(t)+1)}function J(t){s(t.parentNode,n(t))}function u(t){s(t.parentNode,n(t)+1)}function A(t){if(t){N[P]=N[h];N[z]=N[U]}else{N[h]=N[P];N[U]=N[z]}N.collapsed=D}function x(t){g(t);u(t)}function F(t){q(t,0);s(t,t.nodeType===1?t.childNodes.length:t.nodeValue.length)}function v(Y,t){var ab=N[h],W=N[U],aa=N[P],V=N[z],Z=t.startContainer,ad=t.startOffset,X=t.endContainer,ac=t.endOffset;if(Y===0){return G(ab,W,Z,ad)}if(Y===1){return G(aa,V,Z,ad)}if(Y===2){return G(aa,V,X,ac)}if(Y===3){return G(ab,W,X,ac)}}function p(){m(j)}function H(){return m(S)}function d(){return m(E)}function C(Y){var V=this[h],t=this[U],X,W;if((V.nodeType===3||V.nodeType===4)&&V.nodeValue){if(!t){V.parentNode.insertBefore(Y,V)}else{if(t>=V.nodeValue.length){c.insertAfter(Y,V)}else{X=V.splitText(t);V.parentNode.insertBefore(Y,X)}}}else{if(V.childNodes.length>0){W=V.childNodes[t]}if(W){V.insertBefore(Y,W)}else{V.appendChild(Y)}}}function M(V){var t=N.extractContents();N.insertNode(V);V.appendChild(t);N.selectNode(V)}function K(){return k(new b(c),{startContainer:N[h],startOffset:N[U],endContainer:N[P],endOffset:N[z],collapsed:N.collapsed,commonAncestorContainer:N.commonAncestorContainer})}function O(t,V){var W;if(t.nodeType==3){return t}if(V<0){return t}W=t.firstChild;while(W&&V>0){--V;W=W.nextSibling}if(W){return W}return t}function l(){return(N[h]==N[P]&&N[U]==N[z])}function G(X,Z,V,Y){var aa,W,t,ab,ad,ac;if(X==V){if(Z==Y){return 0}if(Z<Y){return -1}return 1}aa=V;while(aa&&aa.parentNode!=X){aa=aa.parentNode}if(aa){W=0;t=X.firstChild;while(t!=aa&&W<Z){W++;t=t.nextSibling}if(Z<=W){return -1}return 1}aa=X;while(aa&&aa.parentNode!=V){aa=aa.parentNode}if(aa){W=0;t=V.firstChild;while(t!=aa&&W<Y){W++;t=t.nextSibling}if(W<Y){return -1}return 1}ab=c.findCommonAncestor(X,V);ad=X;while(ad&&ad.parentNode!=ab){ad=ad.parentNode}if(!ad){ad=ab}ac=V;while(ac&&ac.parentNode!=ab){ac=ac.parentNode}if(!ac){ac=ab}if(ad==ac){return 0}t=ab.firstChild;while(t){if(t==ad){return -1}if(t==ac){return 1}t=t.nextSibling}}function B(V,Y,X){var t,W;if(V){N[h]=Y;N[U]=X}else{N[P]=Y;N[z]=X}t=N[P];while(t.parentNode){t=t.parentNode}W=N[h];while(W.parentNode){W=W.parentNode}if(W==t){if(G(N[h],N[U],N[P],N[z])>0){N.collapse(V)}}else{N.collapse(V)}N.collapsed=l();N.commonAncestorContainer=c.findCommonAncestor(N[h],N[P])}function m(ab){var aa,X=0,ad=0,V,Z,W,Y,t,ac;if(N[h]==N[P]){return f(ab)}for(aa=N[P],V=aa.parentNode;V;aa=V,V=V.parentNode){if(V==N[h]){return r(aa,ab)}++X}for(aa=N[h],V=aa.parentNode;V;aa=V,V=V.parentNode){if(V==N[P]){return T(aa,ab)}++ad}Z=ad-X;W=N[h];while(Z>0){W=W.parentNode;Z--}Y=N[P];while(Z<0){Y=Y.parentNode;Z++}for(t=W.parentNode,ac=Y.parentNode;t!=ac;t=t.parentNode,ac=ac.parentNode){W=t;Y=ac}return o(W,Y,ab)}function f(Z){var ab,Y,X,aa,t,W,V;if(Z!=j){ab=e.createDocumentFragment()}if(N[U]==N[z]){return ab}if(N[h].nodeType==3){Y=N[h].nodeValue;X=Y.substring(N[U],N[z]);if(Z!=E){N[h].deleteData(N[U],N[z]-N[U]);N.collapse(D)}if(Z==j){return}ab.appendChild(e.createTextNode(X));return ab}aa=O(N[h],N[U]);t=N[z]-N[U];while(t>0){W=aa.nextSibling;V=y(aa,Z);if(ab){ab.appendChild(V)}--t;aa=W}if(Z!=E){N.collapse(D)}return ab}function r(ab,Y){var aa,Z,V,t,X,W;if(Y!=j){aa=e.createDocumentFragment()}Z=i(ab,Y);if(aa){aa.appendChild(Z)}V=n(ab);t=V-N[U];if(t<=0){if(Y!=E){N.setEndBefore(ab);N.collapse(R)}return aa}Z=ab.previousSibling;while(t>0){X=Z.previousSibling;W=y(Z,Y);if(aa){aa.insertBefore(W,aa.firstChild)}--t;Z=X}if(Y!=E){N.setEndBefore(ab);N.collapse(R)}return aa}function T(Z,Y){var ab,V,aa,t,X,W;if(Y!=j){ab=e.createDocumentFragment()}aa=Q(Z,Y);if(ab){ab.appendChild(aa)}V=n(Z);++V;t=N[z]-V;aa=Z.nextSibling;while(t>0){X=aa.nextSibling;W=y(aa,Y);if(ab){ab.appendChild(W)}--t;aa=X}if(Y!=E){N.setStartAfter(Z);N.collapse(D)}return ab}function o(Z,t,ac){var W,ae,Y,aa,ab,V,ad,X;if(ac!=j){ae=e.createDocumentFragment()}W=Q(Z,ac);if(ae){ae.appendChild(W)}Y=Z.parentNode;aa=n(Z);ab=n(t);++aa;V=ab-aa;ad=Z.nextSibling;while(V>0){X=ad.nextSibling;W=y(ad,ac);if(ae){ae.appendChild(W)}ad=X;--V}W=i(t,ac);if(ae){ae.appendChild(W)}if(ac!=E){N.setStartAfter(Z);N.collapse(D)}return ae}function i(aa,ab){var W=O(N[P],N[z]-1),ac,Z,Y,t,V,X=W!=N[P];if(W==aa){return L(W,X,R,ab)}ac=W.parentNode;Z=L(ac,R,R,ab);while(ac){while(W){Y=W.previousSibling;t=L(W,X,R,ab);if(ab!=j){Z.insertBefore(t,Z.firstChild)}X=D;W=Y}if(ac==aa){return Z}W=ac.previousSibling;ac=ac.parentNode;V=L(ac,R,R,ab);if(ab!=j){V.appendChild(Z)}Z=V}}function Q(aa,ab){var X=O(N[h],N[U]),Y=X!=N[h],ac,Z,W,t,V;if(X==aa){return L(X,Y,D,ab)}ac=X.parentNode;Z=L(ac,R,D,ab);while(ac){while(X){W=X.nextSibling;t=L(X,Y,D,ab);if(ab!=j){Z.appendChild(t)}Y=D;X=W}if(ac==aa){return Z}X=ac.nextSibling;ac=ac.parentNode;V=L(ac,R,D,ab);if(ab!=j){V.appendChild(Z)}Z=V}}function L(t,Y,ab,ac){var X,W,Z,V,aa;if(Y){return y(t,ac)}if(t.nodeType==3){X=t.nodeValue;if(ab){V=N[U];W=X.substring(V);Z=X.substring(0,V)}else{V=N[z];W=X.substring(0,V);Z=X.substring(V)}if(ac!=E){t.nodeValue=Z}if(ac==j){return}aa=t.cloneNode(R);aa.nodeValue=W;return aa}if(ac==j){return}return t.cloneNode(R)}function y(V,t){if(t!=j){return t==E?V.cloneNode(D):V}V.parentNode.removeChild(V)}}a.Range=b})(tinymce.dom);(function(){function a(d){var b=this,h=d.dom,c=true,f=false;function e(i,j){var k,t=0,q,n,m,l,o,r,p=-1,s;k=i.duplicate();k.collapse(j);s=k.parentElement();if(s.ownerDocument!==d.dom.doc){return}while(s.contentEditable==="false"){s=s.parentNode}if(!s.hasChildNodes()){return{node:s,inside:1}}m=s.children;q=m.length-1;while(t<=q){r=Math.floor((t+q)/2);l=m[r];k.moveToElementText(l);p=k.compareEndPoints(j?"StartToStart":"EndToEnd",i);if(p>0){q=r-1}else{if(p<0){t=r+1}else{return{node:l}}}}if(p<0){if(!l){k.moveToElementText(s);k.collapse(true);l=s;n=true}else{k.collapse(false)}k.setEndPoint(j?"EndToStart":"EndToEnd",i);if(k.compareEndPoints(j?"StartToStart":"StartToEnd",i)>0){k=i.duplicate();k.collapse(j);o=-1;while(s==k.parentElement()){if(k.move("character",-1)==0){break}o++}}o=o||k.text.replace("\r\n"," ").length}else{k.collapse(true);k.setEndPoint(j?"StartToStart":"StartToEnd",i);o=k.text.replace("\r\n"," ").length}return{node:l,position:p,offset:o,inside:n}}function g(){var i=d.getRng(),r=h.createRng(),l,k,p,q,m,j;l=i.item?i.item(0):i.parentElement();if(l.ownerDocument!=h.doc){return r}k=d.isCollapsed();if(i.item){r.setStart(l.parentNode,h.nodeIndex(l));r.setEnd(r.startContainer,r.startOffset+1);return r}function o(A){var u=e(i,A),s,y,z=0,x,v,t;s=u.node;y=u.offset;if(u.inside&&!s.hasChildNodes()){r[A?"setStart":"setEnd"](s,0);return}if(y===v){r[A?"setStartBefore":"setEndAfter"](s);return}if(u.position<0){x=u.inside?s.firstChild:s.nextSibling;if(!x){r[A?"setStartAfter":"setEndAfter"](s);return}if(!y){if(x.nodeType==3){r[A?"setStart":"setEnd"](x,0)}else{r[A?"setStartBefore":"setEndBefore"](x)}return}while(x){t=x.nodeValue;z+=t.length;if(z>=y){s=x;z-=y;z=t.length-z;break}x=x.nextSibling}}else{x=s.previousSibling;if(!x){return r[A?"setStartBefore":"setEndBefore"](s)}if(!y){if(s.nodeType==3){r[A?"setStart":"setEnd"](x,s.nodeValue.length)}else{r[A?"setStartAfter":"setEndAfter"](x)}return}while(x){z+=x.nodeValue.length;if(z>=y){s=x;z-=y;break}x=x.previousSibling}}r[A?"setStart":"setEnd"](s,z)}try{o(true);if(!k){o()}}catch(n){if(n.number==-2147024809){m=b.getBookmark(2);p=i.duplicate();p.collapse(true);l=p.parentElement();if(!k){p=i.duplicate();p.collapse(false);q=p.parentElement();q.innerHTML=q.innerHTML}l.innerHTML=l.innerHTML;b.moveToBookmark(m);i=d.getRng();o(true);if(!k){o()}}else{throw n}}return r}this.getBookmark=function(m){var j=d.getRng(),o,i,l={};function n(u){var u,t,p,s,r,q=[];t=u.parentNode;p=h.getRoot().parentNode;while(t!=p&&t.nodeType!==9){s=t.children;r=s.length;while(r--){if(u===s[r]){q.push(r);break}}u=t;t=t.parentNode}return q}function k(q){var p;p=e(j,q);if(p){return{position:p.position,offset:p.offset,indexes:n(p.node),inside:p.inside}}}if(m===2){if(!j.item){l.start=k(true);if(!d.isCollapsed()){l.end=k()}}else{l.start={ctrl:true,indexes:n(j.item(0))}}}return l};this.moveToBookmark=function(k){var j,i=h.doc.body;function m(o){var r,q,n,p;r=h.getRoot();for(q=o.length-1;q>=0;q--){p=r.children;n=o[q];if(n<=p.length-1){r=p[n]}}return r}function l(r){var n=k[r?"start":"end"],q,p,o;if(n){q=n.position>0;p=i.createTextRange();p.moveToElementText(m(n.indexes));offset=n.offset;if(offset!==o){p.collapse(n.inside||q);p.moveStart("character",q?-offset:offset)}else{p.collapse(r)}j.setEndPoint(r?"StartToStart":"EndToStart",p);if(r){j.collapse(true)}}}if(k.start){if(k.start.ctrl){j=i.createControlRange();j.addElement(m(k.start.indexes));j.select()}else{j=i.createTextRange();l(true);l();j.select()}}};this.addRange=function(i){var n,l,k,p,s,q,r=d.dom.doc,m=r.body;function j(z){var u,y,t,x,v;t=h.create("a");u=z?k:s;y=z?p:q;x=n.duplicate();if(u==r||u==r.documentElement){u=m;y=0}if(u.nodeType==3){u.parentNode.insertBefore(t,u);x.moveToElementText(t);x.moveStart("character",y);h.remove(t);n.setEndPoint(z?"StartToStart":"EndToEnd",x)}else{v=u.childNodes;if(v.length){if(y>=v.length){h.insertAfter(t,v[v.length-1])}else{u.insertBefore(t,v[y])}x.moveToElementText(t)}else{t=r.createTextNode("\uFEFF");u.appendChild(t);x.moveToElementText(t.parentNode);x.collapse(c)}n.setEndPoint(z?"StartToStart":"EndToEnd",x);h.remove(t)}}k=i.startContainer;p=i.startOffset;s=i.endContainer;q=i.endOffset;n=m.createTextRange();if(k==s&&k.nodeType==1&&p==q-1){if(p==q-1){try{l=m.createControlRange();l.addElement(k.childNodes[p]);l.select();return}catch(o){}}}j(true);j();n.select()};this.getRangeAt=g}tinymce.dom.TridentSelection=a})();(function(){var p=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,j=0,d=Object.prototype.toString,o=false,i=true;[0,0].sort(function(){i=false;return 0});var b=function(v,e,z,A){z=z||[];e=e||document;var C=e;if(e.nodeType!==1&&e.nodeType!==9){return[]}if(!v||typeof v!=="string"){return z}var x=[],s,E,H,r,u=true,t=b.isXML(e),B=v,D,G,F,y;do{p.exec("");s=p.exec(B);if(s){B=s[3];x.push(s[1]);if(s[2]){r=s[3];break}}}while(s);if(x.length>1&&k.exec(v)){if(x.length===2&&f.relative[x[0]]){E=h(x[0]+x[1],e)}else{E=f.relative[x[0]]?[e]:b(x.shift(),e);while(x.length){v=x.shift();if(f.relative[v]){v+=x.shift()}E=h(v,E)}}}else{if(!A&&x.length>1&&e.nodeType===9&&!t&&f.match.ID.test(x[0])&&!f.match.ID.test(x[x.length-1])){D=b.find(x.shift(),e,t);e=D.expr?b.filter(D.expr,D.set)[0]:D.set[0]}if(e){D=A?{expr:x.pop(),set:a(A)}:b.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&e.parentNode?e.parentNode:e,t);E=D.expr?b.filter(D.expr,D.set):D.set;if(x.length>0){H=a(E)}else{u=false}while(x.length){G=x.pop();F=G;if(!f.relative[G]){G=""}else{F=x.pop()}if(F==null){F=e}f.relative[G](H,F,t)}}else{H=x=[]}}if(!H){H=E}if(!H){b.error(G||v)}if(d.call(H)==="[object Array]"){if(!u){z.push.apply(z,H)}else{if(e&&e.nodeType===1){for(y=0;H[y]!=null;y++){if(H[y]&&(H[y]===true||H[y].nodeType===1&&b.contains(e,H[y]))){z.push(E[y])}}}else{for(y=0;H[y]!=null;y++){if(H[y]&&H[y].nodeType===1){z.push(E[y])}}}}}else{a(H,z)}if(r){b(r,C,z,A);b.uniqueSort(z)}return z};b.uniqueSort=function(r){if(c){o=i;r.sort(c);if(o){for(var e=1;e<r.length;e++){if(r[e]===r[e-1]){r.splice(e--,1)}}}}return r};b.matches=function(e,r){return b(e,null,null,r)};b.find=function(y,e,z){var x;if(!y){return[]}for(var t=0,s=f.order.length;t<s;t++){var v=f.order[t],u;if((u=f.leftMatch[v].exec(y))){var r=u[1];u.splice(1,1);if(r.substr(r.length-1)!=="\\"){u[1]=(u[1]||"").replace(/\\/g,"");x=f.find[v](u,e,z);if(x!=null){y=y.replace(f.match[v],"");break}}}}if(!x){x=e.getElementsByTagName("*")}return{set:x,expr:y}};b.filter=function(C,B,F,u){var s=C,H=[],z=B,x,e,y=B&&B[0]&&b.isXML(B[0]);while(C&&B.length){for(var A in f.filter){if((x=f.leftMatch[A].exec(C))!=null&&x[2]){var r=f.filter[A],G,E,t=x[1];e=false;x.splice(1,1);if(t.substr(t.length-1)==="\\"){continue}if(z===H){H=[]}if(f.preFilter[A]){x=f.preFilter[A](x,z,F,H,u,y);if(!x){e=G=true}else{if(x===true){continue}}}if(x){for(var v=0;(E=z[v])!=null;v++){if(E){G=r(E,x,v,z);var D=u^!!G;if(F&&G!=null){if(D){e=true}else{z[v]=false}}else{if(D){H.push(E);e=true}}}}}if(G!==undefined){if(!F){z=H}C=C.replace(f.match[A],"");if(!e){return[]}break}}}if(C===s){if(e==null){b.error(C)}else{break}}s=C}return z};b.error=function(e){throw"Syntax error, unrecognized expression: "+e};var f=b.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*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")}},relative:{"+":function(x,r){var t=typeof r==="string",v=t&&!/\W/.test(r),y=t&&!v;if(v){r=r.toLowerCase()}for(var s=0,e=x.length,u;s<e;s++){if((u=x[s])){while((u=u.previousSibling)&&u.nodeType!==1){}x[s]=y||u&&u.nodeName.toLowerCase()===r?u||false:u===r}}if(y){b.filter(r,x,true)}},">":function(x,r){var u=typeof r==="string",v,s=0,e=x.length;if(u&&!/\W/.test(r)){r=r.toLowerCase();for(;s<e;s++){v=x[s];if(v){var t=v.parentNode;x[s]=t.nodeName.toLowerCase()===r?t:false}}}else{for(;s<e;s++){v=x[s];if(v){x[s]=u?v.parentNode:v.parentNode===r}}if(u){b.filter(r,x,true)}}},"":function(t,r,v){var s=j++,e=q,u;if(typeof r==="string"&&!/\W/.test(r)){r=r.toLowerCase();u=r;e=n}e("parentNode",r,s,t,u,v)},"~":function(t,r,v){var s=j++,e=q,u;if(typeof r==="string"&&!/\W/.test(r)){r=r.toLowerCase();u=r;e=n}e("previousSibling",r,s,t,u,v)}},find:{ID:function(r,s,t){if(typeof s.getElementById!=="undefined"&&!t){var e=s.getElementById(r[1]);return e?[e]:[]}},NAME:function(s,v){if(typeof v.getElementsByName!=="undefined"){var r=[],u=v.getElementsByName(s[1]);for(var t=0,e=u.length;t<e;t++){if(u[t].getAttribute("name")===s[1]){r.push(u[t])}}return r.length===0?null:r}},TAG:function(e,r){return r.getElementsByTagName(e[1])}},preFilter:{CLASS:function(t,r,s,e,x,y){t=" "+t[1].replace(/\\/g,"")+" ";if(y){return t}for(var u=0,v;(v=r[u])!=null;u++){if(v){if(x^(v.className&&(" "+v.className+" ").replace(/[\t\n]/g," ").indexOf(t)>=0)){if(!s){e.push(v)}}else{if(s){r[u]=false}}}}return false},ID:function(e){return e[1].replace(/\\/g,"")},TAG:function(r,e){return r[1].toLowerCase()},CHILD:function(e){if(e[1]==="nth"){var r=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(e[2]==="even"&&"2n"||e[2]==="odd"&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=(r[1]+(r[2]||1))-0;e[3]=r[3]-0}e[0]=j++;return e},ATTR:function(u,r,s,e,v,x){var t=u[1].replace(/\\/g,"");if(!x&&f.attrMap[t]){u[1]=f.attrMap[t]}if(u[2]==="~="){u[4]=" "+u[4]+" "}return u},PSEUDO:function(u,r,s,e,v){if(u[1]==="not"){if((p.exec(u[3])||"").length>1||/^\w/.test(u[3])){u[3]=b(u[3],null,null,r)}else{var t=b.filter(u[3],r,s,true^v);if(!s){e.push.apply(e,t)}return false}}else{if(f.match.POS.test(u[0])||f.match.CHILD.test(u[0])){return true}}return u},POS:function(e){e.unshift(true);return e}},filters:{enabled:function(e){return e.disabled===false&&e.type!=="hidden"},disabled:function(e){return e.disabled===true},checked:function(e){return e.checked===true},selected:function(e){e.parentNode.selectedIndex;return e.selected===true},parent:function(e){return !!e.firstChild},empty:function(e){return !e.firstChild},has:function(s,r,e){return !!b(e[3],s).length},header:function(e){return(/h\d/i).test(e.nodeName)},text:function(e){return"text"===e.type},radio:function(e){return"radio"===e.type},checkbox:function(e){return"checkbox"===e.type},file:function(e){return"file"===e.type},password:function(e){return"password"===e.type},submit:function(e){return"submit"===e.type},image:function(e){return"image"===e.type},reset:function(e){return"reset"===e.type},button:function(e){return"button"===e.type||e.nodeName.toLowerCase()==="button"},input:function(e){return(/input|select|textarea|button/i).test(e.nodeName)}},setFilters:{first:function(r,e){return e===0},last:function(s,r,e,t){return r===t.length-1},even:function(r,e){return e%2===0},odd:function(r,e){return e%2===1},lt:function(s,r,e){return r<e[3]-0},gt:function(s,r,e){return r>e[3]-0},nth:function(s,r,e){return e[3]-0===r},eq:function(s,r,e){return e[3]-0===r}},filter:{PSEUDO:function(s,y,x,z){var e=y[1],r=f.filters[e];if(r){return r(s,x,y,z)}else{if(e==="contains"){return(s.textContent||s.innerText||b.getText([s])||"").indexOf(y[3])>=0}else{if(e==="not"){var t=y[3];for(var v=0,u=t.length;v<u;v++){if(t[v]===s){return false}}return true}else{b.error("Syntax error, unrecognized expression: "+e)}}}},CHILD:function(e,t){var x=t[1],r=e;switch(x){case"only":case"first":while((r=r.previousSibling)){if(r.nodeType===1){return false}}if(x==="first"){return true}r=e;case"last":while((r=r.nextSibling)){if(r.nodeType===1){return false}}return true;case"nth":var s=t[2],A=t[3];if(s===1&&A===0){return true}var v=t[0],z=e.parentNode;if(z&&(z.sizcache!==v||!e.nodeIndex)){var u=0;for(r=z.firstChild;r;r=r.nextSibling){if(r.nodeType===1){r.nodeIndex=++u}}z.sizcache=v}var y=e.nodeIndex-A;if(s===0){return y===0}else{return(y%s===0&&y/s>=0)}}},ID:function(r,e){return r.nodeType===1&&r.getAttribute("id")===e},TAG:function(r,e){return(e==="*"&&r.nodeType===1)||r.nodeName.toLowerCase()===e},CLASS:function(r,e){return(" "+(r.className||r.getAttribute("class"))+" ").indexOf(e)>-1},ATTR:function(v,t){var s=t[1],e=f.attrHandle[s]?f.attrHandle[s](v):v[s]!=null?v[s]:v.getAttribute(s),x=e+"",u=t[2],r=t[4];return e==null?u==="!=":u==="="?x===r:u==="*="?x.indexOf(r)>=0:u==="~="?(" "+x+" ").indexOf(r)>=0:!r?x&&e!==false:u==="!="?x!==r:u==="^="?x.indexOf(r)===0:u==="$="?x.substr(x.length-r.length)===r:u==="|="?x===r||x.substr(0,r.length+1)===r+"-":false},POS:function(u,r,s,v){var e=r[2],t=f.setFilters[e];if(t){return t(u,s,r,v)}}}};var k=f.match.POS,g=function(r,e){return"\\"+(e-0+1)};for(var m in f.match){f.match[m]=new RegExp(f.match[m].source+(/(?![^\[]*\])(?![^\(]*\))/.source));f.leftMatch[m]=new RegExp(/(^(?:.|\r|\n)*?)/.source+f.match[m].source.replace(/\\(\d+)/g,g))}var a=function(r,e){r=Array.prototype.slice.call(r,0);if(e){e.push.apply(e,r);return e}return r};try{Array.prototype.slice.call(document.documentElement.childNodes,0)[0].nodeType}catch(l){a=function(u,t){var r=t||[],s=0;if(d.call(u)==="[object Array]"){Array.prototype.push.apply(r,u)}else{if(typeof u.length==="number"){for(var e=u.length;s<e;s++){r.push(u[s])}}else{for(;u[s];s++){r.push(u[s])}}}return r}}var c;if(document.documentElement.compareDocumentPosition){c=function(r,e){if(!r.compareDocumentPosition||!e.compareDocumentPosition){if(r==e){o=true}return r.compareDocumentPosition?-1:1}var s=r.compareDocumentPosition(e)&4?-1:r===e?0:1;if(s===0){o=true}return s}}else{if("sourceIndex" in document.documentElement){c=function(r,e){if(!r.sourceIndex||!e.sourceIndex){if(r==e){o=true}return r.sourceIndex?-1:1}var s=r.sourceIndex-e.sourceIndex;if(s===0){o=true}return s}}else{if(document.createRange){c=function(t,r){if(!t.ownerDocument||!r.ownerDocument){if(t==r){o=true}return t.ownerDocument?-1:1}var s=t.ownerDocument.createRange(),e=r.ownerDocument.createRange();s.setStart(t,0);s.setEnd(t,0);e.setStart(r,0);e.setEnd(r,0);var u=s.compareBoundaryPoints(Range.START_TO_END,e);if(u===0){o=true}return u}}}}b.getText=function(e){var r="",t;for(var s=0;e[s];s++){t=e[s];if(t.nodeType===3||t.nodeType===4){r+=t.nodeValue}else{if(t.nodeType!==8){r+=b.getText(t.childNodes)}}}return r};(function(){var r=document.createElement("div"),s="script"+(new Date()).getTime();r.innerHTML="<a name='"+s+"'/>";var e=document.documentElement;e.insertBefore(r,e.firstChild);if(document.getElementById(s)){f.find.ID=function(u,v,x){if(typeof v.getElementById!=="undefined"&&!x){var t=v.getElementById(u[1]);return t?t.id===u[1]||typeof t.getAttributeNode!=="undefined"&&t.getAttributeNode("id").nodeValue===u[1]?[t]:undefined:[]}};f.filter.ID=function(v,t){var u=typeof v.getAttributeNode!=="undefined"&&v.getAttributeNode("id");return v.nodeType===1&&u&&u.nodeValue===t}}e.removeChild(r);e=r=null})();(function(){var e=document.createElement("div");e.appendChild(document.createComment(""));if(e.getElementsByTagName("*").length>0){f.find.TAG=function(r,v){var u=v.getElementsByTagName(r[1]);if(r[1]==="*"){var t=[];for(var s=0;u[s];s++){if(u[s].nodeType===1){t.push(u[s])}}u=t}return u}}e.innerHTML="<a href='#'></a>";if(e.firstChild&&typeof e.firstChild.getAttribute!=="undefined"&&e.firstChild.getAttribute("href")!=="#"){f.attrHandle.href=function(r){return r.getAttribute("href",2)}}e=null})();if(document.querySelectorAll){(function(){var e=b,s=document.createElement("div");s.innerHTML="<p class='TEST'></p>";if(s.querySelectorAll&&s.querySelectorAll(".TEST").length===0){return}b=function(x,v,t,u){v=v||document;if(!u&&v.nodeType===9&&!b.isXML(v)){try{return a(v.querySelectorAll(x),t)}catch(y){}}return e(x,v,t,u)};for(var r in e){b[r]=e[r]}s=null})()}(function(){var e=document.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>";if(!e.getElementsByClassName||e.getElementsByClassName("e").length===0){return}e.lastChild.className="e";if(e.getElementsByClassName("e").length===1){return}f.order.splice(1,0,"CLASS");f.find.CLASS=function(r,s,t){if(typeof s.getElementsByClassName!=="undefined"&&!t){return s.getElementsByClassName(r[1])}};e=null})();function n(r,x,v,A,y,z){for(var t=0,s=A.length;t<s;t++){var e=A[t];if(e){e=e[r];var u=false;while(e){if(e.sizcache===v){u=A[e.sizset];break}if(e.nodeType===1&&!z){e.sizcache=v;e.sizset=t}if(e.nodeName.toLowerCase()===x){u=e;break}e=e[r]}A[t]=u}}}function q(r,x,v,A,y,z){for(var t=0,s=A.length;t<s;t++){var e=A[t];if(e){e=e[r];var u=false;while(e){if(e.sizcache===v){u=A[e.sizset];break}if(e.nodeType===1){if(!z){e.sizcache=v;e.sizset=t}if(typeof x!=="string"){if(e===x){u=true;break}}else{if(b.filter(x,[e]).length>0){u=e;break}}}e=e[r]}A[t]=u}}}b.contains=document.compareDocumentPosition?function(r,e){return !!(r.compareDocumentPosition(e)&16)}:function(r,e){return r!==e&&(r.contains?r.contains(e):true)};b.isXML=function(e){var r=(e?e.ownerDocument||e:0).documentElement;return r?r.nodeName!=="HTML":false};var h=function(e,y){var t=[],u="",v,s=y.nodeType?[y]:y;while((v=f.match.PSEUDO.exec(e))){u+=v[0];e=e.replace(f.match.PSEUDO,"")}e=f.relative[e]?e+"*":e;for(var x=0,r=s.length;x<r;x++){b(e,s[x],t)}return b.filter(u,t)};window.tinymce.dom.Sizzle=b})();(function(d){var f=d.each,c=d.DOM,b=d.isIE,e=d.isWebKit,a;d.create("tinymce.dom.EventUtils",{EventUtils:function(){this.inits=[];this.events=[]},add:function(m,p,l,j){var g,h=this,i=h.events,k;if(p instanceof Array){k=[];f(p,function(o){k.push(h.add(m,o,l,j))});return k}if(m&&m.hasOwnProperty&&m instanceof Array){k=[];f(m,function(n){n=c.get(n);k.push(h.add(n,p,l,j))});return k}m=c.get(m);if(!m){return}g=function(n){if(h.disabled){return}n=n||window.event;if(n&&b){if(!n.target){n.target=n.srcElement}d.extend(n,h._stoppers)}if(!j){return l(n)}return l.call(j,n)};if(p=="unload"){d.unloads.unshift({func:g});return g}if(p=="init"){if(h.domLoaded){g()}else{h.inits.push(g)}return g}i.push({obj:m,name:p,func:l,cfunc:g,scope:j});h._add(m,p,g);return l},remove:function(l,m,k){var h=this,g=h.events,i=false,j;if(l&&l.hasOwnProperty&&l instanceof Array){j=[];f(l,function(n){n=c.get(n);j.push(h.remove(n,m,k))});return j}l=c.get(l);f(g,function(o,n){if(o.obj==l&&o.name==m&&(!k||(o.func==k||o.cfunc==k))){g.splice(n,1);h._remove(l,m,o.cfunc);i=true;return false}});return i},clear:function(l){var j=this,g=j.events,h,k;if(l){l=c.get(l);for(h=g.length-1;h>=0;h--){k=g[h];if(k.obj===l){j._remove(k.obj,k.name,k.cfunc);k.obj=k.cfunc=null;g.splice(h,1)}}}},cancel:function(g){if(!g){return false}this.stop(g);return this.prevent(g)},stop:function(g){if(g.stopPropagation){g.stopPropagation()}else{g.cancelBubble=true}return false},prevent:function(g){if(g.preventDefault){g.preventDefault()}else{g.returnValue=false}return false},destroy:function(){var g=this;f(g.events,function(j,h){g._remove(j.obj,j.name,j.cfunc);j.obj=j.cfunc=null});g.events=[];g=null},_add:function(h,i,g){if(h.attachEvent){h.attachEvent("on"+i,g)}else{if(h.addEventListener){h.addEventListener(i,g,false)}else{h["on"+i]=g}}},_remove:function(i,j,h){if(i){try{if(i.detachEvent){i.detachEvent("on"+j,h)}else{if(i.removeEventListener){i.removeEventListener(j,h,false)}else{i["on"+j]=null}}}catch(g){}}},_pageInit:function(h){var g=this;if(g.domLoaded){return}g.domLoaded=true;f(g.inits,function(i){i()});g.inits=[]},_wait:function(i){var g=this,h=i.document;if(i.tinyMCE_GZ&&tinyMCE_GZ.loaded){g.domLoaded=1;return}if(h.readyState==="complete"){g._pageInit(i);return}if(h.attachEvent){h.attachEvent("onreadystatechange",function(){if(h.readyState==="complete"){h.detachEvent("onreadystatechange",arguments.callee);g._pageInit(i)}});if(h.documentElement.doScroll&&i==i.top){(function(){if(g.domLoaded){return}try{h.documentElement.doScroll("left")}catch(j){setTimeout(arguments.callee,0);return}g._pageInit(i)})()}}else{if(h.addEventListener){g._add(i,"DOMContentLoaded",function(){g._pageInit(i)})}}g._add(i,"load",function(){g._pageInit(i)})},_stoppers:{preventDefault:function(){this.returnValue=false},stopPropagation:function(){this.cancelBubble=true}}});a=d.dom.Event=new d.dom.EventUtils();a._wait(window);d.addUnload(function(){a.destroy()})})(tinymce);(function(a){a.dom.Element=function(f,d){var b=this,e,c;b.settings=d=d||{};b.id=f;b.dom=e=d.dom||a.DOM;if(!a.isIE){c=e.get(b.id)}a.each(("getPos,getRect,getParent,add,setStyle,getStyle,setStyles,setAttrib,setAttribs,getAttrib,addClass,removeClass,hasClass,getOuterHTML,setOuterHTML,remove,show,hide,isHidden,setHTML,get").split(/,/),function(g){b[g]=function(){var h=[f],j;for(j=0;j<arguments.length;j++){h.push(arguments[j])}h=e[g].apply(e,h);b.update(g);return h}});a.extend(b,{on:function(i,h,g){return a.dom.Event.add(b.id,i,h,g)},getXY:function(){return{x:parseInt(b.getStyle("left")),y:parseInt(b.getStyle("top"))}},getSize:function(){var g=e.get(b.id);return{w:parseInt(b.getStyle("width")||g.clientWidth),h:parseInt(b.getStyle("height")||g.clientHeight)}},moveTo:function(g,h){b.setStyles({left:g,top:h})},moveBy:function(g,i){var h=b.getXY();b.moveTo(h.x+g,h.y+i)},resizeTo:function(g,i){b.setStyles({width:g,height:i})},resizeBy:function(g,j){var i=b.getSize();b.resizeTo(i.w+g,i.h+j)},update:function(h){var g;if(a.isIE6&&d.blocker){h=h||"";if(h.indexOf("get")===0||h.indexOf("has")===0||h.indexOf("is")===0){return}if(h=="remove"){e.remove(b.blocker);return}if(!b.blocker){b.blocker=e.uniqueId();g=e.add(d.container||e.getRoot(),"iframe",{id:b.blocker,style:"position:absolute;",frameBorder:0,src:'javascript:""'});e.setStyle(g,"opacity",0)}else{g=e.get(b.blocker)}e.setStyles(g,{left:b.getStyle("left",1),top:b.getStyle("top",1),width:b.getStyle("width",1),height:b.getStyle("height",1),display:b.getStyle("display",1),zIndex:parseInt(b.getStyle("zIndex",1)||0)-1})}}})}})(tinymce);(function(c){function e(f){return f.replace(/[\n\r]+/g,"")}var b=c.is,a=c.isIE,d=c.each;c.create("tinymce.dom.Selection",{Selection:function(i,h,g){var f=this;f.dom=i;f.win=h;f.serializer=g;d(["onBeforeSetContent","onBeforeGetContent","onSetContent","onGetContent"],function(j){f[j]=new c.util.Dispatcher(f)});if(!f.win.getSelection){f.tridentSel=new c.dom.TridentSelection(f)}if(c.isIE&&i.boxModel){this._fixIESelection()}c.addUnload(f.destroy,f)},setCursorLocation:function(h,i){var f=this;var g=f.dom.createRng();g.setStart(h,i);g.setEnd(h,i);f.setRng(g);f.collapse(false)},getContent:function(g){var f=this,h=f.getRng(),l=f.dom.create("body"),j=f.getSel(),i,k,m;g=g||{};i=k="";g.get=true;g.format=g.format||"html";g.forced_root_block="";f.onBeforeGetContent.dispatch(f,g);if(g.format=="text"){return f.isCollapsed()?"":(h.text||(j.toString?j.toString():""))}if(h.cloneContents){m=h.cloneContents();if(m){l.appendChild(m)}}else{if(b(h.item)||b(h.htmlText)){l.innerHTML="<br>"+(h.item?h.item(0).outerHTML:h.htmlText);l.removeChild(l.firstChild)}else{l.innerHTML=h.toString()}}if(/^\s/.test(l.innerHTML)){i=" "}if(/\s+$/.test(l.innerHTML)){k=" "}g.getInner=true;g.content=f.isCollapsed()?"":i+f.serializer.serialize(l,g)+k;f.onGetContent.dispatch(f,g);return g.content},setContent:function(g,i){var n=this,f=n.getRng(),j,k=n.win.document,m,l;i=i||{format:"html"};i.set=true;g=i.content=g;if(!i.no_events){n.onBeforeSetContent.dispatch(n,i)}g=i.content;if(f.insertNode){g+='<span id="__caret">_</span>';if(f.startContainer==k&&f.endContainer==k){k.body.innerHTML=g}else{f.deleteContents();if(k.body.childNodes.length==0){k.body.innerHTML=g}else{if(f.createContextualFragment){f.insertNode(f.createContextualFragment(g))}else{m=k.createDocumentFragment();l=k.createElement("div");m.appendChild(l);l.outerHTML=g;f.insertNode(m)}}}j=n.dom.get("__caret");f=k.createRange();f.setStartBefore(j);f.setEndBefore(j);n.setRng(f);n.dom.remove("__caret");try{n.setRng(f)}catch(h){}}else{if(f.item){k.execCommand("Delete",false,null);f=n.getRng()}if(/^\s+/.test(g)){f.pasteHTML('<span id="__mce_tmp">_</span>'+g);n.dom.remove("__mce_tmp")}else{f.pasteHTML(g)}}if(!i.no_events){n.onSetContent.dispatch(n,i)}},getStart:function(){var g=this.getRng(),h,f,j,i;if(g.duplicate||g.item){if(g.item){return g.item(0)}j=g.duplicate();j.collapse(1);h=j.parentElement();f=i=g.parentElement();while(i=i.parentNode){if(i==h){h=f;break}}return h}else{h=g.startContainer;if(h.nodeType==1&&h.hasChildNodes()){h=h.childNodes[Math.min(h.childNodes.length-1,g.startOffset)]}if(h&&h.nodeType==3){return h.parentNode}return h}},getEnd:function(){var g=this,h=g.getRng(),i,f;if(h.duplicate||h.item){if(h.item){return h.item(0)}h=h.duplicate();h.collapse(0);i=h.parentElement();if(i&&i.nodeName=="BODY"){return i.lastChild||i}return i}else{i=h.endContainer;f=h.endOffset;if(i.nodeType==1&&i.hasChildNodes()){i=i.childNodes[f>0?f-1:f]}if(i&&i.nodeType==3){return i.parentNode}return i}},getBookmark:function(r,s){var v=this,m=v.dom,g,j,i,n,h,o,p,l="\uFEFF",u;function f(x,y){var t=0;d(m.select(x),function(A,z){if(A==y){t=z}});return t}if(r==2){function k(){var x=v.getRng(true),t=m.getRoot(),y={};function z(C,H){var B=C[H?"startContainer":"endContainer"],G=C[H?"startOffset":"endOffset"],A=[],D,F,E=0;if(B.nodeType==3){if(s){for(D=B.previousSibling;D&&D.nodeType==3;D=D.previousSibling){G+=D.nodeValue.length}}A.push(G)}else{F=B.childNodes;if(G>=F.length&&F.length){E=1;G=Math.max(0,F.length-1)}A.push(v.dom.nodeIndex(F[G],s)+E)}for(;B&&B!=t;B=B.parentNode){A.push(v.dom.nodeIndex(B,s))}return A}y.start=z(x,true);if(!v.isCollapsed()){y.end=z(x)}return y}if(v.tridentSel){return v.tridentSel.getBookmark(r)}return k()}if(r){return{rng:v.getRng()}}g=v.getRng();i=m.uniqueId();n=tinyMCE.activeEditor.selection.isCollapsed();u="overflow:hidden;line-height:0px";if(g.duplicate||g.item){if(!g.item){j=g.duplicate();try{g.collapse();g.pasteHTML('<span data-mce-type="bookmark" id="'+i+'_start" style="'+u+'">'+l+"</span>");if(!n){j.collapse(false);g.moveToElementText(j.parentElement());if(g.compareEndPoints("StartToEnd",j)==0){j.move("character",-1)}j.pasteHTML('<span data-mce-type="bookmark" id="'+i+'_end" style="'+u+'">'+l+"</span>")}}catch(q){return null}}else{o=g.item(0);h=o.nodeName;return{name:h,index:f(h,o)}}}else{o=v.getNode();h=o.nodeName;if(h=="IMG"){return{name:h,index:f(h,o)}}j=g.cloneRange();if(!n){j.collapse(false);j.insertNode(m.create("span",{"data-mce-type":"bookmark",id:i+"_end",style:u},l))}g.collapse(true);g.insertNode(m.create("span",{"data-mce-type":"bookmark",id:i+"_start",style:u},l))}v.moveToBookmark({id:i,keep:1});return{id:i}},moveToBookmark:function(n){var r=this,l=r.dom,i,h,f,q,j,s,o,p;if(n){if(n.start){f=l.createRng();q=l.getRoot();function g(z){var t=n[z?"start":"end"],v,x,y,u;if(t){y=t[0];for(x=q,v=t.length-1;v>=1;v--){u=x.childNodes;if(t[v]>u.length-1){return}x=u[t[v]]}if(x.nodeType===3){y=Math.min(t[0],x.nodeValue.length)}if(x.nodeType===1){y=Math.min(t[0],x.childNodes.length)}if(z){f.setStart(x,y)}else{f.setEnd(x,y)}}return true}if(r.tridentSel){return r.tridentSel.moveToBookmark(n)}if(g(true)&&g()){r.setRng(f)}}else{if(n.id){function k(A){var u=l.get(n.id+"_"+A),z,t,x,y,v=n.keep;if(u){z=u.parentNode;if(A=="start"){if(!v){t=l.nodeIndex(u)}else{z=u.firstChild;t=1}j=s=z;o=p=t}else{if(!v){t=l.nodeIndex(u)}else{z=u.firstChild;t=1}s=z;p=t}if(!v){y=u.previousSibling;x=u.nextSibling;d(c.grep(u.childNodes),function(B){if(B.nodeType==3){B.nodeValue=B.nodeValue.replace(/\uFEFF/g,"")}});while(u=l.get(n.id+"_"+A)){l.remove(u,1)}if(y&&x&&y.nodeType==x.nodeType&&y.nodeType==3&&!c.isOpera){t=y.nodeValue.length;y.appendData(x.nodeValue);l.remove(x);if(A=="start"){j=s=y;o=p=t}else{s=y;p=t}}}}}function m(t){if(l.isBlock(t)&&!t.innerHTML){t.innerHTML=!a?'<br data-mce-bogus="1" />':" "}return t}k("start");k("end");if(j){f=l.createRng();f.setStart(m(j),o);f.setEnd(m(s),p);r.setRng(f)}}else{if(n.name){r.select(l.select(n.name)[n.index])}else{if(n.rng){r.setRng(n.rng)}}}}}},select:function(k,j){var i=this,l=i.dom,g=l.createRng(),f;if(k){f=l.nodeIndex(k);g.setStart(k.parentNode,f);g.setEnd(k.parentNode,f+1);if(j){function h(m,o){var n=new c.dom.TreeWalker(m,m);do{if(m.nodeType==3&&c.trim(m.nodeValue).length!=0){if(o){g.setStart(m,0)}else{g.setEnd(m,m.nodeValue.length)}return}if(m.nodeName=="BR"){if(o){g.setStartBefore(m)}else{g.setEndBefore(m)}return}}while(m=(o?n.next():n.prev()))}h(k,1);h(k)}i.setRng(g)}return k},isCollapsed:function(){var f=this,h=f.getRng(),g=f.getSel();if(!h||h.item){return false}if(h.compareEndPoints){return h.compareEndPoints("StartToEnd",h)===0}return !g||h.collapsed},collapse:function(f){var h=this,g=h.getRng(),i;if(g.item){i=g.item(0);g=h.win.document.body.createTextRange();g.moveToElementText(i)}g.collapse(!!f);h.setRng(g)},getSel:function(){var g=this,f=this.win;return f.getSelection?f.getSelection():f.document.selection},getRng:function(l){var g=this,h,i,k,j=g.win.document;if(l&&g.tridentSel){return g.tridentSel.getRangeAt(0)}try{if(h=g.getSel()){i=h.rangeCount>0?h.getRangeAt(0):(h.createRange?h.createRange():j.createRange())}}catch(f){}if(c.isIE&&i&&i.setStart&&j.selection.createRange().item){k=j.selection.createRange().item(0);i=j.createRange();i.setStartBefore(k);i.setEndAfter(k)}if(!i){i=j.createRange?j.createRange():j.body.createTextRange()}if(g.selectedRange&&g.explicitRange){if(i.compareBoundaryPoints(i.START_TO_START,g.selectedRange)===0&&i.compareBoundaryPoints(i.END_TO_END,g.selectedRange)===0){i=g.explicitRange}else{g.selectedRange=null;g.explicitRange=null}}return i},setRng:function(i){var h,g=this;if(!g.tridentSel){h=g.getSel();if(h){g.explicitRange=i;try{h.removeAllRanges()}catch(f){}h.addRange(i);g.selectedRange=h.rangeCount>0?h.getRangeAt(0):null}}else{if(i.cloneRange){g.tridentSel.addRange(i);return}try{i.select()}catch(f){}}},setNode:function(g){var f=this;f.setContent(f.dom.getOuterHTML(g));return g},getNode:function(){var h=this,g=h.getRng(),i=h.getSel(),l,k=g.startContainer,f=g.endContainer;if(!g){return h.dom.getRoot()}if(g.setStart){l=g.commonAncestorContainer;if(!g.collapsed){if(g.startContainer==g.endContainer){if(g.endOffset-g.startOffset<2){if(g.startContainer.hasChildNodes()){l=g.startContainer.childNodes[g.startOffset]}}}if(k.nodeType===3&&f.nodeType===3){function j(p,m){var o=p;while(p&&p.nodeType===3&&p.length===0){p=m?p.nextSibling:p.previousSibling}return p||o}if(k.length===g.startOffset){k=j(k.nextSibling,true)}else{k=k.parentNode}if(g.endOffset===0){f=j(f.previousSibling,false)}else{f=f.parentNode}if(k&&k===f){return k}}}if(l&&l.nodeType==3){return l.parentNode}return l}return g.item?g.item(0):g.parentElement()},getSelectedBlocks:function(o,g){var m=this,j=m.dom,l,k,h,i=[];l=j.getParent(o||m.getStart(),j.isBlock);k=j.getParent(g||m.getEnd(),j.isBlock);if(l){i.push(l)}if(l&&k&&l!=k){h=l;var f=new c.dom.TreeWalker(l,j.getRoot());while((h=f.next())&&h!=k){if(j.isBlock(h)){i.push(h)}}}if(k&&l!=k){i.push(k)}return i},normalize:function(){var g=this,f,i;if(c.isIE){return}function h(p){var k,o,n,m=g.dom,j=m.getRoot(),l;k=f[(p?"start":"end")+"Container"];o=f[(p?"start":"end")+"Offset"];if(k.nodeType===9){k=k.body;o=0}if(k===j){if(k.hasChildNodes()){k=k.childNodes[Math.min(!p&&o>0?o-1:o,k.childNodes.length-1)];o=0;if(k.hasChildNodes()){l=k;n=new c.dom.TreeWalker(k,j);do{if(l.nodeType===3){o=p?0:l.nodeValue.length-1;k=l;i=true;break}if(/^(BR|IMG)$/.test(l.nodeName)){o=m.nodeIndex(l);k=l.parentNode;if(l.nodeName=="IMG"&&!p){o++}i=true;break}}while(l=(p?n.next():n.prev()))}}}if(i){f["set"+(p?"Start":"End")](k,o)}}f=g.getRng();h(true);if(!f.collapsed){h()}if(i){g.setRng(f)}},destroy:function(g){var f=this;f.win=null;if(!g){c.removeUnload(f.destroy)}},_fixIESelection:function(){var g=this.dom,m=g.doc,h=m.body,j,n,f;m.documentElement.unselectable=true;function i(o,r){var p=h.createTextRange();try{p.moveToPoint(o,r)}catch(q){p=null}return p}function l(p){var o;if(p.button){o=i(p.x,p.y);if(o){if(o.compareEndPoints("StartToStart",n)>0){o.setEndPoint("StartToStart",n)}else{o.setEndPoint("EndToEnd",n)}o.select()}}else{k()}}function k(){var o=m.selection.createRange();if(n&&!o.item&&o.compareEndPoints("StartToEnd",o)===0){n.select()}g.unbind(m,"mouseup",k);g.unbind(m,"mousemove",l);n=j=0}g.bind(m,["mousedown","contextmenu"],function(o){if(o.target.nodeName==="HTML"){if(j){k()}f=m.documentElement;if(f.scrollHeight>f.clientHeight){return}j=1;n=i(o.x,o.y);if(n){g.bind(m,"mouseup",k);g.bind(m,"mousemove",l);g.win.focus();n.select()}}})}})})(tinymce);(function(a){a.dom.Serializer=function(e,i,f){var h,b,d=a.isIE,g=a.each,c;if(!e.apply_source_formatting){e.indent=false}i=i||a.DOM;f=f||new a.html.Schema(e);e.entity_encoding=e.entity_encoding||"named";e.remove_trailing_brs="remove_trailing_brs" in e?e.remove_trailing_brs:true;h=new a.util.Dispatcher(self);b=new a.util.Dispatcher(self);c=new a.html.DomParser(e,f);c.addAttributeFilter("src,href,style",function(k,j){var o=k.length,l,q,n="data-mce-"+j,p=e.url_converter,r=e.url_converter_scope,m;while(o--){l=k[o];q=l.attributes.map[n];if(q!==m){l.attr(j,q.length>0?q:null);l.attr(n,null)}else{q=l.attributes.map[j];if(j==="style"){q=i.serializeStyle(i.parseStyle(q),l.name)}else{if(p){q=p.call(r,q,j,l.name)}}l.attr(j,q.length>0?q:null)}}});c.addAttributeFilter("class",function(j,k){var l=j.length,m,n;while(l--){m=j[l];n=m.attr("class").replace(/\s*mce(Item\w+|Selected)\s*/g,"");m.attr("class",n.length>0?n:null)}});c.addAttributeFilter("data-mce-type",function(j,l,k){var m=j.length,n;while(m--){n=j[m];if(n.attributes.map["data-mce-type"]==="bookmark"&&!k.cleanup){n.remove()}}});c.addNodeFilter("script,style",function(k,l){var m=k.length,n,o;function j(p){return p.replace(/(<!--\[CDATA\[|\]\]-->)/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi,"").replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}while(m--){n=k[m];o=n.firstChild?n.firstChild.value:"";if(l==="script"){n.attr("type",(n.attr("type")||"text/javascript").replace(/^mce\-/,""));if(o.length>0){n.firstChild.value="// <![CDATA[\n"+j(o)+"\n// ]]>"}}else{if(o.length>0){n.firstChild.value="<!--\n"+j(o)+"\n-->"}}}});c.addNodeFilter("#comment",function(j,k){var l=j.length,m;while(l--){m=j[l];if(m.value.indexOf("[CDATA[")===0){m.name="#cdata";m.type=4;m.value=m.value.replace(/^\[CDATA\[|\]\]$/g,"")}else{if(m.value.indexOf("mce:protected ")===0){m.name="#text";m.type=3;m.raw=true;m.value=unescape(m.value).substr(14)}}}});c.addNodeFilter("xml:namespace,input",function(j,k){var l=j.length,m;while(l--){m=j[l];if(m.type===7){m.remove()}else{if(m.type===1){if(k==="input"&&!("type" in m.attributes.map)){m.attr("type","text")}}}}});if(e.fix_list_elements){c.addNodeFilter("ul,ol",function(k,l){var m=k.length,n,j;while(m--){n=k[m];j=n.parent;if(j.name==="ul"||j.name==="ol"){if(n.prev&&n.prev.name==="li"){n.prev.append(n)}}}})}c.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style",function(j,k){var l=j.length;while(l--){j[l].attr(k,null)}});return{schema:f,addNodeFilter:c.addNodeFilter,addAttributeFilter:c.addAttributeFilter,onPreProcess:h,onPostProcess:b,serialize:function(o,m){var l,p,k,j,n;if(d&&i.select("script,style,select,map").length>0){n=o.innerHTML;o=o.cloneNode(false);i.setHTML(o,n)}else{o=o.cloneNode(true)}l=o.ownerDocument.implementation;if(l.createHTMLDocument){p=l.createHTMLDocument("");g(o.nodeName=="BODY"?o.childNodes:[o],function(q){p.body.appendChild(p.importNode(q,true))});if(o.nodeName!="BODY"){o=p.body.firstChild}else{o=p.body}k=i.doc;i.doc=p}m=m||{};m.format=m.format||"html";if(!m.no_events){m.node=o;h.dispatch(self,m)}j=new a.html.Serializer(e,f);m.content=j.serialize(c.parse(m.getInner?o.innerHTML:a.trim(i.getOuterHTML(o),m),m));if(!m.cleanup){m.content=m.content.replace(/\uFEFF|\u200B/g,"")}if(!m.no_events){b.dispatch(self,m)}if(k){i.doc=k}m.node=null;return m.content},addRules:function(j){f.addValidElements(j)},setRules:function(j){f.setValidElements(j)}}}})(tinymce);(function(a){a.dom.ScriptLoader=function(h){var c=0,k=1,i=2,l={},j=[],f={},d=[],g=0,e;function b(m,v){var x=this,q=a.DOM,s,o,r,n;function p(){q.remove(n);if(s){s.onreadystatechange=s.onload=s=null}v()}function u(){if(typeof(console)!=="undefined"&&console.log){console.log("Failed to load: "+m)}}n=q.uniqueId();if(a.isIE6){o=new a.util.URI(m);r=location;if(o.host==r.hostname&&o.port==r.port&&(o.protocol+":")==r.protocol&&o.protocol.toLowerCase()!="file"){a.util.XHR.send({url:a._addVer(o.getURI()),success:function(y){var t=q.create("script",{type:"text/javascript"});t.text=y;document.getElementsByTagName("head")[0].appendChild(t);q.remove(t);p()},error:u});return}}s=q.create("script",{id:n,type:"text/javascript",src:a._addVer(m)});if(!a.isIE){s.onload=p}s.onerror=u;if(!a.isOpera){s.onreadystatechange=function(){var t=s.readyState;if(t=="complete"||t=="loaded"){p()}}}(document.getElementsByTagName("head")[0]||document.body).appendChild(s)}this.isDone=function(m){return l[m]==i};this.markDone=function(m){l[m]=i};this.add=this.load=function(m,q,n){var o,p=l[m];if(p==e){j.push(m);l[m]=c}if(q){if(!f[m]){f[m]=[]}f[m].push({func:q,scope:n||this})}};this.loadQueue=function(n,m){this.loadScripts(j,n,m)};this.loadScripts=function(m,q,p){var o;function n(r){a.each(f[r],function(s){s.func.call(s.scope)});f[r]=e}d.push({func:q,scope:p||this});o=function(){var r=a.grep(m);m.length=0;a.each(r,function(s){if(l[s]==i){n(s);return}if(l[s]!=k){l[s]=k;g++;b(s,function(){l[s]=i;g--;n(s);o()})}});if(!g){a.each(d,function(s){s.func.call(s.scope)});d.length=0}};o()}};a.ScriptLoader=new a.dom.ScriptLoader()})(tinymce);tinymce.dom.TreeWalker=function(a,c){var b=a;function d(i,f,e,j){var h,g;if(i){if(!j&&i[f]){return i[f]}if(i!=c){h=i[e];if(h){return h}for(g=i.parentNode;g&&g!=c;g=g.parentNode){h=g[e];if(h){return h}}}}}this.current=function(){return b};this.next=function(e){return(b=d(b,"firstChild","nextSibling",e))};this.prev=function(e){return(b=d(b,"lastChild","previousSibling",e))}};(function(a){a.dom.RangeUtils=function(c){var b="\uFEFF";this.walk=function(d,s){var i=d.startContainer,l=d.startOffset,t=d.endContainer,m=d.endOffset,j,g,o,h,r,q,e;e=c.select("td.mceSelected,th.mceSelected");if(e.length>0){a.each(e,function(u){s([u])});return}function f(u){var v;v=u[0];if(v.nodeType===3&&v===i&&l>=v.nodeValue.length){u.splice(0,1)}v=u[u.length-1];if(m===0&&u.length>0&&v===t&&v.nodeType===3){u.splice(u.length-1,1)}return u}function p(x,v,u){var y=[];for(;x&&x!=u;x=x[v]){y.push(x)}return y}function n(v,u){do{if(v.parentNode==u){return v}v=v.parentNode}while(v)}function k(x,v,y){var u=y?"nextSibling":"previousSibling";for(h=x,r=h.parentNode;h&&h!=v;h=r){r=h.parentNode;q=p(h==x?h:h[u],u);if(q.length){if(!y){q.reverse()}s(f(q))}}}if(i.nodeType==1&&i.hasChildNodes()){i=i.childNodes[l]}if(t.nodeType==1&&t.hasChildNodes()){t=t.childNodes[Math.min(m-1,t.childNodes.length-1)]}if(i==t){return s(f([i]))}j=c.findCommonAncestor(i,t);for(h=i;h;h=h.parentNode){if(h===t){return k(i,j,true)}if(h===j){break}}for(h=t;h;h=h.parentNode){if(h===i){return k(t,j)}if(h===j){break}}g=n(i,j)||i;o=n(t,j)||t;k(i,g,true);q=p(g==i?g:g.nextSibling,"nextSibling",o==t?o.nextSibling:o);if(q.length){s(f(q))}k(t,o)};this.split=function(e){var h=e.startContainer,d=e.startOffset,i=e.endContainer,g=e.endOffset;function f(j,k){return j.splitText(k)}if(h==i&&h.nodeType==3){if(d>0&&d<h.nodeValue.length){i=f(h,d);h=i.previousSibling;if(g>d){g=g-d;h=i=f(i,g).previousSibling;g=i.nodeValue.length;d=0}else{g=0}}}else{if(h.nodeType==3&&d>0&&d<h.nodeValue.length){h=f(h,d);d=0}if(i.nodeType==3&&g>0&&g<i.nodeValue.length){i=f(i,g).previousSibling;g=i.nodeValue.length}}return{startContainer:h,startOffset:d,endContainer:i,endOffset:g}}};a.dom.RangeUtils.compareRanges=function(c,b){if(c&&b){if(c.item||c.duplicate){if(c.item&&b.item&&c.item(0)===b.item(0)){return true}if(c.isEqual&&b.isEqual&&b.isEqual(c)){return true}}else{return c.startContainer==b.startContainer&&c.startOffset==b.startOffset}}return false}})(tinymce);(function(b){var a=b.dom.Event,c=b.each;b.create("tinymce.ui.KeyboardNavigation",{KeyboardNavigation:function(e,f){var p=this,m=e.root,l=e.items,n=e.enableUpDown,i=e.enableLeftRight||!e.enableUpDown,k=e.excludeFromTabOrder,j,h,o,d,g;f=f||b.DOM;j=function(q){g=q.target.id};h=function(q){f.setAttrib(q.target.id,"tabindex","-1")};d=function(q){var r=f.get(g);f.setAttrib(r,"tabindex","0");r.focus()};p.focus=function(){f.get(g).focus()};p.destroy=function(){c(l,function(q){f.unbind(f.get(q.id),"focus",j);f.unbind(f.get(q.id),"blur",h)});f.unbind(f.get(m),"focus",d);f.unbind(f.get(m),"keydown",o);l=f=m=p.focus=j=h=o=d=null;p.destroy=function(){}};p.moveFocus=function(u,r){var q=-1,t=p.controls,s;if(!g){return}c(l,function(x,v){if(x.id===g){q=v;return false}});q+=u;if(q<0){q=l.length-1}else{if(q>=l.length){q=0}}s=l[q];f.setAttrib(g,"tabindex","-1");f.setAttrib(s.id,"tabindex","0");f.get(s.id).focus();if(e.actOnFocus){e.onAction(s.id)}if(r){a.cancel(r)}};o=function(y){var u=37,t=39,x=38,z=40,q=27,s=14,r=13,v=32;switch(y.keyCode){case u:if(i){p.moveFocus(-1)}break;case t:if(i){p.moveFocus(1)}break;case x:if(n){p.moveFocus(-1)}break;case z:if(n){p.moveFocus(1)}break;case q:if(e.onCancel){e.onCancel();a.cancel(y)}break;case s:case r:case v:if(e.onAction){e.onAction(g);a.cancel(y)}break}};c(l,function(s,q){var r;if(!s.id){s.id=f.uniqueId("_mce_item_")}if(k){f.bind(s.id,"blur",h);r="-1"}else{r=(q===0?"0":"-1")}f.setAttrib(s.id,"tabindex",r);f.bind(f.get(s.id),"focus",j)});if(l[0]){g=l[0].id}f.setAttrib(m,"tabindex","-1");f.bind(f.get(m),"focus",d);f.bind(f.get(m),"keydown",o)}})})(tinymce);(function(c){var b=c.DOM,a=c.is;c.create("tinymce.ui.Control",{Control:function(f,e,d){this.id=f;this.settings=e=e||{};this.rendered=false;this.onRender=new c.util.Dispatcher(this);this.classPrefix="";this.scope=e.scope||this;this.disabled=0;this.active=0;this.editor=d},setAriaProperty:function(f,e){var d=b.get(this.id+"_aria")||b.get(this.id);if(d){b.setAttrib(d,"aria-"+f,!!e)}},focus:function(){b.get(this.id).focus()},setDisabled:function(d){if(d!=this.disabled){this.setAriaProperty("disabled",d);this.setState("Disabled",d);this.setState("Enabled",!d);this.disabled=d}},isDisabled:function(){return this.disabled},setActive:function(d){if(d!=this.active){this.setState("Active",d);this.active=d;this.setAriaProperty("pressed",d)}},isActive:function(){return this.active},setState:function(f,d){var e=b.get(this.id);f=this.classPrefix+f;if(d){b.addClass(e,f)}else{b.removeClass(e,f)}},isRendered:function(){return this.rendered},renderHTML:function(){},renderTo:function(d){b.setHTML(d,this.renderHTML())},postRender:function(){var e=this,d;if(a(e.disabled)){d=e.disabled;e.disabled=-1;e.setDisabled(d)}if(a(e.active)){d=e.active;e.active=-1;e.setActive(d)}},remove:function(){b.remove(this.id);this.destroy()},destroy:function(){c.dom.Event.clear(this.id)}})})(tinymce);tinymce.create("tinymce.ui.Container:tinymce.ui.Control",{Container:function(c,b,a){this.parent(c,b,a);this.controls=[];this.lookup={}},add:function(a){this.lookup[a.id]=a;this.controls.push(a);return a},get:function(a){return this.lookup[a]}});tinymce.create("tinymce.ui.Separator:tinymce.ui.Control",{Separator:function(b,a){this.parent(b,a);this.classPrefix="mceSeparator";this.setDisabled(true)},renderHTML:function(){return tinymce.DOM.createHTML("span",{"class":this.classPrefix,role:"separator","aria-orientation":"vertical",tabindex:"-1"})}});(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create("tinymce.ui.MenuItem:tinymce.ui.Control",{MenuItem:function(g,f){this.parent(g,f);this.classPrefix="mceMenuItem"},setSelected:function(f){this.setState("Selected",f);this.setAriaProperty("checked",!!f);this.selected=f},isSelected:function(){return this.selected},postRender:function(){var f=this;f.parent();if(c(f.selected)){f.setSelected(f.selected)}}})})(tinymce);(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create("tinymce.ui.Menu:tinymce.ui.MenuItem",{Menu:function(h,g){var f=this;f.parent(h,g);f.items={};f.collapsed=false;f.menuCount=0;f.onAddItem=new d.util.Dispatcher(this)},expand:function(g){var f=this;if(g){a(f,function(h){if(h.expand){h.expand()}},"items",f)}f.collapsed=false},collapse:function(g){var f=this;if(g){a(f,function(h){if(h.collapse){h.collapse()}},"items",f)}f.collapsed=true},isCollapsed:function(){return this.collapsed},add:function(f){if(!f.settings){f=new d.ui.MenuItem(f.id||b.uniqueId(),f)}this.onAddItem.dispatch(this,f);return this.items[f.id]=f},addSeparator:function(){return this.add({separator:true})},addMenu:function(f){if(!f.collapse){f=this.createMenu(f)}this.menuCount++;return this.add(f)},hasMenus:function(){return this.menuCount!==0},remove:function(f){delete this.items[f.id]},removeAll:function(){var f=this;a(f,function(g){if(g.removeAll){g.removeAll()}else{g.remove()}g.destroy()},"items",f);f.items={}},createMenu:function(g){var f=new d.ui.Menu(g.id||b.uniqueId(),g);f.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return f}})})(tinymce);(function(e){var d=e.is,c=e.DOM,f=e.each,a=e.dom.Event,b=e.dom.Element;e.create("tinymce.ui.DropMenu:tinymce.ui.Menu",{DropMenu:function(h,g){g=g||{};g.container=g.container||c.doc.body;g.offset_x=g.offset_x||0;g.offset_y=g.offset_y||0;g.vp_offset_x=g.vp_offset_x||0;g.vp_offset_y=g.vp_offset_y||0;if(d(g.icons)&&!g.icons){g["class"]+=" mceNoIcons"}this.parent(h,g);this.onShowMenu=new e.util.Dispatcher(this);this.onHideMenu=new e.util.Dispatcher(this);this.classPrefix="mceMenu"},createMenu:function(j){var h=this,i=h.settings,g;j.container=j.container||i.container;j.parent=h;j.constrain=j.constrain||i.constrain;j["class"]=j["class"]||i["class"];j.vp_offset_x=j.vp_offset_x||i.vp_offset_x;j.vp_offset_y=j.vp_offset_y||i.vp_offset_y;j.keyboard_focus=i.keyboard_focus;g=new e.ui.DropMenu(j.id||c.uniqueId(),j);g.onAddItem.add(h.onAddItem.dispatch,h.onAddItem);return g},focus:function(){var g=this;if(g.keyboardNav){g.keyboardNav.focus()}},update:function(){var i=this,j=i.settings,g=c.get("menu_"+i.id+"_tbl"),l=c.get("menu_"+i.id+"_co"),h,k;h=j.max_width?Math.min(g.clientWidth,j.max_width):g.clientWidth;k=j.max_height?Math.min(g.clientHeight,j.max_height):g.clientHeight;if(!c.boxModel){i.element.setStyles({width:h+2,height:k+2})}else{i.element.setStyles({width:h,height:k})}if(j.max_width){c.setStyle(l,"width",h)}if(j.max_height){c.setStyle(l,"height",k);if(g.clientHeight<j.max_height){c.setStyle(l,"overflow","hidden")}}},showMenu:function(p,n,r){var z=this,A=z.settings,o,g=c.getViewPort(),u,l,v,q,i=2,k,j,m=z.classPrefix;z.collapse(1);if(z.isMenuVisible){return}if(!z.rendered){o=c.add(z.settings.container,z.renderNode());f(z.items,function(h){h.postRender()});z.element=new b("menu_"+z.id,{blocker:1,container:A.container})}else{o=c.get("menu_"+z.id)}if(!e.isOpera){c.setStyles(o,{left:-65535,top:-65535})}c.show(o);z.update();p+=A.offset_x||0;n+=A.offset_y||0;g.w-=4;g.h-=4;if(A.constrain){u=o.clientWidth-i;l=o.clientHeight-i;v=g.x+g.w;q=g.y+g.h;if((p+A.vp_offset_x+u)>v){p=r?r-u:Math.max(0,(v-A.vp_offset_x)-u)}if((n+A.vp_offset_y+l)>q){n=Math.max(0,(q-A.vp_offset_y)-l)}}c.setStyles(o,{left:p,top:n});z.element.update();z.isMenuVisible=1;z.mouseClickFunc=a.add(o,"click",function(s){var h;s=s.target;if(s&&(s=c.getParent(s,"tr"))&&!c.hasClass(s,m+"ItemSub")){h=z.items[s.id];if(h.isDisabled()){return}k=z;while(k){if(k.hideMenu){k.hideMenu()}k=k.settings.parent}if(h.settings.onclick){h.settings.onclick(s)}return a.cancel(s)}});if(z.hasMenus()){z.mouseOverFunc=a.add(o,"mouseover",function(x){var h,t,s;x=x.target;if(x&&(x=c.getParent(x,"tr"))){h=z.items[x.id];if(z.lastMenu){z.lastMenu.collapse(1)}if(h.isDisabled()){return}if(x&&c.hasClass(x,m+"ItemSub")){t=c.getRect(x);h.showMenu((t.x+t.w-i),t.y-i,t.x);z.lastMenu=h;c.addClass(c.get(h.id).firstChild,m+"ItemActive")}}})}a.add(o,"keydown",z._keyHandler,z);z.onShowMenu.dispatch(z);if(A.keyboard_focus){z._setupKeyboardNav()}},hideMenu:function(j){var g=this,i=c.get("menu_"+g.id),h;if(!g.isMenuVisible){return}if(g.keyboardNav){g.keyboardNav.destroy()}a.remove(i,"mouseover",g.mouseOverFunc);a.remove(i,"click",g.mouseClickFunc);a.remove(i,"keydown",g._keyHandler);c.hide(i);g.isMenuVisible=0;if(!j){g.collapse(1)}if(g.element){g.element.hide()}if(h=c.get(g.id)){c.removeClass(h.firstChild,g.classPrefix+"ItemActive")}g.onHideMenu.dispatch(g)},add:function(i){var g=this,h;i=g.parent(i);if(g.isRendered&&(h=c.get("menu_"+g.id))){g._add(c.select("tbody",h)[0],i)}return i},collapse:function(g){this.parent(g);this.hideMenu(1)},remove:function(g){c.remove(g.id);this.destroy();return this.parent(g)},destroy:function(){var g=this,h=c.get("menu_"+g.id);if(g.keyboardNav){g.keyboardNav.destroy()}a.remove(h,"mouseover",g.mouseOverFunc);a.remove(c.select("a",h),"focus",g.mouseOverFunc);a.remove(h,"click",g.mouseClickFunc);a.remove(h,"keydown",g._keyHandler);if(g.element){g.element.remove()}c.remove(h)},renderNode:function(){var i=this,j=i.settings,l,h,k,g;g=c.create("div",{role:"listbox",id:"menu_"+i.id,"class":j["class"],style:"position:absolute;left:0;top:0;z-index:200000;outline:0"});if(i.settings.parent){c.setAttrib(g,"aria-parent","menu_"+i.settings.parent.id)}k=c.add(g,"div",{role:"presentation",id:"menu_"+i.id+"_co","class":i.classPrefix+(j["class"]?" "+j["class"]:"")});i.element=new b("menu_"+i.id,{blocker:1,container:j.container});if(j.menu_line){c.add(k,"span",{"class":i.classPrefix+"Line"})}l=c.add(k,"table",{role:"presentation",id:"menu_"+i.id+"_tbl",border:0,cellPadding:0,cellSpacing:0});h=c.add(l,"tbody");f(i.items,function(m){i._add(h,m)});i.rendered=true;return g},_setupKeyboardNav:function(){var i,h,g=this;i=c.get("menu_"+g.id);h=c.select("a[role=option]","menu_"+g.id);h.splice(0,0,i);g.keyboardNav=new e.ui.KeyboardNavigation({root:"menu_"+g.id,items:h,onCancel:function(){g.hideMenu()},enableUpDown:true});i.focus()},_keyHandler:function(g){var h=this,i;switch(g.keyCode){case 37:if(h.settings.parent){h.hideMenu();h.settings.parent.focus();a.cancel(g)}break;case 39:if(h.mouseOverFunc){h.mouseOverFunc(g)}break}},_add:function(j,h){var i,q=h.settings,p,l,k,m=this.classPrefix,g;if(q.separator){l=c.add(j,"tr",{id:h.id,"class":m+"ItemSeparator"});c.add(l,"td",{"class":m+"ItemSeparator"});if(i=l.previousSibling){c.addClass(i,"mceLast")}return}i=l=c.add(j,"tr",{id:h.id,"class":m+"Item "+m+"ItemEnabled"});i=k=c.add(i,q.titleItem?"th":"td");i=p=c.add(i,"a",{id:h.id+"_aria",role:q.titleItem?"presentation":"option",href:"javascript:;",onclick:"return false;",onmousedown:"return false;"});if(q.parent){c.setAttrib(p,"aria-haspopup","true");c.setAttrib(p,"aria-owns","menu_"+h.id)}c.addClass(k,q["class"]);g=c.add(i,"span",{"class":"mceIcon"+(q.icon?" mce_"+q.icon:"")});if(q.icon_src){c.add(g,"img",{src:q.icon_src})}i=c.add(i,q.element||"span",{"class":"mceText",title:h.settings.title},h.settings.title);if(h.settings.style){c.setAttrib(i,"style",h.settings.style)}if(j.childNodes.length==1){c.addClass(l,"mceFirst")}if((i=l.previousSibling)&&c.hasClass(i,m+"ItemSeparator")){c.addClass(l,"mceFirst")}if(h.collapse){c.addClass(l,m+"ItemSub")}if(i=l.previousSibling){c.removeClass(i,"mceLast")}c.addClass(l,"mceLast")}})})(tinymce);(function(b){var a=b.DOM;b.create("tinymce.ui.Button:tinymce.ui.Control",{Button:function(e,d,c){this.parent(e,d,c);this.classPrefix="mceButton"},renderHTML:function(){var f=this.classPrefix,e=this.settings,d,c;c=a.encode(e.label||"");d='<a role="button" id="'+this.id+'" href="javascript:;" class="'+f+" "+f+"Enabled "+e["class"]+(c?" "+f+"Labeled":"")+'" onmousedown="return false;" onclick="return false;" aria-labelledby="'+this.id+'_voice" title="'+a.encode(e.title)+'">';if(e.image&&!(this.editor&&this.editor.forcedHighContrastMode)){d+='<img class="mceIcon" src="'+e.image+'" alt="'+a.encode(e.title)+'" />'+c}else{d+='<span class="mceIcon '+e["class"]+'"></span>'+(c?'<span class="'+f+'Label">'+c+"</span>":"")}d+='<span class="mceVoiceLabel mceIconOnly" style="display: none;" id="'+this.id+'_voice">'+e.title+"</span>";d+="</a>";return d},postRender:function(){var d=this,e=d.settings,c;if(b.isIE&&d.editor){b.dom.Event.add(d.id,"mousedown",function(f){var g=d.editor.selection.getNode().nodeName;c=g==="IMG"?d.editor.selection.getBookmark():null})}b.dom.Event.add(d.id,"click",function(f){if(!d.isDisabled()){if(b.isIE&&d.editor&&c!==null){d.editor.selection.moveToBookmark(c)}return e.onclick.call(e.scope,f)}});b.dom.Event.add(d.id,"keyup",function(f){if(!d.isDisabled()&&f.keyCode==b.VK.SPACEBAR){return e.onclick.call(e.scope,f)}})}})})(tinymce);(function(d){var c=d.DOM,b=d.dom.Event,e=d.each,a=d.util.Dispatcher;d.create("tinymce.ui.ListBox:tinymce.ui.Control",{ListBox:function(i,h,f){var g=this;g.parent(i,h,f);g.items=[];g.onChange=new a(g);g.onPostRender=new a(g);g.onAdd=new a(g);g.onRenderMenu=new d.util.Dispatcher(this);g.classPrefix="mceListBox"},select:function(h){var g=this,j,i;if(h==undefined){return g.selectByIndex(-1)}if(h&&typeof(h)=="function"){i=h}else{i=function(f){return f==h}}if(h!=g.selectedValue){e(g.items,function(k,f){if(i(k.value)){j=1;g.selectByIndex(f);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(f){var h=this,i,j,g;if(f!=h.selectedIndex){i=c.get(h.id+"_text");g=c.get(h.id+"_voiceDesc");j=h.items[f];if(j){h.selectedValue=j.value;h.selectedIndex=f;c.setHTML(i,c.encode(j.title));c.setHTML(g,h.settings.title+" - "+j.title);c.removeClass(i,"mceTitle");c.setAttrib(h.id,"aria-valuenow",j.title)}else{c.setHTML(i,c.encode(h.settings.title));c.setHTML(g,c.encode(h.settings.title));c.addClass(i,"mceTitle");h.selectedValue=h.selectedIndex=null;c.setAttrib(h.id,"aria-valuenow",h.settings.title)}i=0}},add:function(i,f,h){var g=this;h=h||{};h=d.extend(h,{title:i,value:f});g.items.push(h);g.onAdd.dispatch(g,h)},getLength:function(){return this.items.length},renderHTML:function(){var i="",f=this,g=f.settings,j=f.classPrefix;i='<span role="listbox" aria-haspopup="true" aria-labelledby="'+f.id+'_voiceDesc" aria-describedby="'+f.id+'_voiceDesc"><table role="presentation" tabindex="0" id="'+f.id+'" cellpadding="0" cellspacing="0" class="'+j+" "+j+"Enabled"+(g["class"]?(" "+g["class"]):"")+'"><tbody><tr>';i+="<td>"+c.createHTML("span",{id:f.id+"_voiceDesc","class":"voiceLabel",style:"display:none;"},f.settings.title);i+=c.createHTML("a",{id:f.id+"_text",tabindex:-1,href:"javascript:;","class":"mceText",onclick:"return false;",onmousedown:"return false;"},c.encode(f.settings.title))+"</td>";i+="<td>"+c.createHTML("a",{id:f.id+"_open",tabindex:-1,href:"javascript:;","class":"mceOpen",onclick:"return false;",onmousedown:"return false;"},'<span><span style="display:none;" class="mceIconOnly" aria-hidden="true">\u25BC</span></span>')+"</td>";i+="</tr></tbody></table></span>";return i},showMenu:function(){var g=this,i,h=c.get(this.id),f;if(g.isDisabled()||g.items.length==0){return}if(g.menu&&g.menu.isMenuVisible){return g.hideMenu()}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}i=c.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.keyboard_focus=!d.isOpera;if(g.oldID){f.items[g.oldID].setSelected(0)}e(g.items,function(j){if(j.value===g.selectedValue){f.items[j.id].setSelected(1);g.oldID=j.id}});f.showMenu(0,h.clientHeight);b.add(c.doc,"mousedown",g.hideMenu,g);c.addClass(g.id,g.classPrefix+"Selected")},hideMenu:function(g){var f=this;if(f.menu&&f.menu.isMenuVisible){c.removeClass(f.id,f.classPrefix+"Selected");if(g&&g.type=="mousedown"&&(g.target.id==f.id+"_text"||g.target.id==f.id+"_open")){return}if(!g||!c.getParent(g.target,".mceMenu")){c.removeClass(f.id,f.classPrefix+"Selected");b.remove(c.doc,"mousedown",f.hideMenu,f);f.menu.hideMenu()}}},renderMenu:function(){var g=this,f;f=g.settings.control_manager.createDropMenu(g.id+"_menu",{menu_line:1,"class":g.classPrefix+"Menu mceNoIcons",max_width:150,max_height:150});f.onHideMenu.add(function(){g.hideMenu();g.focus()});f.add({title:g.settings.title,"class":"mceMenuItemTitle",onclick:function(){if(g.settings.onselect("")!==false){g.select("")}}});e(g.items,function(h){if(h.value===undefined){f.add({title:h.title,role:"option","class":"mceMenuItemTitle",onclick:function(){if(g.settings.onselect("")!==false){g.select("")}}})}else{h.id=c.uniqueId();h.role="option";h.onclick=function(){if(g.settings.onselect(h.value)!==false){g.select(h.value)}};f.add(h)}});g.onRenderMenu.dispatch(g,f);g.menu=f},postRender:function(){var f=this,g=f.classPrefix;b.add(f.id,"click",f.showMenu,f);b.add(f.id,"keydown",function(h){if(h.keyCode==32){f.showMenu(h);b.cancel(h)}});b.add(f.id,"focus",function(){if(!f._focused){f.keyDownHandler=b.add(f.id,"keydown",function(h){if(h.keyCode==40){f.showMenu();b.cancel(h)}});f.keyPressHandler=b.add(f.id,"keypress",function(i){var h;if(i.keyCode==13){h=f.selectedValue;f.selectedValue=null;b.cancel(i);f.settings.onselect(h)}})}f._focused=1});b.add(f.id,"blur",function(){b.remove(f.id,"keydown",f.keyDownHandler);b.remove(f.id,"keypress",f.keyPressHandler);f._focused=0});if(d.isIE6||!c.boxModel){b.add(f.id,"mouseover",function(){if(!c.hasClass(f.id,g+"Disabled")){c.addClass(f.id,g+"Hover")}});b.add(f.id,"mouseout",function(){if(!c.hasClass(f.id,g+"Disabled")){c.removeClass(f.id,g+"Hover")}})}f.onPostRender.dispatch(f,c.get(f.id))},destroy:function(){this.parent();b.clear(this.id+"_text");b.clear(this.id+"_open")}})})(tinymce);(function(d){var c=d.DOM,b=d.dom.Event,e=d.each,a=d.util.Dispatcher;d.create("tinymce.ui.NativeListBox:tinymce.ui.ListBox",{NativeListBox:function(g,f){this.parent(g,f);this.classPrefix="mceNativeListBox"},setDisabled:function(f){c.get(this.id).disabled=f;this.setAriaProperty("disabled",f)},isDisabled:function(){return c.get(this.id).disabled},select:function(h){var g=this,j,i;if(h==undefined){return g.selectByIndex(-1)}if(h&&typeof(h)=="function"){i=h}else{i=function(f){return f==h}}if(h!=g.selectedValue){e(g.items,function(k,f){if(i(k.value)){j=1;g.selectByIndex(f);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(f){c.get(this.id).selectedIndex=f+1;this.selectedValue=this.items[f]?this.items[f].value:null},add:function(j,g,f){var i,h=this;f=f||{};f.value=g;if(h.isRendered()){c.add(c.get(this.id),"option",f,j)}i={title:j,value:g,attribs:f};h.items.push(i);h.onAdd.dispatch(h,i)},getLength:function(){return this.items.length},renderHTML:function(){var g,f=this;g=c.createHTML("option",{value:""},"-- "+f.settings.title+" --");e(f.items,function(h){g+=c.createHTML("option",{value:h.value},h.title)});g=c.createHTML("select",{id:f.id,"class":"mceNativeListBox","aria-labelledby":f.id+"_aria"},g);g+=c.createHTML("span",{id:f.id+"_aria",style:"display: none"},f.settings.title);return g},postRender:function(){var g=this,h,i=true;g.rendered=true;function f(k){var j=g.items[k.target.selectedIndex-1];if(j&&(j=j.value)){g.onChange.dispatch(g,j);if(g.settings.onselect){g.settings.onselect(j)}}}b.add(g.id,"change",f);b.add(g.id,"keydown",function(k){var j;b.remove(g.id,"change",h);i=false;j=b.add(g.id,"blur",function(){if(i){return}i=true;b.add(g.id,"change",f);b.remove(g.id,"blur",j)});if(d.isWebKit&&(k.keyCode==37||k.keyCode==39)){return b.prevent(k)}if(k.keyCode==13||k.keyCode==32){f(k);return b.cancel(k)}});g.onPostRender.dispatch(g,c.get(g.id))}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create("tinymce.ui.MenuButton:tinymce.ui.Button",{MenuButton:function(g,f,e){this.parent(g,f,e);this.onRenderMenu=new c.util.Dispatcher(this);f.menu_container=f.menu_container||b.doc.body},showMenu:function(){var g=this,j,i,h=b.get(g.id),f;if(g.isDisabled()){return}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}if(g.isMenuVisible){return g.hideMenu()}j=b.getPos(g.settings.menu_container);i=b.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.vp_offset_x=i.x;f.settings.vp_offset_y=i.y;f.settings.keyboard_focus=g._focused;f.showMenu(0,h.clientHeight);a.add(b.doc,"mousedown",g.hideMenu,g);g.setState("Selected",1);g.isMenuVisible=1},renderMenu:function(){var f=this,e;e=f.settings.control_manager.createDropMenu(f.id+"_menu",{menu_line:1,"class":this.classPrefix+"Menu",icons:f.settings.icons});e.onHideMenu.add(function(){f.hideMenu();f.focus()});f.onRenderMenu.dispatch(f,e);f.menu=e},hideMenu:function(g){var f=this;if(g&&g.type=="mousedown"&&b.getParent(g.target,function(h){return h.id===f.id||h.id===f.id+"_open"})){return}if(!g||!b.getParent(g.target,".mceMenu")){f.setState("Selected",0);a.remove(b.doc,"mousedown",f.hideMenu,f);if(f.menu){f.menu.hideMenu()}}f.isMenuVisible=0},postRender:function(){var e=this,f=e.settings;a.add(e.id,"click",function(){if(!e.isDisabled()){if(f.onclick){f.onclick(e.value)}e.showMenu()}})}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create("tinymce.ui.SplitButton:tinymce.ui.MenuButton",{SplitButton:function(g,f,e){this.parent(g,f,e);this.classPrefix="mceSplitButton"},renderHTML:function(){var i,f=this,g=f.settings,e;i="<tbody><tr>";if(g.image){e=b.createHTML("img ",{src:g.image,role:"presentation","class":"mceAction "+g["class"]})}else{e=b.createHTML("span",{"class":"mceAction "+g["class"]},"")}e+=b.createHTML("span",{"class":"mceVoiceLabel mceIconOnly",id:f.id+"_voice",style:"display:none;"},g.title);i+="<td >"+b.createHTML("a",{role:"button",id:f.id+"_action",tabindex:"-1",href:"javascript:;","class":"mceAction "+g["class"],onclick:"return false;",onmousedown:"return false;",title:g.title},e)+"</td>";e=b.createHTML("span",{"class":"mceOpen "+g["class"]},'<span style="display:none;" class="mceIconOnly" aria-hidden="true">\u25BC</span>');i+="<td >"+b.createHTML("a",{role:"button",id:f.id+"_open",tabindex:"-1",href:"javascript:;","class":"mceOpen "+g["class"],onclick:"return false;",onmousedown:"return false;",title:g.title},e)+"</td>";i+="</tr></tbody>";i=b.createHTML("table",{role:"presentation","class":"mceSplitButton mceSplitButtonEnabled "+g["class"],cellpadding:"0",cellspacing:"0",title:g.title},i);return b.createHTML("div",{id:f.id,role:"button",tabindex:"0","aria-labelledby":f.id+"_voice","aria-haspopup":"true"},i)},postRender:function(){var e=this,g=e.settings,f;if(g.onclick){f=function(h){if(!e.isDisabled()){g.onclick(e.value);a.cancel(h)}};a.add(e.id+"_action","click",f);a.add(e.id,["click","keydown"],function(h){var k=32,m=14,i=13,j=38,l=40;if((h.keyCode===32||h.keyCode===13||h.keyCode===14)&&!h.altKey&&!h.ctrlKey&&!h.metaKey){f();a.cancel(h)}else{if(h.type==="click"||h.keyCode===l){e.showMenu();a.cancel(h)}}})}a.add(e.id+"_open","click",function(h){e.showMenu();a.cancel(h)});a.add([e.id,e.id+"_open"],"focus",function(){e._focused=1});a.add([e.id,e.id+"_open"],"blur",function(){e._focused=0});if(c.isIE6||!b.boxModel){a.add(e.id,"mouseover",function(){if(!b.hasClass(e.id,"mceSplitButtonDisabled")){b.addClass(e.id,"mceSplitButtonHover")}});a.add(e.id,"mouseout",function(){if(!b.hasClass(e.id,"mceSplitButtonDisabled")){b.removeClass(e.id,"mceSplitButtonHover")}})}},destroy:function(){this.parent();a.clear(this.id+"_action");a.clear(this.id+"_open");a.clear(this.id)}})})(tinymce);(function(d){var c=d.DOM,a=d.dom.Event,b=d.is,e=d.each;d.create("tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton",{ColorSplitButton:function(i,h,f){var g=this;g.parent(i,h,f);g.settings=h=d.extend({colors:"000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF",grid_width:8,default_color:"#888888"},g.settings);g.onShowMenu=new d.util.Dispatcher(g);g.onHideMenu=new d.util.Dispatcher(g);g.value=h.default_color},showMenu:function(){var f=this,g,j,i,h;if(f.isDisabled()){return}if(!f.isMenuRendered){f.renderMenu();f.isMenuRendered=true}if(f.isMenuVisible){return f.hideMenu()}i=c.get(f.id);c.show(f.id+"_menu");c.addClass(i,"mceSplitButtonSelected");h=c.getPos(i);c.setStyles(f.id+"_menu",{left:h.x,top:h.y+i.clientHeight,zIndex:200000});i=0;a.add(c.doc,"mousedown",f.hideMenu,f);f.onShowMenu.dispatch(f);if(f._focused){f._keyHandler=a.add(f.id+"_menu","keydown",function(k){if(k.keyCode==27){f.hideMenu()}});c.select("a",f.id+"_menu")[0].focus()}f.isMenuVisible=1},hideMenu:function(g){var f=this;if(f.isMenuVisible){if(g&&g.type=="mousedown"&&c.getParent(g.target,function(h){return h.id===f.id+"_open"})){return}if(!g||!c.getParent(g.target,".mceSplitButtonMenu")){c.removeClass(f.id,"mceSplitButtonSelected");a.remove(c.doc,"mousedown",f.hideMenu,f);a.remove(f.id+"_menu","keydown",f._keyHandler);c.hide(f.id+"_menu")}f.isMenuVisible=0;f.onHideMenu.dispatch()}},renderMenu:function(){var p=this,h,k=0,q=p.settings,g,j,l,o,f;o=c.add(q.menu_container,"div",{role:"listbox",id:p.id+"_menu","class":q.menu_class+" "+q["class"],style:"position:absolute;left:0;top:-1000px;"});h=c.add(o,"div",{"class":q["class"]+" mceSplitButtonMenu"});c.add(h,"span",{"class":"mceMenuLine"});g=c.add(h,"table",{role:"presentation","class":"mceColorSplitMenu"});j=c.add(g,"tbody");k=0;e(b(q.colors,"array")?q.colors:q.colors.split(","),function(m){m=m.replace(/^#/,"");if(!k--){l=c.add(j,"tr");k=q.grid_width-1}g=c.add(l,"td");var i={href:"javascript:;",style:{backgroundColor:"#"+m},title:p.editor.getLang("colors."+m,m),"data-mce-color":"#"+m};if(!d.isIE){i.role="option"}g=c.add(g,"a",i);if(p.editor.forcedHighContrastMode){g=c.add(g,"canvas",{width:16,height:16,"aria-hidden":"true"});if(g.getContext&&(f=g.getContext("2d"))){f.fillStyle="#"+m;f.fillRect(0,0,16,16)}else{c.remove(g)}}});if(q.more_colors_func){g=c.add(j,"tr");g=c.add(g,"td",{colspan:q.grid_width,"class":"mceMoreColors"});g=c.add(g,"a",{role:"option",id:p.id+"_more",href:"javascript:;",onclick:"return false;","class":"mceMoreColors"},q.more_colors_title);a.add(g,"click",function(i){q.more_colors_func.call(q.more_colors_scope||this);return a.cancel(i)})}c.addClass(h,"mceColorSplitMenu");new d.ui.KeyboardNavigation({root:p.id+"_menu",items:c.select("a",p.id+"_menu"),onCancel:function(){p.hideMenu();p.focus()}});a.add(p.id+"_menu","mousedown",function(i){return a.cancel(i)});a.add(p.id+"_menu","click",function(i){var m;i=c.getParent(i.target,"a",j);if(i&&i.nodeName.toLowerCase()=="a"&&(m=i.getAttribute("data-mce-color"))){p.setColor(m)}return a.cancel(i)});return o},setColor:function(f){this.displayColor(f);this.hideMenu();this.settings.onselect(f)},displayColor:function(g){var f=this;c.setStyle(f.id+"_preview","backgroundColor",g);f.value=g},postRender:function(){var f=this,g=f.id;f.parent();c.add(g+"_action","div",{id:g+"_preview","class":"mceColorPreview"});c.setStyle(f.id+"_preview","backgroundColor",f.value)},destroy:function(){this.parent();a.clear(this.id+"_menu");a.clear(this.id+"_more");c.remove(this.id+"_menu")}})})(tinymce);(function(b){var d=b.DOM,c=b.each,a=b.dom.Event;b.create("tinymce.ui.ToolbarGroup:tinymce.ui.Container",{renderHTML:function(){var f=this,i=[],e=f.controls,j=b.each,g=f.settings;i.push('<div id="'+f.id+'" role="group" aria-labelledby="'+f.id+'_voice">');i.push("<span role='application'>");i.push('<span id="'+f.id+'_voice" class="mceVoiceLabel" style="display:none;">'+d.encode(g.name)+"</span>");j(e,function(h){i.push(h.renderHTML())});i.push("</span>");i.push("</div>");return i.join("")},focus:function(){var e=this;d.get(e.id).focus()},postRender:function(){var f=this,e=[];c(f.controls,function(g){c(g.controls,function(h){if(h.id){e.push(h)}})});f.keyNav=new b.ui.KeyboardNavigation({root:f.id,items:e,onCancel:function(){if(b.isWebKit){d.get(f.editor.id+"_ifr").focus()}f.editor.focus()},excludeFromTabOrder:!f.settings.tab_focus_toolbar})},destroy:function(){var e=this;e.parent();e.keyNav.destroy();a.clear(e.id)}})})(tinymce);(function(a){var c=a.DOM,b=a.each;a.create("tinymce.ui.Toolbar:tinymce.ui.Container",{renderHTML:function(){var m=this,f="",j,k,n=m.settings,e,d,g,l;l=m.controls;for(e=0;e<l.length;e++){k=l[e];d=l[e-1];g=l[e+1];if(e===0){j="mceToolbarStart";if(k.Button){j+=" mceToolbarStartButton"}else{if(k.SplitButton){j+=" mceToolbarStartSplitButton"}else{if(k.ListBox){j+=" mceToolbarStartListBox"}}}f+=c.createHTML("td",{"class":j},c.createHTML("span",null,"<!-- IE -->"))}if(d&&k.ListBox){if(d.Button||d.SplitButton){f+=c.createHTML("td",{"class":"mceToolbarEnd"},c.createHTML("span",null,"<!-- IE -->"))}}if(c.stdMode){f+='<td style="position: relative">'+k.renderHTML()+"</td>"}else{f+="<td>"+k.renderHTML()+"</td>"}if(g&&k.ListBox){if(g.Button||g.SplitButton){f+=c.createHTML("td",{"class":"mceToolbarStart"},c.createHTML("span",null,"<!-- IE -->"))}}}j="mceToolbarEnd";if(k.Button){j+=" mceToolbarEndButton"}else{if(k.SplitButton){j+=" mceToolbarEndSplitButton"}else{if(k.ListBox){j+=" mceToolbarEndListBox"}}}f+=c.createHTML("td",{"class":j},c.createHTML("span",null,"<!-- IE -->"));return c.createHTML("table",{id:m.id,"class":"mceToolbar"+(n["class"]?" "+n["class"]:""),cellpadding:"0",cellspacing:"0",align:m.settings.align||"",role:"presentation",tabindex:"-1"},"<tbody><tr>"+f+"</tr></tbody>")}})})(tinymce);(function(b){var a=b.util.Dispatcher,c=b.each;b.create("tinymce.AddOnManager",{AddOnManager:function(){var d=this;d.items=[];d.urls={};d.lookup={};d.onAdd=new a(d)},get:function(d){if(this.lookup[d]){return this.lookup[d].instance}else{return undefined}},dependencies:function(e){var d;if(this.lookup[e]){d=this.lookup[e].dependencies}return d||[]},requireLangPack:function(e){var d=b.settings;if(d&&d.language&&d.language_load!==false){b.ScriptLoader.add(this.urls[e]+"/langs/"+d.language+".js")}},add:function(f,e,d){this.items.push(e);this.lookup[f]={instance:e,dependencies:d};this.onAdd.dispatch(this,f,e);return e},createUrl:function(d,e){if(typeof e==="object"){return e}else{return{prefix:d.prefix,resource:e,suffix:d.suffix}}},addComponents:function(f,d){var e=this.urls[f];b.each(d,function(g){b.ScriptLoader.add(e+"/"+g)})},load:function(j,f,d,h){var g=this,e=f;function i(){var k=g.dependencies(j);b.each(k,function(m){var l=g.createUrl(f,m);g.load(l.resource,l,undefined,undefined)});if(d){if(h){d.call(h)}else{d.call(b.ScriptLoader)}}}if(g.urls[j]){return}if(typeof f==="object"){e=f.prefix+f.resource+f.suffix}if(e.indexOf("/")!=0&&e.indexOf("://")==-1){e=b.baseURL+"/"+e}g.urls[j]=e.substring(0,e.lastIndexOf("/"));if(g.lookup[j]){i()}else{b.ScriptLoader.add(e,i,h)}}});b.PluginManager=new b.AddOnManager();b.ThemeManager=new b.AddOnManager()}(tinymce));(function(j){var g=j.each,d=j.extend,k=j.DOM,i=j.dom.Event,f=j.ThemeManager,b=j.PluginManager,e=j.explode,h=j.util.Dispatcher,a,c=0;j.documentBaseURL=window.location.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");if(!/[\/\\]$/.test(j.documentBaseURL)){j.documentBaseURL+="/"}j.baseURL=new j.util.URI(j.documentBaseURL).toAbsolute(j.baseURL);j.baseURI=new j.util.URI(j.baseURL);j.onBeforeUnload=new h(j);i.add(window,"beforeunload",function(l){j.onBeforeUnload.dispatch(j,l)});j.onAddEditor=new h(j);j.onRemoveEditor=new h(j);j.EditorManager=d(j,{editors:[],i18n:{},activeEditor:null,init:function(q){var n=this,p,l=j.ScriptLoader,u,o=[],m;function r(x,y,t){var v=x[y];if(!v){return}if(j.is(v,"string")){t=v.replace(/\.\w+$/,"");t=t?j.resolve(t):0;v=j.resolve(v)}return v.apply(t||this,Array.prototype.slice.call(arguments,2))}q=d({theme:"simple",language:"en"},q);n.settings=q;i.add(document,"init",function(){var s,v;r(q,"onpageload");switch(q.mode){case"exact":s=q.elements||"";if(s.length>0){g(e(s),function(x){if(k.get(x)){m=new j.Editor(x,q);o.push(m);m.render(1)}else{g(document.forms,function(y){g(y.elements,function(z){if(z.name===x){x="mce_editor_"+c++;k.setAttrib(z,"id",x);m=new j.Editor(x,q);o.push(m);m.render(1)}})})}})}break;case"textareas":case"specific_textareas":function t(y,x){return x.constructor===RegExp?x.test(y.className):k.hasClass(y,x)}g(k.select("textarea"),function(x){if(q.editor_deselector&&t(x,q.editor_deselector)){return}if(!q.editor_selector||t(x,q.editor_selector)){u=k.get(x.name);if(!x.id&&!u){x.id=x.name}if(!x.id||n.get(x.id)){x.id=k.uniqueId()}m=new j.Editor(x.id,q);o.push(m);m.render(1)}});break}if(q.oninit){s=v=0;g(o,function(x){v++;if(!x.initialized){x.onInit.add(function(){s++;if(s==v){r(q,"oninit")}})}else{s++}if(s==v){r(q,"oninit")}})}})},get:function(l){if(l===a){return this.editors}return this.editors[l]},getInstanceById:function(l){return this.get(l)},add:function(m){var l=this,n=l.editors;n[m.id]=m;n.push(m);l._setActive(m);l.onAddEditor.dispatch(l,m);return m},remove:function(n){var m=this,l,o=m.editors;if(!o[n.id]){return null}delete o[n.id];for(l=0;l<o.length;l++){if(o[l]==n){o.splice(l,1);break}}if(m.activeEditor==n){m._setActive(o[0])}n.destroy();m.onRemoveEditor.dispatch(m,n);return n},execCommand:function(r,p,o){var q=this,n=q.get(o),l;switch(r){case"mceFocus":n.focus();return true;case"mceAddEditor":case"mceAddControl":if(!q.get(o)){new j.Editor(o,q.settings).render()}return true;case"mceAddFrameControl":l=o.window;l.tinyMCE=tinyMCE;l.tinymce=j;j.DOM.doc=l.document;j.DOM.win=l;n=new j.Editor(o.element_id,o);n.render();if(j.isIE){function m(){n.destroy();l.detachEvent("onunload",m);l=l.tinyMCE=l.tinymce=null}l.attachEvent("onunload",m)}o.page_window=null;return true;case"mceRemoveEditor":case"mceRemoveControl":if(n){n.remove()}return true;case"mceToggleEditor":if(!n){q.execCommand("mceAddControl",0,o);return true}if(n.isHidden()){n.show()}else{n.hide()}return true}if(q.activeEditor){return q.activeEditor.execCommand(r,p,o)}return false},execInstanceCommand:function(p,o,n,m){var l=this.get(p);if(l){return l.execCommand(o,n,m)}return false},triggerSave:function(){g(this.editors,function(l){l.save()})},addI18n:function(n,q){var l,m=this.i18n;if(!j.is(n,"string")){g(n,function(r,p){g(r,function(t,s){g(t,function(v,u){if(s==="common"){m[p+"."+u]=v}else{m[p+"."+s+"."+u]=v}})})})}else{g(q,function(r,p){m[n+"."+p]=r})}},_setActive:function(l){this.selectedInstance=this.activeEditor=l}})})(tinymce);(function(n){var o=n.DOM,k=n.dom.Event,f=n.extend,l=n.util.Dispatcher,i=n.each,a=n.isGecko,b=n.isIE,e=n.isWebKit,d=n.is,h=n.ThemeManager,c=n.PluginManager,p=n.inArray,m=n.grep,g=n.explode,j=n.VK;n.create("tinymce.Editor",{Editor:function(u,r){var q=this;q.id=q.editorId=u;q.execCommands={};q.queryStateCommands={};q.queryValueCommands={};q.isNotDirty=false;q.plugins={};i(["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(s){q[s]=new l(q)});q.settings=r=f({id:u,language:"en",docs_language:"en",theme:"simple",skin:"default",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:n.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,doctype:n.isIE6?'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">':"<!DOCTYPE>",visual_table_class:"mceItemTable",visual:1,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%",apply_source_formatting:1,directionality:"ltr",forced_root_block:"p",hidden_input:1,padd_empty_editor:1,render_ui:1,init_theme:1,force_p_newlines:1,indentation:"30px",keep_styles:1,fix_table_elements:1,inline_styles:1,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",indent_after:"p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr",validate:true,entity_encoding:"named",url_converter:q.convertURL,url_converter_scope:q,ie7_compat:true},r);q.documentBaseURI=new n.util.URI(r.document_base_url||n.documentBaseURL,{base_uri:tinyMCE.baseURI});q.baseURI=n.baseURI;q.contentCSS=[];q.execCallback("setup",q)},render:function(u){var v=this,x=v.settings,y=v.id,q=n.ScriptLoader;if(!k.domLoaded){k.add(document,"init",function(){v.render()});return}tinyMCE.settings=x;if(!v.getElement()){return}if(n.isIDevice&&!n.isIOS5){return}if(!/TEXTAREA|INPUT/i.test(v.getElement().nodeName)&&x.hidden_input&&o.getParent(y,"form")){o.insertAfter(o.create("input",{type:"hidden",name:y}),y)}if(n.WindowManager){v.windowManager=new n.WindowManager(v)}if(x.encoding=="xml"){v.onGetContent.add(function(s,t){if(t.save){t.content=o.encode(t.content)}})}if(x.add_form_submit_trigger){v.onSubmit.addToTop(function(){if(v.initialized){v.save();v.isNotDirty=1}})}if(x.add_unload_trigger){v._beforeUnload=tinyMCE.onBeforeUnload.add(function(){if(v.initialized&&!v.destroyed&&!v.isHidden()){v.save({format:"raw",no_events:true})}})}n.addUnload(v.destroy,v);if(x.submit_patch){v.onBeforeRenderUI.add(function(){var s=v.getElement().form;if(!s){return}if(s._mceOldSubmit){return}if(!s.submit.nodeType&&!s.submit.length){v.formElement=s;s._mceOldSubmit=s.submit;s.submit=function(){n.triggerSave();v.isNotDirty=1;return v.formElement._mceOldSubmit(v.formElement)}}s=null})}function r(){if(x.language&&x.language_load!==false){q.add(n.baseURL+"/langs/"+x.language+".js")}if(x.theme&&x.theme.charAt(0)!="-"&&!h.urls[x.theme]){h.load(x.theme,"themes/"+x.theme+"/editor_template"+n.suffix+".js")}i(g(x.plugins),function(t){if(t&&!c.urls[t]){if(t.charAt(0)=="-"){t=t.substr(1,t.length);var s=c.dependencies(t);i(s,function(A){var z={prefix:"plugins/",resource:A,suffix:"/editor_plugin"+n.suffix+".js"};var A=c.createUrl(z,A);c.load(A.resource,A)})}else{if(t=="safari"){return}c.load(t,{prefix:"plugins/",resource:t,suffix:"/editor_plugin"+n.suffix+".js"})}}});q.loadQueue(function(){if(!v.removed){v.init()}})}r()},init:function(){var v,I=this,J=I.settings,F,B,E=I.getElement(),r,q,G,z,D,H,A,x=[];n.add(I);J.aria_label=J.aria_label||o.getAttrib(E,"aria-label",I.getLang("aria.rich_text_area"));if(J.theme){J.theme=J.theme.replace(/-/,"");r=h.get(J.theme);I.theme=new r();if(I.theme.init&&J.init_theme){I.theme.init(I,h.urls[J.theme]||n.documentBaseURL.replace(/\/$/,""))}}function C(K){var L=c.get(K),t=c.urls[K]||n.documentBaseURL.replace(/\/$/,""),s;if(L&&n.inArray(x,K)===-1){i(c.dependencies(K),function(u){C(u)});s=new L(I,t);I.plugins[K]=s;if(s.init){s.init(I,t);x.push(K)}}}i(g(J.plugins.replace(/\-/g,"")),C);if(J.popup_css!==false){if(J.popup_css){J.popup_css=I.documentBaseURI.toAbsolute(J.popup_css)}else{J.popup_css=I.baseURI.toAbsolute("themes/"+J.theme+"/skins/"+J.skin+"/dialog.css")}}if(J.popup_css_add){J.popup_css+=","+I.documentBaseURI.toAbsolute(J.popup_css_add)}I.controlManager=new n.ControlManager(I);if(J.custom_undo_redo){I.onBeforeExecCommand.add(function(t,K,u,L,s){if(K!="Undo"&&K!="Redo"&&K!="mceRepaint"&&(!s||!s.skip_undo)){I.undoManager.beforeChange()}});I.onExecCommand.add(function(t,K,u,L,s){if(K!="Undo"&&K!="Redo"&&K!="mceRepaint"&&(!s||!s.skip_undo)){I.undoManager.add()}})}I.onExecCommand.add(function(s,t){if(!/^(FontName|FontSize)$/.test(t)){I.nodeChanged()}});if(a){function y(s,t){if(!t||!t.initial){I.execCommand("mceRepaint")}}I.onUndo.add(y);I.onRedo.add(y);I.onSetContent.add(y)}I.onBeforeRenderUI.dispatch(I,I.controlManager);if(J.render_ui){F=J.width||E.style.width||E.offsetWidth;B=J.height||E.style.height||E.offsetHeight;I.orgDisplay=E.style.display;H=/^[0-9\.]+(|px)$/i;if(H.test(""+F)){F=Math.max(parseInt(F)+(r.deltaWidth||0),100)}if(H.test(""+B)){B=Math.max(parseInt(B)+(r.deltaHeight||0),100)}r=I.theme.renderUI({targetNode:E,width:F,height:B,deltaWidth:J.delta_width,deltaHeight:J.delta_height});I.editorContainer=r.editorContainer}if(document.domain&&location.hostname!=document.domain){n.relaxedDomain=document.domain}o.setStyles(r.sizeContainer||r.editorContainer,{width:F,height:B});if(J.content_css){n.each(g(J.content_css),function(s){I.contentCSS.push(I.documentBaseURI.toAbsolute(s))})}B=(r.iframeHeight||B)+(typeof(B)=="number"?(r.deltaHeight||0):"");if(B<100){B=100}I.iframeHTML=J.doctype+'<html><head xmlns="http://www.w3.org/1999/xhtml">';if(J.document_base_url!=n.documentBaseURL){I.iframeHTML+='<base href="'+I.documentBaseURI.getURI()+'" />'}if(J.ie7_compat){I.iframeHTML+='<meta http-equiv="X-UA-Compatible" content="IE=7" />'}else{I.iframeHTML+='<meta http-equiv="X-UA-Compatible" content="IE=edge" />'}I.iframeHTML+='<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';for(A=0;A<I.contentCSS.length;A++){I.iframeHTML+='<link type="text/css" rel="stylesheet" href="'+I.contentCSS[A]+'" />'}I.contentCSS=[];z=J.body_id||"tinymce";if(z.indexOf("=")!=-1){z=I.getParam("body_id","","hash");z=z[I.id]||z}D=J.body_class||"";if(D.indexOf("=")!=-1){D=I.getParam("body_class","","hash");D=D[I.id]||""}I.iframeHTML+='</head><body id="'+z+'" class="mceContentBody '+D+'" onload="window.parent.tinyMCE.get(\''+I.id+"').onLoad.dispatch();\"><br></body></html>";if(n.relaxedDomain&&(b||(n.isOpera&&parseFloat(opera.version())<11))){G='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinyMCE.get("'+I.id+'");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()'}v=o.add(r.iframeContainer,"iframe",{id:I.id+"_ifr",src:G||'javascript:""',frameBorder:"0",allowTransparency:"true",title:J.aria_label,style:{width:"100%",height:B,display:"block"}});I.contentAreaContainer=r.iframeContainer;o.get(r.editorContainer).style.display=I.orgDisplay;o.get(I.id).style.display="none";o.setAttrib(I.id,"aria-hidden",true);if(!n.relaxedDomain||!G){I.setupIframe()}E=v=r=null},setupIframe:function(){var r=this,x=r.settings,y=o.get(r.id),z=r.getDoc(),v,q;if(!b||!n.relaxedDomain){z.open();z.write(r.iframeHTML);z.close();if(n.relaxedDomain){z.domain=n.relaxedDomain}}q=r.getBody();q.disabled=true;if(!x.readonly){q.contentEditable=true}q.disabled=false;r.schema=new n.html.Schema(x);r.dom=new n.dom.DOMUtils(r.getDoc(),{keep_values:true,url_converter:r.convertURL,url_converter_scope:r,hex_colors:x.force_hex_style_colors,class_filter:x.class_filter,update_styles:1,fix_ie_paragraphs:1,schema:r.schema});r.parser=new n.html.DomParser(x,r.schema);if(!r.settings.allow_html_in_named_anchor){r.parser.addAttributeFilter("name",function(s,t){var B=s.length,D,A,C,E;while(B--){E=s[B];if(E.name==="a"&&E.firstChild){C=E.parent;D=E.lastChild;do{A=D.prev;C.insert(D,E);D=A}while(D)}}})}r.parser.addAttributeFilter("src,href,style",function(s,t){var A=s.length,C,E=r.dom,D,B;while(A--){C=s[A];D=C.attr(t);B="data-mce-"+t;if(!C.attributes.map[B]){if(t==="style"){C.attr(B,E.serializeStyle(E.parseStyle(D),C.name))}else{C.attr(B,r.convertURL(D,t,C.name))}}}});r.parser.addNodeFilter("script",function(s,t){var A=s.length,B;while(A--){B=s[A];B.attr("type","mce-"+(B.attr("type")||"text/javascript"))}});r.parser.addNodeFilter("#cdata",function(s,t){var A=s.length,B;while(A--){B=s[A];B.type=8;B.name="#comment";B.value="[CDATA["+B.value+"]]"}});r.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(t,A){var B=t.length,C,s=r.schema.getNonEmptyElements();while(B--){C=t[B];if(C.isEmpty(s)){C.empty().append(new n.html.Node("br",1)).shortEnded=true}}});r.serializer=new n.dom.Serializer(x,r.dom,r.schema);r.selection=new n.dom.Selection(r.dom,r.getWin(),r.serializer);r.formatter=new n.Formatter(this);r.formatter.register({alignleft:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"left"}},{selector:"img,table",collapsed:false,styles:{"float":"left"}}],aligncenter:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"center"}},{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"}},{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"}}],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(s){return true},onformat:function(A,s,t){i(t,function(C,B){r.dom.setAttrib(A,B,C)})}},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}]});i("p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp".split(/\s/),function(s){r.formatter.register(s,{block:s,remove:"all"})});r.formatter.register(r.settings.formats);r.undoManager=new n.UndoManager(r);r.undoManager.onAdd.add(function(t,s){if(t.hasUndo()){return r.onChange.dispatch(r,s,t)}});r.undoManager.onUndo.add(function(t,s){return r.onUndo.dispatch(r,s,t)});r.undoManager.onRedo.add(function(t,s){return r.onRedo.dispatch(r,s,t)});r.forceBlocks=new n.ForceBlocks(r,{forced_root_block:x.forced_root_block});r.editorCommands=new n.EditorCommands(r);r.serializer.onPreProcess.add(function(s,t){return r.onPreProcess.dispatch(r,t,s)});r.serializer.onPostProcess.add(function(s,t){return r.onPostProcess.dispatch(r,t,s)});r.onPreInit.dispatch(r);if(!x.gecko_spellcheck){r.getBody().spellcheck=0}if(!x.readonly){r._addEvents()}r.controlManager.onPostRender.dispatch(r,r.controlManager);r.onPostRender.dispatch(r);r.quirks=new n.util.Quirks(this);if(x.directionality){r.getBody().dir=x.directionality}if(x.nowrap){r.getBody().style.whiteSpace="nowrap"}if(x.handle_node_change_callback){r.onNodeChange.add(function(t,s,A){r.execCallback("handle_node_change_callback",r.id,A,-1,-1,true,r.selection.isCollapsed())})}if(x.save_callback){r.onSaveContent.add(function(s,A){var t=r.execCallback("save_callback",r.id,A.content,r.getBody());if(t){A.content=t}})}if(x.onchange_callback){r.onChange.add(function(t,s){r.execCallback("onchange_callback",r,s)})}if(x.protect){r.onBeforeSetContent.add(function(s,t){if(x.protect){i(x.protect,function(A){t.content=t.content.replace(A,function(B){return"<!--mce:protected "+escape(B)+"-->"})})}})}if(x.convert_newlines_to_brs){r.onBeforeSetContent.add(function(s,t){if(t.initial){t.content=t.content.replace(/\r?\n/g,"<br />")}})}if(x.preformatted){r.onPostProcess.add(function(s,t){t.content=t.content.replace(/^\s*<pre.*?>/,"");t.content=t.content.replace(/<\/pre>\s*$/,"");if(t.set){t.content='<pre class="mceItemHidden">'+t.content+"</pre>"}})}if(x.verify_css_classes){r.serializer.attribValueFilter=function(C,A){var B,t;if(C=="class"){if(!r.classesRE){t=r.dom.getClasses();if(t.length>0){B="";i(t,function(s){B+=(B?"|":"")+s["class"]});r.classesRE=new RegExp("("+B+")","gi")}}return !r.classesRE||/(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(A)||r.classesRE.test(A)?A:""}return A}}if(x.cleanup_callback){r.onBeforeSetContent.add(function(s,t){t.content=r.execCallback("cleanup_callback","insert_to_editor",t.content,t)});r.onPreProcess.add(function(s,t){if(t.set){r.execCallback("cleanup_callback","insert_to_editor_dom",t.node,t)}if(t.get){r.execCallback("cleanup_callback","get_from_editor_dom",t.node,t)}});r.onPostProcess.add(function(s,t){if(t.set){t.content=r.execCallback("cleanup_callback","insert_to_editor",t.content,t)}if(t.get){t.content=r.execCallback("cleanup_callback","get_from_editor",t.content,t)}})}if(x.save_callback){r.onGetContent.add(function(s,t){if(t.save){t.content=r.execCallback("save_callback",r.id,t.content,r.getBody())}})}if(x.handle_event_callback){r.onEvent.add(function(s,t,A){if(r.execCallback("handle_event_callback",t,s,A)===false){k.cancel(t)}})}r.onSetContent.add(function(){r.addVisual(r.getBody())});if(x.padd_empty_editor){r.onPostProcess.add(function(s,t){t.content=t.content.replace(/^(<p[^>]*>( | |\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/,"")})}if(a){function u(s,t){i(s.dom.select("a"),function(B){var A=B.parentNode;if(s.dom.isBlock(A)&&A.lastChild===B){s.dom.add(A,"br",{"data-mce-bogus":1})}})}r.onExecCommand.add(function(s,t){if(t==="CreateLink"){u(s)}});r.onSetContent.add(r.selection.onSetContent.add(u))}r.load({initial:true,format:"html"});r.startContent=r.getContent({format:"raw"});r.undoManager.add();r.initialized=true;r.onInit.dispatch(r);r.execCallback("setupcontent_callback",r.id,r.getBody(),r.getDoc());r.execCallback("init_instance_callback",r);r.focus(true);r.nodeChanged({initial:1});i(r.contentCSS,function(s){r.dom.loadCSS(s)});if(x.auto_focus){setTimeout(function(){var s=n.get(x.auto_focus);s.selection.select(s.getBody(),1);s.selection.collapse(1);s.getBody().focus();s.getWin().focus()},100)}y=null},focus:function(v){var z,r=this,u=r.selection,y=r.settings.content_editable,s,q,x=r.getDoc();if(!v){s=u.getRng();if(s.item){q=s.item(0)}r._refreshContentEditable();if(!y){r.getWin().focus()}if(n.isGecko){r.getBody().focus()}if(q&&q.ownerDocument==x){s=x.body.createControlRange();s.addElement(q);s.select()}}if(n.activeEditor!=r){if((z=n.activeEditor)!=null){z.onDeactivate.dispatch(z,r)}r.onActivate.dispatch(r,z)}n._setActive(r)},execCallback:function(v){var q=this,u=q.settings[v],r;if(!u){return}if(q.callbackLookup&&(r=q.callbackLookup[v])){u=r.func;r=r.scope}if(d(u,"string")){r=u.replace(/\.\w+$/,"");r=r?n.resolve(r):0;u=n.resolve(u);q.callbackLookup=q.callbackLookup||{};q.callbackLookup[v]={func:u,scope:r}}return u.apply(r||q,Array.prototype.slice.call(arguments,1))},translate:function(q){var t=this.settings.language||"en",r=n.i18n;if(!q){return""}return r[t+"."+q]||q.replace(/{\#([^}]+)\}/g,function(u,s){return r[t+"."+s]||"{#"+s+"}"})},getLang:function(r,q){return n.i18n[(this.settings.language||"en")+"."+r]||(d(q)?q:"{#"+r+"}")},getParam:function(x,s,q){var t=n.trim,r=d(this.settings[x])?this.settings[x]:s,u;if(q==="hash"){u={};if(d(r,"string")){i(r.indexOf("=")>0?r.split(/[;,](?![^=;,]*(?:[;,]|$))/):r.split(","),function(y){y=y.split("=");if(y.length>1){u[t(y[0])]=t(y[1])}else{u[t(y[0])]=t(y)}})}else{u=r}return u}return r},nodeChanged:function(u){var q=this,r=q.selection,v=r.getStart()||q.getBody();if(q.initialized){u=u||{};v=b&&v.ownerDocument!=q.getDoc()?q.getBody():v;u.parents=[];q.dom.getParent(v,function(s){if(s.nodeName=="BODY"){return true}u.parents.push(s)});q.onNodeChange.dispatch(q,u?u.controlManager||q.controlManager:q.controlManager,v,r.isCollapsed(),u)}},addButton:function(u,r){var q=this;q.buttons=q.buttons||{};q.buttons[u]=r},addCommand:function(q,s,r){this.execCommands[q]={func:s,scope:r||this}},addQueryStateHandler:function(q,s,r){this.queryStateCommands[q]={func:s,scope:r||this}},addQueryValueHandler:function(q,s,r){this.queryValueCommands[q]={func:s,scope:r||this}},addShortcut:function(s,v,q,u){var r=this,x;if(!r.settings.custom_shortcuts){return false}r.shortcuts=r.shortcuts||{};if(d(q,"string")){x=q;q=function(){r.execCommand(x,false,null)}}if(d(q,"object")){x=q;q=function(){r.execCommand(x[0],x[1],x[2])}}i(g(s),function(t){var y={func:q,scope:u||this,desc:v,alt:false,ctrl:false,shift:false};i(g(t,"+"),function(z){switch(z){case"alt":case"ctrl":case"shift":y[z]=true;break;default:y.charCode=z.charCodeAt(0);y.keyCode=z.toUpperCase().charCodeAt(0)}});r.shortcuts[(y.ctrl?"ctrl":"")+","+(y.alt?"alt":"")+","+(y.shift?"shift":"")+","+y.keyCode]=y});return true},execCommand:function(y,x,A,q){var u=this,v=0,z,r;if(!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(y)&&(!q||!q.skip_focus)){u.focus()}q=f({},q);u.onBeforeExecCommand.dispatch(u,y,x,A,q);if(q.terminate){return false}if(u.execCallback("execcommand_callback",u.id,u.selection.getNode(),y,x,A)){u.onExecCommand.dispatch(u,y,x,A,q);return true}if(z=u.execCommands[y]){r=z.func.call(z.scope,x,A);if(r!==true){u.onExecCommand.dispatch(u,y,x,A,q);return r}}i(u.plugins,function(s){if(s.execCommand&&s.execCommand(y,x,A)){u.onExecCommand.dispatch(u,y,x,A,q);v=1;return false}});if(v){return true}if(u.theme&&u.theme.execCommand&&u.theme.execCommand(y,x,A)){u.onExecCommand.dispatch(u,y,x,A,q);return true}if(u.editorCommands.execCommand(y,x,A)){u.onExecCommand.dispatch(u,y,x,A,q);return true}u.getDoc().execCommand(y,x,A);u.onExecCommand.dispatch(u,y,x,A,q)},queryCommandState:function(v){var r=this,x,u;if(r._isHidden()){return}if(x=r.queryStateCommands[v]){u=x.func.call(x.scope);if(u!==true){return u}}x=r.editorCommands.queryCommandState(v);if(x!==-1){return x}try{return this.getDoc().queryCommandState(v)}catch(q){}},queryCommandValue:function(x){var r=this,v,u;if(r._isHidden()){return}if(v=r.queryValueCommands[x]){u=v.func.call(v.scope);if(u!==true){return u}}v=r.editorCommands.queryCommandValue(x);if(d(v)){return v}try{return this.getDoc().queryCommandValue(x)}catch(q){}},show:function(){var q=this;o.show(q.getContainer());o.hide(q.id);q.load()},hide:function(){var q=this,r=q.getDoc();if(b&&r){r.execCommand("SelectAll")}q.save();o.hide(q.getContainer());o.setStyle(q.id,"display",q.orgDisplay)},isHidden:function(){return !o.isHidden(this.id)},setProgressState:function(q,r,s){this.onSetProgressState.dispatch(this,q,r,s);return q},load:function(u){var q=this,s=q.getElement(),r;if(s){u=u||{};u.load=true;r=q.setContent(d(s.value)?s.value:s.innerHTML,u);u.element=s;if(!u.no_events){q.onLoadContent.dispatch(q,u)}u.element=s=null;return r}},save:function(v){var q=this,u=q.getElement(),r,s;if(!u||!q.initialized){return}v=v||{};v.save=true;if(!v.no_events){q.undoManager.typing=false;q.undoManager.add()}v.element=u;r=v.content=q.getContent(v);if(!v.no_events){q.onSaveContent.dispatch(q,v)}r=v.content;if(!/TEXTAREA|INPUT/i.test(u.nodeName)){u.innerHTML=r;if(s=o.getParent(q.id,"form")){i(s.elements,function(t){if(t.name==q.id){t.value=r;return false}})}}else{u.value=r}v.element=u=null;return r},setContent:function(v,t){var s=this,r,q=s.getBody(),u;t=t||{};t.format=t.format||"html";t.set=true;t.content=v;if(!t.no_events){s.onBeforeSetContent.dispatch(s,t)}v=t.content;if(!n.isIE&&(v.length===0||/^\s+$/.test(v))){u=s.settings.forced_root_block;if(u){v="<"+u+'><br data-mce-bogus="1"></'+u+">"}else{v='<br data-mce-bogus="1">'}q.innerHTML=v;s.selection.select(q,true);s.selection.collapse(true);return}if(t.format!=="raw"){v=new n.html.Serializer({},s.schema).serialize(s.parser.parse(v))}t.content=n.trim(v);s.dom.setHTML(q,t.content);if(!t.no_events){s.onSetContent.dispatch(s,t)}s.selection.normalize();return t.content},getContent:function(r){var q=this,s;r=r||{};r.format=r.format||"html";r.get=true;if(!r.no_events){q.onBeforeGetContent.dispatch(q,r)}if(r.format=="raw"){s=q.getBody().innerHTML}else{s=q.serializer.serialize(q.getBody(),r)}r.content=n.trim(s);if(!r.no_events){q.onGetContent.dispatch(q,r)}return r.content},isDirty:function(){var q=this;return n.trim(q.startContent)!=n.trim(q.getContent({format:"raw",no_events:1}))&&!q.isNotDirty},getContainer:function(){var q=this;if(!q.container){q.container=o.get(q.editorContainer||q.id+"_parent")}return q.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return o.get(this.settings.content_element||this.id)},getWin:function(){var q=this,r;if(!q.contentWindow){r=o.get(q.id+"_ifr");if(r){q.contentWindow=r.contentWindow}}return q.contentWindow},getDoc:function(){var r=this,q;if(!r.contentDocument){q=r.getWin();if(q){r.contentDocument=q.document}}return r.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(q,y,x){var r=this,v=r.settings;if(v.urlconverter_callback){return r.execCallback("urlconverter_callback",q,x,true,y)}if(!v.convert_urls||(x&&x.nodeName=="LINK")||q.indexOf("file:")===0){return q}if(v.relative_urls){return r.documentBaseURI.toRelative(q)}q=r.documentBaseURI.toAbsolute(q,v.remove_script_host);return q},addVisual:function(u){var q=this,r=q.settings;u=u||q.getBody();if(!d(q.hasVisual)){q.hasVisual=r.visual}i(q.dom.select("table,a",u),function(t){var s;switch(t.nodeName){case"TABLE":s=q.dom.getAttrib(t,"border");if(!s||s=="0"){if(q.hasVisual){q.dom.addClass(t,r.visual_table_class)}else{q.dom.removeClass(t,r.visual_table_class)}}return;case"A":s=q.dom.getAttrib(t,"name");if(s){if(q.hasVisual){q.dom.addClass(t,"mceItemAnchor")}else{q.dom.removeClass(t,"mceItemAnchor")}}return}});q.onVisualAid.dispatch(q,u,q.hasVisual)},remove:function(){var q=this,r=q.getContainer();q.removed=1;q.hide();q.execCallback("remove_instance_callback",q);q.onRemove.dispatch(q);q.onExecCommand.listeners=[];n.remove(q);o.remove(r)},destroy:function(r){var q=this;if(q.destroyed){return}if(!r){n.removeUnload(q.destroy);tinyMCE.onBeforeUnload.remove(q._beforeUnload);if(q.theme&&q.theme.destroy){q.theme.destroy()}q.controlManager.destroy();q.selection.destroy();q.dom.destroy();if(!q.settings.content_editable){k.clear(q.getWin());k.clear(q.getDoc())}k.clear(q.getBody());k.clear(q.formElement)}if(q.formElement){q.formElement.submit=q.formElement._mceOldSubmit;q.formElement._mceOldSubmit=null}q.contentAreaContainer=q.formElement=q.container=q.settings.content_element=q.bodyElement=q.contentDocument=q.contentWindow=null;if(q.selection){q.selection=q.selection.win=q.selection.dom=q.selection.dom.doc=null}q.destroyed=1},_addEvents:function(){var D=this,u,E=D.settings,r=D.dom,y={mouseup:"onMouseUp",mousedown:"onMouseDown",click:"onClick",keyup:"onKeyUp",keydown:"onKeyDown",keypress:"onKeyPress",submit:"onSubmit",reset:"onReset",contextmenu:"onContextMenu",dblclick:"onDblClick",paste:"onPaste"};function q(t,F){var s=t.type;if(D.removed){return}if(D.onEvent.dispatch(D,t,F)!==false){D[y[t.fakeType||t.type]].dispatch(D,t,F)}}i(y,function(t,s){switch(s){case"contextmenu":r.bind(D.getDoc(),s,q);break;case"paste":r.bind(D.getBody(),s,function(F){q(F)});break;case"submit":case"reset":r.bind(D.getElement().form||o.getParent(D.id,"form"),s,q);break;default:r.bind(E.content_editable?D.getBody():D.getDoc(),s,q)}});r.bind(E.content_editable?D.getBody():(a?D.getDoc():D.getWin()),"focus",function(s){D.focus(true)});if(n.isGecko){r.bind(D.getDoc(),"DOMNodeInserted",function(t){var s;t=t.target;if(t.nodeType===1&&t.nodeName==="IMG"&&(s=t.getAttribute("data-mce-src"))){t.src=D.documentBaseURI.toAbsolute(s)}})}if(a){function v(){var G=this,I=G.getDoc(),H=G.settings;if(a&&!H.readonly){G._refreshContentEditable();try{I.execCommand("styleWithCSS",0,false)}catch(F){if(!G._isHidden()){try{I.execCommand("useCSS",0,true)}catch(F){}}}if(!H.table_inline_editing){try{I.execCommand("enableInlineTableEditing",false,false)}catch(F){}}if(!H.object_resizing){try{I.execCommand("enableObjectResizing",false,false)}catch(F){}}}}D.onBeforeExecCommand.add(v);D.onMouseDown.add(v)}D.onMouseUp.add(D.nodeChanged);D.onKeyUp.add(function(s,t){var F=t.keyCode;if((F>=33&&F<=36)||(F>=37&&F<=40)||F==13||F==45||F==46||F==8||(n.isMac&&(F==91||F==93))||t.ctrlKey){D.nodeChanged()}});D.onKeyDown.add(function(t,F){if(F.keyCode!=j.BACKSPACE){return}var s=t.selection.getRng();if(!s.collapsed){return}var H=s.startContainer;var G=s.startOffset;while(H&&H.nodeType&&H.nodeType!=1&&H.parentNode){H=H.parentNode}if(H&&H.parentNode&&H.parentNode.tagName==="BLOCKQUOTE"&&H.parentNode.firstChild==H&&G==0){t.formatter.toggle("blockquote",null,H.parentNode);s.setStart(H,0);s.setEnd(H,0);t.selection.setRng(s);t.selection.collapse(false)}});D.onReset.add(function(){D.setContent(D.startContent,{format:"raw"})});if(E.custom_shortcuts){if(E.custom_undo_redo_keyboard_shortcuts){D.addShortcut("ctrl+z",D.getLang("undo_desc"),"Undo");D.addShortcut("ctrl+y",D.getLang("redo_desc"),"Redo")}D.addShortcut("ctrl+b",D.getLang("bold_desc"),"Bold");D.addShortcut("ctrl+i",D.getLang("italic_desc"),"Italic");D.addShortcut("ctrl+u",D.getLang("underline_desc"),"Underline");for(u=1;u<=6;u++){D.addShortcut("ctrl+"+u,"",["FormatBlock",false,"h"+u])}D.addShortcut("ctrl+7","",["FormatBlock",false,"p"]);D.addShortcut("ctrl+8","",["FormatBlock",false,"div"]);D.addShortcut("ctrl+9","",["FormatBlock",false,"address"]);function x(t){var s=null;if(!t.altKey&&!t.ctrlKey&&!t.metaKey){return s}i(D.shortcuts,function(F){if(n.isMac&&F.ctrl!=t.metaKey){return}else{if(!n.isMac&&F.ctrl!=t.ctrlKey){return}}if(F.alt!=t.altKey){return}if(F.shift!=t.shiftKey){return}if(t.keyCode==F.keyCode||(t.charCode&&t.charCode==F.charCode)){s=F;return false}});return s}D.onKeyUp.add(function(s,t){var F=x(t);if(F){return k.cancel(t)}});D.onKeyPress.add(function(s,t){var F=x(t);if(F){return k.cancel(t)}});D.onKeyDown.add(function(s,t){var F=x(t);if(F){F.func.call(F.scope);return k.cancel(t)}})}if(n.isIE){r.bind(D.getDoc(),"controlselect",function(F){var t=D.resizeInfo,s;F=F.target;if(F.nodeName!=="IMG"){return}if(t){r.unbind(t.node,t.ev,t.cb)}if(!r.hasClass(F,"mceItemNoResize")){ev="resizeend";s=r.bind(F,ev,function(H){var G;H=H.target;if(G=r.getStyle(H,"width")){r.setAttrib(H,"width",G.replace(/[^0-9%]+/g,""));r.setStyle(H,"width","")}if(G=r.getStyle(H,"height")){r.setAttrib(H,"height",G.replace(/[^0-9%]+/g,""));r.setStyle(H,"height","")}})}else{ev="resizestart";s=r.bind(F,"resizestart",k.cancel,k)}t=D.resizeInfo={node:F,ev:ev,cb:s}})}if(n.isOpera){D.onClick.add(function(s,t){k.prevent(t)})}if(E.custom_undo_redo){function A(){D.undoManager.typing=false;D.undoManager.add()}var z=n.isGecko?"blur":"focusout";r.bind(D.getDoc(),z,function(s){if(!D.removed&&D.undoManager.typing){A()}});D.dom.bind(D.dom.getRoot(),"dragend",function(s){A()});D.onKeyUp.add(function(s,F){var t=F.keyCode;if((t>=33&&t<=36)||(t>=37&&t<=40)||t==13||t==45||F.ctrlKey){A()}});D.onKeyDown.add(function(s,G){var F=G.keyCode,t;if(F==8){t=D.getDoc().selection;if(t&&t.createRange&&t.createRange().item){D.undoManager.beforeChange();s.dom.remove(t.createRange().item(0));A();return k.cancel(G)}}if((F>=33&&F<=36)||(F>=37&&F<=40)||F==13||F==45){if(n.isIE&&F==13){D.undoManager.beforeChange()}if(D.undoManager.typing){A()}return}if((F<16||F>20)&&F!=224&&F!=91&&!D.undoManager.typing){D.undoManager.beforeChange();D.undoManager.typing=true;D.undoManager.add()}});D.onMouseDown.add(function(){if(D.undoManager.typing){A()}})}if(n.isGecko){function C(){var s=D.dom.getAttribs(D.selection.getStart().cloneNode(false));return function(){var t=D.selection.getStart();if(t!==D.getBody()){D.dom.setAttrib(t,"style",null);i(s,function(F){t.setAttributeNode(F.cloneNode(true))})}}}function B(){var t=D.selection;return !t.isCollapsed()&&t.getStart()!=t.getEnd()}D.onKeyPress.add(function(s,F){var t;if((F.keyCode==8||F.keyCode==46)&&B()){t=C();D.getDoc().execCommand("delete",false,null);t();return k.cancel(F)}});D.dom.bind(D.getDoc(),"cut",function(t){var s;if(B()){s=C();D.onKeyUp.addToTop(k.cancel,k);setTimeout(function(){s();D.onKeyUp.remove(k.cancel,k)},0)}})}},_refreshContentEditable:function(){var r=this,q,s;if(r._isHidden()){q=r.getBody();s=q.parentNode;s.removeChild(q);s.appendChild(q);q.focus()}},_isHidden:function(){var q;if(!a){return 0}q=this.selection.getSel();return(!q||!q.rangeCount||q.rangeCount==0)}})})(tinymce);(function(c){var d=c.each,e,a=true,b=false;c.EditorCommands=function(n){var m=n.dom,p=n.selection,j={state:{},exec:{},value:{}},k=n.settings,q=n.formatter,o;function r(z,y,x){var v;z=z.toLowerCase();if(v=j.exec[z]){v(z,y,x);return a}return b}function l(x){var v;x=x.toLowerCase();if(v=j.state[x]){return v(x)}return -1}function h(x){var v;x=x.toLowerCase();if(v=j.value[x]){return v(x)}return b}function u(v,x){x=x||"exec";d(v,function(z,y){d(y.toLowerCase().split(","),function(A){j[x][A]=z})})}c.extend(this,{execCommand:r,queryCommandState:l,queryCommandValue:h,addCommands:u});function f(y,x,v){if(x===e){x=b}if(v===e){v=null}return n.getDoc().execCommand(y,x,v)}function t(v){return q.match(v)}function s(v,x){q.toggle(v,x?{value:x}:e)}function i(v){o=p.getBookmark(v)}function g(){p.moveToBookmark(o)}u({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){n.undoManager.add()},"Cut,Copy,Paste":function(z){var y=n.getDoc(),v;try{f(z)}catch(x){v=a}if(v||!y.queryCommandSupported(z)){if(c.isGecko){n.windowManager.confirm(n.getLang("clipboard_msg"),function(A){if(A){open("http://www.mozilla.org/editor/midasdemo/securityprefs.html","_blank")}})}else{n.windowManager.alert(n.getLang("clipboard_no_support"))}}},unlink:function(v){if(p.isCollapsed()){p.select(p.getNode())}f(v);p.collapse(b)},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(v){var x=v.substring(7);d("left,center,right,full".split(","),function(y){if(x!=y){q.remove("align"+y)}});s("align"+x);r("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(y){var v,x;f(y);v=m.getParent(p.getNode(),"ol,ul");if(v){x=v.parentNode;if(/^(H[1-6]|P|ADDRESS|PRE)$/.test(x.nodeName)){i();m.split(x,v);g()}}},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(v){s(v)},"ForeColor,HiliteColor,FontName":function(y,x,v){s(y,v)},FontSize:function(z,y,x){var v,A;if(x>=1&&x<=7){A=c.explode(k.font_size_style_values);v=c.explode(k.font_size_classes);if(v){x=v[x-1]||x}else{x=A[x-1]||x}}s(z,x)},RemoveFormat:function(v){q.remove(v)},mceBlockQuote:function(v){s("blockquote")},FormatBlock:function(y,x,v){return s(v||"p")},mceCleanup:function(){var v=p.getBookmark();n.setContent(n.getContent({cleanup:a}),{cleanup:a});p.moveToBookmark(v)},mceRemoveNode:function(z,y,x){var v=x||p.getNode();if(v!=n.getBody()){i();n.dom.remove(v,a);g()}},mceSelectNodeDepth:function(z,y,x){var v=0;m.getParent(p.getNode(),function(A){if(A.nodeType==1&&v++==x){p.select(A);return b}},n.getBody())},mceSelectNode:function(y,x,v){p.select(v)},mceInsertContent:function(B,I,K){var y,J,E,z,F,G,D,C,L,x,A,M,v,H;y=n.parser;J=new c.html.Serializer({},n.schema);v='<span id="mce_marker" data-mce-type="bookmark">\uFEFF</span>';G={content:K,format:"html"};p.onBeforeSetContent.dispatch(p,G);K=G.content;if(K.indexOf("{$caret}")==-1){K+="{$caret}"}K=K.replace(/\{\$caret\}/,v);if(!p.isCollapsed()){n.getDoc().execCommand("Delete",false,null)}E=p.getNode();G={context:E.nodeName.toLowerCase()};F=y.parse(K,G);A=F.lastChild;if(A.attr("id")=="mce_marker"){D=A;for(A=A.prev;A;A=A.walk(true)){if(A.type==3||!m.isBlock(A.name)){A.parent.insert(D,A,A.name==="br");break}}}if(!G.invalid){K=J.serialize(F);A=E.firstChild;M=E.lastChild;if(!A||(A===M&&A.nodeName==="BR")){m.setHTML(E,K)}else{p.setContent(K)}}else{p.setContent(v);E=n.selection.getNode();z=n.getBody();if(E.nodeType==9){E=A=z}else{A=E}while(A!==z){E=A;A=A.parentNode}K=E==z?z.innerHTML:m.getOuterHTML(E);K=J.serialize(y.parse(K.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i,function(){return J.serialize(F)})));if(E==z){m.setHTML(z,K)}else{m.setOuterHTML(E,K)}}D=m.get("mce_marker");C=m.getRect(D);L=m.getViewPort(n.getWin());if((C.y+C.h>L.y+L.h||C.y<L.y)||(C.x>L.x+L.w||C.x<L.x)){H=c.isIE?n.getDoc().documentElement:n.getBody();H.scrollLeft=C.x;H.scrollTop=C.y-L.h+25}x=m.createRng();A=D.previousSibling;if(A&&A.nodeType==3){x.setStart(A,A.nodeValue.length)}else{x.setStartBefore(D);x.setEndBefore(D)}m.remove(D);p.setRng(x);p.onSetContent.dispatch(p,G);n.addVisual()},mceInsertRawHTML:function(y,x,v){p.setContent("tiny_mce_marker");n.setContent(n.getContent().replace(/tiny_mce_marker/g,function(){return v}))},mceSetContent:function(y,x,v){n.setContent(v)},"Indent,Outdent":function(z){var x,v,y;x=k.indentation;v=/[a-z%]+$/i.exec(x);x=parseInt(x);if(!l("InsertUnorderedList")&&!l("InsertOrderedList")){d(p.getSelectedBlocks(),function(A){if(z=="outdent"){y=Math.max(0,parseInt(A.style.paddingLeft||0)-x);m.setStyle(A,"paddingLeft",y?y+v:"")}else{m.setStyle(A,"paddingLeft",(parseInt(A.style.paddingLeft||0)+x)+v)}})}else{f(z)}},mceRepaint:function(){var x;if(c.isGecko){try{i(a);if(p.getSel()){p.getSel().selectAllChildren(n.getBody())}p.collapse(a);g()}catch(v){}}},mceToggleFormat:function(y,x,v){q.toggle(v)},InsertHorizontalRule:function(){n.execCommand("mceInsertContent",false,"<hr />")},mceToggleVisualAid:function(){n.hasVisual=!n.hasVisual;n.addVisual()},mceReplaceContent:function(y,x,v){n.execCommand("mceInsertContent",false,v.replace(/\{\$selection\}/g,p.getContent({format:"text"})))},mceInsertLink:function(z,y,x){var v;if(typeof(x)=="string"){x={href:x}}v=m.getParent(p.getNode(),"a");x.href=x.href.replace(" ","%20");if(!v||!x.href){q.remove("link")}if(x.href){q.apply("link",x,v)}},selectAll:function(){var x=m.getRoot(),v=m.createRng();v.setStart(x,0);v.setEnd(x,x.childNodes.length);n.selection.setRng(v)}});u({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(z){var x="align"+z.substring(7);var v=p.isCollapsed()?[p.getNode()]:p.getSelectedBlocks();var y=c.map(v,function(A){return !!q.matchNode(A,x)});return c.inArray(y,a)!==-1},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(v){return t(v)},mceBlockQuote:function(){return t("blockquote")},Outdent:function(){var v;if(k.inline_styles){if((v=m.getParent(p.getStart(),m.isBlock))&&parseInt(v.style.paddingLeft)>0){return a}if((v=m.getParent(p.getEnd(),m.isBlock))&&parseInt(v.style.paddingLeft)>0){return a}}return l("InsertUnorderedList")||l("InsertOrderedList")||(!k.inline_styles&&!!m.getParent(p.getNode(),"BLOCKQUOTE"))},"InsertUnorderedList,InsertOrderedList":function(v){return m.getParent(p.getNode(),v=="insertunorderedlist"?"UL":"OL")}},"state");u({"FontSize,FontName":function(y){var x=0,v;if(v=m.getParent(p.getNode(),"span")){if(y=="fontsize"){x=v.style.fontSize}else{x=v.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()}}return x}},"value");if(k.custom_undo_redo){u({Undo:function(){n.undoManager.undo()},Redo:function(){n.undoManager.redo()}})}}})(tinymce);(function(b){var a=b.util.Dispatcher;b.UndoManager=function(f){var d,e=0,h=[],c;function g(){return b.trim(f.getContent({format:"raw",no_events:1}))}return d={typing:false,onAdd:new a(d),onUndo:new a(d),onRedo:new a(d),beforeChange:function(){c=f.selection.getBookmark(2,true)},add:function(m){var j,k=f.settings,l;m=m||{};m.content=g();l=h[e];if(l&&l.content==m.content){return null}if(h[e]){h[e].beforeBookmark=c}if(k.custom_undo_redo_levels){if(h.length>k.custom_undo_redo_levels){for(j=0;j<h.length-1;j++){h[j]=h[j+1]}h.length--;e=h.length}}m.bookmark=f.selection.getBookmark(2,true);if(e<h.length-1){h.length=e+1}h.push(m);e=h.length-1;d.onAdd.dispatch(d,m);f.isNotDirty=0;return m},undo:function(){var k,j;if(d.typing){d.add();d.typing=false}if(e>0){k=h[--e];f.setContent(k.content,{format:"raw"});f.selection.moveToBookmark(k.beforeBookmark);d.onUndo.dispatch(d,k)}return k},redo:function(){var i;if(e<h.length-1){i=h[++e];f.setContent(i.content,{format:"raw"});f.selection.moveToBookmark(i.bookmark);d.onRedo.dispatch(d,i)}return i},clear:function(){h=[];e=0;d.typing=false},hasUndo:function(){return e>0||this.typing},hasRedo:function(){return e<h.length-1&&!this.typing}}}})(tinymce);(function(l){var j=l.dom.Event,c=l.isIE,a=l.isGecko,b=l.isOpera,i=l.each,h=l.extend,d=true,g=false;function k(o){var p,n,m;do{if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(o.nodeName)){if(p){n=o.cloneNode(false);n.appendChild(p);p=n}else{p=m=o.cloneNode(false)}p.removeAttribute("id")}}while(o=o.parentNode);if(p){return{wrapper:p,inner:m}}}function f(n,o){var m=o.ownerDocument.createRange();m.setStart(n.endContainer,n.endOffset);m.setEndAfter(o);return m.cloneContents().textContent.length==0}function e(o,q,m){var n,p;if(q.isEmpty(m)){n=q.getParent(m,"ul,ol");if(!q.getParent(n.parentNode,"ul,ol")){q.split(n,m);p=q.create("p",0,'<br data-mce-bogus="1" />');q.replace(p,m);o.select(p,1)}return g}return d}l.create("tinymce.ForceBlocks",{ForceBlocks:function(m){var n=this,o=m.settings,p;n.editor=m;n.dom=m.dom;p=(o.forced_root_block||"p").toLowerCase();o.element=p.toUpperCase();m.onPreInit.add(n.setup,n)},setup:function(){var n=this,m=n.editor,p=m.settings,u=m.dom,o=m.selection,q=m.schema.getBlockElements();if(p.forced_root_block){function v(){var y=o.getStart(),t=m.getBody(),s,z,D,F,E,x,A,B=-16777215;if(!y||y.nodeType!==1){return}while(y!=t){if(q[y.nodeName]){return}y=y.parentNode}s=o.getRng();if(s.setStart){z=s.startContainer;D=s.startOffset;F=s.endContainer;E=s.endOffset}else{if(s.item){s=m.getDoc().body.createTextRange();s.moveToElementText(s.item(0))}tmpRng=s.duplicate();tmpRng.collapse(true);D=tmpRng.move("character",B)*-1;if(!tmpRng.collapsed){tmpRng=s.duplicate();tmpRng.collapse(false);E=(tmpRng.move("character",B)*-1)-D}}for(y=t.firstChild;y;y){if(y.nodeType===3||(y.nodeType==1&&!q[y.nodeName])){if(!x){x=u.create(p.forced_root_block);y.parentNode.insertBefore(x,y)}A=y;y=y.nextSibling;x.appendChild(A)}else{x=null;y=y.nextSibling}}if(s.setStart){s.setStart(z,D);s.setEnd(F,E);o.setRng(s)}else{try{s=m.getDoc().body.createTextRange();s.moveToElementText(t);s.collapse(true);s.moveStart("character",D);if(E>0){s.moveEnd("character",E)}s.select()}catch(C){}}m.nodeChanged()}m.onKeyUp.add(v);m.onClick.add(v)}if(p.force_br_newlines){if(c){m.onKeyPress.add(function(s,t){var x;if(t.keyCode==13&&o.getNode().nodeName!="LI"){o.setContent('<br id="__" /> ',{format:"raw"});x=u.get("__");x.removeAttribute("id");o.select(x);o.collapse();return j.cancel(t)}})}}if(p.force_p_newlines){if(!c){m.onKeyPress.add(function(s,t){if(t.keyCode==13&&!t.shiftKey&&!n.insertPara(t)){j.cancel(t)}})}else{l.addUnload(function(){n._previousFormats=0});m.onKeyPress.add(function(s,t){n._previousFormats=0;if(t.keyCode==13&&!t.shiftKey&&s.selection.isCollapsed()&&p.keep_styles){n._previousFormats=k(s.selection.getStart())}});m.onKeyUp.add(function(t,y){if(y.keyCode==13&&!y.shiftKey){var x=t.selection.getStart(),s=n._previousFormats;if(!x.hasChildNodes()&&s){x=u.getParent(x,u.isBlock);if(x&&x.nodeName!="LI"){x.innerHTML="";if(n._previousFormats){x.appendChild(s.wrapper);s.inner.innerHTML="\uFEFF"}else{x.innerHTML="\uFEFF"}o.select(x,1);o.collapse(true);t.getDoc().execCommand("Delete",false,null);n._previousFormats=0}}}})}if(a){m.onKeyDown.add(function(s,t){if((t.keyCode==8||t.keyCode==46)&&!t.shiftKey){n.backspaceDelete(t,t.keyCode==8)}})}}if(l.isWebKit){function r(t){var s=o.getRng(),x,A=u.create("div",null," "),z,y=u.getViewPort(t.getWin()).h;s.insertNode(x=u.create("br"));s.setStartAfter(x);s.setEndAfter(x);o.setRng(s);if(o.getSel().focusNode==x.previousSibling){o.select(u.insertAfter(u.doc.createTextNode("\u00a0"),x));o.collapse(d)}u.insertAfter(A,x);z=u.getPos(A).y;u.remove(A);if(z>y){t.getWin().scrollTo(0,z)}}m.onKeyPress.add(function(s,t){if(t.keyCode==13&&(t.shiftKey||(p.force_br_newlines&&!u.getParent(o.getNode(),"h1,h2,h3,h4,h5,h6,ol,ul")))){r(s);j.cancel(t)}})}if(c){if(p.element!="P"){m.onKeyPress.add(function(s,t){n.lastElm=o.getNode().nodeName});m.onKeyUp.add(function(t,x){var z,y=o.getNode(),s=t.getBody();if(s.childNodes.length===1&&y.nodeName=="P"){y=u.rename(y,p.element);o.select(y);o.collapse();t.nodeChanged()}else{if(x.keyCode==13&&!x.shiftKey&&n.lastElm!="P"){z=u.getParent(y,"p");if(z){u.rename(z,p.element);t.nodeChanged()}}}})}}},getParentBlock:function(o){var m=this.dom;return m.getParent(o,m.isBlock)},insertPara:function(Q){var E=this,v=E.editor,M=v.dom,R=v.getDoc(),V=v.settings,F=v.selection.getSel(),G=F.getRangeAt(0),U=R.body;var J,K,H,O,N,q,o,u,z,m,C,T,p,x,I,L=M.getViewPort(v.getWin()),B,D,A;v.undoManager.beforeChange();J=R.createRange();J.setStart(F.anchorNode,F.anchorOffset);J.collapse(d);K=R.createRange();K.setStart(F.focusNode,F.focusOffset);K.collapse(d);H=J.compareBoundaryPoints(J.START_TO_END,K)<0;O=H?F.anchorNode:F.focusNode;N=H?F.anchorOffset:F.focusOffset;q=H?F.focusNode:F.anchorNode;o=H?F.focusOffset:F.anchorOffset;if(O===q&&/^(TD|TH)$/.test(O.nodeName)){if(O.firstChild.nodeName=="BR"){M.remove(O.firstChild)}if(O.childNodes.length==0){v.dom.add(O,V.element,null,"<br />");T=v.dom.add(O,V.element,null,"<br />")}else{I=O.innerHTML;O.innerHTML="";v.dom.add(O,V.element,null,I);T=v.dom.add(O,V.element,null,"<br />")}G=R.createRange();G.selectNodeContents(T);G.collapse(1);v.selection.setRng(G);return g}if(O==U&&q==U&&U.firstChild&&v.dom.isBlock(U.firstChild)){O=q=O.firstChild;N=o=0;J=R.createRange();J.setStart(O,0);K=R.createRange();K.setStart(q,0)}if(!R.body.hasChildNodes()){R.body.appendChild(M.create("br"))}O=O.nodeName=="HTML"?R.body:O;O=O.nodeName=="BODY"?O.firstChild:O;q=q.nodeName=="HTML"?R.body:q;q=q.nodeName=="BODY"?q.firstChild:q;u=E.getParentBlock(O);z=E.getParentBlock(q);m=u?u.nodeName:V.element;if(I=E.dom.getParent(u,"li,pre")){if(I.nodeName=="LI"){return e(v.selection,E.dom,I)}return d}if(u&&(u.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(M.getStyle(u,"position",1)))){m=V.element;u=null}if(z&&(z.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(M.getStyle(u,"position",1)))){m=V.element;z=null}if(/(TD|TABLE|TH|CAPTION)/.test(m)||(u&&m=="DIV"&&/left|right/gi.test(M.getStyle(u,"float",1)))){m=V.element;u=z=null}C=(u&&u.nodeName==m)?u.cloneNode(0):v.dom.create(m);T=(z&&z.nodeName==m)?z.cloneNode(0):v.dom.create(m);T.removeAttribute("id");if(/^(H[1-6])$/.test(m)&&f(G,u)){T=v.dom.create(V.element)}I=p=O;do{if(I==U||I.nodeType==9||E.dom.isBlock(I)||/(TD|TABLE|TH|CAPTION)/.test(I.nodeName)){break}p=I}while((I=I.previousSibling?I.previousSibling:I.parentNode));I=x=q;do{if(I==U||I.nodeType==9||E.dom.isBlock(I)||/(TD|TABLE|TH|CAPTION)/.test(I.nodeName)){break}x=I}while((I=I.nextSibling?I.nextSibling:I.parentNode));if(p.nodeName==m){J.setStart(p,0)}else{J.setStartBefore(p)}J.setEnd(O,N);C.appendChild(J.cloneContents()||R.createTextNode(""));try{K.setEndAfter(x)}catch(P){}K.setStart(q,o);T.appendChild(K.cloneContents()||R.createTextNode(""));G=R.createRange();if(!p.previousSibling&&p.parentNode.nodeName==m){G.setStartBefore(p.parentNode)}else{if(J.startContainer.nodeName==m&&J.startOffset==0){G.setStartBefore(J.startContainer)}else{G.setStart(J.startContainer,J.startOffset)}}if(!x.nextSibling&&x.parentNode.nodeName==m){G.setEndAfter(x.parentNode)}else{G.setEnd(K.endContainer,K.endOffset)}G.deleteContents();if(b){v.getWin().scrollTo(0,L.y)}if(C.firstChild&&C.firstChild.nodeName==m){C.innerHTML=C.firstChild.innerHTML}if(T.firstChild&&T.firstChild.nodeName==m){T.innerHTML=T.firstChild.innerHTML}function S(y,s){var r=[],X,W,t;y.innerHTML="";if(V.keep_styles){W=s;do{if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(W.nodeName)){X=W.cloneNode(g);M.setAttrib(X,"id","");r.push(X)}}while(W=W.parentNode)}if(r.length>0){for(t=r.length-1,X=y;t>=0;t--){X=X.appendChild(r[t])}r[0].innerHTML=b?"\u00a0":"<br />";return r[0]}else{y.innerHTML=b?"\u00a0":"<br />"}}if(M.isEmpty(C)){S(C,O)}if(M.isEmpty(T)){A=S(T,q)}if(b&&parseFloat(opera.version())<9.5){G.insertNode(C);G.insertNode(T)}else{G.insertNode(T);G.insertNode(C)}T.normalize();C.normalize();v.selection.select(T,true);v.selection.collapse(true);B=v.dom.getPos(T).y;if(B<L.y||B+25>L.y+L.h){v.getWin().scrollTo(0,B<L.y?B:B-L.h+25)}v.undoManager.add();return g},backspaceDelete:function(u,B){var C=this,s=C.editor,y=s.getBody(),q=s.dom,p,v=s.selection,o=v.getRng(),x=o.startContainer,p,z,A,m;if(!B&&o.collapsed&&x.nodeType==1&&o.startOffset==x.childNodes.length){m=new l.dom.TreeWalker(x.lastChild,x);for(p=x.lastChild;p;p=m.prev()){if(p.nodeType==3){o.setStart(p,p.nodeValue.length);o.collapse(true);v.setRng(o);return}}}if(x&&s.dom.isBlock(x)&&!/^(TD|TH)$/.test(x.nodeName)&&B){if(x.childNodes.length==0||(x.childNodes.length==1&&x.firstChild.nodeName=="BR")){p=x;while((p=p.previousSibling)&&!s.dom.isBlock(p)){}if(p){if(x!=y.firstChild){z=s.dom.doc.createTreeWalker(p,NodeFilter.SHOW_TEXT,null,g);while(A=z.nextNode()){p=A}o=s.getDoc().createRange();o.setStart(p,p.nodeValue?p.nodeValue.length:0);o.setEnd(p,p.nodeValue?p.nodeValue.length:0);v.setRng(o);s.dom.remove(x)}return j.cancel(u)}}}}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each,e=c.extend;c.create("tinymce.ControlManager",{ControlManager:function(f,j){var h=this,g;j=j||{};h.editor=f;h.controls={};h.onAdd=new c.util.Dispatcher(h);h.onPostRender=new c.util.Dispatcher(h);h.prefix=j.prefix||f.id+"_";h._cls={};h.onPostRender.add(function(){d(h.controls,function(i){i.postRender()})})},get:function(f){return this.controls[this.prefix+f]||this.controls[f]},setActive:function(h,f){var g=null;if(g=this.get(h)){g.setActive(f)}return g},setDisabled:function(h,f){var g=null;if(g=this.get(h)){g.setDisabled(f)}return g},add:function(g){var f=this;if(g){f.controls[g.id]=g;f.onAdd.dispatch(g,f)}return g},createControl:function(i){var h,g=this,f=g.editor;d(f.plugins,function(j){if(j.createControl){h=j.createControl(i,g);if(h){return false}}});switch(i){case"|":case"separator":return g.createSeparator()}if(!h&&f.buttons&&(h=f.buttons[i])){return g.createButton(i,h)}return g.add(h)},createDropMenu:function(f,n,h){var m=this,i=m.editor,j,g,k,l;n=e({"class":"mceDropDown",constrain:i.settings.constrain_menus},n);n["class"]=n["class"]+" "+i.getParam("skin")+"Skin";if(k=i.getParam("skin_variant")){n["class"]+=" "+i.getParam("skin")+"Skin"+k.substring(0,1).toUpperCase()+k.substring(1)}f=m.prefix+f;l=h||m._cls.dropmenu||c.ui.DropMenu;j=m.controls[f]=new l(f,n);j.onAddItem.add(function(r,q){var p=q.settings;p.title=i.getLang(p.title,p.title);if(!p.onclick){p.onclick=function(o){if(p.cmd){i.execCommand(p.cmd,p.ui||false,p.value)}}}});i.onRemove.add(function(){j.destroy()});if(c.isIE){j.onShowMenu.add(function(){i.focus();g=i.selection.getBookmark(1)});j.onHideMenu.add(function(){if(g){i.selection.moveToBookmark(g);g=0}})}return m.add(j)},createListBox:function(f,n,h){var l=this,j=l.editor,i,k,m;if(l.get(f)){return null}n.title=j.translate(n.title);n.scope=n.scope||j;if(!n.onselect){n.onselect=function(o){j.execCommand(n.cmd,n.ui||false,o||n.value)}}n=e({title:n.title,"class":"mce_"+f,scope:n.scope,control_manager:l},n);f=l.prefix+f;function g(o){return o.settings.use_accessible_selects&&!c.isGecko}if(j.settings.use_native_selects||g(j)){k=new c.ui.NativeListBox(f,n)}else{m=h||l._cls.listbox||c.ui.ListBox;k=new m(f,n,j)}l.controls[f]=k;if(c.isWebKit){k.onPostRender.add(function(p,o){a.add(o,"mousedown",function(){j.bookmark=j.selection.getBookmark(1)});a.add(o,"focus",function(){j.selection.moveToBookmark(j.bookmark);j.bookmark=null})})}if(k.hideMenu){j.onMouseDown.add(k.hideMenu,k)}return l.add(k)},createButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.label=g.translate(i.label);i.scope=i.scope||g;if(!i.onclick&&!i.menu_button){i.onclick=function(){g.execCommand(i.cmd,i.ui||false,i.value)}}i=e({title:i.title,"class":"mce_"+m,unavailable_prefix:g.getLang("unavailable",""),scope:i.scope,control_manager:h},i);m=h.prefix+m;if(i.menu_button){f=l||h._cls.menubutton||c.ui.MenuButton;k=new f(m,i,g);g.onMouseDown.add(k.hideMenu,k)}else{f=h._cls.button||c.ui.Button;k=new f(m,i,g)}return h.add(k)},createMenuButton:function(h,f,g){f=f||{};f.menu_button=1;return this.createButton(h,f,g)},createSplitButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.scope=i.scope||g;if(!i.onclick){i.onclick=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}if(!i.onselect){i.onselect=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}i=e({title:i.title,"class":"mce_"+m,scope:i.scope,control_manager:h},i);m=h.prefix+m;f=l||h._cls.splitbutton||c.ui.SplitButton;k=h.add(new f(m,i,g));g.onMouseDown.add(k.hideMenu,k);return k},createColorSplitButton:function(f,n,h){var l=this,j=l.editor,i,k,m,g;if(l.get(f)){return null}n.title=j.translate(n.title);n.scope=n.scope||j;if(!n.onclick){n.onclick=function(o){if(c.isIE){g=j.selection.getBookmark(1)}j.execCommand(n.cmd,n.ui||false,o||n.value)}}if(!n.onselect){n.onselect=function(o){j.execCommand(n.cmd,n.ui||false,o||n.value)}}n=e({title:n.title,"class":"mce_"+f,menu_class:j.getParam("skin")+"Skin",scope:n.scope,more_colors_title:j.getLang("more_colors")},n);f=l.prefix+f;m=h||l._cls.colorsplitbutton||c.ui.ColorSplitButton;k=new m(f,n,j);j.onMouseDown.add(k.hideMenu,k);j.onRemove.add(function(){k.destroy()});if(c.isIE){k.onShowMenu.add(function(){j.focus();g=j.selection.getBookmark(1)});k.onHideMenu.add(function(){if(g){j.selection.moveToBookmark(g);g=0}})}return l.add(k)},createToolbar:function(k,h,j){var i,g=this,f;k=g.prefix+k;f=j||g._cls.toolbar||c.ui.Toolbar;i=new f(k,h,g.editor);if(g.get(k)){return null}return g.add(i)},createToolbarGroup:function(k,h,j){var i,g=this,f;k=g.prefix+k;f=j||this._cls.toolbarGroup||c.ui.ToolbarGroup;i=new f(k,h,g.editor);if(g.get(k)){return null}return g.add(i)},createSeparator:function(g){var f=g||this._cls.separator||c.ui.Separator;return new f()},setControlType:function(g,f){return this._cls[g.toLowerCase()]=f},destroy:function(){d(this.controls,function(f){f.destroy()});this.controls=null}})})(tinymce);(function(d){var a=d.util.Dispatcher,e=d.each,c=d.isIE,b=d.isOpera;d.create("tinymce.WindowManager",{WindowManager:function(f){var g=this;g.editor=f;g.onOpen=new a(g);g.onClose=new a(g);g.params={};g.features={}},open:function(z,h){var v=this,k="",n,m,i=v.editor.settings.dialog_type=="modal",q,o,j,g=d.DOM.getViewPort(),r;z=z||{};h=h||{};o=b?g.w:screen.width;j=b?g.h:screen.height;z.name=z.name||"mc_"+new Date().getTime();z.width=parseInt(z.width||320);z.height=parseInt(z.height||240);z.resizable=true;z.left=z.left||parseInt(o/2)-(z.width/2);z.top=z.top||parseInt(j/2)-(z.height/2);h.inline=false;h.mce_width=z.width;h.mce_height=z.height;h.mce_auto_focus=z.auto_focus;if(i){if(c){z.center=true;z.help=false;z.dialogWidth=z.width+"px";z.dialogHeight=z.height+"px";z.scroll=z.scrollbars||false}}e(z,function(p,f){if(d.is(p,"boolean")){p=p?"yes":"no"}if(!/^(name|url)$/.test(f)){if(c&&i){k+=(k?";":"")+f+":"+p}else{k+=(k?",":"")+f+"="+p}}});v.features=z;v.params=h;v.onOpen.dispatch(v,z,h);r=z.url||z.file;r=d._addVer(r);try{if(c&&i){q=1;window.showModalDialog(r,window,k)}else{q=window.open(r,z.name,k)}}catch(l){}if(!q){alert(v.editor.getLang("popup_blocked"))}},close:function(f){f.close();this.onClose.dispatch(this)},createInstance:function(i,h,g,m,l,k){var j=d.resolve(i);return new j(h,g,m,l,k)},confirm:function(h,f,i,g){g=g||window;f.call(i||this,g.confirm(this._decode(this.editor.getLang(h,h))))},alert:function(h,f,j,g){var i=this;g=g||window;g.alert(i._decode(i.editor.getLang(h,h)));if(f){f.call(j||i)}},resizeBy:function(f,g,h){h.resizeBy(f,g)},_decode:function(f){return d.DOM.decode(f).replace(/\\n/g,"\n")}})}(tinymce));(function(a){a.Formatter=function(V){var M={},P=a.each,c=V.dom,q=V.selection,t=a.dom.TreeWalker,K=new a.dom.RangeUtils(c),d=V.schema.isValidChild,F=c.isBlock,l=V.settings.forced_root_block,s=c.nodeIndex,E="\uFEFF",e=/^(src|href|style)$/,S=false,B=true,p;function z(W){return W instanceof Array}function m(X,W){return c.getParents(X,W,c.getRoot())}function b(W){return W.nodeType===1&&W.id==="_mce_caret"}function R(W){return W?M[W]:M}function k(W,X){if(W){if(typeof(W)!=="string"){P(W,function(Z,Y){k(Y,Z)})}else{X=X.length?X:[X];P(X,function(Y){if(Y.deep===p){Y.deep=!Y.selector}if(Y.split===p){Y.split=!Y.selector||Y.inline}if(Y.remove===p&&Y.selector&&!Y.inline){Y.remove="none"}if(Y.selector&&Y.inline){Y.mixed=true;Y.block_expand=true}if(typeof(Y.classes)==="string"){Y.classes=Y.classes.split(/\s+/)}});M[W]=X}}}var i=function(X){var W;V.dom.getParent(X,function(Y){W=V.dom.getStyle(Y,"text-decoration");return W&&W!=="none"});return W};var I=function(W){var X;if(W.nodeType===1&&W.parentNode&&W.parentNode.nodeType===1){X=i(W.parentNode);if(V.dom.getStyle(W,"color")&&X){V.dom.setStyle(W,"text-decoration",X)}else{if(V.dom.getStyle(W,"textdecoration")===X){V.dom.setStyle(W,"text-decoration",null)}}}};function T(Z,ag,ab){var ac=R(Z),ah=ac[0],af,X,ae,ad=q.isCollapsed();function W(al,ak){ak=ak||ah;if(al){if(ak.onformat){ak.onformat(al,ak,ag,ab)}P(ak.styles,function(an,am){c.setStyle(al,am,r(an,ag))});P(ak.attributes,function(an,am){c.setAttrib(al,am,r(an,ag))});P(ak.classes,function(am){am=r(am,ag);if(!c.hasClass(al,am)){c.addClass(al,am)}})}}function aa(){function am(at,aq){var ar=new t(aq);for(ab=ar.current();ab;ab=ar.prev()){if(ab.childNodes.length>1||ab==at){return ab}}}var al=V.selection.getRng();var ap=al.startContainer;var ak=al.endContainer;if(ap!=ak&&al.endOffset==0){var ao=am(ap,ak);var an=ao.nodeType==3?ao.length:ao.childNodes.length;al.setEnd(ao,an)}return al}function Y(an,at,aq,ap,al){var ak=[],am=-1,ar,av=-1,ao=-1,au;P(an.childNodes,function(ax,aw){if(ax.nodeName==="UL"||ax.nodeName==="OL"){am=aw;ar=ax;return false}});P(an.childNodes,function(ax,aw){if(ax.nodeName==="SPAN"&&c.getAttrib(ax,"data-mce-type")=="bookmark"){if(ax.id==at.id+"_start"){av=aw}else{if(ax.id==at.id+"_end"){ao=aw}}}});if(am<=0||(av<am&&ao>am)){P(a.grep(an.childNodes),al);return 0}else{au=aq.cloneNode(S);P(a.grep(an.childNodes),function(ax,aw){if((av<am&&aw<am)||(av>am&&aw>am)){ak.push(ax);ax.parentNode.removeChild(ax)}});if(av<am){an.insertBefore(au,ar)}else{if(av>am){an.insertBefore(au,ar.nextSibling)}}ap.push(au);P(ak,function(aw){au.appendChild(aw)});return au}}function ai(al,an,ap){var ak=[],ao,am;ao=ah.inline||ah.block;am=c.create(ao);W(am);K.walk(al,function(aq){var ar;function at(au){var ax=au.nodeName.toLowerCase(),aw=au.parentNode.nodeName.toLowerCase(),av;if(g(ax,"br")){ar=0;if(ah.block){c.remove(au)}return}if(ah.wrapper&&x(au,Z,ag)){ar=0;return}if(ah.block&&!ah.wrapper&&G(ax)){au=c.rename(au,ao);W(au);ak.push(au);ar=0;return}if(ah.selector){P(ac,function(ay){if("collapsed" in ay&&ay.collapsed!==ad){return}if(c.is(au,ay.selector)&&!b(au)){W(au,ay);av=true}});if(!ah.inline||av){ar=0;return}}if(d(ao,ax)&&d(aw,ao)&&!(!ap&&au.nodeType===3&&au.nodeValue.length===1&&au.nodeValue.charCodeAt(0)===65279)&&!b(au)){if(!ar){ar=am.cloneNode(S);au.parentNode.insertBefore(ar,au);ak.push(ar)}ar.appendChild(au)}else{if(ax=="li"&&an){ar=Y(au,an,am,ak,at)}else{ar=0;P(a.grep(au.childNodes),at);ar=0}}}P(aq,at)});if(ah.wrap_links===false){P(ak,function(aq){function ar(aw){var av,au,at;if(aw.nodeName==="A"){au=am.cloneNode(S);ak.push(au);at=a.grep(aw.childNodes);for(av=0;av<at.length;av++){au.appendChild(at[av])}aw.appendChild(au)}P(a.grep(aw.childNodes),ar)}ar(aq)})}P(ak,function(at){var aq;function au(aw){var av=0;P(aw.childNodes,function(ax){if(!f(ax)&&!H(ax)){av++}});return av}function ar(av){var ax,aw;P(av.childNodes,function(ay){if(ay.nodeType==1&&!H(ay)&&!b(ay)){ax=ay;return S}});if(ax&&h(ax,ah)){aw=ax.cloneNode(S);W(aw);c.replace(aw,av,B);c.remove(ax,1)}return aw||av}aq=au(at);if((ak.length>1||!F(at))&&aq===0){c.remove(at,1);return}if(ah.inline||ah.wrapper){if(!ah.exact&&aq===1){at=ar(at)}P(ac,function(av){P(c.select(av.inline,at),function(ax){var aw;if(av.wrap_links===false){aw=ax.parentNode;do{if(aw.nodeName==="A"){return}}while(aw=aw.parentNode)}U(av,ag,ax,av.exact?ax:null)})});if(x(at.parentNode,Z,ag)){c.remove(at,1);at=0;return B}if(ah.merge_with_parents){c.getParent(at.parentNode,function(av){if(x(av,Z,ag)){c.remove(at,1);at=0;return B}})}if(at&&ah.merge_siblings!==false){at=u(C(at),at);at=u(at,C(at,B))}}})}if(ah){if(ab){if(ab.nodeType){X=c.createRng();X.setStartBefore(ab);X.setEndAfter(ab);ai(o(X,ac),null,true)}else{ai(ab,null,true)}}else{if(!ad||!ah.inline||c.select("td.mceSelected,th.mceSelected").length){var aj=V.selection.getNode();V.selection.setRng(aa());af=q.getBookmark();ai(o(q.getRng(B),ac),af);if(ah.styles&&(ah.styles.color||ah.styles.textDecoration)){a.walk(aj,I,"childNodes");I(aj)}q.moveToBookmark(af);N(q.getRng(B));V.nodeChanged()}else{Q("apply",Z,ag)}}}}function A(Y,ag,aa){var ab=R(Y),ai=ab[0],af,ae,X;function Z(an){var am,al,ak;am=a.grep(an.childNodes);for(al=0,ak=ab.length;al<ak;al++){if(U(ab[al],ag,an,an)){break}}if(ai.deep){for(al=0,ak=am.length;al<ak;al++){Z(am[al])}}}function ac(ak){var al;P(m(ak.parentNode).reverse(),function(am){var an;if(!al&&am.id!="_start"&&am.id!="_end"){an=x(am,Y,ag);if(an&&an.split!==false){al=am}}});return al}function W(an,ak,ap,at){var au,ar,aq,am,ao,al;if(an){al=an.parentNode;for(au=ak.parentNode;au&&au!=al;au=au.parentNode){ar=au.cloneNode(S);for(ao=0;ao<ab.length;ao++){if(U(ab[ao],ag,ar,ar)){ar=0;break}}if(ar){if(aq){ar.appendChild(aq)}if(!am){am=ar}aq=ar}}if(at&&(!ai.mixed||!F(an))){ak=c.split(an,ak)}if(aq){ap.parentNode.insertBefore(aq,ap);am.appendChild(ap)}}return ak}function ah(ak){return W(ac(ak),ak,ak,true)}function ad(am){var al=c.get(am?"_start":"_end"),ak=al[am?"firstChild":"lastChild"];if(H(ak)){ak=ak[am?"firstChild":"lastChild"]}c.remove(al,true);return ak}function aj(ak){var al,am;ak=o(ak,ab,B);if(ai.split){al=J(ak,B);am=J(ak);if(al!=am){al=O(al,"span",{id:"_start","data-mce-type":"bookmark"});am=O(am,"span",{id:"_end","data-mce-type":"bookmark"});ah(al);ah(am);al=ad(B);am=ad()}else{al=am=ah(al)}ak.startContainer=al.parentNode;ak.startOffset=s(al);ak.endContainer=am.parentNode;ak.endOffset=s(am)+1}K.walk(ak,function(an){P(an,function(ao){Z(ao);if(ao.nodeType===1&&V.dom.getStyle(ao,"text-decoration")==="underline"&&ao.parentNode&&i(ao.parentNode)==="underline"){U({deep:false,exact:true,inline:"span",styles:{textDecoration:"underline"}},null,ao)}})})}if(aa){if(aa.nodeType){X=c.createRng();X.setStartBefore(aa);X.setEndAfter(aa);aj(X)}else{aj(aa)}return}if(!q.isCollapsed()||!ai.inline||c.select("td.mceSelected,th.mceSelected").length){af=q.getBookmark();aj(q.getRng(B));q.moveToBookmark(af);if(ai.inline&&j(Y,ag,q.getStart())){N(q.getRng(true))}V.nodeChanged()}else{Q("remove",Y,ag)}if(a.isWebKit){V.execCommand("mceCleanup")}}function D(X,Z,Y){var W=R(X);if(j(X,Z,Y)&&(!("toggle" in W[0])||W[0]["toggle"])){A(X,Z,Y)}else{T(X,Z,Y)}}function x(X,W,ac,aa){var Y=R(W),ad,ab,Z;function ae(ai,ak,al){var ah,aj,af=ak[al],ag;if(ak.onmatch){return ak.onmatch(ai,ak,al)}if(af){if(af.length===p){for(ah in af){if(af.hasOwnProperty(ah)){if(al==="attributes"){aj=c.getAttrib(ai,ah)}else{aj=L(ai,ah)}if(aa&&!aj&&!ak.exact){return}if((!aa||ak.exact)&&!g(aj,r(af[ah],ac))){return}}}}else{for(ag=0;ag<af.length;ag++){if(al==="attributes"?c.getAttrib(ai,af[ag]):L(ai,af[ag])){return ak}}}}return ak}if(Y&&X){for(ab=0;ab<Y.length;ab++){ad=Y[ab];if(h(X,ad)&&ae(X,ad,"attributes")&&ae(X,ad,"styles")){if(Z=ad.classes){for(ab=0;ab<Z.length;ab++){if(!c.hasClass(X,Z[ab])){return}}}return ad}}}}function j(Y,aa,Z){var X;function W(ab){ab=c.getParent(ab,function(ac){return !!x(ac,Y,aa,true)});return x(ab,Y,aa)}if(Z){return W(Z)}Z=q.getNode();if(W(Z)){return B}X=q.getStart();if(X!=Z){if(W(X)){return B}}return S}function v(ad,ac){var aa,ab=[],Z={},Y,X,W;aa=q.getStart();c.getParent(aa,function(ag){var af,ae;for(af=0;af<ad.length;af++){ae=ad[af];if(!Z[ae]&&x(ag,ae,ac)){Z[ae]=true;ab.push(ae)}}});return ab}function y(aa){var ac=R(aa),Z,Y,ab,X,W;if(ac){Z=q.getStart();Y=m(Z);for(X=ac.length-1;X>=0;X--){W=ac[X].selector;if(!W){return B}for(ab=Y.length-1;ab>=0;ab--){if(c.is(Y[ab],W)){return B}}}}return S}a.extend(this,{get:R,register:k,apply:T,remove:A,toggle:D,match:j,matchAll:v,matchNode:x,canApply:y});function h(W,X){if(g(W,X.inline)){return B}if(g(W,X.block)){return B}if(X.selector){return c.is(W,X.selector)}}function g(X,W){X=X||"";W=W||"";X=""+(X.nodeName||X);W=""+(W.nodeName||W);return X.toLowerCase()==W.toLowerCase()}function L(X,W){var Y=c.getStyle(X,W);if(W=="color"||W=="backgroundColor"){Y=c.toHex(Y)}if(W=="fontWeight"&&Y==700){Y="bold"}return""+Y}function r(W,X){if(typeof(W)!="string"){W=W(X)}else{if(X){W=W.replace(/%(\w+)/g,function(Z,Y){return X[Y]||Z})}}return W}function f(W){return W&&W.nodeType===3&&/^([\t \r\n]+|)$/.test(W.nodeValue)}function O(Y,X,W){var Z=c.create(X,W);Y.parentNode.insertBefore(Z,Y);Z.appendChild(Y);return Z}function o(W,ai,Z){var Y=W.startContainer,ad=W.startOffset,al=W.endContainer,af=W.endOffset,ak,ah,ac,ag;function aj(ar){var am,ap,aq,ao,an;am=ap=ar?Y:al;an=ar?"previousSibling":"nextSibling";root=c.getRoot();if(am.nodeType==3&&!f(am)){if(ar?ad>0:af<am.nodeValue.length){return am}}for(;;){if(!ai[0].block_expand&&F(ap)){return ap}for(ao=ap[an];ao;ao=ao[an]){if(!H(ao)&&!f(ao)){return ap}}if(ap.parentNode==root){am=ap;break}ap=ap.parentNode}return am}function ab(am,an){if(an===p){an=am.nodeType===3?am.length:am.childNodes.length}while(am&&am.hasChildNodes()){am=am.childNodes[an];if(am){an=am.nodeType===3?am.length:am.childNodes.length}}return{node:am,offset:an}}if(Y.nodeType==1&&Y.hasChildNodes()){ah=Y.childNodes.length-1;Y=Y.childNodes[ad>ah?ah:ad];if(Y.nodeType==3){ad=0}}if(al.nodeType==1&&al.hasChildNodes()){ah=al.childNodes.length-1;al=al.childNodes[af>ah?ah:af-1];if(al.nodeType==3){af=al.nodeValue.length}}if(H(Y.parentNode)||H(Y)){Y=H(Y)?Y:Y.parentNode;Y=Y.nextSibling||Y;if(Y.nodeType==3){ad=0}}if(H(al.parentNode)||H(al)){al=H(al)?al:al.parentNode;al=al.previousSibling||al;if(al.nodeType==3){af=al.length}}if(ai[0].inline){if(W.collapsed){function ae(an,ar,au){var aq,ao,at,am;function ap(aw,ay){var az,av,ax=aw.nodeValue;if(typeof(ay)=="undefined"){ay=au?ax.length:0}if(au){az=ax.lastIndexOf(" ",ay);av=ax.lastIndexOf("\u00a0",ay);az=az>av?az:av;if(az!==-1&&!Z){az++}}else{az=ax.indexOf(" ",ay);av=ax.indexOf("\u00a0",ay);az=az!==-1&&(av===-1||az<av)?az:av}return az}if(an.nodeType===3){at=ap(an,ar);if(at!==-1){return{container:an,offset:at}}am=an}aq=new t(an,c.getParent(an,F)||V.getBody());while(ao=aq[au?"prev":"next"]()){if(ao.nodeType===3){am=ao;at=ap(ao);if(at!==-1){return{container:ao,offset:at}}}else{if(F(ao)){break}}}if(am){if(au){ar=0}else{ar=am.length}return{container:am,offset:ar}}}ag=ae(Y,ad,true);if(ag){Y=ag.container;ad=ag.offset}ag=ae(al,af);if(ag){al=ag.container;af=ag.offset}}ac=ab(al,af);if(ac.node){while(ac.node&&ac.offset===0&&ac.node.previousSibling){ac=ab(ac.node.previousSibling)}if(ac.node&&ac.offset>0&&ac.node.nodeType===3&&ac.node.nodeValue.charAt(ac.offset-1)===" "){if(ac.offset>1){al=ac.node;al.splitText(ac.offset-1)}else{if(ac.node.previousSibling){}}}}}if(ai[0].inline||ai[0].block_expand){if(!ai[0].inline||(Y.nodeType!=3||ad===0)){Y=aj(true)}if(!ai[0].inline||(al.nodeType!=3||af===al.nodeValue.length)){al=aj()}}if(ai[0].selector&&ai[0].expand!==S&&!ai[0].inline){function aa(an,am){var ao,ap,ar,aq;if(an.nodeType==3&&an.nodeValue.length==0&&an[am]){an=an[am]}ao=m(an);for(ap=0;ap<ao.length;ap++){for(ar=0;ar<ai.length;ar++){aq=ai[ar];if("collapsed" in aq&&aq.collapsed!==W.collapsed){continue}if(c.is(ao[ap],aq.selector)){return ao[ap]}}}return an}Y=aa(Y,"previousSibling");al=aa(al,"nextSibling")}if(ai[0].block||ai[0].selector){function X(an,am,ap){var ao;if(!ai[0].wrapper){ao=c.getParent(an,ai[0].block)}if(!ao){ao=c.getParent(an.nodeType==3?an.parentNode:an,F)}if(ao&&ai[0].wrapper){ao=m(ao,"ul,ol").reverse()[0]||ao}if(!ao){ao=an;while(ao[am]&&!F(ao[am])){ao=ao[am];if(g(ao,"br")){break}}}return ao||an}Y=X(Y,"previousSibling");al=X(al,"nextSibling");if(ai[0].block){if(!F(Y)){Y=aj(true)}if(!F(al)){al=aj()}}}if(Y.nodeType==1){ad=s(Y);Y=Y.parentNode}if(al.nodeType==1){af=s(al)+1;al=al.parentNode}return{startContainer:Y,startOffset:ad,endContainer:al,endOffset:af}}function U(ac,ab,Z,W){var Y,X,aa;if(!h(Z,ac)){return S}if(ac.remove!="all"){P(ac.styles,function(ae,ad){ae=r(ae,ab);if(typeof(ad)==="number"){ad=ae;W=0}if(!W||g(L(W,ad),ae)){c.setStyle(Z,ad,"")}aa=1});if(aa&&c.getAttrib(Z,"style")==""){Z.removeAttribute("style");Z.removeAttribute("data-mce-style")}P(ac.attributes,function(af,ad){var ae;af=r(af,ab);if(typeof(ad)==="number"){ad=af;W=0}if(!W||g(c.getAttrib(W,ad),af)){if(ad=="class"){af=c.getAttrib(Z,ad);if(af){ae="";P(af.split(/\s+/),function(ag){if(/mce\w+/.test(ag)){ae+=(ae?" ":"")+ag}});if(ae){c.setAttrib(Z,ad,ae);return}}}if(ad=="class"){Z.removeAttribute("className")}if(e.test(ad)){Z.removeAttribute("data-mce-"+ad)}Z.removeAttribute(ad)}});P(ac.classes,function(ad){ad=r(ad,ab);if(!W||c.hasClass(W,ad)){c.removeClass(Z,ad)}});X=c.getAttribs(Z);for(Y=0;Y<X.length;Y++){if(X[Y].nodeName.indexOf("_")!==0){return S}}}if(ac.remove!="none"){n(Z,ac);return B}}function n(Y,Z){var W=Y.parentNode,X;if(Z.block){if(!l){function aa(ac,ab,ad){ac=C(ac,ab,ad);return !ac||(ac.nodeName=="BR"||F(ac))}if(F(Y)&&!F(W)){if(!aa(Y,S)&&!aa(Y.firstChild,B,1)){Y.insertBefore(c.create("br"),Y.firstChild)}if(!aa(Y,B)&&!aa(Y.lastChild,S,1)){Y.appendChild(c.create("br"))}}}else{if(W==c.getRoot()){if(!Z.list_block||!g(Y,Z.list_block)){P(a.grep(Y.childNodes),function(ab){if(d(l,ab.nodeName.toLowerCase())){if(!X){X=O(ab,l)}else{X.appendChild(ab)}}else{X=0}})}}}}if(Z.selector&&Z.inline&&!g(Z.inline,Y)){return}c.remove(Y,1)}function C(X,W,Y){if(X){W=W?"nextSibling":"previousSibling";for(X=Y?X:X[W];X;X=X[W]){if(X.nodeType==1||!f(X)){return X}}}}function H(W){return W&&W.nodeType==1&&W.getAttribute("data-mce-type")=="bookmark"}function u(aa,Z){var W,Y,X;function ac(af,ae){if(af.nodeName!=ae.nodeName){return S}function ad(ah){var ai={};P(c.getAttribs(ah),function(aj){var ak=aj.nodeName.toLowerCase();if(ak.indexOf("_")!==0&&ak!=="style"){ai[ak]=c.getAttrib(ah,ak)}});return ai}function ag(ak,aj){var ai,ah;for(ah in ak){if(ak.hasOwnProperty(ah)){ai=aj[ah];if(ai===p){return S}if(ak[ah]!=ai){return S}delete aj[ah]}}for(ah in aj){if(aj.hasOwnProperty(ah)){return S}}return B}if(!ag(ad(af),ad(ae))){return S}if(!ag(c.parseStyle(c.getAttrib(af,"style")),c.parseStyle(c.getAttrib(ae,"style")))){return S}return B}if(aa&&Z){function ab(ae,ad){for(Y=ae;Y;Y=Y[ad]){if(Y.nodeType==3&&Y.nodeValue.length!==0){return ae}if(Y.nodeType==1&&!H(Y)){return Y}}return ae}aa=ab(aa,"previousSibling");Z=ab(Z,"nextSibling");if(ac(aa,Z)){for(Y=aa.nextSibling;Y&&Y!=Z;){X=Y;Y=Y.nextSibling;aa.appendChild(X)}c.remove(Z);P(a.grep(Z.childNodes),function(ad){aa.appendChild(ad)});return aa}}return Z}function G(W){return/^(h[1-6]|p|div|pre|address|dl|dt|dd)$/.test(W)}function J(X,ab){var W,aa,Y,Z;W=X[ab?"startContainer":"endContainer"];aa=X[ab?"startOffset":"endOffset"];if(W.nodeType==1){Y=W.childNodes.length-1;if(!ab&&aa){aa--}W=W.childNodes[aa>Y?Y:aa]}if(W.nodeType===3&&ab&&aa>=W.nodeValue.length){W=new t(W,V.getBody()).next()||W}if(W.nodeType===3&&!ab&&aa==0){W=new t(W,V.getBody()).prev()||W}return W}function Q(af,W,ad){var ai,ag="_mce_caret",X=V.settings.caret_debug;ai=a.isGecko?"\u200B":E;function Y(ak){var aj=c.create("span",{id:ag,"data-mce-bogus":true,style:X?"color:red":""});if(ak){aj.appendChild(V.getDoc().createTextNode(ai))}return aj}function ae(ak,aj){while(ak){if((ak.nodeType===3&&ak.nodeValue!==ai)||ak.childNodes.length>1){return false}if(aj&&ak.nodeType===1){aj.push(ak)}ak=ak.firstChild}return true}function ab(aj){while(aj){if(aj.id===ag){return aj}aj=aj.parentNode}}function aa(aj){var ak;if(aj){ak=new t(aj,aj);for(aj=ak.current();aj;aj=ak.next()){if(aj.nodeType===3){return aj}}}}function Z(al,ak){var am,aj;if(!al){al=ab(q.getStart());if(!al){while(al=c.get(ag)){Z(al,false)}}}else{aj=q.getRng(true);if(ae(al)){if(ak!==false){aj.setStartBefore(al);aj.setEndBefore(al)}c.remove(al)}else{am=aa(al);if(am.nodeValue.charAt(0)===E){am=am.deleteData(0,1)}c.remove(al,1)}q.setRng(aj)}}function ac(){var al,aj,ap,ao,am,ak,an;al=q.getRng(true);ao=al.startOffset;ak=al.startContainer;an=ak.nodeValue;aj=ab(q.getStart());if(aj){ap=aa(aj)}if(an&&ao>0&&ao<an.length&&/\w/.test(an.charAt(ao))&&/\w/.test(an.charAt(ao-1))){am=q.getBookmark();al.collapse(true);al=o(al,R(W));al=K.split(al);T(W,ad,al);q.moveToBookmark(am)}else{if(!aj||ap.nodeValue!==ai){aj=Y(true);ap=aj.firstChild;al.insertNode(aj);ao=1;T(W,ad,aj)}else{T(W,ad,aj)}q.setCursorLocation(ap,ao)}}function ah(){var aj=q.getRng(true),ak,am,ap,ao,al,at,ar=[],an,aq;ak=aj.startContainer;am=aj.startOffset;al=ak;if(ak.nodeType==3){if(am!=ak.nodeValue.length||ak.nodeValue===ai){ao=true}al=al.parentNode}while(al){if(x(al,W,ad)){at=al;break}if(al.nextSibling){ao=true}ar.push(al);al=al.parentNode}if(!at){return}if(ao){ap=q.getBookmark();aj.collapse(true);aj=o(aj,R(W),true);aj=K.split(aj);A(W,ad,aj);q.moveToBookmark(ap)}else{aq=Y();al=aq;for(an=ar.length-1;an>=0;an--){al.appendChild(ar[an].cloneNode(false));al=al.firstChild}al.appendChild(c.doc.createTextNode(ai));al=al.firstChild;c.insertAfter(aq,at);q.setCursorLocation(al,1)}}if(!self._hasCaretEvents){V.onBeforeGetContent.addToTop(function(){var aj=[],ak;if(ae(ab(q.getStart()),aj)){ak=aj.length;while(ak--){c.setAttrib(aj[ak],"data-mce-bogus","1")}}});a.each("onMouseUp onKeyUp".split(" "),function(aj){V[aj].addToTop(function(){Z()})});V.onKeyDown.addToTop(function(aj,al){var ak=al.keyCode;if(ak==8||ak==37||ak==39){Z(ab(q.getStart()))}});self._hasCaretEvents=true}if(af=="apply"){ac()}else{ah()}}function N(X){var W=X.startContainer,ac=X.startOffset,ab,aa,Y,Z;if(W.nodeType==3&&ac>=W.nodeValue.length-1){W=W.parentNode;ac=s(W)+1}if(W.nodeType==1){Y=W.childNodes;W=Y[Math.min(ac,Y.length-1)];ab=new t(W);if(ac>Y.length-1){ab.next()}for(aa=ab.current();aa;aa=ab.next()){if(aa.nodeType==3&&!f(aa)){Z=c.create("a",null,E);aa.parentNode.insertBefore(Z,aa);X.setStart(aa,0);q.setRng(X);c.remove(Z);return}}}}}})(tinymce);tinymce.onAddEditor.add(function(e,a){var d,h,g,c=a.settings;if(c.inline_styles){h=e.explode(c.font_size_legacy_values);function b(j,i){e.each(i,function(l,k){if(l){g.setStyle(j,k,l)}});g.rename(j,"span")}d={font:function(j,i){b(i,{backgroundColor:i.style.backgroundColor,color:i.color,fontFamily:i.face,fontSize:h[parseInt(i.size)-1]})},u:function(j,i){b(i,{textDecoration:"underline"})},strike:function(j,i){b(i,{textDecoration:"line-through"})}};function f(i,j){g=i.dom;if(c.convert_fonts_to_spans){e.each(g.select("font,u,strike",j.node),function(k){d[k.nodeName.toLowerCase()](a.dom,k)})}}a.onPreProcess.add(f);a.onSetContent.add(f);a.onInit.add(function(){a.selection.onSetContent.add(f)})}}); \ No newline at end of file +(function(e){var a=/^\s*|\s*$/g,b,d="B".replace(/A(.)|B/,"$1")==="$1";var c={majorVersion:"3",minorVersion:"5.8",releaseDate:"2012-11-20",_init:function(){var s=this,q=document,o=navigator,g=o.userAgent,m,f,l,k,j,r;s.isOpera=e.opera&&opera.buildNumber;s.isWebKit=/WebKit/.test(g);s.isIE=!s.isWebKit&&!s.isOpera&&(/MSIE/gi).test(g)&&(/Explorer/gi).test(o.appName);s.isIE6=s.isIE&&/MSIE [56]/.test(g);s.isIE7=s.isIE&&/MSIE [7]/.test(g);s.isIE8=s.isIE&&/MSIE [8]/.test(g);s.isIE9=s.isIE&&/MSIE [9]/.test(g);s.isGecko=!s.isWebKit&&/Gecko/.test(g);s.isMac=g.indexOf("Mac")!=-1;s.isAir=/adobeair/i.test(g);s.isIDevice=/(iPad|iPhone)/.test(g);s.isIOS5=s.isIDevice&&g.match(/AppleWebKit\/(\d*)/)[1]>=534;if(e.tinyMCEPreInit){s.suffix=tinyMCEPreInit.suffix;s.baseURL=tinyMCEPreInit.base;s.query=tinyMCEPreInit.query;return}s.suffix="";f=q.getElementsByTagName("base");for(m=0;m<f.length;m++){r=f[m].href;if(r){if(/^https?:\/\/[^\/]+$/.test(r)){r+="/"}k=r?r.match(/.*\//)[0]:""}}function h(i){if(i.src&&/tiny_mce(|_gzip|_jquery|_prototype|_full)(_dev|_src)?.js/.test(i.src)){if(/_(src|dev)\.js/g.test(i.src)){s.suffix="_src"}if((j=i.src.indexOf("?"))!=-1){s.query=i.src.substring(j+1)}s.baseURL=i.src.substring(0,i.src.lastIndexOf("/"));if(k&&s.baseURL.indexOf("://")==-1&&s.baseURL.indexOf("/")!==0){s.baseURL=k+s.baseURL}return s.baseURL}return null}f=q.getElementsByTagName("script");for(m=0;m<f.length;m++){if(h(f[m])){return}}l=q.getElementsByTagName("head")[0];if(l){f=l.getElementsByTagName("script");for(m=0;m<f.length;m++){if(h(f[m])){return}}}return},is:function(g,f){if(!f){return g!==b}if(f=="array"&&c.isArray(g)){return true}return typeof(g)==f},isArray:Array.isArray||function(f){return Object.prototype.toString.call(f)==="[object Array]"},makeMap:function(f,j,h){var g;f=f||[];j=j||",";if(typeof(f)=="string"){f=f.split(j)}h=h||{};g=f.length;while(g--){h[f[g]]={}}return h},each:function(i,f,h){var j,g;if(!i){return 0}h=h||i;if(i.length!==b){for(j=0,g=i.length;j<g;j++){if(f.call(h,i[j],j,i)===false){return 0}}}else{for(j in i){if(i.hasOwnProperty(j)){if(f.call(h,i[j],j,i)===false){return 0}}}}return 1},trim:function(f){return(f?""+f:"").replace(a,"")},create:function(o,f,j){var n=this,g,i,k,l,h,m=0;o=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(o);k=o[3].match(/(^|\.)(\w+)$/i)[2];i=n.createNS(o[3].replace(/\.\w+$/,""),j);if(i[k]){return}if(o[2]=="static"){i[k]=f;if(this.onCreate){this.onCreate(o[2],o[3],i[k])}return}if(!f[k]){f[k]=function(){};m=1}i[k]=f[k];n.extend(i[k].prototype,f);if(o[5]){g=n.resolve(o[5]).prototype;l=o[5].match(/\.(\w+)$/i)[1];h=i[k];if(m){i[k]=function(){return g[l].apply(this,arguments)}}else{i[k]=function(){this.parent=g[l];return h.apply(this,arguments)}}i[k].prototype[k]=i[k];n.each(g,function(p,q){i[k].prototype[q]=g[q]});n.each(f,function(p,q){if(g[q]){i[k].prototype[q]=function(){this.parent=g[q];return p.apply(this,arguments)}}else{if(q!=k){i[k].prototype[q]=p}}})}n.each(f["static"],function(p,q){i[k][q]=p});if(this.onCreate){this.onCreate(o[2],o[3],i[k].prototype)}},walk:function(i,h,j,g){g=g||this;if(i){if(j){i=i[j]}c.each(i,function(k,f){if(h.call(g,k,f,j)===false){return false}c.walk(k,h,j,g)})}},createNS:function(j,h){var g,f;h=h||e;j=j.split(".");for(g=0;g<j.length;g++){f=j[g];if(!h[f]){h[f]={}}h=h[f]}return h},resolve:function(j,h){var g,f;h=h||e;j=j.split(".");for(g=0,f=j.length;g<f;g++){h=h[j[g]];if(!h){break}}return h},addUnload:function(j,i){var h=this,g;g=function(){var f=h.unloads,l,m;if(f){for(m in f){l=f[m];if(l&&l.func){l.func.call(l.scope,1)}}if(e.detachEvent){e.detachEvent("onbeforeunload",k);e.detachEvent("onunload",g)}else{if(e.removeEventListener){e.removeEventListener("unload",g,false)}}h.unloads=l=f=w=g=0;if(e.CollectGarbage){CollectGarbage()}}};function k(){var l=document;function f(){l.detachEvent("onstop",f);if(g){g()}l=0}if(l.readyState=="interactive"){if(l){l.attachEvent("onstop",f)}e.setTimeout(function(){if(l){l.detachEvent("onstop",f)}},0)}}j={func:j,scope:i||this};if(!h.unloads){if(e.attachEvent){e.attachEvent("onunload",g);e.attachEvent("onbeforeunload",k)}else{if(e.addEventListener){e.addEventListener("unload",g,false)}}h.unloads=[j]}else{h.unloads.push(j)}return j},removeUnload:function(i){var g=this.unloads,h=null;c.each(g,function(j,f){if(j&&j.func==i){g.splice(f,1);h=i;return false}});return h},explode:function(f,g){if(!f||c.is(f,"array")){return f}return c.map(f.split(g||","),c.trim)},_addVer:function(g){var f;if(!this.query){return g}f=(g.indexOf("?")==-1?"?":"&")+this.query;if(g.indexOf("#")==-1){return g+f}return g.replace("#",f+"#")},_replace:function(h,f,g){if(d){return g.replace(h,function(){var l=f,j=arguments,k;for(k=0;k<j.length-2;k++){if(j[k]===b){l=l.replace(new RegExp("\\$"+k,"g"),"")}else{l=l.replace(new RegExp("\\$"+k,"g"),j[k])}}return l})}return g.replace(h,f)}};c._init();e.tinymce=e.tinyMCE=c})(window);(function(f,e){var d=e.is,b=/^(href|src|style)$/i,c;if(!f&&window.console){return console.log("Load jQuery first!")}e.$=f;e.adapter={patchEditor:function(j){var i=f.fn;function h(m,n){var l=this;if(n){l.removeAttr("data-mce-style")}return i.css.apply(l,arguments)}function g(m,n){var l=this;if(b.test(m)){if(n!==c){l.each(function(o,p){j.dom.setAttrib(p,m,n)});return l}else{return l.attr("data-mce-"+m)}}return i.attr.apply(l,arguments)}function k(l){if(l.css!==h){l.css=h;l.attr=g;l.tinymce=j;l.pushStack=function(){return k(i.pushStack.apply(this,arguments))}}return l}j.$=function(l,m){var n=j.getDoc();return k(f(l||n,n||m))}}};e.extend=f.extend;e.extend(e,{map:f.map,grep:function(g,h){return f.grep(g,h||function(){return 1})},inArray:function(g,h){return f.inArray(h,g||[])}});var a={"tinymce.dom.DOMUtils":{select:function(i,h){var g=this;return f.find(i,g.get(h)||g.get(g.settings.root_element)||g.doc,[])},is:function(h,g){return f(this.get(h)).is(g)}}};e.onCreate=function(g,i,h){e.extend(h,a[i])}})(window.jQuery,tinymce);tinymce.create("tinymce.util.Dispatcher",{scope:null,listeners:null,inDispatch:false,Dispatcher:function(a){this.scope=a||this;this.listeners=[]},add:function(b,a){this.listeners.push({cb:b,scope:a||this.scope});return b},addToTop:function(d,b){var a=this,c={cb:d,scope:b||a.scope};if(a.inDispatch){a.listeners=[c].concat(a.listeners)}else{a.listeners.unshift(c)}return d},remove:function(c){var b=this.listeners,a=null;tinymce.each(b,function(e,d){if(c==e.cb){a=e;b.splice(d,1);return false}});return a},dispatch:function(){var a=this,e,b=arguments,c,d=a.listeners,f;a.inDispatch=true;for(c=0;c<d.length;c++){f=d[c];e=f.cb.apply(f.scope,b.length>0?b:[f.scope]);if(e===false){break}}a.inDispatch=false;return e}});(function(){var a=tinymce.each;tinymce.create("tinymce.util.URI",{URI:function(e,g){var f=this,i,d,c,h;e=tinymce.trim(e);g=f.settings=g||{};if(/^([\w\-]+):([^\/]{2})/i.test(e)||/^\s*#/.test(e)){f.source=e;return}if(e.indexOf("/")===0&&e.indexOf("//")!==0){e=(g.base_uri?g.base_uri.protocol||"http":"http")+"://mce_host"+e}if(!/^[\w\-]*:?\/\//.test(e)){h=g.base_uri?g.base_uri.path:new tinymce.util.URI(location.href).directory;e=((g.base_uri&&g.base_uri.protocol)||"http")+"://mce_host"+f.toAbsPath(h,e)}e=e.replace(/@@/g,"(mce_at)");e=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@\/]*):?([^:@\/]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(e);a(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(b,j){var k=e[j];if(k){k=k.replace(/\(mce_at\)/g,"@@")}f[b]=k});c=g.base_uri;if(c){if(!f.protocol){f.protocol=c.protocol}if(!f.userInfo){f.userInfo=c.userInfo}if(!f.port&&f.host==="mce_host"){f.port=c.port}if(!f.host||f.host==="mce_host"){f.host=c.host}f.source=""}},setPath:function(c){var b=this;c=/^(.*?)\/?(\w+)?$/.exec(c);b.path=c[0];b.directory=c[1];b.file=c[2];b.source="";b.getURI()},toRelative:function(b){var d=this,f;if(b==="./"){return b}b=new tinymce.util.URI(b,{base_uri:d});if((b.host!="mce_host"&&d.host!=b.host&&b.host)||d.port!=b.port||d.protocol!=b.protocol){return b.getURI()}var c=d.getURI(),e=b.getURI();if(c==e||(c.charAt(c.length-1)=="/"&&c.substr(0,c.length-1)==e)){return c}f=d.toRelPath(d.path,b.path);if(b.query){f+="?"+b.query}if(b.anchor){f+="#"+b.anchor}return f},toAbsolute:function(b,c){b=new tinymce.util.URI(b,{base_uri:this});return b.getURI(this.host==b.host&&this.protocol==b.protocol?c:0)},toRelPath:function(g,h){var c,f=0,d="",e,b;g=g.substring(0,g.lastIndexOf("/"));g=g.split("/");c=h.split("/");if(g.length>=c.length){for(e=0,b=g.length;e<b;e++){if(e>=c.length||g[e]!=c[e]){f=e+1;break}}}if(g.length<c.length){for(e=0,b=c.length;e<b;e++){if(e>=g.length||g[e]!=c[e]){f=e+1;break}}}if(f===1){return h}for(e=0,b=g.length-(f-1);e<b;e++){d+="../"}for(e=f-1,b=c.length;e<b;e++){if(e!=f-1){d+="/"+c[e]}else{d+=c[e]}}return d},toAbsPath:function(e,f){var c,b=0,h=[],d,g;d=/\/$/.test(f)?"/":"";e=e.split("/");f=f.split("/");a(e,function(i){if(i){h.push(i)}});e=h;for(c=f.length-1,h=[];c>=0;c--){if(f[c].length===0||f[c]==="."){continue}if(f[c]===".."){b++;continue}if(b>0){b--;continue}h.push(f[c])}c=e.length-b;if(c<=0){g=h.reverse().join("/")}else{g=e.slice(0,c).join("/")+"/"+h.reverse().join("/")}if(g.indexOf("/")!==0){g="/"+g}if(d&&g.lastIndexOf("/")!==g.length-1){g+=d}return g},getURI:function(d){var c,b=this;if(!b.source||d){c="";if(!d){if(b.protocol){c+=b.protocol+"://"}if(b.userInfo){c+=b.userInfo+"@"}if(b.host){c+=b.host}if(b.port){c+=":"+b.port}}if(b.path){c+=b.path}if(b.query){c+="?"+b.query}if(b.anchor){c+="#"+b.anchor}b.source=c}return b.source}})})();(function(){var a=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(d){var b=this.get(d),c;if(b){a(b.split("&"),function(e){e=e.split("=");c=c||{};c[unescape(e[0])]=unescape(e[1])})}return c},setHash:function(j,b,g,f,i,c){var h="";a(b,function(e,d){h+=(!h?"":"&")+escape(d)+"="+escape(e)});this.set(j,h,g,f,i,c)},get:function(i){var h=document.cookie,g,f=i+"=",d;if(!h){return}d=h.indexOf("; "+f);if(d==-1){d=h.indexOf(f);if(d!==0){return null}}else{d+=2}g=h.indexOf(";",d);if(g==-1){g=h.length}return unescape(h.substring(d+f.length,g))},set:function(i,b,g,f,h,c){document.cookie=i+"="+escape(b)+((g)?"; expires="+g.toGMTString():"")+((f)?"; path="+escape(f):"")+((h)?"; domain="+h:"")+((c)?"; secure":"")},remove:function(c,e,d){var b=new Date();b.setTime(b.getTime()-1000);this.set(c,"",b,e,d)}})})();(function(){function serialize(o,quote){var i,v,t,name;quote=quote||'"';if(o==null){return"null"}t=typeof o;if(t=="string"){v="\bb\tt\nn\ff\rr\"\"''\\\\";return quote+o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(a,b){if(quote==='"'&&a==="'"){return a}i=v.indexOf(b);if(i+1){return"\\"+v.charAt(i+1)}a=b.charCodeAt().toString(16);return"\\u"+"0000".substring(a.length)+a})+quote}if(t=="object"){if(o.hasOwnProperty&&Object.prototype.toString.call(o)==="[object Array]"){for(i=0,v="[";i<o.length;i++){v+=(i>0?",":"")+serialize(o[i],quote)}return v+"]"}v="{";for(name in o){if(o.hasOwnProperty(name)){v+=typeof o[name]!="function"?(v.length>1?","+quote:quote)+name+quote+":"+serialize(o[name],quote):""}}return v+"}"}return""+o}tinymce.util.JSON={serialize:serialize,parse:function(s){try{return eval("("+s+")")}catch(ex){}}}})();tinymce.create("static tinymce.util.XHR",{send:function(g){var a,e,b=window,h=0;function f(){if(!g.async||a.readyState==4||h++>10000){if(g.success&&h<10000&&a.status==200){g.success.call(g.success_scope,""+a.responseText,a,g)}else{if(g.error){g.error.call(g.error_scope,h>10000?"TIMED_OUT":"GENERAL",a,g)}}a=null}else{b.setTimeout(f,10)}}g.scope=g.scope||this;g.success_scope=g.success_scope||g.scope;g.error_scope=g.error_scope||g.scope;g.async=g.async===false?false:true;g.data=g.data||"";function d(i){a=0;try{a=new ActiveXObject(i)}catch(c){}return a}a=b.XMLHttpRequest?new XMLHttpRequest():d("Microsoft.XMLHTTP")||d("Msxml2.XMLHTTP");if(a){if(a.overrideMimeType){a.overrideMimeType(g.content_type)}a.open(g.type||(g.data?"POST":"GET"),g.url,g.async);if(g.content_type){a.setRequestHeader("Content-Type",g.content_type)}a.setRequestHeader("X-Requested-With","XMLHttpRequest");a.send(g.data);if(!g.async){return f()}e=b.setTimeout(f,10)}}});(function(){var c=tinymce.extend,b=tinymce.util.JSON,a=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(d){this.settings=c({},d);this.count=0},send:function(f){var e=f.error,d=f.success;f=c(this.settings,f);f.success=function(h,g){h=b.parse(h);if(typeof(h)=="undefined"){h={error:"JSON Parse error."}}if(h.error){e.call(f.error_scope||f.scope,h.error,g)}else{d.call(f.success_scope||f.scope,h.result)}};f.error=function(h,g){if(e){e.call(f.error_scope||f.scope,h,g)}};f.data=b.serialize({id:f.id||"c"+(this.count++),method:f.method,params:f.params});f.content_type="application/json";a.send(f)},"static":{sendRPC:function(d){return new tinymce.util.JSONRequest().send(d)}}})}());(function(a){a.VK={BACKSPACE:8,DELETE:46,DOWN:40,ENTER:13,LEFT:37,RIGHT:39,SPACEBAR:32,TAB:9,UP:38,modifierPressed:function(b){return b.shiftKey||b.ctrlKey||b.altKey},metaKeyPressed:function(b){return a.isMac?b.metaKey:b.ctrlKey&&!b.altKey}}})(tinymce);tinymce.util.Quirks=function(a){var j=tinymce.VK,f=j.BACKSPACE,k=j.DELETE,e=a.dom,l=a.selection,H=a.settings,v=a.parser,o=a.serializer,E=tinymce.each;function A(N,M){try{a.getDoc().execCommand(N,false,M)}catch(L){}}function n(){var L=a.getDoc().documentMode;return L?L:6}function z(L){return L.isDefaultPrevented()}function J(){function L(O){var M,Q,N,P;M=l.getRng();Q=e.getParent(M.startContainer,e.isBlock);if(O){Q=e.getNext(Q,e.isBlock)}if(Q){N=Q.firstChild;while(N&&N.nodeType==3&&N.nodeValue.length===0){N=N.nextSibling}if(N&&N.nodeName==="SPAN"){P=N.cloneNode(false)}}E(e.select("span",Q),function(R){R.setAttribute("data-mce-mark","1")});a.getDoc().execCommand(O?"ForwardDelete":"Delete",false,null);Q=e.getParent(M.startContainer,e.isBlock);E(e.select("span",Q),function(R){var S=l.getBookmark();if(P){e.replace(P.cloneNode(false),R,true)}else{if(!R.getAttribute("data-mce-mark")){e.remove(R,true)}else{R.removeAttribute("data-mce-mark")}}l.moveToBookmark(S)})}a.onKeyDown.add(function(M,O){var N;N=O.keyCode==k;if(!z(O)&&(N||O.keyCode==f)&&!j.modifierPressed(O)){O.preventDefault();L(N)}});a.addCommand("Delete",function(){L()})}function q(){function L(O){var N=e.create("body");var P=O.cloneContents();N.appendChild(P);return l.serializer.serialize(N,{format:"html"})}function M(N){var P=L(N);var Q=e.createRng();Q.selectNode(a.getBody());var O=L(Q);return P===O}a.onKeyDown.add(function(O,Q){var P=Q.keyCode,N;if(!z(Q)&&(P==k||P==f)){N=O.selection.isCollapsed();if(N&&!e.isEmpty(O.getBody())){return}if(tinymce.isIE&&!N){return}if(!N&&!M(O.selection.getRng())){return}O.setContent("");O.selection.setCursorLocation(O.getBody(),0);O.nodeChanged()}})}function I(){a.onKeyDown.add(function(L,M){if(!z(M)&&M.keyCode==65&&j.metaKeyPressed(M)){M.preventDefault();L.execCommand("SelectAll")}})}function K(){if(!a.settings.content_editable){e.bind(a.getDoc(),"focusin",function(L){l.setRng(l.getRng())});e.bind(a.getDoc(),"mousedown",function(L){if(L.target==a.getDoc().documentElement){a.getWin().focus();l.setRng(l.getRng())}})}}function B(){a.onKeyDown.add(function(L,O){if(!z(O)&&O.keyCode===f){if(l.isCollapsed()&&l.getRng(true).startOffset===0){var N=l.getNode();var M=N.previousSibling;if(M&&M.nodeName&&M.nodeName.toLowerCase()==="hr"){e.remove(M);tinymce.dom.Event.cancel(O)}}}})}function y(){if(!Range.prototype.getClientRects){a.onMouseDown.add(function(M,N){if(!z(N)&&N.target.nodeName==="HTML"){var L=M.getBody();L.blur();setTimeout(function(){L.focus()},0)}})}}function h(){a.onClick.add(function(L,M){M=M.target;if(/^(IMG|HR)$/.test(M.nodeName)){l.getSel().setBaseAndExtent(M,0,M,1)}if(M.nodeName=="A"&&e.hasClass(M,"mceItemAnchor")){l.select(M)}L.nodeChanged()})}function c(){function M(){var O=e.getAttribs(l.getStart().cloneNode(false));return function(){var P=l.getStart();if(P!==a.getBody()){e.setAttrib(P,"style",null);E(O,function(Q){P.setAttributeNode(Q.cloneNode(true))})}}}function L(){return !l.isCollapsed()&&e.getParent(l.getStart(),e.isBlock)!=e.getParent(l.getEnd(),e.isBlock)}function N(O,P){P.preventDefault();return false}a.onKeyPress.add(function(O,Q){var P;if(!z(Q)&&(Q.keyCode==8||Q.keyCode==46)&&L()){P=M();O.getDoc().execCommand("delete",false,null);P();Q.preventDefault();return false}});e.bind(a.getDoc(),"cut",function(P){var O;if(!z(P)&&L()){O=M();a.onKeyUp.addToTop(N);setTimeout(function(){O();a.onKeyUp.remove(N)},0)}})}function b(){var M,L;e.bind(a.getDoc(),"selectionchange",function(){if(L){clearTimeout(L);L=0}L=window.setTimeout(function(){var N=l.getRng();if(!M||!tinymce.dom.RangeUtils.compareRanges(N,M)){a.nodeChanged();M=N}},50)})}function x(){document.body.setAttribute("role","application")}function t(){a.onKeyDown.add(function(L,N){if(!z(N)&&N.keyCode===f){if(l.isCollapsed()&&l.getRng(true).startOffset===0){var M=l.getNode().previousSibling;if(M&&M.nodeName&&M.nodeName.toLowerCase()==="table"){return tinymce.dom.Event.cancel(N)}}}})}function C(){if(n()>7){return}A("RespectVisibilityInDesign",true);a.contentStyles.push(".mceHideBrInPre pre br {display: none}");e.addClass(a.getBody(),"mceHideBrInPre");v.addNodeFilter("pre",function(L,N){var O=L.length,Q,M,R,P;while(O--){Q=L[O].getAll("br");M=Q.length;while(M--){R=Q[M];P=R.prev;if(P&&P.type===3&&P.value.charAt(P.value-1)!="\n"){P.value+="\n"}else{R.parent.insert(new tinymce.html.Node("#text",3),R,true).value="\n"}}}});o.addNodeFilter("pre",function(L,N){var O=L.length,Q,M,R,P;while(O--){Q=L[O].getAll("br");M=Q.length;while(M--){R=Q[M];P=R.prev;if(P&&P.type==3){P.value=P.value.replace(/\r?\n$/,"")}}}})}function g(){e.bind(a.getBody(),"mouseup",function(N){var M,L=l.getNode();if(L.nodeName=="IMG"){if(M=e.getStyle(L,"width")){e.setAttrib(L,"width",M.replace(/[^0-9%]+/g,""));e.setStyle(L,"width","")}if(M=e.getStyle(L,"height")){e.setAttrib(L,"height",M.replace(/[^0-9%]+/g,""));e.setStyle(L,"height","")}}})}function d(){a.onKeyDown.add(function(R,S){var Q,L,M,O,P,T,N;Q=S.keyCode==k;if(!z(S)&&(Q||S.keyCode==f)&&!j.modifierPressed(S)){L=l.getRng();M=L.startContainer;O=L.startOffset;N=L.collapsed;if(M.nodeType==3&&M.nodeValue.length>0&&((O===0&&!N)||(N&&O===(Q?0:1)))){nonEmptyElements=R.schema.getNonEmptyElements();S.preventDefault();P=e.create("br",{id:"__tmp"});M.parentNode.insertBefore(P,M);R.getDoc().execCommand(Q?"ForwardDelete":"Delete",false,null);M=l.getRng().startContainer;T=M.previousSibling;if(T&&T.nodeType==1&&!e.isBlock(T)&&e.isEmpty(T)&&!nonEmptyElements[T.nodeName.toLowerCase()]){e.remove(T)}e.remove("__tmp")}}})}function G(){a.onKeyDown.add(function(P,Q){var N,M,R,L,O;if(z(Q)||Q.keyCode!=j.BACKSPACE){return}N=l.getRng();M=N.startContainer;R=N.startOffset;L=e.getRoot();O=M;if(!N.collapsed||R!==0){return}while(O&&O.parentNode&&O.parentNode.firstChild==O&&O.parentNode!=L){O=O.parentNode}if(O.tagName==="BLOCKQUOTE"){P.formatter.toggle("blockquote",null,O);N=e.createRng();N.setStart(M,0);N.setEnd(M,0);l.setRng(N)}})}function F(){function L(){a._refreshContentEditable();A("StyleWithCSS",false);A("enableInlineTableEditing",false);if(!H.object_resizing){A("enableObjectResizing",false)}}if(!H.readonly){a.onBeforeExecCommand.add(L);a.onMouseDown.add(L)}}function s(){function L(M,N){E(e.select("a"),function(Q){var O=Q.parentNode,P=e.getRoot();if(O.lastChild===Q){while(O&&!e.isBlock(O)){if(O.parentNode.lastChild!==O||O===P){return}O=O.parentNode}e.add(O,"br",{"data-mce-bogus":1})}})}a.onExecCommand.add(function(M,N){if(N==="CreateLink"){L(M)}});a.onSetContent.add(l.onSetContent.add(L))}function m(){if(H.forced_root_block){a.onInit.add(function(){A("DefaultParagraphSeparator",H.forced_root_block)})}}function p(){function L(N,M){if(!N||!M.initial){a.execCommand("mceRepaint")}}a.onUndo.add(L);a.onRedo.add(L);a.onSetContent.add(L)}function i(){a.onKeyDown.add(function(M,N){var L;if(!z(N)&&N.keyCode==f){L=M.getDoc().selection.createRange();if(L&&L.item){N.preventDefault();M.undoManager.beforeChange();e.remove(L.item(0));M.undoManager.add()}}})}function r(){var L;if(n()>=10){L="";E("p div h1 h2 h3 h4 h5 h6".split(" "),function(M,N){L+=(N>0?",":"")+M+":empty"});a.contentStyles.push(L+"{padding-right: 1px !important}")}}function u(){var N,M,ad,L,Y,ab,Z,ac,O,P,aa,W,V,X=document,T=a.getDoc();if(!H.object_resizing||H.webkit_fake_resize===false){return}A("enableObjectResizing",false);aa={n:[0.5,0,0,-1],e:[1,0.5,1,0],s:[0.5,1,0,1],w:[0,0.5,-1,0],nw:[0,0,-1,-1],ne:[1,0,1,-1],se:[1,1,1,1],sw:[0,1,-1,1]};function R(ah){var ag,af;ag=ah.screenX-ab;af=ah.screenY-Z;W=ag*Y[2]+ac;V=af*Y[3]+O;W=W<5?5:W;V=V<5?5:V;if(j.modifierPressed(ah)||(ad.nodeName=="IMG"&&Y[2]*Y[3]!==0)){W=Math.round(V/P);V=Math.round(W*P)}e.setStyles(L,{width:W,height:V});if(Y[2]<0&&L.clientWidth<=W){e.setStyle(L,"left",N+(ac-W))}if(Y[3]<0&&L.clientHeight<=V){e.setStyle(L,"top",M+(O-V))}}function ae(){function af(ag,ah){if(ah){if(ad.style[ag]||!a.schema.isValid(ad.nodeName.toLowerCase(),ag)){e.setStyle(ad,ag,ah)}else{e.setAttrib(ad,ag,ah)}}}af("width",W);af("height",V);e.unbind(T,"mousemove",R);e.unbind(T,"mouseup",ae);if(X!=T){e.unbind(X,"mousemove",R);e.unbind(X,"mouseup",ae)}e.remove(L);Q(ad)}function Q(ai){var ag,ah,af;S();ag=e.getPos(ai);N=ag.x;M=ag.y;ah=ai.offsetWidth;af=ai.offsetHeight;if(ad!=ai){ad=ai;W=V=0}E(aa,function(al,aj){var ak;ak=e.get("mceResizeHandle"+aj);if(!ak){ak=e.add(T.documentElement,"div",{id:"mceResizeHandle"+aj,"class":"mceResizeHandle",style:"cursor:"+aj+"-resize; margin:0; padding:0"});e.bind(ak,"mousedown",function(am){am.preventDefault();ae();ab=am.screenX;Z=am.screenY;ac=ad.clientWidth;O=ad.clientHeight;P=O/ac;Y=al;L=ad.cloneNode(true);e.addClass(L,"mceClonedResizable");e.setStyles(L,{left:N,top:M,margin:0});T.documentElement.appendChild(L);e.bind(T,"mousemove",R);e.bind(T,"mouseup",ae);if(X!=T){e.bind(X,"mousemove",R);e.bind(X,"mouseup",ae)}})}else{e.show(ak)}e.setStyles(ak,{left:(ah*al[0]+N)-(ak.offsetWidth/2),top:(af*al[1]+M)-(ak.offsetHeight/2)})});if(!tinymce.isOpera&&ad.nodeName=="IMG"){ad.setAttribute("data-mce-selected","1")}}function S(){if(ad){ad.removeAttribute("data-mce-selected")}for(var af in aa){e.hide("mceResizeHandle"+af)}}a.contentStyles.push(".mceResizeHandle {position: absolute;border: 1px solid black;background: #FFF;width: 5px;height: 5px;z-index: 10000}.mceResizeHandle:hover {background: #000}img[data-mce-selected] {outline: 1px solid black}img.mceClonedResizable, table.mceClonedResizable {position: absolute;outline: 1px dashed black;opacity: .5;z-index: 10000}");function U(){var af=e.getParent(l.getNode(),"table,img");E(e.select("img[data-mce-selected]"),function(ag){ag.removeAttribute("data-mce-selected")});if(af){Q(af)}else{S()}}a.onNodeChange.add(U);e.bind(T,"selectionchange",U);a.serializer.addAttributeFilter("data-mce-selected",function(af,ag){var ah=af.length;while(ah--){af[ah].attr(ag,null)}})}function D(){if(n()<9){v.addNodeFilter("noscript",function(L){var M=L.length,N,O;while(M--){N=L[M];O=N.firstChild;if(O){N.attr("data-mce-innertext",O.value)}}});o.addNodeFilter("noscript",function(L){var M=L.length,N,P,O;while(M--){N=L[M];P=L[M].firstChild;if(P){P.value=tinymce.html.Entities.decode(P.value)}else{O=N.attributes.map["data-mce-innertext"];if(O){N.attr("data-mce-innertext",null);P=new tinymce.html.Node("#text",3);P.value=O;P.raw=true;N.append(P)}}}})}}t();G();q();if(tinymce.isWebKit){d();J();K();h();m();if(tinymce.isIDevice){b()}else{u();I()}}if(tinymce.isIE){B();x();C();g();i();r();D()}if(tinymce.isGecko){B();y();c();F();s();p()}if(tinymce.isOpera){u()}};(function(j){var a,g,d,k=/[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,b=/[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,f=/[<>&\"\']/g,c=/&(#x|#)?([\w]+);/g,i={128:"\u20AC",130:"\u201A",131:"\u0192",132:"\u201E",133:"\u2026",134:"\u2020",135:"\u2021",136:"\u02C6",137:"\u2030",138:"\u0160",139:"\u2039",140:"\u0152",142:"\u017D",145:"\u2018",146:"\u2019",147:"\u201C",148:"\u201D",149:"\u2022",150:"\u2013",151:"\u2014",152:"\u02DC",153:"\u2122",154:"\u0161",155:"\u203A",156:"\u0153",158:"\u017E",159:"\u0178"};g={'"':""","'":"'","<":"<",">":">","&":"&"};d={"<":"<",">":">","&":"&",""":'"',"'":"'"};function h(l){var m;m=document.createElement("div");m.innerHTML=l;return m.textContent||m.innerText||l}function e(m,p){var n,o,l,q={};if(m){m=m.split(",");p=p||10;for(n=0;n<m.length;n+=2){o=String.fromCharCode(parseInt(m[n],p));if(!g[o]){l="&"+m[n+1]+";";q[o]=l;q[l]=o}}return q}}a=e("50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,t9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,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);j.html=j.html||{};j.html.Entities={encodeRaw:function(m,l){return m.replace(l?k:b,function(n){return g[n]||n})},encodeAllRaw:function(l){return(""+l).replace(f,function(m){return g[m]||m})},encodeNumeric:function(m,l){return m.replace(l?k:b,function(n){if(n.length>1){return"&#"+(((n.charCodeAt(0)-55296)*1024)+(n.charCodeAt(1)-56320)+65536)+";"}return g[n]||"&#"+n.charCodeAt(0)+";"})},encodeNamed:function(n,l,m){m=m||a;return n.replace(l?k:b,function(o){return g[o]||m[o]||o})},getEncodeFunc:function(l,o){var p=j.html.Entities;o=e(o)||a;function m(r,q){return r.replace(q?k:b,function(s){return g[s]||o[s]||"&#"+s.charCodeAt(0)+";"||s})}function n(r,q){return p.encodeNamed(r,q,o)}l=j.makeMap(l.replace(/\+/g,","));if(l.named&&l.numeric){return m}if(l.named){if(o){return n}return p.encodeNamed}if(l.numeric){return p.encodeNumeric}return p.encodeRaw},decode:function(l){return l.replace(c,function(n,m,o){if(m){o=parseInt(o,m.length===2?16:10);if(o>65535){o-=65536;return String.fromCharCode(55296+(o>>10),56320+(o&1023))}else{return i[o]||String.fromCharCode(o)}}return d[n]||a[n]||h(n)})}}})(tinymce);tinymce.html.Styles=function(d,f){var k=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,h=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,b=/\s*([^:]+):\s*([^;]+);?/g,l=/\s+$/,m=/rgb/,e,g,a={},j;d=d||{};j="\\\" \\' \\; \\: ; : \uFEFF".split(" ");for(g=0;g<j.length;g++){a[j[g]]="\uFEFF"+g;a["\uFEFF"+g]=j[g]}function c(n,q,p,i){function o(r){r=parseInt(r).toString(16);return r.length>1?r:"0"+r}return"#"+o(q)+o(p)+o(i)}return{toHex:function(i){return i.replace(k,c)},parse:function(s){var z={},q,n,x,r,v=d.url_converter,y=d.url_converter_scope||this;function p(D,G){var F,C,B,E;F=z[D+"-top"+G];if(!F){return}C=z[D+"-right"+G];if(F!=C){return}B=z[D+"-bottom"+G];if(C!=B){return}E=z[D+"-left"+G];if(B!=E){return}z[D+G]=E;delete z[D+"-top"+G];delete z[D+"-right"+G];delete z[D+"-bottom"+G];delete z[D+"-left"+G]}function u(C){var D=z[C],B;if(!D||D.indexOf(" ")<0){return}D=D.split(" ");B=D.length;while(B--){if(D[B]!==D[0]){return false}}z[C]=D[0];return true}function A(D,C,B,E){if(!u(C)){return}if(!u(B)){return}if(!u(E)){return}z[D]=z[C]+" "+z[B]+" "+z[E];delete z[C];delete z[B];delete z[E]}function t(B){r=true;return a[B]}function i(C,B){if(r){C=C.replace(/\uFEFF[0-9]/g,function(D){return a[D]})}if(!B){C=C.replace(/\\([\'\";:])/g,"$1")}return C}function o(C,B,F,E,G,D){G=G||D;if(G){G=i(G);return"'"+G.replace(/\'/g,"\\'")+"'"}B=i(B||F||E);if(v){B=v.call(y,B,"style")}return"url('"+B.replace(/\'/g,"\\'")+"')"}if(s){s=s.replace(/\\[\"\';:\uFEFF]/g,t).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(B){return B.replace(/[;:]/g,t)});while(q=b.exec(s)){n=q[1].replace(l,"").toLowerCase();x=q[2].replace(l,"");if(n&&x.length>0){if(n==="font-weight"&&x==="700"){x="bold"}else{if(n==="color"||n==="background-color"){x=x.toLowerCase()}}x=x.replace(k,c);x=x.replace(h,o);z[n]=r?i(x,true):x}b.lastIndex=q.index+q[0].length}p("border","");p("border","-width");p("border","-color");p("border","-style");p("padding","");p("margin","");A("border","border-width","border-style","border-color");if(z.border==="medium none"){delete z.border}}return z},serialize:function(p,r){var o="",n,q;function i(t){var x,u,s,v;x=f.styles[t];if(x){for(u=0,s=x.length;u<s;u++){t=x[u];v=p[t];if(v!==e&&v.length>0){o+=(o.length>0?" ":"")+t+": "+v+";"}}}}if(r&&f&&f.styles){i("*");i(r)}else{for(n in p){q=p[n];if(q!==e&&q.length>0){o+=(o.length>0?" ":"")+n+": "+q+";"}}}return o}}};(function(f){var a={},e=f.makeMap,g=f.each;function d(j,i){return j.split(i||",")}function h(m,l){var j,k={};function i(n){return n.replace(/[A-Z]+/g,function(o){return i(m[o])})}for(j in m){if(m.hasOwnProperty(j)){m[j]=i(m[j])}}i(l).replace(/#/g,"#text").replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g,function(q,o,n,p){n=d(n,"|");k[o]={attributes:e(n),attributesOrder:n,children:e(p,"|",{"#comment":{}})}});return k}function b(){var i=a.html5;if(!i){i=a.html5=h({A:"id|accesskey|class|dir|draggable|item|hidden|itemprop|role|spellcheck|style|subject|title|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup",B:"#|a|abbr|area|audio|b|bdo|br|button|canvas|cite|code|command|datalist|del|dfn|em|embed|i|iframe|img|input|ins|kbd|keygen|label|link|map|mark|meta|meter|noscript|object|output|progress|q|ruby|samp|script|select|small|span|strong|sub|sup|svg|textarea|time|var|video|wbr",C:"#|a|abbr|area|address|article|aside|audio|b|bdo|blockquote|br|button|canvas|cite|code|command|datalist|del|details|dfn|dialog|div|dl|em|embed|fieldset|figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|i|iframe|img|input|ins|kbd|keygen|label|link|map|mark|menu|meta|meter|nav|noscript|ol|object|output|p|pre|progress|q|ruby|samp|script|section|select|small|span|strong|style|sub|sup|svg|table|textarea|time|ul|var|video"},"html[A|manifest][body|head]head[A][base|command|link|meta|noscript|script|style|title]title[A][#]base[A|href|target][]link[A|href|rel|media|type|sizes][]meta[A|http-equiv|name|content|charset][]style[A|type|media|scoped][#]script[A|charset|type|src|defer|async][#]noscript[A][C]body[A][C]section[A][C]nav[A][C]article[A][C]aside[A][C]h1[A][B]h2[A][B]h3[A][B]h4[A][B]h5[A][B]h6[A][B]hgroup[A][h1|h2|h3|h4|h5|h6]header[A][C]footer[A][C]address[A][C]p[A][B]br[A][]pre[A][B]dialog[A][dd|dt]blockquote[A|cite][C]ol[A|start|reversed][li]ul[A][li]li[A|value][C]dl[A][dd|dt]dt[A][B]dd[A][C]a[A|href|target|ping|rel|media|type][B]em[A][B]strong[A][B]small[A][B]cite[A][B]q[A|cite][B]dfn[A][B]abbr[A][B]code[A][B]var[A][B]samp[A][B]kbd[A][B]sub[A][B]sup[A][B]i[A][B]b[A][B]mark[A][B]progress[A|value|max][B]meter[A|value|min|max|low|high|optimum][B]time[A|datetime][B]ruby[A][B|rt|rp]rt[A][B]rp[A][B]bdo[A][B]span[A][B]ins[A|cite|datetime][B]del[A|cite|datetime][B]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][]object[A|data|type|height|width|usemap|name|form|classid][param]param[A|name|value][]details[A|open][C|legend]command[A|type|label|icon|disabled|checked|radiogroup][]menu[A|type|label][C|li]legend[A][C|B]div[A][C]source[A|src|type|media][]audio[A|src|autobuffer|autoplay|loop|controls][source]video[A|src|autobuffer|autoplay|loop|controls|width|height|poster][source]hr[A][]form[A|accept-charset|action|autocomplete|enctype|method|name|novalidate|target][C]fieldset[A|disabled|form|name][C|legend]label[A|form|for][B]input[A|type|accept|alt|autocomplete|autofocus|checked|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|height|list|max|maxlength|min|multiple|pattern|placeholder|readonly|required|size|src|step|width|files|value|name][]button[A|autofocus|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|name|value|type][B]select[A|autofocus|disabled|form|multiple|name|size][option|optgroup]datalist[A][B|option]optgroup[A|disabled|label][option]option[A|disabled|selected|label|value][]textarea[A|autofocus|disabled|form|maxlength|name|placeholder|readonly|required|rows|cols|wrap][]keygen[A|autofocus|challenge|disabled|form|keytype|name][]output[A|for|form|name][B]canvas[A|width|height][]map[A|name][B|C]area[A|shape|coords|href|alt|target|media|rel|ping|type][]mathml[A][]svg[A][]table[A|border][caption|colgroup|thead|tfoot|tbody|tr]caption[A][C]colgroup[A|span][col]col[A|span][]thead[A][tr]tfoot[A][tr]tbody[A][tr]tr[A][th|td]th[A|headers|rowspan|colspan|scope][B]td[A|headers|rowspan|colspan][C]wbr[A][]")}return i}function c(){var i=a.html4;if(!i){i=a.html4=h({Z:"H|K|N|O|P",Y:"X|form|R|Q",ZG:"E|span|width|align|char|charoff|valign",X:"p|T|div|U|W|isindex|fieldset|table",ZF:"E|align|char|charoff|valign",W:"pre|hr|blockquote|address|center|noframes",ZE:"abbr|axis|headers|scope|rowspan|colspan|align|char|charoff|valign|nowrap|bgcolor|width|height",ZD:"[E][S]",U:"ul|ol|dl|menu|dir",ZC:"p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q",T:"h1|h2|h3|h4|h5|h6",ZB:"X|S|Q",S:"R|P",ZA:"a|G|J|M|O|P",R:"a|H|K|N|O",Q:"noscript|P",P:"ins|del|script",O:"input|select|textarea|label|button",N:"M|L",M:"em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym",L:"sub|sup",K:"J|I",J:"tt|i|b|u|s|strike",I:"big|small|font|basefont",H:"G|F",G:"br|span|bdo",F:"object|applet|img|map|iframe",E:"A|B|C",D:"accesskey|tabindex|onfocus|onblur",C:"onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup",B:"lang|xml:lang|dir",A:"id|class|style|title"},"script[id|charset|type|language|src|defer|xml:space][]style[B|id|type|media|title|xml:space][]object[E|declare|classid|codebase|data|type|codetype|archive|standby|width|height|usemap|name|tabindex|align|border|hspace|vspace][#|param|Y]param[id|name|value|valuetype|type][]p[E|align][#|S]a[E|D|charset|type|name|href|hreflang|rel|rev|shape|coords|target][#|Z]br[A|clear][]span[E][#|S]bdo[A|C|B][#|S]applet[A|codebase|archive|code|object|alt|name|width|height|align|hspace|vspace][#|param|Y]h1[E|align][#|S]img[E|src|alt|name|longdesc|width|height|usemap|ismap|align|border|hspace|vspace][]map[B|C|A|name][X|form|Q|area]h2[E|align][#|S]iframe[A|longdesc|name|src|frameborder|marginwidth|marginheight|scrolling|align|width|height][#|Y]h3[E|align][#|S]tt[E][#|S]i[E][#|S]b[E][#|S]u[E][#|S]s[E][#|S]strike[E][#|S]big[E][#|S]small[E][#|S]font[A|B|size|color|face][#|S]basefont[id|size|color|face][]em[E][#|S]strong[E][#|S]dfn[E][#|S]code[E][#|S]q[E|cite][#|S]samp[E][#|S]kbd[E][#|S]var[E][#|S]cite[E][#|S]abbr[E][#|S]acronym[E][#|S]sub[E][#|S]sup[E][#|S]input[E|D|type|name|value|checked|disabled|readonly|size|maxlength|src|alt|usemap|onselect|onchange|accept|align][]select[E|name|size|multiple|disabled|tabindex|onfocus|onblur|onchange][optgroup|option]optgroup[E|disabled|label][option]option[E|selected|disabled|label|value][]textarea[E|D|name|rows|cols|disabled|readonly|onselect|onchange][]label[E|for|accesskey|onfocus|onblur][#|S]button[E|D|name|value|type|disabled][#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]h4[E|align][#|S]ins[E|cite|datetime][#|Y]h5[E|align][#|S]del[E|cite|datetime][#|Y]h6[E|align][#|S]div[E|align][#|Y]ul[E|type|compact][li]li[E|type|value][#|Y]ol[E|type|compact|start][li]dl[E|compact][dt|dd]dt[E][#|S]dd[E][#|Y]menu[E|compact][li]dir[E|compact][li]pre[E|width|xml:space][#|ZA]hr[E|align|noshade|size|width][]blockquote[E|cite][#|Y]address[E][#|S|p]center[E][#|Y]noframes[E][#|Y]isindex[A|B|prompt][]fieldset[E][#|legend|Y]legend[E|accesskey|align][#|S]table[E|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor][caption|col|colgroup|thead|tfoot|tbody|tr]caption[E|align][#|S]col[ZG][]colgroup[ZG][col]thead[ZF][tr]tr[ZF|bgcolor][th|td]th[E|ZE][#|Y]form[E|action|method|name|enctype|onsubmit|onreset|accept|accept-charset|target][#|X|R|Q]noscript[E][#|Y]td[E|ZE][#|Y]tfoot[ZF][tr]tbody[ZF][tr]area[E|D|shape|coords|href|nohref|alt|target][]base[id|href|target][]body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]")}return i}f.html.Schema=function(A){var u=this,s={},k={},j=[],D,y;var o,q,z,r,v,n,p={};function m(F,E,H){var G=A[F];if(!G){G=a[F];if(!G){G=e(E," ",e(E.toUpperCase()," "));G=f.extend(G,H);a[F]=G}}else{G=e(G,",",e(G.toUpperCase()," "))}return G}A=A||{};y=A.schema=="html5"?b():c();if(A.verify_html===false){A.valid_elements="*[*]"}if(A.valid_styles){D={};g(A.valid_styles,function(F,E){D[E]=f.explode(F)})}o=m("whitespace_elements","pre script noscript style textarea");q=m("self_closing_elements","colgroup dd dt li option p td tfoot th thead tr");z=m("short_ended_elements","area base basefont br col frame hr img input isindex link meta param embed source wbr");r=m("boolean_attributes","checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls");n=m("non_empty_elements","td th iframe video audio object",z);textBlockElementsMap=m("text_block_elements","h1 h2 h3 h4 h5 h6 p div address pre form blockquote center dir fieldset header footer article section hgroup aside nav figure");v=m("block_elements","hr table tbody thead tfoot th tr td li ol ul caption dl dt dd noscript menu isindex samp option datalist select optgroup",textBlockElementsMap);function i(E){return new RegExp("^"+E.replace(/([?+*])/g,".$1")+"$")}function C(L){var K,G,Z,V,aa,F,I,U,X,Q,Y,ac,O,J,W,E,S,H,ab,ad,P,T,N=/^([#+\-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,R=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,M=/[*?+]/;if(L){L=d(L);if(s["@"]){S=s["@"].attributes;H=s["@"].attributesOrder}for(K=0,G=L.length;K<G;K++){F=N.exec(L[K]);if(F){W=F[1];Q=F[2];E=F[3];X=F[4];O={};J=[];I={attributes:O,attributesOrder:J};if(W==="#"){I.paddEmpty=true}if(W==="-"){I.removeEmpty=true}if(S){for(ad in S){O[ad]=S[ad]}J.push.apply(J,H)}if(X){X=d(X,"|");for(Z=0,V=X.length;Z<V;Z++){F=R.exec(X[Z]);if(F){U={};ac=F[1];Y=F[2].replace(/::/g,":");W=F[3];T=F[4];if(ac==="!"){I.attributesRequired=I.attributesRequired||[];I.attributesRequired.push(Y);U.required=true}if(ac==="-"){delete O[Y];J.splice(f.inArray(J,Y),1);continue}if(W){if(W==="="){I.attributesDefault=I.attributesDefault||[];I.attributesDefault.push({name:Y,value:T});U.defaultValue=T}if(W===":"){I.attributesForced=I.attributesForced||[];I.attributesForced.push({name:Y,value:T});U.forcedValue=T}if(W==="<"){U.validValues=e(T,"?")}}if(M.test(Y)){I.attributePatterns=I.attributePatterns||[];U.pattern=i(Y);I.attributePatterns.push(U)}else{if(!O[Y]){J.push(Y)}O[Y]=U}}}}if(!S&&Q=="@"){S=O;H=J}if(E){I.outputName=Q;s[E]=I}if(M.test(Q)){I.pattern=i(Q);j.push(I)}else{s[Q]=I}}}}}function t(E){s={};j=[];C(E);g(y,function(G,F){k[F]=G.children})}function l(F){var E=/^(~)?(.+)$/;if(F){g(d(F),function(J){var H=E.exec(J),I=H[1]==="~",K=I?"span":"div",G=H[2];k[G]=k[K];p[G]=K;if(!I){v[G.toUpperCase()]={};v[G]={}}if(!s[G]){s[G]=s[K]}g(k,function(L,M){if(L[K]){L[G]=L[K]}})})}}function x(F){var E=/^([+\-]?)(\w+)\[([^\]]+)\]$/;if(F){g(d(F),function(J){var I=E.exec(J),G,H;if(I){H=I[1];if(H){G=k[I[2]]}else{G=k[I[2]]={"#comment":{}}}G=k[I[2]];g(d(I[3],"|"),function(K){if(H==="-"){delete G[K]}else{G[K]={}}})}})}}function B(E){var G=s[E],F;if(G){return G}F=j.length;while(F--){G=j[F];if(G.pattern.test(E)){return G}}}if(!A.valid_elements){g(y,function(F,E){s[E]={attributes:F.attributes,attributesOrder:F.attributesOrder};k[E]=F.children});if(A.schema!="html5"){g(d("strong/b,em/i"),function(E){E=d(E,"/");s[E[1]].outputName=E[0]})}s.img.attributesDefault=[{name:"alt",value:""}];g(d("ol,ul,sub,sup,blockquote,span,font,a,table,tbody,tr,strong,em,b,i"),function(E){if(s[E]){s[E].removeEmpty=true}});g(d("p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption"),function(E){s[E].paddEmpty=true})}else{t(A.valid_elements)}l(A.custom_elements);x(A.valid_children);C(A.extended_valid_elements);x("+ol[ul|ol],+ul[ul|ol]");if(A.invalid_elements){f.each(f.explode(A.invalid_elements),function(E){if(s[E]){delete s[E]}})}if(!B("span")){C("span[!data-mce-type|*]")}u.children=k;u.styles=D;u.getBoolAttrs=function(){return r};u.getBlockElements=function(){return v};u.getTextBlockElements=function(){return textBlockElementsMap};u.getShortEndedElements=function(){return z};u.getSelfClosingElements=function(){return q};u.getNonEmptyElements=function(){return n};u.getWhiteSpaceElements=function(){return o};u.isValidChild=function(E,G){var F=k[E];return !!(F&&F[G])};u.isValid=function(F,E){var H,G,I=B(F);if(I){if(E){if(I.attributes[E]){return true}H=I.attributePatterns;if(H){G=H.length;while(G--){if(H[G].pattern.test(F)){return true}}}}else{return true}}return false};u.getElementRule=B;u.getCustomElements=function(){return p};u.addValidElements=C;u.setValidElements=t;u.addCustomElements=l;u.addValidChildren=x;u.elements=s}})(tinymce);(function(a){a.html.SaxParser=function(c,e){var b=this,d=function(){};c=c||{};b.schema=e=e||new a.html.Schema();if(c.fix_self_closing!==false){c.fix_self_closing=true}a.each("comment cdata text start end pi doctype".split(" "),function(f){if(f){b[f]=c[f]||d}});b.parse=function(E){var n=this,g,G=0,I,B,A=[],N,Q,C,r,z,s,M,H,O,v,m,k,t,R,o,P,F,S,L,f,J,l,D,K,h,x=0,j=a.html.Entities.decode,y,q;function u(T){var V,U;V=A.length;while(V--){if(A[V].name===T){break}}if(V>=0){for(U=A.length-1;U>=V;U--){T=A[U];if(T.valid){n.end(T.name)}}A.length=V}}function p(U,T,Y,X,W){var Z,V;T=T.toLowerCase();Y=T in H?T:j(Y||X||W||"");if(v&&!z&&T.indexOf("data-")!==0){Z=P[T];if(!Z&&F){V=F.length;while(V--){Z=F[V];if(Z.pattern.test(T)){break}}if(V===-1){Z=null}}if(!Z){return}if(Z.validValues&&!(Y in Z.validValues)){return}}N.map[T]=Y;N.push({name:T,value:Y})}l=new RegExp("<(?:(?:!--([\\w\\W]*?)-->)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*|\\/|\\s+)>))","g");D=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g;K={script:/<\/script[^>]*>/gi,style:/<\/style[^>]*>/gi,noscript:/<\/noscript[^>]*>/gi};M=e.getShortEndedElements();J=c.self_closing_elements||e.getSelfClosingElements();H=e.getBoolAttrs();v=c.validate;s=c.remove_internals;y=c.fix_self_closing;q=a.isIE;o=/^:/;while(g=l.exec(E)){if(G<g.index){n.text(j(E.substr(G,g.index-G)))}if(I=g[6]){I=I.toLowerCase();if(q&&o.test(I)){I=I.substr(1)}u(I)}else{if(I=g[7]){I=I.toLowerCase();if(q&&o.test(I)){I=I.substr(1)}O=I in M;if(y&&J[I]&&A.length>0&&A[A.length-1].name===I){u(I)}if(!v||(m=e.getElementRule(I))){k=true;if(v){P=m.attributes;F=m.attributePatterns}if(R=g[8]){z=R.indexOf("data-mce-type")!==-1;if(z&&s){k=false}N=[];N.map={};R.replace(D,p)}else{N=[];N.map={}}if(v&&!z){S=m.attributesRequired;L=m.attributesDefault;f=m.attributesForced;if(f){Q=f.length;while(Q--){t=f[Q];r=t.name;h=t.value;if(h==="{$uid}"){h="mce_"+x++}N.map[r]=h;N.push({name:r,value:h})}}if(L){Q=L.length;while(Q--){t=L[Q];r=t.name;if(!(r in N.map)){h=t.value;if(h==="{$uid}"){h="mce_"+x++}N.map[r]=h;N.push({name:r,value:h})}}}if(S){Q=S.length;while(Q--){if(S[Q] in N.map){break}}if(Q===-1){k=false}}if(N.map["data-mce-bogus"]){k=false}}if(k){n.start(I,N,O)}}else{k=false}if(B=K[I]){B.lastIndex=G=g.index+g[0].length;if(g=B.exec(E)){if(k){C=E.substr(G,g.index-G)}G=g.index+g[0].length}else{C=E.substr(G);G=E.length}if(k&&C.length>0){n.text(C,true)}if(k){n.end(I)}l.lastIndex=G;continue}if(!O){if(!R||R.indexOf("/")!=R.length-1){A.push({name:I,valid:k})}else{if(k){n.end(I)}}}}else{if(I=g[1]){n.comment(I)}else{if(I=g[2]){n.cdata(I)}else{if(I=g[3]){n.doctype(I)}else{if(I=g[4]){n.pi(I,g[5])}}}}}}G=g.index+g[0].length}if(G<E.length){n.text(j(E.substr(G)))}for(Q=A.length-1;Q>=0;Q--){I=A[Q];if(I.valid){n.end(I.name)}}}}})(tinymce);(function(d){var c=/^[ \t\r\n]*$/,e={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};function a(k,l,j){var i,h,f=j?"lastChild":"firstChild",g=j?"prev":"next";if(k[f]){return k[f]}if(k!==l){i=k[g];if(i){return i}for(h=k.parent;h&&h!==l;h=h.parent){i=h[g];if(i){return i}}}}function b(f,g){this.name=f;this.type=g;if(g===1){this.attributes=[];this.attributes.map={}}}d.extend(b.prototype,{replace:function(g){var f=this;if(g.parent){g.remove()}f.insert(g,f);f.remove();return f},attr:function(h,l){var f=this,g,j,k;if(typeof h!=="string"){for(j in h){f.attr(j,h[j])}return f}if(g=f.attributes){if(l!==k){if(l===null){if(h in g.map){delete g.map[h];j=g.length;while(j--){if(g[j].name===h){g=g.splice(j,1);return f}}}return f}if(h in g.map){j=g.length;while(j--){if(g[j].name===h){g[j].value=l;break}}}else{g.push({name:h,value:l})}g.map[h]=l;return f}else{return g.map[h]}}},clone:function(){var g=this,n=new b(g.name,g.type),h,f,m,j,k;if(m=g.attributes){k=[];k.map={};for(h=0,f=m.length;h<f;h++){j=m[h];if(j.name!=="id"){k[k.length]={name:j.name,value:j.value};k.map[j.name]=j.value}}n.attributes=k}n.value=g.value;n.shortEnded=g.shortEnded;return n},wrap:function(g){var f=this;f.parent.insert(g,f);g.append(f);return f},unwrap:function(){var f=this,h,g;for(h=f.firstChild;h;){g=h.next;f.insert(h,f,true);h=g}f.remove()},remove:function(){var f=this,h=f.parent,g=f.next,i=f.prev;if(h){if(h.firstChild===f){h.firstChild=g;if(g){g.prev=null}}else{i.next=g}if(h.lastChild===f){h.lastChild=i;if(i){i.next=null}}else{g.prev=i}f.parent=f.next=f.prev=null}return f},append:function(h){var f=this,g;if(h.parent){h.remove()}g=f.lastChild;if(g){g.next=h;h.prev=g;f.lastChild=h}else{f.lastChild=f.firstChild=h}h.parent=f;return h},insert:function(h,f,i){var g;if(h.parent){h.remove()}g=f.parent||this;if(i){if(f===g.firstChild){g.firstChild=h}else{f.prev.next=h}h.prev=f.prev;h.next=f;f.prev=h}else{if(f===g.lastChild){g.lastChild=h}else{f.next.prev=h}h.next=f.next;h.prev=f;f.next=h}h.parent=g;return h},getAll:function(g){var f=this,h,i=[];for(h=f.firstChild;h;h=a(h,f)){if(h.name===g){i.push(h)}}return i},empty:function(){var g=this,f,h,j;if(g.firstChild){f=[];for(j=g.firstChild;j;j=a(j,g)){f.push(j)}h=f.length;while(h--){j=f[h];j.parent=j.firstChild=j.lastChild=j.next=j.prev=null}}g.firstChild=g.lastChild=null;return g},isEmpty:function(k){var f=this,j=f.firstChild,h,g;if(j){do{if(j.type===1){if(j.attributes.map["data-mce-bogus"]){continue}if(k[j.name]){return false}h=j.attributes.length;while(h--){g=j.attributes[h].name;if(g==="name"||g.indexOf("data-mce-")===0){return false}}}if(j.type===8){return false}if((j.type===3&&!c.test(j.value))){return false}}while(j=a(j,f))}return true},walk:function(f){return a(this,null,f)}});d.extend(b,{create:function(g,f){var i,h;i=new b(g,e[g]||1);if(f){for(h in f){i.attr(h,f[h])}}return i}});d.html.Node=b})(tinymce);(function(b){var a=b.html.Node;b.html.DomParser=function(g,h){var f=this,e={},d=[],i={},c={};g=g||{};g.validate="validate" in g?g.validate:true;g.root_name=g.root_name||"body";f.schema=h=h||new b.html.Schema();function j(n){var p,q,y,x,A,o,r,l,u,v,k,t,m,z,s;t=b.makeMap("tr,td,th,tbody,thead,tfoot,table");k=h.getNonEmptyElements();m=h.getTextBlockElements();for(p=0;p<n.length;p++){q=n[p];if(!q.parent||q.fixed){continue}if(m[q.name]&&q.parent.name=="li"){z=q.next;while(z){if(m[z.name]){z.name="li";z.fixed=true;q.parent.insert(z,q.parent)}else{break}z=z.next}q.unwrap(q);continue}x=[q];for(y=q.parent;y&&!h.isValidChild(y.name,q.name)&&!t[y.name];y=y.parent){x.push(y)}if(y&&x.length>1){x.reverse();A=o=f.filterNode(x[0].clone());for(u=0;u<x.length-1;u++){if(h.isValidChild(o.name,x[u].name)){r=f.filterNode(x[u].clone());o.append(r)}else{r=o}for(l=x[u].firstChild;l&&l!=x[u+1];){s=l.next;r.append(l);l=s}o=r}if(!A.isEmpty(k)){y.insert(A,x[0],true);y.insert(q,A)}else{y.insert(q,x[0],true)}y=x[0];if(y.isEmpty(k)||y.firstChild===y.lastChild&&y.firstChild.name==="br"){y.empty().remove()}}else{if(q.parent){if(q.name==="li"){z=q.prev;if(z&&(z.name==="ul"||z.name==="ul")){z.append(q);continue}z=q.next;if(z&&(z.name==="ul"||z.name==="ul")){z.insert(q,z.firstChild,true);continue}q.wrap(f.filterNode(new a("ul",1)));continue}if(h.isValidChild(q.parent.name,"div")&&h.isValidChild("div",q.name)){q.wrap(f.filterNode(new a("div",1)))}else{if(q.name==="style"||q.name==="script"){q.empty().remove()}else{q.unwrap()}}}}}}f.filterNode=function(m){var l,k,n;if(k in e){n=i[k];if(n){n.push(m)}else{i[k]=[m]}}l=d.length;while(l--){k=d[l].name;if(k in m.attributes.map){n=c[k];if(n){n.push(m)}else{c[k]=[m]}}}return m};f.addNodeFilter=function(k,l){b.each(b.explode(k),function(m){var n=e[m];if(!n){e[m]=n=[]}n.push(l)})};f.addAttributeFilter=function(k,l){b.each(b.explode(k),function(m){var n;for(n=0;n<d.length;n++){if(d[n].name===m){d[n].callbacks.push(l);return}}d.push({name:m,callbacks:[l]})})};f.parse=function(v,m){var n,J,B,A,D,C,x,r,F,N,z,o,E,M=[],L,t,k,y,s,p,u,q;m=m||{};i={};c={};o=b.extend(b.makeMap("script,style,head,html,body,title,meta,param"),h.getBlockElements());u=h.getNonEmptyElements();p=h.children;z=g.validate;q="forced_root_block" in m?m.forced_root_block:g.forced_root_block;s=h.getWhiteSpaceElements();E=/^[ \t\r\n]+/;t=/[ \t\r\n]+$/;k=/[ \t\r\n]+/g;y=/^[ \t\r\n]+$/;function G(){var O=J.firstChild,l,P;while(O){l=O.next;if(O.type==3||(O.type==1&&O.name!=="p"&&!o[O.name]&&!O.attr("data-mce-type"))){if(!P){P=K(q,1);J.insert(P,O);P.append(O)}else{P.append(O)}}else{P=null}O=l}}function K(l,O){var P=new a(l,O),Q;if(l in e){Q=i[l];if(Q){Q.push(P)}else{i[l]=[P]}}return P}function I(P){var Q,l,O;for(Q=P.prev;Q&&Q.type===3;){l=Q.value.replace(t,"");if(l.length>0){Q.value=l;Q=Q.prev}else{O=Q.prev;Q.remove();Q=O}}}function H(O){var P,l={};for(P in O){if(P!=="li"&&P!="p"){l[P]=O[P]}}return l}n=new b.html.SaxParser({validate:z,self_closing_elements:H(h.getSelfClosingElements()),cdata:function(l){B.append(K("#cdata",4)).value=l},text:function(P,l){var O;if(!L){P=P.replace(k," ");if(B.lastChild&&o[B.lastChild.name]){P=P.replace(E,"")}}if(P.length!==0){O=K("#text",3);O.raw=!!l;B.append(O).value=P}},comment:function(l){B.append(K("#comment",8)).value=l},pi:function(l,O){B.append(K(l,7)).value=O;I(B)},doctype:function(O){var l;l=B.append(K("#doctype",10));l.value=O;I(B)},start:function(l,W,P){var U,R,Q,O,S,X,V,T;Q=z?h.getElementRule(l):{};if(Q){U=K(Q.outputName||l,1);U.attributes=W;U.shortEnded=P;B.append(U);T=p[B.name];if(T&&p[U.name]&&!T[U.name]){M.push(U)}R=d.length;while(R--){S=d[R].name;if(S in W.map){F=c[S];if(F){F.push(U)}else{c[S]=[U]}}}if(o[l]){I(U)}if(!P){B=U}if(!L&&s[l]){L=true}}},end:function(l){var S,P,R,O,Q;P=z?h.getElementRule(l):{};if(P){if(o[l]){if(!L){S=B.firstChild;if(S&&S.type===3){R=S.value.replace(E,"");if(R.length>0){S.value=R;S=S.next}else{O=S.next;S.remove();S=O}while(S&&S.type===3){R=S.value;O=S.next;if(R.length===0||y.test(R)){S.remove();S=O}S=O}}S=B.lastChild;if(S&&S.type===3){R=S.value.replace(t,"");if(R.length>0){S.value=R;S=S.prev}else{O=S.prev;S.remove();S=O}while(S&&S.type===3){R=S.value;O=S.prev;if(R.length===0||y.test(R)){S.remove();S=O}S=O}}}}if(L&&s[l]){L=false}if(P.removeEmpty||P.paddEmpty){if(B.isEmpty(u)){if(P.paddEmpty){B.empty().append(new a("#text","3")).value="\u00a0"}else{if(!B.attributes.map.name&&!B.attributes.map.id){Q=B.parent;B.empty().remove();B=Q;return}}}}B=B.parent}}},h);J=B=new a(m.context||g.root_name,11);n.parse(v);if(z&&M.length){if(!m.context){j(M)}else{m.invalid=true}}if(q&&J.name=="body"){G()}if(!m.invalid){for(N in i){F=e[N];A=i[N];x=A.length;while(x--){if(!A[x].parent){A.splice(x,1)}}for(D=0,C=F.length;D<C;D++){F[D](A,N,m)}}for(D=0,C=d.length;D<C;D++){F=d[D];if(F.name in c){A=c[F.name];x=A.length;while(x--){if(!A[x].parent){A.splice(x,1)}}for(x=0,r=F.callbacks.length;x<r;x++){F.callbacks[x](A,F.name,m)}}}}return J};if(g.remove_trailing_brs){f.addNodeFilter("br",function(n,m){var r,q=n.length,o,v=b.extend({},h.getBlockElements()),k=h.getNonEmptyElements(),t,s,p,u;v.body=1;for(r=0;r<q;r++){o=n[r];t=o.parent;if(v[o.parent.name]&&o===t.lastChild){p=o.prev;while(p){u=p.name;if(u!=="span"||p.attr("data-mce-type")!=="bookmark"){if(u!=="br"){break}if(u==="br"){o=null;break}}p=p.prev}if(o){o.remove();if(t.isEmpty(k)){elementRule=h.getElementRule(t.name);if(elementRule){if(elementRule.removeEmpty){t.remove()}else{if(elementRule.paddEmpty){t.empty().append(new b.html.Node("#text",3)).value="\u00a0"}}}}}}else{s=o;while(t.firstChild===s&&t.lastChild===s){s=t;if(v[t.name]){break}t=t.parent}if(s===t){textNode=new b.html.Node("#text",3);textNode.value="\u00a0";o.replace(textNode)}}}})}if(!g.allow_html_in_named_anchor){f.addAttributeFilter("id,name",function(k,l){var n=k.length,p,m,o,q;while(n--){q=k[n];if(q.name==="a"&&q.firstChild&&!q.attr("href")){o=q.parent;p=q.lastChild;do{m=p.prev;o.insert(p,q);p=m}while(p)}}})}}})(tinymce);tinymce.html.Writer=function(e){var c=[],a,b,d,f,g;e=e||{};a=e.indent;b=tinymce.makeMap(e.indent_before||"");d=tinymce.makeMap(e.indent_after||"");f=tinymce.html.Entities.getEncodeFunc(e.entity_encoding||"raw",e.entities);g=e.element_format=="html";return{start:function(m,k,p){var n,j,h,o;if(a&&b[m]&&c.length>0){o=c[c.length-1];if(o.length>0&&o!=="\n"){c.push("\n")}}c.push("<",m);if(k){for(n=0,j=k.length;n<j;n++){h=k[n];c.push(" ",h.name,'="',f(h.value,true),'"')}}if(!p||g){c[c.length]=">"}else{c[c.length]=" />"}if(p&&a&&d[m]&&c.length>0){o=c[c.length-1];if(o.length>0&&o!=="\n"){c.push("\n")}}},end:function(h){var i;c.push("</",h,">");if(a&&d[h]&&c.length>0){i=c[c.length-1];if(i.length>0&&i!=="\n"){c.push("\n")}}},text:function(i,h){if(i.length>0){c[c.length]=h?i:f(i)}},cdata:function(h){c.push("<![CDATA[",h,"]]>")},comment:function(h){c.push("<!--",h,"-->")},pi:function(h,i){if(i){c.push("<?",h," ",i,"?>")}else{c.push("<?",h,"?>")}if(a){c.push("\n")}},doctype:function(h){c.push("<!DOCTYPE",h,">",a?"\n":"")},reset:function(){c.length=0},getContent:function(){return c.join("").replace(/\n$/,"")}}};(function(a){a.html.Serializer=function(c,d){var b=this,e=new a.html.Writer(c);c=c||{};c.validate="validate" in c?c.validate:true;b.schema=d=d||new a.html.Schema();b.writer=e;b.serialize=function(h){var g,i;i=c.validate;g={3:function(k,j){e.text(k.value,k.raw)},8:function(j){e.comment(j.value)},7:function(j){e.pi(j.name,j.value)},10:function(j){e.doctype(j.value)},4:function(j){e.cdata(j.value)},11:function(j){if((j=j.firstChild)){do{f(j)}while(j=j.next)}}};e.reset();function f(k){var t=g[k.type],j,o,s,r,p,u,n,m,q;if(!t){j=k.name;o=k.shortEnded;s=k.attributes;if(i&&s&&s.length>1){u=[];u.map={};q=d.getElementRule(k.name);for(n=0,m=q.attributesOrder.length;n<m;n++){r=q.attributesOrder[n];if(r in s.map){p=s.map[r];u.map[r]=p;u.push({name:r,value:p})}}for(n=0,m=s.length;n<m;n++){r=s[n].name;if(!(r in u.map)){p=s.map[r];u.map[r]=p;u.push({name:r,value:p})}}s=u}e.start(k.name,s,o);if(!o){if((k=k.firstChild)){do{f(k)}while(k=k.next)}e.end(j)}}else{t(k)}}if(h.type==1&&!c.inner){f(h)}else{g[11](h)}return e.getContent()}}})(tinymce);tinymce.dom={};(function(b,h){var g=!!document.addEventListener;function c(k,j,l,i){if(k.addEventListener){k.addEventListener(j,l,i||false)}else{if(k.attachEvent){k.attachEvent("on"+j,l)}}}function e(k,j,l,i){if(k.removeEventListener){k.removeEventListener(j,l,i||false)}else{if(k.detachEvent){k.detachEvent("on"+j,l)}}}function a(n,l){var i,k=l||{};function j(){return false}function m(){return true}for(i in n){if(i!=="layerX"&&i!=="layerY"){k[i]=n[i]}}if(!k.target){k.target=k.srcElement||document}k.preventDefault=function(){k.isDefaultPrevented=m;if(n){if(n.preventDefault){n.preventDefault()}else{n.returnValue=false}}};k.stopPropagation=function(){k.isPropagationStopped=m;if(n){if(n.stopPropagation){n.stopPropagation()}else{n.cancelBubble=true}}};k.stopImmediatePropagation=function(){k.isImmediatePropagationStopped=m;k.stopPropagation()};if(!k.isDefaultPrevented){k.isDefaultPrevented=j;k.isPropagationStopped=j;k.isImmediatePropagationStopped=j}return k}function d(m,n,l){var k=m.document,j={type:"ready"};function i(){if(!l.domLoaded){l.domLoaded=true;n(j)}}if(k.readyState=="complete"){i();return}if(g){c(m,"DOMContentLoaded",i)}else{c(k,"readystatechange",function(){if(k.readyState==="complete"){e(k,"readystatechange",arguments.callee);i()}});if(k.documentElement.doScroll&&m===m.top){(function(){try{k.documentElement.doScroll("left")}catch(o){setTimeout(arguments.callee,0);return}i()})()}}c(m,"load",i)}function f(k){var q=this,p={},i,o,n,m,l;m="onmouseenter" in document.documentElement;n="onfocusin" in document.documentElement;l={mouseenter:"mouseover",mouseleave:"mouseout"};i=1;q.domLoaded=false;q.events=p;function j(t,x){var s,u,r,v;s=p[x][t.type];if(s){for(u=0,r=s.length;u<r;u++){v=s[u];if(v&&v.func.call(v.scope,t)===false){t.preventDefault()}if(t.isImmediatePropagationStopped()){return}}}}q.bind=function(x,A,D,E){var s,t,u,r,B,z,C,v=window;function y(F){j(a(F||v.event),s)}if(!x||x.nodeType===3||x.nodeType===8){return}if(!x[h]){s=i++;x[h]=s;p[s]={}}else{s=x[h];if(!p[s]){p[s]={}}}E=E||x;A=A.split(" ");u=A.length;while(u--){r=A[u];z=y;B=C=false;if(r==="DOMContentLoaded"){r="ready"}if((q.domLoaded||x.readyState=="complete")&&r==="ready"){q.domLoaded=true;D.call(E,a({type:r}));continue}if(!m){B=l[r];if(B){z=function(F){var H,G;H=F.currentTarget;G=F.relatedTarget;if(G&&H.contains){G=H.contains(G)}else{while(G&&G!==H){G=G.parentNode}}if(!G){F=a(F||v.event);F.type=F.type==="mouseout"?"mouseleave":"mouseenter";F.target=H;j(F,s)}}}}if(!n&&(r==="focusin"||r==="focusout")){C=true;B=r==="focusin"?"focus":"blur";z=function(F){F=a(F||v.event);F.type=F.type==="focus"?"focusin":"focusout";j(F,s)}}t=p[s][r];if(!t){p[s][r]=t=[{func:D,scope:E}];t.fakeName=B;t.capture=C;t.nativeHandler=z;if(!g){t.proxyHandler=k(s)}if(r==="ready"){d(x,z,q)}else{c(x,B||r,g?z:t.proxyHandler,C)}}else{t.push({func:D,scope:E})}}x=t=0;return D};q.unbind=function(x,z,A){var s,u,v,B,r,t;if(!x||x.nodeType===3||x.nodeType===8){return q}s=x[h];if(s){t=p[s];if(z){z=z.split(" ");v=z.length;while(v--){r=z[v];u=t[r];if(u){if(A){B=u.length;while(B--){if(u[B].func===A){u.splice(B,1)}}}if(!A||u.length===0){delete t[r];e(x,u.fakeName||r,g?u.nativeHandler:u.proxyHandler,u.capture)}}}}else{for(r in t){u=t[r];e(x,u.fakeName||r,g?u.nativeHandler:u.proxyHandler,u.capture)}t={}}for(r in t){return q}delete p[s];try{delete x[h]}catch(y){x[h]=null}}return q};q.fire=function(u,s,r){var v,t;if(!u||u.nodeType===3||u.nodeType===8){return q}t=a(null,r);t.type=s;do{v=u[h];if(v){j(t,v)}u=u.parentNode||u.ownerDocument||u.defaultView||u.parentWindow}while(u&&!t.isPropagationStopped());return q};q.clean=function(u){var s,r,t=q.unbind;if(!u||u.nodeType===3||u.nodeType===8){return q}if(u[h]){t(u)}if(!u.getElementsByTagName){u=u.document}if(u&&u.getElementsByTagName){t(u);r=u.getElementsByTagName("*");s=r.length;while(s--){u=r[s];if(u[h]){t(u)}}}return q};q.callNativeHandler=function(s,r){if(p){p[s][r.type].nativeHandler(r)}};q.destory=function(){p={}};q.add=function(v,s,u,t){if(typeof(v)==="string"){v=document.getElementById(v)}if(v&&v instanceof Array){var r=v.length;while(r--){q.add(v[r],s,u,t)}return}if(s==="init"){s="ready"}return q.bind(v,s instanceof Array?s.join(" "):s,u,t)};q.remove=function(v,s,u,t){if(!v){return q}if(typeof(v)==="string"){v=document.getElementById(v)}if(v instanceof Array){var r=v.length;while(r--){q.remove(v[r],s,u,t)}return q}return q.unbind(v,s instanceof Array?s.join(" "):s,u)};q.clear=function(r){if(typeof(r)==="string"){r=document.getElementById(r)}return q.clean(r)};q.cancel=function(r){if(r){q.prevent(r);q.stop(r)}return false};q.prevent=function(r){if(!r.preventDefault){r=a(r)}r.preventDefault();return false};q.stop=function(r){if(!r.stopPropagation){r=a(r)}r.stopPropagation();return false}}b.EventUtils=f;b.Event=new f(function(i){return function(j){tinymce.dom.Event.callNativeHandler(i,j)}});b.Event.bind(window,"ready",function(){});b=0})(tinymce.dom,"data-mce-expando");tinymce.dom.TreeWalker=function(a,c){var b=a;function d(i,f,e,j){var h,g;if(i){if(!j&&i[f]){return i[f]}if(i!=c){h=i[e];if(h){return h}for(g=i.parentNode;g&&g!=c;g=g.parentNode){h=g[e];if(h){return h}}}}}this.current=function(){return b};this.next=function(e){return(b=d(b,"firstChild","nextSibling",e))};this.prev=function(e){return(b=d(b,"lastChild","previousSibling",e))}};(function(e){var g=e.each,d=e.is,f=e.isWebKit,b=e.isIE,h=e.html.Entities,c=/^([a-z0-9],?)+$/i,a=/^[ \t\r\n]*$/;e.create("tinymce.dom.DOMUtils",{doc:null,root:null,files:null,pixelStyles:/^(top|left|bottom|right|width|height|borderWidth)$/,props:{"for":"htmlFor","class":"className",className:"className",checked:"checked",disabled:"disabled",maxlength:"maxLength",readonly:"readOnly",selected:"selected",value:"value",id:"id",name:"name",type:"type"},DOMUtils:function(o,l){var k=this,i,j,n;k.doc=o;k.win=window;k.files={};k.cssFlicker=false;k.counter=0;k.stdMode=!e.isIE||o.documentMode>=8;k.boxModel=!e.isIE||o.compatMode=="CSS1Compat"||k.stdMode;k.hasOuterHTML="outerHTML" in o.createElement("a");k.settings=l=e.extend({keep_values:false,hex_colors:1},l);k.schema=l.schema;k.styles=new e.html.Styles({url_converter:l.url_converter,url_converter_scope:l.url_converter_scope},l.schema);if(e.isIE6){try{o.execCommand("BackgroundImageCache",false,true)}catch(m){k.cssFlicker=true}}k.fixDoc(o);k.events=l.ownEvents?new e.dom.EventUtils(l.proxy):e.dom.Event;e.addUnload(k.destroy,k);n=l.schema?l.schema.getBlockElements():{};k.isBlock=function(q){if(!q){return false}var p=q.nodeType;if(p){return !!(p===1&&n[q.nodeName])}return !!n[q]}},fixDoc:function(k){var j=this.settings,i;if(b&&j.schema){("abbr article aside audio canvas details figcaption figure footer header hgroup mark menu meter nav output progress section summary time video").replace(/\w+/g,function(l){k.createElement(l)});for(i in j.schema.getCustomElements()){k.createElement(i)}}},clone:function(k,i){var j=this,m,l;if(!b||k.nodeType!==1||i){return k.cloneNode(i)}l=j.doc;if(!i){m=l.createElement(k.nodeName);g(j.getAttribs(k),function(n){j.setAttrib(m,n.nodeName,j.getAttrib(k,n.nodeName))});return m}return m.firstChild},getRoot:function(){var i=this,j=i.settings;return(j&&i.get(j.root_element))||i.doc.body},getViewPort:function(j){var k,i;j=!j?this.win:j;k=j.document;i=this.boxModel?k.documentElement:k.body;return{x:j.pageXOffset||i.scrollLeft,y:j.pageYOffset||i.scrollTop,w:j.innerWidth||i.clientWidth,h:j.innerHeight||i.clientHeight}},getRect:function(l){var k,i=this,j;l=i.get(l);k=i.getPos(l);j=i.getSize(l);return{x:k.x,y:k.y,w:j.w,h:j.h}},getSize:function(l){var j=this,i,k;l=j.get(l);i=j.getStyle(l,"width");k=j.getStyle(l,"height");if(i.indexOf("px")===-1){i=0}if(k.indexOf("px")===-1){k=0}return{w:parseInt(i,10)||l.offsetWidth||l.clientWidth,h:parseInt(k,10)||l.offsetHeight||l.clientHeight}},getParent:function(k,j,i){return this.getParents(k,j,i,false)},getParents:function(s,m,k,q){var j=this,i,l=j.settings,p=[];s=j.get(s);q=q===undefined;if(l.strict_root){k=k||j.getRoot()}if(d(m,"string")){i=m;if(m==="*"){m=function(o){return o.nodeType==1}}else{m=function(o){return j.is(o,i)}}}while(s){if(s==k||!s.nodeType||s.nodeType===9){break}if(!m||m(s)){if(q){p.push(s)}else{return s}}s=s.parentNode}return q?p:null},get:function(i){var j;if(i&&this.doc&&typeof(i)=="string"){j=i;i=this.doc.getElementById(i);if(i&&i.id!==j){return this.doc.getElementsByName(j)[1]}}return i},getNext:function(j,i){return this._findSib(j,i,"nextSibling")},getPrev:function(j,i){return this._findSib(j,i,"previousSibling")},add:function(l,o,i,k,m){var j=this;return this.run(l,function(r){var q,n;q=d(o,"string")?j.doc.createElement(o):o;j.setAttribs(q,i);if(k){if(k.nodeType){q.appendChild(k)}else{j.setHTML(q,k)}}return !m?r.appendChild(q):q})},create:function(k,i,j){return this.add(this.doc.createElement(k),k,i,j,1)},createHTML:function(q,i,m){var p="",l=this,j;p+="<"+q;for(j in i){if(i.hasOwnProperty(j)){p+=" "+j+'="'+l.encode(i[j])+'"'}}if(typeof(m)!="undefined"){return p+">"+m+"</"+q+">"}return p+" />"},remove:function(i,j){return this.run(i,function(l){var m,k=l.parentNode;if(!k){return null}if(j){while(m=l.firstChild){if(!e.isIE||m.nodeType!==3||m.nodeValue){k.insertBefore(m,l)}else{l.removeChild(m)}}}return k.removeChild(l)})},setStyle:function(l,i,j){var k=this;return k.run(l,function(o){var n,m;n=o.style;i=i.replace(/-(\D)/g,function(q,p){return p.toUpperCase()});if(k.pixelStyles.test(i)&&(e.is(j,"number")||/^[\-0-9\.]+$/.test(j))){j+="px"}switch(i){case"opacity":if(b){n.filter=j===""?"":"alpha(opacity="+(j*100)+")";if(!l.currentStyle||!l.currentStyle.hasLayout){n.display="inline-block"}}n[i]=n["-moz-opacity"]=n["-khtml-opacity"]=j||"";break;case"float":b?n.styleFloat=j:n.cssFloat=j;break;default:n[i]=j||""}if(k.settings.update_styles){k.setAttrib(o,"data-mce-style")}})},getStyle:function(l,i,k){l=this.get(l);if(!l){return}if(this.doc.defaultView&&k){i=i.replace(/[A-Z]/g,function(m){return"-"+m});try{return this.doc.defaultView.getComputedStyle(l,null).getPropertyValue(i)}catch(j){return null}}i=i.replace(/-(\D)/g,function(n,m){return m.toUpperCase()});if(i=="float"){i=b?"styleFloat":"cssFloat"}if(l.currentStyle&&k){return l.currentStyle[i]}return l.style?l.style[i]:undefined},setStyles:function(l,m){var j=this,k=j.settings,i;i=k.update_styles;k.update_styles=0;g(m,function(o,p){j.setStyle(l,p,o)});k.update_styles=i;if(k.update_styles){j.setAttrib(l,k.cssText)}},removeAllAttribs:function(i){return this.run(i,function(l){var k,j=l.attributes;for(k=j.length-1;k>=0;k--){l.removeAttributeNode(j.item(k))}})},setAttrib:function(k,l,i){var j=this;if(!k||!l){return}if(j.settings.strict){l=l.toLowerCase()}return this.run(k,function(p){var o=j.settings;var m=p.getAttribute(l);if(i!==null){switch(l){case"style":if(!d(i,"string")){g(i,function(q,r){j.setStyle(p,r,q)});return}if(o.keep_values){if(i&&!j._isRes(i)){p.setAttribute("data-mce-style",i,2)}else{p.removeAttribute("data-mce-style",2)}}p.style.cssText=i;break;case"class":p.className=i||"";break;case"src":case"href":if(o.keep_values){if(o.url_converter){i=o.url_converter.call(o.url_converter_scope||j,i,l,p)}j.setAttrib(p,"data-mce-"+l,i,2)}break;case"shape":p.setAttribute("data-mce-style",i);break}}if(d(i)&&i!==null&&i.length!==0){p.setAttribute(l,""+i,2)}else{p.removeAttribute(l,2)}if(tinyMCE.activeEditor&&m!=i){var n=tinyMCE.activeEditor;n.onSetAttrib.dispatch(n,p,l,i)}})},setAttribs:function(j,k){var i=this;return this.run(j,function(l){g(k,function(m,o){i.setAttrib(l,o,m)})})},getAttrib:function(m,o,k){var i,j=this,l;m=j.get(m);if(!m||m.nodeType!==1){return k===l?false:k}if(!d(k)){k=""}if(/^(src|href|style|coords|shape)$/.test(o)){i=m.getAttribute("data-mce-"+o);if(i){return i}}if(b&&j.props[o]){i=m[j.props[o]];i=i&&i.nodeValue?i.nodeValue:i}if(!i){i=m.getAttribute(o,2)}if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(o)){if(m[j.props[o]]===true&&i===""){return o}return i?o:""}if(m.nodeName==="FORM"&&m.getAttributeNode(o)){return m.getAttributeNode(o).nodeValue}if(o==="style"){i=i||m.style.cssText;if(i){i=j.serializeStyle(j.parseStyle(i),m.nodeName);if(j.settings.keep_values&&!j._isRes(i)){m.setAttribute("data-mce-style",i)}}}if(f&&o==="class"&&i){i=i.replace(/(apple|webkit)\-[a-z\-]+/gi,"")}if(b){switch(o){case"rowspan":case"colspan":if(i===1){i=""}break;case"size":if(i==="+0"||i===20||i===0){i=""}break;case"width":case"height":case"vspace":case"checked":case"disabled":case"readonly":if(i===0){i=""}break;case"hspace":if(i===-1){i=""}break;case"maxlength":case"tabindex":if(i===32768||i===2147483647||i==="32768"){i=""}break;case"multiple":case"compact":case"noshade":case"nowrap":if(i===65535){return o}return k;case"shape":i=i.toLowerCase();break;default:if(o.indexOf("on")===0&&i){i=e._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1",""+i)}}}return(i!==l&&i!==null&&i!=="")?""+i:k},getPos:function(q,l){var j=this,i=0,p=0,m,o=j.doc,k;q=j.get(q);l=l||o.body;if(q){if(q.getBoundingClientRect){q=q.getBoundingClientRect();m=j.boxModel?o.documentElement:o.body;i=q.left+(o.documentElement.scrollLeft||o.body.scrollLeft)-m.clientTop;p=q.top+(o.documentElement.scrollTop||o.body.scrollTop)-m.clientLeft;return{x:i,y:p}}k=q;while(k&&k!=l&&k.nodeType){i+=k.offsetLeft||0;p+=k.offsetTop||0;k=k.offsetParent}k=q.parentNode;while(k&&k!=l&&k.nodeType){i-=k.scrollLeft||0;p-=k.scrollTop||0;k=k.parentNode}}return{x:i,y:p}},parseStyle:function(i){return this.styles.parse(i)},serializeStyle:function(j,i){return this.styles.serialize(j,i)},addStyle:function(j){var k=this.doc,i;styleElm=k.getElementById("mceDefaultStyles");if(!styleElm){styleElm=k.createElement("style"),styleElm.id="mceDefaultStyles";styleElm.type="text/css";i=k.getElementsByTagName("head")[0];if(i.firstChild){i.insertBefore(styleElm,i.firstChild)}else{i.appendChild(styleElm)}}if(styleElm.styleSheet){styleElm.styleSheet.cssText+=j}else{styleElm.appendChild(k.createTextNode(j))}},loadCSS:function(i){var k=this,l=k.doc,j;if(!i){i=""}j=l.getElementsByTagName("head")[0];g(i.split(","),function(m){var n;if(k.files[m]){return}k.files[m]=true;n=k.create("link",{rel:"stylesheet",href:e._addVer(m)});if(b&&l.documentMode&&l.recalc){n.onload=function(){if(l.recalc){l.recalc()}n.onload=null}}j.appendChild(n)})},addClass:function(i,j){return this.run(i,function(k){var l;if(!j){return 0}if(this.hasClass(k,j)){return k.className}l=this.removeClass(k,j);return k.className=(l!=""?(l+" "):"")+j})},removeClass:function(k,l){var i=this,j;return i.run(k,function(n){var m;if(i.hasClass(n,l)){if(!j){j=new RegExp("(^|\\s+)"+l+"(\\s+|$)","g")}m=n.className.replace(j," ");m=e.trim(m!=" "?m:"");n.className=m;if(!m){n.removeAttribute("class");n.removeAttribute("className")}return m}return n.className})},hasClass:function(j,i){j=this.get(j);if(!j||!i){return false}return(" "+j.className+" ").indexOf(" "+i+" ")!==-1},show:function(i){return this.setStyle(i,"display","block")},hide:function(i){return this.setStyle(i,"display","none")},isHidden:function(i){i=this.get(i);return !i||i.style.display=="none"||this.getStyle(i,"display")=="none"},uniqueId:function(i){return(!i?"mce_":i)+(this.counter++)},setHTML:function(k,j){var i=this;return i.run(k,function(m){if(b){while(m.firstChild){m.removeChild(m.firstChild)}try{m.innerHTML="<br />"+j;m.removeChild(m.firstChild)}catch(l){var n=i.create("div");n.innerHTML="<br />"+j;g(e.grep(n.childNodes),function(p,o){if(o&&m.canHaveHTML){m.appendChild(p)}})}}else{m.innerHTML=j}return j})},getOuterHTML:function(k){var j,i=this;k=i.get(k);if(!k){return null}if(k.nodeType===1&&i.hasOuterHTML){return k.outerHTML}j=(k.ownerDocument||i.doc).createElement("body");j.appendChild(k.cloneNode(true));return j.innerHTML},setOuterHTML:function(l,j,m){var i=this;function k(p,o,r){var s,q;q=r.createElement("body");q.innerHTML=o;s=q.lastChild;while(s){i.insertAfter(s.cloneNode(true),p);s=s.previousSibling}i.remove(p)}return this.run(l,function(o){o=i.get(o);if(o.nodeType==1){m=m||o.ownerDocument||i.doc;if(b){try{if(b&&o.nodeType==1){o.outerHTML=j}else{k(o,j,m)}}catch(n){k(o,j,m)}}else{k(o,j,m)}}})},decode:h.decode,encode:h.encodeAllRaw,insertAfter:function(i,j){j=this.get(j);return this.run(i,function(l){var k,m;k=j.parentNode;m=j.nextSibling;if(m){k.insertBefore(l,m)}else{k.appendChild(l)}return l})},replace:function(m,l,i){var j=this;if(d(l,"array")){m=m.cloneNode(true)}return j.run(l,function(k){if(i){g(e.grep(k.childNodes),function(n){m.appendChild(n)})}return k.parentNode.replaceChild(m,k)})},rename:function(l,i){var k=this,j;if(l.nodeName!=i.toUpperCase()){j=k.create(i);g(k.getAttribs(l),function(m){k.setAttrib(j,m.nodeName,k.getAttrib(l,m.nodeName))});k.replace(j,l,1)}return j||l},findCommonAncestor:function(k,i){var l=k,j;while(l){j=i;while(j&&l!=j){j=j.parentNode}if(l==j){break}l=l.parentNode}if(!l&&k.ownerDocument){return k.ownerDocument.documentElement}return l},toHex:function(i){var k=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(i);function j(l){l=parseInt(l,10).toString(16);return l.length>1?l:"0"+l}if(k){i="#"+j(k[1])+j(k[2])+j(k[3]);return i}return i},getClasses:function(){var n=this,j=[],m,o={},p=n.settings.class_filter,l;if(n.classes){return n.classes}function q(i){g(i.imports,function(s){q(s)});g(i.cssRules||i.rules,function(s){switch(s.type||1){case 1:if(s.selectorText){g(s.selectorText.split(","),function(r){r=r.replace(/^\s*|\s*$|^\s\./g,"");if(/\.mce/.test(r)||!/\.[\w\-]+$/.test(r)){return}l=r;r=e._replace(/.*\.([a-z0-9_\-]+).*/i,"$1",r);if(p&&!(r=p(r,l))){return}if(!o[r]){j.push({"class":r});o[r]=1}})}break;case 3:q(s.styleSheet);break}})}try{g(n.doc.styleSheets,q)}catch(k){}if(j.length>0){n.classes=j}return j},run:function(l,k,j){var i=this,m;if(i.doc&&typeof(l)==="string"){l=i.get(l)}if(!l){return false}j=j||this;if(!l.nodeType&&(l.length||l.length===0)){m=[];g(l,function(o,n){if(o){if(typeof(o)=="string"){o=i.doc.getElementById(o)}m.push(k.call(j,o,n))}});return m}return k.call(j,l)},getAttribs:function(j){var i;j=this.get(j);if(!j){return[]}if(b){i=[];if(j.nodeName=="OBJECT"){return j.attributes}if(j.nodeName==="OPTION"&&this.getAttrib(j,"selected")){i.push({specified:1,nodeName:"selected"})}j.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi,"").replace(/[\w:\-]+/gi,function(k){i.push({specified:1,nodeName:k})});return i}return j.attributes},isEmpty:function(m,k){var r=this,o,n,q,j,l,p=0;m=m.firstChild;if(m){j=new e.dom.TreeWalker(m,m.parentNode);k=k||r.schema?r.schema.getNonEmptyElements():null;do{q=m.nodeType;if(q===1){if(m.getAttribute("data-mce-bogus")){continue}l=m.nodeName.toLowerCase();if(k&&k[l]){if(l==="br"){p++;continue}return false}n=r.getAttribs(m);o=m.attributes.length;while(o--){l=m.attributes[o].nodeName;if(l==="name"||l==="data-mce-bookmark"){return false}}}if(q==8){return false}if((q===3&&!a.test(m.nodeValue))){return false}}while(m=j.next())}return p<=1},destroy:function(j){var i=this;i.win=i.doc=i.root=i.events=i.frag=null;if(!j){e.removeUnload(i.destroy)}},createRng:function(){var i=this.doc;return i.createRange?i.createRange():new e.dom.Range(this)},nodeIndex:function(m,n){var i=0,k,l,j;if(m){for(k=m.nodeType,m=m.previousSibling,l=m;m;m=m.previousSibling){j=m.nodeType;if(n&&j==3){if(j==k||!m.nodeValue.length){continue}}i++;k=j}}return i},split:function(m,l,p){var q=this,i=q.createRng(),n,k,o;function j(v){var t,s=v.childNodes,u=v.nodeType;function x(A){var z=A.previousSibling&&A.previousSibling.nodeName=="SPAN";var y=A.nextSibling&&A.nextSibling.nodeName=="SPAN";return z&&y}if(u==1&&v.getAttribute("data-mce-type")=="bookmark"){return}for(t=s.length-1;t>=0;t--){j(s[t])}if(u!=9){if(u==3&&v.nodeValue.length>0){var r=e.trim(v.nodeValue).length;if(!q.isBlock(v.parentNode)||r>0||r===0&&x(v)){return}}else{if(u==1){s=v.childNodes;if(s.length==1&&s[0]&&s[0].nodeType==1&&s[0].getAttribute("data-mce-type")=="bookmark"){v.parentNode.insertBefore(s[0],v)}if(s.length||/^(br|hr|input|img)$/i.test(v.nodeName)){return}}}q.remove(v)}return v}if(m&&l){i.setStart(m.parentNode,q.nodeIndex(m));i.setEnd(l.parentNode,q.nodeIndex(l));n=i.extractContents();i=q.createRng();i.setStart(l.parentNode,q.nodeIndex(l)+1);i.setEnd(m.parentNode,q.nodeIndex(m)+1);k=i.extractContents();o=m.parentNode;o.insertBefore(j(n),m);if(p){o.replaceChild(p,l)}else{o.insertBefore(l,m)}o.insertBefore(j(k),m);q.remove(m);return p||l}},bind:function(l,i,k,j){return this.events.add(l,i,k,j||this)},unbind:function(k,i,j){return this.events.remove(k,i,j)},fire:function(k,j,i){return this.events.fire(k,j,i)},getContentEditable:function(j){var i;if(j.nodeType!=1){return null}i=j.getAttribute("data-mce-contenteditable");if(i&&i!=="inherit"){return i}return j.contentEditable!=="inherit"?j.contentEditable:null},_findSib:function(l,i,j){var k=this,m=i;if(l){if(d(m,"string")){m=function(n){return k.is(n,i)}}for(l=l[j];l;l=l[j]){if(m(l)){return l}}}return null},_isRes:function(i){return/^(top|left|bottom|right|width|height)/i.test(i)||/;\s*(top|left|bottom|right|width|height)/i.test(i)}});e.DOM=new e.dom.DOMUtils(document,{process_html:0})})(tinymce);(function(a){function b(c){var O=this,e=c.doc,U=0,F=1,j=2,E=true,S=false,W="startOffset",h="startContainer",Q="endContainer",A="endOffset",k=tinymce.extend,n=c.nodeIndex;k(O,{startContainer:e,startOffset:0,endContainer:e,endOffset:0,collapsed:E,commonAncestorContainer:e,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:q,setEnd:s,setStartBefore:g,setStartAfter:J,setEndBefore:K,setEndAfter:u,collapse:B,selectNode:y,selectNodeContents:G,compareBoundaryPoints:v,deleteContents:p,extractContents:I,cloneContents:d,insertNode:D,surroundContents:N,cloneRange:L,toStringIE:T});function x(){return e.createDocumentFragment()}function q(X,t){C(E,X,t)}function s(X,t){C(S,X,t)}function g(t){q(t.parentNode,n(t))}function J(t){q(t.parentNode,n(t)+1)}function K(t){s(t.parentNode,n(t))}function u(t){s(t.parentNode,n(t)+1)}function B(t){if(t){O[Q]=O[h];O[A]=O[W]}else{O[h]=O[Q];O[W]=O[A]}O.collapsed=E}function y(t){g(t);u(t)}function G(t){q(t,0);s(t,t.nodeType===1?t.childNodes.length:t.nodeValue.length)}function v(aa,t){var ad=O[h],Y=O[W],ac=O[Q],X=O[A],ab=t.startContainer,af=t.startOffset,Z=t.endContainer,ae=t.endOffset;if(aa===0){return H(ad,Y,ab,af)}if(aa===1){return H(ac,X,ab,af)}if(aa===2){return H(ac,X,Z,ae)}if(aa===3){return H(ad,Y,Z,ae)}}function p(){l(j)}function I(){return l(U)}function d(){return l(F)}function D(aa){var X=this[h],t=this[W],Z,Y;if((X.nodeType===3||X.nodeType===4)&&X.nodeValue){if(!t){X.parentNode.insertBefore(aa,X)}else{if(t>=X.nodeValue.length){c.insertAfter(aa,X)}else{Z=X.splitText(t);X.parentNode.insertBefore(aa,Z)}}}else{if(X.childNodes.length>0){Y=X.childNodes[t]}if(Y){X.insertBefore(aa,Y)}else{X.appendChild(aa)}}}function N(X){var t=O.extractContents();O.insertNode(X);X.appendChild(t);O.selectNode(X)}function L(){return k(new b(c),{startContainer:O[h],startOffset:O[W],endContainer:O[Q],endOffset:O[A],collapsed:O.collapsed,commonAncestorContainer:O.commonAncestorContainer})}function P(t,X){var Y;if(t.nodeType==3){return t}if(X<0){return t}Y=t.firstChild;while(Y&&X>0){--X;Y=Y.nextSibling}if(Y){return Y}return t}function m(){return(O[h]==O[Q]&&O[W]==O[A])}function H(Z,ab,X,aa){var ac,Y,t,ad,af,ae;if(Z==X){if(ab==aa){return 0}if(ab<aa){return -1}return 1}ac=X;while(ac&&ac.parentNode!=Z){ac=ac.parentNode}if(ac){Y=0;t=Z.firstChild;while(t!=ac&&Y<ab){Y++;t=t.nextSibling}if(ab<=Y){return -1}return 1}ac=Z;while(ac&&ac.parentNode!=X){ac=ac.parentNode}if(ac){Y=0;t=X.firstChild;while(t!=ac&&Y<aa){Y++;t=t.nextSibling}if(Y<aa){return -1}return 1}ad=c.findCommonAncestor(Z,X);af=Z;while(af&&af.parentNode!=ad){af=af.parentNode}if(!af){af=ad}ae=X;while(ae&&ae.parentNode!=ad){ae=ae.parentNode}if(!ae){ae=ad}if(af==ae){return 0}t=ad.firstChild;while(t){if(t==af){return -1}if(t==ae){return 1}t=t.nextSibling}}function C(X,aa,Z){var t,Y;if(X){O[h]=aa;O[W]=Z}else{O[Q]=aa;O[A]=Z}t=O[Q];while(t.parentNode){t=t.parentNode}Y=O[h];while(Y.parentNode){Y=Y.parentNode}if(Y==t){if(H(O[h],O[W],O[Q],O[A])>0){O.collapse(X)}}else{O.collapse(X)}O.collapsed=m();O.commonAncestorContainer=c.findCommonAncestor(O[h],O[Q])}function l(ad){var ac,Z=0,af=0,X,ab,Y,aa,t,ae;if(O[h]==O[Q]){return f(ad)}for(ac=O[Q],X=ac.parentNode;X;ac=X,X=X.parentNode){if(X==O[h]){return r(ac,ad)}++Z}for(ac=O[h],X=ac.parentNode;X;ac=X,X=X.parentNode){if(X==O[Q]){return V(ac,ad)}++af}ab=af-Z;Y=O[h];while(ab>0){Y=Y.parentNode;ab--}aa=O[Q];while(ab<0){aa=aa.parentNode;ab++}for(t=Y.parentNode,ae=aa.parentNode;t!=ae;t=t.parentNode,ae=ae.parentNode){Y=t;aa=ae}return o(Y,aa,ad)}function f(ac){var ae,af,t,Y,Z,ad,aa,X,ab;if(ac!=j){ae=x()}if(O[W]==O[A]){return ae}if(O[h].nodeType==3){af=O[h].nodeValue;t=af.substring(O[W],O[A]);if(ac!=F){Y=O[h];X=O[W];ab=O[A]-O[W];if(X===0&&ab>=Y.nodeValue.length-1){Y.parentNode.removeChild(Y)}else{Y.deleteData(X,ab)}O.collapse(E)}if(ac==j){return}if(t.length>0){ae.appendChild(e.createTextNode(t))}return ae}Y=P(O[h],O[W]);Z=O[A]-O[W];while(Y&&Z>0){ad=Y.nextSibling;aa=z(Y,ac);if(ae){ae.appendChild(aa)}--Z;Y=ad}if(ac!=F){O.collapse(E)}return ae}function r(ad,aa){var ac,ab,X,t,Z,Y;if(aa!=j){ac=x()}ab=i(ad,aa);if(ac){ac.appendChild(ab)}X=n(ad);t=X-O[W];if(t<=0){if(aa!=F){O.setEndBefore(ad);O.collapse(S)}return ac}ab=ad.previousSibling;while(t>0){Z=ab.previousSibling;Y=z(ab,aa);if(ac){ac.insertBefore(Y,ac.firstChild)}--t;ab=Z}if(aa!=F){O.setEndBefore(ad);O.collapse(S)}return ac}function V(ab,aa){var ad,X,ac,t,Z,Y;if(aa!=j){ad=x()}ac=R(ab,aa);if(ad){ad.appendChild(ac)}X=n(ab);++X;t=O[A]-X;ac=ab.nextSibling;while(ac&&t>0){Z=ac.nextSibling;Y=z(ac,aa);if(ad){ad.appendChild(Y)}--t;ac=Z}if(aa!=F){O.setStartAfter(ab);O.collapse(E)}return ad}function o(ab,t,ae){var Y,ag,aa,ac,ad,X,af,Z;if(ae!=j){ag=x()}Y=R(ab,ae);if(ag){ag.appendChild(Y)}aa=ab.parentNode;ac=n(ab);ad=n(t);++ac;X=ad-ac;af=ab.nextSibling;while(X>0){Z=af.nextSibling;Y=z(af,ae);if(ag){ag.appendChild(Y)}af=Z;--X}Y=i(t,ae);if(ag){ag.appendChild(Y)}if(ae!=F){O.setStartAfter(ab);O.collapse(E)}return ag}function i(ac,ad){var Y=P(O[Q],O[A]-1),ae,ab,aa,t,X,Z=Y!=O[Q];if(Y==ac){return M(Y,Z,S,ad)}ae=Y.parentNode;ab=M(ae,S,S,ad);while(ae){while(Y){aa=Y.previousSibling;t=M(Y,Z,S,ad);if(ad!=j){ab.insertBefore(t,ab.firstChild)}Z=E;Y=aa}if(ae==ac){return ab}Y=ae.previousSibling;ae=ae.parentNode;X=M(ae,S,S,ad);if(ad!=j){X.appendChild(ab)}ab=X}}function R(ac,ad){var Z=P(O[h],O[W]),aa=Z!=O[h],ae,ab,Y,t,X;if(Z==ac){return M(Z,aa,E,ad)}ae=Z.parentNode;ab=M(ae,S,E,ad);while(ae){while(Z){Y=Z.nextSibling;t=M(Z,aa,E,ad);if(ad!=j){ab.appendChild(t)}aa=E;Z=Y}if(ae==ac){return ab}Z=ae.nextSibling;ae=ae.parentNode;X=M(ae,S,E,ad);if(ad!=j){X.appendChild(ab)}ab=X}}function M(t,aa,ad,ae){var Z,Y,ab,X,ac;if(aa){return z(t,ae)}if(t.nodeType==3){Z=t.nodeValue;if(ad){X=O[W];Y=Z.substring(X);ab=Z.substring(0,X)}else{X=O[A];Y=Z.substring(0,X);ab=Z.substring(X)}if(ae!=F){t.nodeValue=ab}if(ae==j){return}ac=c.clone(t,S);ac.nodeValue=Y;return ac}if(ae==j){return}return c.clone(t,S)}function z(X,t){if(t!=j){return t==F?c.clone(X,E):X}X.parentNode.removeChild(X)}function T(){return c.create("body",null,d()).outerText}return O}a.Range=b;b.prototype.toString=function(){return this.toStringIE()}})(tinymce.dom);(function(){function a(d){var b=this,h=d.dom,c=true,f=false;function e(i,j){var k,t=0,q,n,m,l,o,r,p=-1,s;k=i.duplicate();k.collapse(j);s=k.parentElement();if(s.ownerDocument!==d.dom.doc){return}while(s.contentEditable==="false"){s=s.parentNode}if(!s.hasChildNodes()){return{node:s,inside:1}}m=s.children;q=m.length-1;while(t<=q){r=Math.floor((t+q)/2);l=m[r];k.moveToElementText(l);p=k.compareEndPoints(j?"StartToStart":"EndToEnd",i);if(p>0){q=r-1}else{if(p<0){t=r+1}else{return{node:l}}}}if(p<0){if(!l){k.moveToElementText(s);k.collapse(true);l=s;n=true}else{k.collapse(false)}o=0;while(k.compareEndPoints(j?"StartToStart":"StartToEnd",i)!==0){if(k.move("character",1)===0||s!=k.parentElement()){break}o++}}else{k.collapse(true);o=0;while(k.compareEndPoints(j?"StartToStart":"StartToEnd",i)!==0){if(k.move("character",-1)===0||s!=k.parentElement()){break}o++}}return{node:l,position:p,offset:o,inside:n}}function g(){var i=d.getRng(),r=h.createRng(),l,k,p,q,m,j;l=i.item?i.item(0):i.parentElement();if(l.ownerDocument!=h.doc){return r}k=d.isCollapsed();if(i.item){r.setStart(l.parentNode,h.nodeIndex(l));r.setEnd(r.startContainer,r.startOffset+1);return r}function o(A){var u=e(i,A),s,y,z=0,x,v,t;s=u.node;y=u.offset;if(u.inside&&!s.hasChildNodes()){r[A?"setStart":"setEnd"](s,0);return}if(y===v){r[A?"setStartBefore":"setEndAfter"](s);return}if(u.position<0){x=u.inside?s.firstChild:s.nextSibling;if(!x){r[A?"setStartAfter":"setEndAfter"](s);return}if(!y){if(x.nodeType==3){r[A?"setStart":"setEnd"](x,0)}else{r[A?"setStartBefore":"setEndBefore"](x)}return}while(x){t=x.nodeValue;z+=t.length;if(z>=y){s=x;z-=y;z=t.length-z;break}x=x.nextSibling}}else{x=s.previousSibling;if(!x){return r[A?"setStartBefore":"setEndBefore"](s)}if(!y){if(s.nodeType==3){r[A?"setStart":"setEnd"](x,s.nodeValue.length)}else{r[A?"setStartAfter":"setEndAfter"](x)}return}while(x){z+=x.nodeValue.length;if(z>=y){s=x;z-=y;break}x=x.previousSibling}}r[A?"setStart":"setEnd"](s,z)}try{o(true);if(!k){o()}}catch(n){if(n.number==-2147024809){m=b.getBookmark(2);p=i.duplicate();p.collapse(true);l=p.parentElement();if(!k){p=i.duplicate();p.collapse(false);q=p.parentElement();q.innerHTML=q.innerHTML}l.innerHTML=l.innerHTML;b.moveToBookmark(m);i=d.getRng();o(true);if(!k){o()}}else{throw n}}return r}this.getBookmark=function(m){var j=d.getRng(),o,i,l={};function n(u){var t,p,s,r,q=[];t=u.parentNode;p=h.getRoot().parentNode;while(t!=p&&t.nodeType!==9){s=t.children;r=s.length;while(r--){if(u===s[r]){q.push(r);break}}u=t;t=t.parentNode}return q}function k(q){var p;p=e(j,q);if(p){return{position:p.position,offset:p.offset,indexes:n(p.node),inside:p.inside}}}if(m===2){if(!j.item){l.start=k(true);if(!d.isCollapsed()){l.end=k()}}else{l.start={ctrl:true,indexes:n(j.item(0))}}}return l};this.moveToBookmark=function(k){var j,i=h.doc.body;function m(o){var r,q,n,p;r=h.getRoot();for(q=o.length-1;q>=0;q--){p=r.children;n=o[q];if(n<=p.length-1){r=p[n]}}return r}function l(r){var n=k[r?"start":"end"],q,p,o;if(n){q=n.position>0;p=i.createTextRange();p.moveToElementText(m(n.indexes));offset=n.offset;if(offset!==o){p.collapse(n.inside||q);p.moveStart("character",q?-offset:offset)}else{p.collapse(r)}j.setEndPoint(r?"StartToStart":"EndToStart",p);if(r){j.collapse(true)}}}if(k.start){if(k.start.ctrl){j=i.createControlRange();j.addElement(m(k.start.indexes));j.select()}else{j=i.createTextRange();l(true);l();j.select()}}};this.addRange=function(i){var n,l,k,p,v,q,t,s=d.dom.doc,m=s.body,r,u;function j(C){var y,B,x,A,z;x=h.create("a");y=C?k:v;B=C?p:q;A=n.duplicate();if(y==s||y==s.documentElement){y=m;B=0}if(y.nodeType==3){y.parentNode.insertBefore(x,y);A.moveToElementText(x);A.moveStart("character",B);h.remove(x);n.setEndPoint(C?"StartToStart":"EndToEnd",A)}else{z=y.childNodes;if(z.length){if(B>=z.length){h.insertAfter(x,z[z.length-1])}else{y.insertBefore(x,z[B])}A.moveToElementText(x)}else{if(y.canHaveHTML){y.innerHTML="<span>\uFEFF</span>";x=y.firstChild;A.moveToElementText(x);A.collapse(f)}}n.setEndPoint(C?"StartToStart":"EndToEnd",A);h.remove(x)}}k=i.startContainer;p=i.startOffset;v=i.endContainer;q=i.endOffset;n=m.createTextRange();if(k==v&&k.nodeType==1){if(p==q&&!k.hasChildNodes()){if(k.canHaveHTML){t=k.previousSibling;if(t&&!t.hasChildNodes()&&h.isBlock(t)){t.innerHTML="\uFEFF"}else{t=null}k.innerHTML="<span>\uFEFF</span><span>\uFEFF</span>";n.moveToElementText(k.lastChild);n.select();h.doc.selection.clear();k.innerHTML="";if(t){t.innerHTML=""}return}else{p=h.nodeIndex(k);k=k.parentNode}}if(p==q-1){try{u=k.childNodes[p];l=m.createControlRange();l.addElement(u);l.select();r=d.getRng();if(r.item&&u===r.item(0)){return}}catch(o){}}}j(true);j();n.select()};this.getRangeAt=g}tinymce.dom.TridentSelection=a})();(function(a){a.dom.Element=function(f,d){var b=this,e,c;b.settings=d=d||{};b.id=f;b.dom=e=d.dom||a.DOM;if(!a.isIE){c=e.get(b.id)}a.each(("getPos,getRect,getParent,add,setStyle,getStyle,setStyles,setAttrib,setAttribs,getAttrib,addClass,removeClass,hasClass,getOuterHTML,setOuterHTML,remove,show,hide,isHidden,setHTML,get").split(/,/),function(g){b[g]=function(){var h=[f],j;for(j=0;j<arguments.length;j++){h.push(arguments[j])}h=e[g].apply(e,h);b.update(g);return h}});a.extend(b,{on:function(i,h,g){return a.dom.Event.add(b.id,i,h,g)},getXY:function(){return{x:parseInt(b.getStyle("left")),y:parseInt(b.getStyle("top"))}},getSize:function(){var g=e.get(b.id);return{w:parseInt(b.getStyle("width")||g.clientWidth),h:parseInt(b.getStyle("height")||g.clientHeight)}},moveTo:function(g,h){b.setStyles({left:g,top:h})},moveBy:function(g,i){var h=b.getXY();b.moveTo(h.x+g,h.y+i)},resizeTo:function(g,i){b.setStyles({width:g,height:i})},resizeBy:function(g,j){var i=b.getSize();b.resizeTo(i.w+g,i.h+j)},update:function(h){var g;if(a.isIE6&&d.blocker){h=h||"";if(h.indexOf("get")===0||h.indexOf("has")===0||h.indexOf("is")===0){return}if(h=="remove"){e.remove(b.blocker);return}if(!b.blocker){b.blocker=e.uniqueId();g=e.add(d.container||e.getRoot(),"iframe",{id:b.blocker,style:"position:absolute;",frameBorder:0,src:'javascript:""'});e.setStyle(g,"opacity",0)}else{g=e.get(b.blocker)}e.setStyles(g,{left:b.getStyle("left",1),top:b.getStyle("top",1),width:b.getStyle("width",1),height:b.getStyle("height",1),display:b.getStyle("display",1),zIndex:parseInt(b.getStyle("zIndex",1)||0)-1})}}})}})(tinymce);(function(d){function f(g){return g.replace(/[\n\r]+/g,"")}var c=d.is,b=d.isIE,e=d.each,a=d.dom.TreeWalker;d.create("tinymce.dom.Selection",{Selection:function(k,j,i,h){var g=this;g.dom=k;g.win=j;g.serializer=i;g.editor=h;e(["onBeforeSetContent","onBeforeGetContent","onSetContent","onGetContent"],function(l){g[l]=new d.util.Dispatcher(g)});if(!g.win.getSelection){g.tridentSel=new d.dom.TridentSelection(g)}if(d.isIE&&k.boxModel){this._fixIESelection()}d.addUnload(g.destroy,g)},setCursorLocation:function(i,j){var g=this;var h=g.dom.createRng();h.setStart(i,j);h.setEnd(i,j);g.setRng(h);g.collapse(false)},getContent:function(h){var g=this,i=g.getRng(),m=g.dom.create("body"),k=g.getSel(),j,l,o;h=h||{};j=l="";h.get=true;h.format=h.format||"html";h.forced_root_block="";g.onBeforeGetContent.dispatch(g,h);if(h.format=="text"){return g.isCollapsed()?"":(i.text||(k.toString?k.toString():""))}if(i.cloneContents){o=i.cloneContents();if(o){m.appendChild(o)}}else{if(c(i.item)||c(i.htmlText)){m.innerHTML="<br>"+(i.item?i.item(0).outerHTML:i.htmlText);m.removeChild(m.firstChild)}else{m.innerHTML=i.toString()}}if(/^\s/.test(m.innerHTML)){j=" "}if(/\s+$/.test(m.innerHTML)){l=" "}h.getInner=true;h.content=g.isCollapsed()?"":j+g.serializer.serialize(m,h)+l;g.onGetContent.dispatch(g,h);return h.content},setContent:function(h,j){var o=this,g=o.getRng(),k,l=o.win.document,n,m;j=j||{format:"html"};j.set=true;h=j.content=h;if(!j.no_events){o.onBeforeSetContent.dispatch(o,j)}h=j.content;if(g.insertNode){h+='<span id="__caret">_</span>';if(g.startContainer==l&&g.endContainer==l){l.body.innerHTML=h}else{g.deleteContents();if(l.body.childNodes.length===0){l.body.innerHTML=h}else{if(g.createContextualFragment){g.insertNode(g.createContextualFragment(h))}else{n=l.createDocumentFragment();m=l.createElement("div");n.appendChild(m);m.outerHTML=h;g.insertNode(n)}}}k=o.dom.get("__caret");g=l.createRange();g.setStartBefore(k);g.setEndBefore(k);o.setRng(g);o.dom.remove("__caret");try{o.setRng(g)}catch(i){}}else{if(g.item){l.execCommand("Delete",false,null);g=o.getRng()}if(/^\s+/.test(h)){g.pasteHTML('<span id="__mce_tmp">_</span>'+h);o.dom.remove("__mce_tmp")}else{g.pasteHTML(h)}}if(!j.no_events){o.onSetContent.dispatch(o,j)}},getStart:function(){var i=this,h=i.getRng(),j,g,l,k;if(h.duplicate||h.item){if(h.item){return h.item(0)}l=h.duplicate();l.collapse(1);j=l.parentElement();if(j.ownerDocument!==i.dom.doc){j=i.dom.getRoot()}g=k=h.parentElement();while(k=k.parentNode){if(k==j){j=g;break}}return j}else{j=h.startContainer;if(j.nodeType==1&&j.hasChildNodes()){j=j.childNodes[Math.min(j.childNodes.length-1,h.startOffset)]}if(j&&j.nodeType==3){return j.parentNode}return j}},getEnd:function(){var h=this,g=h.getRng(),j,i;if(g.duplicate||g.item){if(g.item){return g.item(0)}g=g.duplicate();g.collapse(0);j=g.parentElement();if(j.ownerDocument!==h.dom.doc){j=h.dom.getRoot()}if(j&&j.nodeName=="BODY"){return j.lastChild||j}return j}else{j=g.endContainer;i=g.endOffset;if(j.nodeType==1&&j.hasChildNodes()){j=j.childNodes[i>0?i-1:i]}if(j&&j.nodeType==3){return j.parentNode}return j}},getBookmark:function(s,v){var y=this,n=y.dom,h,k,j,o,i,p,q,m="\uFEFF",x;function g(z,A){var t=0;e(n.select(z),function(C,B){if(C==A){t=B}});return t}function u(t){function z(E){var A,D,C,B=E?"start":"end";A=t[B+"Container"];D=t[B+"Offset"];if(A.nodeType==1&&A.nodeName=="TR"){C=A.childNodes;A=C[Math.min(E?D:D-1,C.length-1)];if(A){D=E?0:A.childNodes.length;t["set"+(E?"Start":"End")](A,D)}}}z(true);z();return t}function l(){var z=y.getRng(true),t=n.getRoot(),A={};function B(E,J){var D=E[J?"startContainer":"endContainer"],I=E[J?"startOffset":"endOffset"],C=[],F,H,G=0;if(D.nodeType==3){if(v){for(F=D.previousSibling;F&&F.nodeType==3;F=F.previousSibling){I+=F.nodeValue.length}}C.push(I)}else{H=D.childNodes;if(I>=H.length&&H.length){G=1;I=Math.max(0,H.length-1)}C.push(y.dom.nodeIndex(H[I],v)+G)}for(;D&&D!=t;D=D.parentNode){C.push(y.dom.nodeIndex(D,v))}return C}A.start=B(z,true);if(!y.isCollapsed()){A.end=B(z)}return A}if(s==2){if(y.tridentSel){return y.tridentSel.getBookmark(s)}return l()}if(s){return{rng:y.getRng()}}h=y.getRng();j=n.uniqueId();o=tinyMCE.activeEditor.selection.isCollapsed();x="overflow:hidden;line-height:0px";if(h.duplicate||h.item){if(!h.item){k=h.duplicate();try{h.collapse();h.pasteHTML('<span data-mce-type="bookmark" id="'+j+'_start" style="'+x+'">'+m+"</span>");if(!o){k.collapse(false);h.moveToElementText(k.parentElement());if(h.compareEndPoints("StartToEnd",k)===0){k.move("character",-1)}k.pasteHTML('<span data-mce-type="bookmark" id="'+j+'_end" style="'+x+'">'+m+"</span>")}}catch(r){return null}}else{p=h.item(0);i=p.nodeName;return{name:i,index:g(i,p)}}}else{p=y.getNode();i=p.nodeName;if(i=="IMG"){return{name:i,index:g(i,p)}}k=u(h.cloneRange());if(!o){k.collapse(false);k.insertNode(n.create("span",{"data-mce-type":"bookmark",id:j+"_end",style:x},m))}h=u(h);h.collapse(true);h.insertNode(n.create("span",{"data-mce-type":"bookmark",id:j+"_start",style:x},m))}y.moveToBookmark({id:j,keep:1});return{id:j}},moveToBookmark:function(o){var s=this,m=s.dom,j,i,g,r,k,u,p,q;function h(A){var t=o[A?"start":"end"],x,y,z,v;if(t){z=t[0];for(y=r,x=t.length-1;x>=1;x--){v=y.childNodes;if(t[x]>v.length-1){return}y=v[t[x]]}if(y.nodeType===3){z=Math.min(t[0],y.nodeValue.length)}if(y.nodeType===1){z=Math.min(t[0],y.childNodes.length)}if(A){g.setStart(y,z)}else{g.setEnd(y,z)}}return true}function l(B){var v=m.get(o.id+"_"+B),A,t,y,z,x=o.keep;if(v){A=v.parentNode;if(B=="start"){if(!x){t=m.nodeIndex(v)}else{A=v.firstChild;t=1}k=u=A;p=q=t}else{if(!x){t=m.nodeIndex(v)}else{A=v.firstChild;t=1}u=A;q=t}if(!x){z=v.previousSibling;y=v.nextSibling;e(d.grep(v.childNodes),function(C){if(C.nodeType==3){C.nodeValue=C.nodeValue.replace(/\uFEFF/g,"")}});while(v=m.get(o.id+"_"+B)){m.remove(v,1)}if(z&&y&&z.nodeType==y.nodeType&&z.nodeType==3&&!d.isOpera){t=z.nodeValue.length;z.appendData(y.nodeValue);m.remove(y);if(B=="start"){k=u=z;p=q=t}else{u=z;q=t}}}}}function n(t){if(m.isBlock(t)&&!t.innerHTML&&!b){t.innerHTML='<br data-mce-bogus="1" />'}return t}if(o){if(o.start){g=m.createRng();r=m.getRoot();if(s.tridentSel){return s.tridentSel.moveToBookmark(o)}if(h(true)&&h()){s.setRng(g)}}else{if(o.id){l("start");l("end");if(k){g=m.createRng();g.setStart(n(k),p);g.setEnd(n(u),q);s.setRng(g)}}else{if(o.name){s.select(m.select(o.name)[o.index])}else{if(o.rng){s.setRng(o.rng)}}}}}},select:function(l,k){var j=this,m=j.dom,h=m.createRng(),g;function i(n,p){var o=new a(n,n);do{if(n.nodeType==3&&d.trim(n.nodeValue).length!==0){if(p){h.setStart(n,0)}else{h.setEnd(n,n.nodeValue.length)}return}if(n.nodeName=="BR"){if(p){h.setStartBefore(n)}else{h.setEndBefore(n)}return}}while(n=(p?o.next():o.prev()))}if(l){g=m.nodeIndex(l);h.setStart(l.parentNode,g);h.setEnd(l.parentNode,g+1);if(k){i(l,1);i(l)}j.setRng(h)}return l},isCollapsed:function(){var g=this,i=g.getRng(),h=g.getSel();if(!i||i.item){return false}if(i.compareEndPoints){return i.compareEndPoints("StartToEnd",i)===0}return !h||i.collapsed},collapse:function(g){var i=this,h=i.getRng(),j;if(h.item){j=h.item(0);h=i.win.document.body.createTextRange();h.moveToElementText(j)}h.collapse(!!g);i.setRng(h)},getSel:function(){var h=this,g=this.win;return g.getSelection?g.getSelection():g.document.selection},getRng:function(m){var h=this,j,g,l,k=h.win.document;if(m&&h.tridentSel){return h.tridentSel.getRangeAt(0)}try{if(j=h.getSel()){g=j.rangeCount>0?j.getRangeAt(0):(j.createRange?j.createRange():k.createRange())}}catch(i){}if(d.isIE&&g&&g.setStart&&k.selection.createRange().item){l=k.selection.createRange().item(0);g=k.createRange();g.setStartBefore(l);g.setEndAfter(l)}if(!g){g=k.createRange?k.createRange():k.body.createTextRange()}if(g.setStart&&g.startContainer.nodeType===9&&g.collapsed){l=h.dom.getRoot();g.setStart(l,0);g.setEnd(l,0)}if(h.selectedRange&&h.explicitRange){if(g.compareBoundaryPoints(g.START_TO_START,h.selectedRange)===0&&g.compareBoundaryPoints(g.END_TO_END,h.selectedRange)===0){g=h.explicitRange}else{h.selectedRange=null;h.explicitRange=null}}return g},setRng:function(k,g){var j,i=this;if(!i.tridentSel){j=i.getSel();if(j){i.explicitRange=k;try{j.removeAllRanges()}catch(h){}j.addRange(k);if(g===false&&j.extend){j.collapse(k.endContainer,k.endOffset);j.extend(k.startContainer,k.startOffset)}i.selectedRange=j.rangeCount>0?j.getRangeAt(0):null}}else{if(k.cloneRange){try{i.tridentSel.addRange(k);return}catch(h){}}try{k.select()}catch(h){}}},setNode:function(h){var g=this;g.setContent(g.dom.getOuterHTML(h));return h},getNode:function(){var i=this,h=i.getRng(),j=i.getSel(),m,l=h.startContainer,g=h.endContainer;function k(q,o){var p=q;while(q&&q.nodeType===3&&q.length===0){q=o?q.nextSibling:q.previousSibling}return q||p}if(!h){return i.dom.getRoot()}if(h.setStart){m=h.commonAncestorContainer;if(!h.collapsed){if(h.startContainer==h.endContainer){if(h.endOffset-h.startOffset<2){if(h.startContainer.hasChildNodes()){m=h.startContainer.childNodes[h.startOffset]}}}if(l.nodeType===3&&g.nodeType===3){if(l.length===h.startOffset){l=k(l.nextSibling,true)}else{l=l.parentNode}if(h.endOffset===0){g=k(g.previousSibling,false)}else{g=g.parentNode}if(l&&l===g){return l}}}if(m&&m.nodeType==3){return m.parentNode}return m}return h.item?h.item(0):h.parentElement()},getSelectedBlocks:function(p,h){var o=this,k=o.dom,m,l,i,j=[];m=k.getParent(p||o.getStart(),k.isBlock);l=k.getParent(h||o.getEnd(),k.isBlock);if(m){j.push(m)}if(m&&l&&m!=l){i=m;var g=new a(m,k.getRoot());while((i=g.next())&&i!=l){if(k.isBlock(i)){j.push(i)}}}if(l&&m!=l){j.push(l)}return j},isForward:function(){var i=this.dom,g=this.getSel(),j,h;if(!g||g.anchorNode==null||g.focusNode==null){return true}j=i.createRng();j.setStart(g.anchorNode,g.anchorOffset);j.collapse(true);h=i.createRng();h.setStart(g.focusNode,g.focusOffset);h.collapse(true);return j.compareBoundaryPoints(j.START_TO_START,h)<=0},normalize:function(){var h=this,g,m,l,j,i;function k(p){var o,r,n,s=h.dom,u=s.getRoot(),q,t,v;function y(z,A){var B=new a(z,s.getParent(z.parentNode,s.isBlock)||u);while(z=B[A?"prev":"next"]()){if(z.nodeName==="BR"){return true}}}function x(B,z){var C,A;z=z||o;C=new a(z,s.getParent(z.parentNode,s.isBlock)||u);while(q=C[B?"prev":"next"]()){if(q.nodeType===3&&q.nodeValue.length>0){o=q;r=B?q.nodeValue.length:0;m=true;return}if(s.isBlock(q)||t[q.nodeName.toLowerCase()]){return}A=q}if(l&&A){o=A;m=true;r=0}}o=g[(p?"start":"end")+"Container"];r=g[(p?"start":"end")+"Offset"];t=s.schema.getNonEmptyElements();if(o.nodeType===9){o=s.getRoot();r=0}if(o===u){if(p){q=o.childNodes[r>0?r-1:0];if(q){v=q.nodeName.toLowerCase();if(t[q.nodeName]||q.nodeName=="TABLE"){return}}}if(o.hasChildNodes()){o=o.childNodes[Math.min(!p&&r>0?r-1:r,o.childNodes.length-1)];r=0;if(o.hasChildNodes()&&!/TABLE/.test(o.nodeName)){q=o;n=new a(o,u);do{if(q.nodeType===3&&q.nodeValue.length>0){r=p?0:q.nodeValue.length;o=q;m=true;break}if(t[q.nodeName.toLowerCase()]){r=s.nodeIndex(q);o=q.parentNode;if(q.nodeName=="IMG"&&!p){r++}m=true;break}}while(q=(p?n.next():n.prev()))}}}if(l){if(o.nodeType===3&&r===0){x(true)}if(o.nodeType===1){q=o.childNodes[r];if(q&&q.nodeName==="BR"&&!y(q)&&!y(q,true)){x(true,o.childNodes[r])}}}if(p&&!l&&o.nodeType===3&&r===o.nodeValue.length){x(false)}if(m){g["set"+(p?"Start":"End")](o,r)}}if(d.isIE){return}g=h.getRng();l=g.collapsed;k(true);if(!l){k()}if(m){if(l){g.collapse(true)}h.setRng(g,h.isForward())}},selectorChanged:function(g,j){var h=this,i;if(!h.selectorChangedData){h.selectorChangedData={};i={};h.editor.onNodeChange.addToTop(function(l,k,o){var p=h.dom,m=p.getParents(o,null,p.getRoot()),n={};e(h.selectorChangedData,function(r,q){e(m,function(s){if(p.is(s,q)){if(!i[q]){e(r,function(t){t(true,{node:s,selector:q,parents:m})});i[q]=r}n[q]=r;return false}})});e(i,function(r,q){if(!n[q]){delete i[q];e(r,function(s){s(false,{node:o,selector:q,parents:m})})}})})}if(!h.selectorChangedData[g]){h.selectorChangedData[g]=[]}h.selectorChangedData[g].push(j);return h},scrollIntoView:function(k){var j,h,g=this,i=g.dom;h=i.getViewPort(g.editor.getWin());j=i.getPos(k).y;if(j<h.y||j+25>h.y+h.h){g.editor.getWin().scrollTo(0,j<h.y?j:j-h.h+25)}},destroy:function(h){var g=this;g.win=null;if(!h){d.removeUnload(g.destroy)}},_fixIESelection:function(){var h=this.dom,n=h.doc,i=n.body,k,o,g;function j(p,s){var q=i.createTextRange();try{q.moveToPoint(p,s)}catch(r){q=null}return q}function m(q){var p;if(q.button){p=j(q.x,q.y);if(p){if(p.compareEndPoints("StartToStart",o)>0){p.setEndPoint("StartToStart",o)}else{p.setEndPoint("EndToEnd",o)}p.select()}}else{l()}}function l(){var p=n.selection.createRange();if(o&&!p.item&&p.compareEndPoints("StartToEnd",p)===0){o.select()}h.unbind(n,"mouseup",l);h.unbind(n,"mousemove",m);o=k=0}n.documentElement.unselectable=true;h.bind(n,["mousedown","contextmenu"],function(p){if(p.target.nodeName==="HTML"){if(k){l()}g=n.documentElement;if(g.scrollHeight>g.clientHeight){return}k=1;o=j(p.x,p.y);if(o){h.bind(n,"mouseup",l);h.bind(n,"mousemove",m);h.win.focus();o.select()}}})}})})(tinymce);(function(a){a.dom.Serializer=function(e,i,f){var h,b,d=a.isIE,g=a.each,c;if(!e.apply_source_formatting){e.indent=false}i=i||a.DOM;f=f||new a.html.Schema(e);e.entity_encoding=e.entity_encoding||"named";e.remove_trailing_brs="remove_trailing_brs" in e?e.remove_trailing_brs:true;h=new a.util.Dispatcher(self);b=new a.util.Dispatcher(self);c=new a.html.DomParser(e,f);c.addAttributeFilter("src,href,style",function(k,j){var o=k.length,l,q,n="data-mce-"+j,p=e.url_converter,r=e.url_converter_scope,m;while(o--){l=k[o];q=l.attributes.map[n];if(q!==m){l.attr(j,q.length>0?q:null);l.attr(n,null)}else{q=l.attributes.map[j];if(j==="style"){q=i.serializeStyle(i.parseStyle(q),l.name)}else{if(p){q=p.call(r,q,j,l.name)}}l.attr(j,q.length>0?q:null)}}});c.addAttributeFilter("class",function(j,k){var l=j.length,m,n;while(l--){m=j[l];n=m.attr("class").replace(/(?:^|\s)mce(Item\w+|Selected)(?!\S)/g,"");m.attr("class",n.length>0?n:null)}});c.addAttributeFilter("data-mce-type",function(j,l,k){var m=j.length,n;while(m--){n=j[m];if(n.attributes.map["data-mce-type"]==="bookmark"&&!k.cleanup){n.remove()}}});c.addAttributeFilter("data-mce-expando",function(j,l,k){var m=j.length;while(m--){j[m].attr(l,null)}});c.addNodeFilter("noscript",function(j){var k=j.length,l;while(k--){l=j[k].firstChild;if(l){l.value=a.html.Entities.decode(l.value)}}});c.addNodeFilter("script,style",function(k,l){var m=k.length,n,o;function j(p){return p.replace(/(<!--\[CDATA\[|\]\]-->)/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*((<!--)?(\s*\/\/)?\s*<!\[CDATA\[|(<!--\s*)?\/\*\s*<!\[CDATA\[\s*\*\/|(\/\/)?\s*<!--|\/\*\s*<!--\s*\*\/)\s*[\r\n]*/gi,"").replace(/\s*(\/\*\s*\]\]>\s*\*\/(-->)?|\s*\/\/\s*\]\]>(-->)?|\/\/\s*(-->)?|\]\]>|\/\*\s*-->\s*\*\/|\s*-->\s*)\s*$/g,"")}while(m--){n=k[m];o=n.firstChild?n.firstChild.value:"";if(l==="script"){n.attr("type",(n.attr("type")||"text/javascript").replace(/^mce\-/,""));if(o.length>0){n.firstChild.value="// <![CDATA[\n"+j(o)+"\n// ]]>"}}else{if(o.length>0){n.firstChild.value="<!--\n"+j(o)+"\n-->"}}}});c.addNodeFilter("#comment",function(j,k){var l=j.length,m;while(l--){m=j[l];if(m.value.indexOf("[CDATA[")===0){m.name="#cdata";m.type=4;m.value=m.value.replace(/^\[CDATA\[|\]\]$/g,"")}else{if(m.value.indexOf("mce:protected ")===0){m.name="#text";m.type=3;m.raw=true;m.value=unescape(m.value).substr(14)}}}});c.addNodeFilter("xml:namespace,input",function(j,k){var l=j.length,m;while(l--){m=j[l];if(m.type===7){m.remove()}else{if(m.type===1){if(k==="input"&&!("type" in m.attributes.map)){m.attr("type","text")}}}}});if(e.fix_list_elements){c.addNodeFilter("ul,ol",function(k,l){var m=k.length,n,j;while(m--){n=k[m];j=n.parent;if(j.name==="ul"||j.name==="ol"){if(n.prev&&n.prev.name==="li"){n.prev.append(n)}}}})}c.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style",function(j,k){var l=j.length;while(l--){j[l].attr(k,null)}});return{schema:f,addNodeFilter:c.addNodeFilter,addAttributeFilter:c.addAttributeFilter,onPreProcess:h,onPostProcess:b,serialize:function(o,m){var l,p,k,j,n;if(d&&i.select("script,style,select,map").length>0){n=o.innerHTML;o=o.cloneNode(false);i.setHTML(o,n)}else{o=o.cloneNode(true)}l=o.ownerDocument.implementation;if(l.createHTMLDocument){p=l.createHTMLDocument("");g(o.nodeName=="BODY"?o.childNodes:[o],function(q){p.body.appendChild(p.importNode(q,true))});if(o.nodeName!="BODY"){o=p.body.firstChild}else{o=p.body}k=i.doc;i.doc=p}m=m||{};m.format=m.format||"html";if(!m.no_events){m.node=o;h.dispatch(self,m)}j=new a.html.Serializer(e,f);m.content=j.serialize(c.parse(a.trim(m.getInner?o.innerHTML:i.getOuterHTML(o)),m));if(!m.cleanup){m.content=m.content.replace(/\uFEFF/g,"")}if(!m.no_events){b.dispatch(self,m)}if(k){i.doc=k}m.node=null;return m.content},addRules:function(j){f.addValidElements(j)},setRules:function(j){f.setValidElements(j)}}}})(tinymce);(function(a){a.dom.ScriptLoader=function(h){var c=0,k=1,i=2,l={},j=[],e={},d=[],g=0,f;function b(m,v){var x=this,q=a.DOM,s,o,r,n;function p(){q.remove(n);if(s){s.onreadystatechange=s.onload=s=null}v()}function u(){if(typeof(console)!=="undefined"&&console.log){console.log("Failed to load: "+m)}}n=q.uniqueId();if(a.isIE6){o=new a.util.URI(m);r=location;if(o.host==r.hostname&&o.port==r.port&&(o.protocol+":")==r.protocol&&o.protocol.toLowerCase()!="file"){a.util.XHR.send({url:a._addVer(o.getURI()),success:function(y){var t=q.create("script",{type:"text/javascript"});t.text=y;document.getElementsByTagName("head")[0].appendChild(t);q.remove(t);p()},error:u});return}}s=document.createElement("script");s.id=n;s.type="text/javascript";s.src=a._addVer(m);if(!a.isIE){s.onload=p}s.onerror=u;if(!a.isOpera){s.onreadystatechange=function(){var t=s.readyState;if(t=="complete"||t=="loaded"){p()}}}(document.getElementsByTagName("head")[0]||document.body).appendChild(s)}this.isDone=function(m){return l[m]==i};this.markDone=function(m){l[m]=i};this.add=this.load=function(m,q,n){var o,p=l[m];if(p==f){j.push(m);l[m]=c}if(q){if(!e[m]){e[m]=[]}e[m].push({func:q,scope:n||this})}};this.loadQueue=function(n,m){this.loadScripts(j,n,m)};this.loadScripts=function(m,q,p){var o;function n(r){a.each(e[r],function(s){s.func.call(s.scope)});e[r]=f}d.push({func:q,scope:p||this});o=function(){var r=a.grep(m);m.length=0;a.each(r,function(s){if(l[s]==i){n(s);return}if(l[s]!=k){l[s]=k;g++;b(s,function(){l[s]=i;g--;n(s);o()})}});if(!g){a.each(d,function(s){s.func.call(s.scope)});d.length=0}};o()}};a.ScriptLoader=new a.dom.ScriptLoader()})(tinymce);(function(a){a.dom.RangeUtils=function(c){var b="\uFEFF";this.walk=function(d,s){var i=d.startContainer,l=d.startOffset,t=d.endContainer,m=d.endOffset,j,g,o,h,r,q,e;e=c.select("td.mceSelected,th.mceSelected");if(e.length>0){a.each(e,function(u){s([u])});return}function f(u){var v;v=u[0];if(v.nodeType===3&&v===i&&l>=v.nodeValue.length){u.splice(0,1)}v=u[u.length-1];if(m===0&&u.length>0&&v===t&&v.nodeType===3){u.splice(u.length-1,1)}return u}function p(x,v,u){var y=[];for(;x&&x!=u;x=x[v]){y.push(x)}return y}function n(v,u){do{if(v.parentNode==u){return v}v=v.parentNode}while(v)}function k(x,v,y){var u=y?"nextSibling":"previousSibling";for(h=x,r=h.parentNode;h&&h!=v;h=r){r=h.parentNode;q=p(h==x?h:h[u],u);if(q.length){if(!y){q.reverse()}s(f(q))}}}if(i.nodeType==1&&i.hasChildNodes()){i=i.childNodes[l]}if(t.nodeType==1&&t.hasChildNodes()){t=t.childNodes[Math.min(m-1,t.childNodes.length-1)]}if(i==t){return s(f([i]))}j=c.findCommonAncestor(i,t);for(h=i;h;h=h.parentNode){if(h===t){return k(i,j,true)}if(h===j){break}}for(h=t;h;h=h.parentNode){if(h===i){return k(t,j)}if(h===j){break}}g=n(i,j)||i;o=n(t,j)||t;k(i,g,true);q=p(g==i?g:g.nextSibling,"nextSibling",o==t?o.nextSibling:o);if(q.length){s(f(q))}k(t,o)};this.split=function(e){var h=e.startContainer,d=e.startOffset,i=e.endContainer,g=e.endOffset;function f(j,k){return j.splitText(k)}if(h==i&&h.nodeType==3){if(d>0&&d<h.nodeValue.length){i=f(h,d);h=i.previousSibling;if(g>d){g=g-d;h=i=f(i,g).previousSibling;g=i.nodeValue.length;d=0}else{g=0}}}else{if(h.nodeType==3&&d>0&&d<h.nodeValue.length){h=f(h,d);d=0}if(i.nodeType==3&&g>0&&g<i.nodeValue.length){i=f(i,g).previousSibling;g=i.nodeValue.length}}return{startContainer:h,startOffset:d,endContainer:i,endOffset:g}}};a.dom.RangeUtils.compareRanges=function(c,b){if(c&&b){if(c.item||c.duplicate){if(c.item&&b.item&&c.item(0)===b.item(0)){return true}if(c.isEqual&&b.isEqual&&b.isEqual(c)){return true}}else{return c.startContainer==b.startContainer&&c.startOffset==b.startOffset}}return false}})(tinymce);(function(b){var a=b.dom.Event,c=b.each;b.create("tinymce.ui.KeyboardNavigation",{KeyboardNavigation:function(e,f){var q=this,n=e.root,m=e.items,o=e.enableUpDown,i=e.enableLeftRight||!e.enableUpDown,l=e.excludeFromTabOrder,k,h,p,d,g;f=f||b.DOM;k=function(r){g=r.target.id};h=function(r){f.setAttrib(r.target.id,"tabindex","-1")};d=function(r){var s=f.get(g);f.setAttrib(s,"tabindex","0");s.focus()};q.focus=function(){f.get(g).focus()};q.destroy=function(){c(m,function(s){var t=f.get(s.id);f.unbind(t,"focus",k);f.unbind(t,"blur",h)});var r=f.get(n);f.unbind(r,"focus",d);f.unbind(r,"keydown",p);m=f=n=q.focus=k=h=p=d=null;q.destroy=function(){}};q.moveFocus=function(v,s){var r=-1,u=q.controls,t;if(!g){return}c(m,function(y,x){if(y.id===g){r=x;return false}});r+=v;if(r<0){r=m.length-1}else{if(r>=m.length){r=0}}t=m[r];f.setAttrib(g,"tabindex","-1");f.setAttrib(t.id,"tabindex","0");f.get(t.id).focus();if(e.actOnFocus){e.onAction(t.id)}if(s){a.cancel(s)}};p=function(z){var v=37,u=39,y=38,A=40,r=27,t=14,s=13,x=32;switch(z.keyCode){case v:if(i){q.moveFocus(-1)}break;case u:if(i){q.moveFocus(1)}break;case y:if(o){q.moveFocus(-1)}break;case A:if(o){q.moveFocus(1)}break;case r:if(e.onCancel){e.onCancel();a.cancel(z)}break;case t:case s:case x:if(e.onAction){e.onAction(g);a.cancel(z)}break}};c(m,function(t,r){var s,u;if(!t.id){t.id=f.uniqueId("_mce_item_")}u=f.get(t.id);if(l){f.bind(u,"blur",h);s="-1"}else{s=(r===0?"0":"-1")}u.setAttribute("tabindex",s);f.bind(u,"focus",k)});if(m[0]){g=m[0].id}f.setAttrib(n,"tabindex","-1");var j=f.get(n);f.bind(j,"focus",d);f.bind(j,"keydown",p)}})})(tinymce);(function(c){var b=c.DOM,a=c.is;c.create("tinymce.ui.Control",{Control:function(f,e,d){this.id=f;this.settings=e=e||{};this.rendered=false;this.onRender=new c.util.Dispatcher(this);this.classPrefix="";this.scope=e.scope||this;this.disabled=0;this.active=0;this.editor=d},setAriaProperty:function(f,e){var d=b.get(this.id+"_aria")||b.get(this.id);if(d){b.setAttrib(d,"aria-"+f,!!e)}},focus:function(){b.get(this.id).focus()},setDisabled:function(d){if(d!=this.disabled){this.setAriaProperty("disabled",d);this.setState("Disabled",d);this.setState("Enabled",!d);this.disabled=d}},isDisabled:function(){return this.disabled},setActive:function(d){if(d!=this.active){this.setState("Active",d);this.active=d;this.setAriaProperty("pressed",d)}},isActive:function(){return this.active},setState:function(f,d){var e=b.get(this.id);f=this.classPrefix+f;if(d){b.addClass(e,f)}else{b.removeClass(e,f)}},isRendered:function(){return this.rendered},renderHTML:function(){},renderTo:function(d){b.setHTML(d,this.renderHTML())},postRender:function(){var e=this,d;if(a(e.disabled)){d=e.disabled;e.disabled=-1;e.setDisabled(d)}if(a(e.active)){d=e.active;e.active=-1;e.setActive(d)}},remove:function(){b.remove(this.id);this.destroy()},destroy:function(){c.dom.Event.clear(this.id)}})})(tinymce);tinymce.create("tinymce.ui.Container:tinymce.ui.Control",{Container:function(c,b,a){this.parent(c,b,a);this.controls=[];this.lookup={}},add:function(a){this.lookup[a.id]=a;this.controls.push(a);return a},get:function(a){return this.lookup[a]}});tinymce.create("tinymce.ui.Separator:tinymce.ui.Control",{Separator:function(b,a){this.parent(b,a);this.classPrefix="mceSeparator";this.setDisabled(true)},renderHTML:function(){return tinymce.DOM.createHTML("span",{"class":this.classPrefix,role:"separator","aria-orientation":"vertical",tabindex:"-1"})}});(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create("tinymce.ui.MenuItem:tinymce.ui.Control",{MenuItem:function(g,f){this.parent(g,f);this.classPrefix="mceMenuItem"},setSelected:function(f){this.setState("Selected",f);this.setAriaProperty("checked",!!f);this.selected=f},isSelected:function(){return this.selected},postRender:function(){var f=this;f.parent();if(c(f.selected)){f.setSelected(f.selected)}}})})(tinymce);(function(d){var c=d.is,b=d.DOM,e=d.each,a=d.walk;d.create("tinymce.ui.Menu:tinymce.ui.MenuItem",{Menu:function(h,g){var f=this;f.parent(h,g);f.items={};f.collapsed=false;f.menuCount=0;f.onAddItem=new d.util.Dispatcher(this)},expand:function(g){var f=this;if(g){a(f,function(h){if(h.expand){h.expand()}},"items",f)}f.collapsed=false},collapse:function(g){var f=this;if(g){a(f,function(h){if(h.collapse){h.collapse()}},"items",f)}f.collapsed=true},isCollapsed:function(){return this.collapsed},add:function(f){if(!f.settings){f=new d.ui.MenuItem(f.id||b.uniqueId(),f)}this.onAddItem.dispatch(this,f);return this.items[f.id]=f},addSeparator:function(){return this.add({separator:true})},addMenu:function(f){if(!f.collapse){f=this.createMenu(f)}this.menuCount++;return this.add(f)},hasMenus:function(){return this.menuCount!==0},remove:function(f){delete this.items[f.id]},removeAll:function(){var f=this;a(f,function(g){if(g.removeAll){g.removeAll()}else{g.remove()}g.destroy()},"items",f);f.items={}},createMenu:function(g){var f=new d.ui.Menu(g.id||b.uniqueId(),g);f.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return f}})})(tinymce);(function(e){var d=e.is,c=e.DOM,f=e.each,a=e.dom.Event,b=e.dom.Element;e.create("tinymce.ui.DropMenu:tinymce.ui.Menu",{DropMenu:function(h,g){g=g||{};g.container=g.container||c.doc.body;g.offset_x=g.offset_x||0;g.offset_y=g.offset_y||0;g.vp_offset_x=g.vp_offset_x||0;g.vp_offset_y=g.vp_offset_y||0;if(d(g.icons)&&!g.icons){g["class"]+=" mceNoIcons"}this.parent(h,g);this.onShowMenu=new e.util.Dispatcher(this);this.onHideMenu=new e.util.Dispatcher(this);this.classPrefix="mceMenu"},createMenu:function(j){var h=this,i=h.settings,g;j.container=j.container||i.container;j.parent=h;j.constrain=j.constrain||i.constrain;j["class"]=j["class"]||i["class"];j.vp_offset_x=j.vp_offset_x||i.vp_offset_x;j.vp_offset_y=j.vp_offset_y||i.vp_offset_y;j.keyboard_focus=i.keyboard_focus;g=new e.ui.DropMenu(j.id||c.uniqueId(),j);g.onAddItem.add(h.onAddItem.dispatch,h.onAddItem);return g},focus:function(){var g=this;if(g.keyboardNav){g.keyboardNav.focus()}},update:function(){var i=this,j=i.settings,g=c.get("menu_"+i.id+"_tbl"),l=c.get("menu_"+i.id+"_co"),h,k;h=j.max_width?Math.min(g.offsetWidth,j.max_width):g.offsetWidth;k=j.max_height?Math.min(g.offsetHeight,j.max_height):g.offsetHeight;if(!c.boxModel){i.element.setStyles({width:h+2,height:k+2})}else{i.element.setStyles({width:h,height:k})}if(j.max_width){c.setStyle(l,"width",h)}if(j.max_height){c.setStyle(l,"height",k);if(g.clientHeight<j.max_height){c.setStyle(l,"overflow","hidden")}}},showMenu:function(p,n,r){var z=this,A=z.settings,o,g=c.getViewPort(),u,l,v,q,i=2,k,j,m=z.classPrefix;z.collapse(1);if(z.isMenuVisible){return}if(!z.rendered){o=c.add(z.settings.container,z.renderNode());f(z.items,function(h){h.postRender()});z.element=new b("menu_"+z.id,{blocker:1,container:A.container})}else{o=c.get("menu_"+z.id)}if(!e.isOpera){c.setStyles(o,{left:-65535,top:-65535})}c.show(o);z.update();p+=A.offset_x||0;n+=A.offset_y||0;g.w-=4;g.h-=4;if(A.constrain){u=o.clientWidth-i;l=o.clientHeight-i;v=g.x+g.w;q=g.y+g.h;if((p+A.vp_offset_x+u)>v){p=r?r-u:Math.max(0,(v-A.vp_offset_x)-u)}if((n+A.vp_offset_y+l)>q){n=Math.max(0,(q-A.vp_offset_y)-l)}}c.setStyles(o,{left:p,top:n});z.element.update();z.isMenuVisible=1;z.mouseClickFunc=a.add(o,"click",function(s){var h;s=s.target;if(s&&(s=c.getParent(s,"tr"))&&!c.hasClass(s,m+"ItemSub")){h=z.items[s.id];if(h.isDisabled()){return}k=z;while(k){if(k.hideMenu){k.hideMenu()}k=k.settings.parent}if(h.settings.onclick){h.settings.onclick(s)}return false}});if(z.hasMenus()){z.mouseOverFunc=a.add(o,"mouseover",function(x){var h,t,s;x=x.target;if(x&&(x=c.getParent(x,"tr"))){h=z.items[x.id];if(z.lastMenu){z.lastMenu.collapse(1)}if(h.isDisabled()){return}if(x&&c.hasClass(x,m+"ItemSub")){t=c.getRect(x);h.showMenu((t.x+t.w-i),t.y-i,t.x);z.lastMenu=h;c.addClass(c.get(h.id).firstChild,m+"ItemActive")}}})}a.add(o,"keydown",z._keyHandler,z);z.onShowMenu.dispatch(z);if(A.keyboard_focus){z._setupKeyboardNav()}},hideMenu:function(j){var g=this,i=c.get("menu_"+g.id),h;if(!g.isMenuVisible){return}if(g.keyboardNav){g.keyboardNav.destroy()}a.remove(i,"mouseover",g.mouseOverFunc);a.remove(i,"click",g.mouseClickFunc);a.remove(i,"keydown",g._keyHandler);c.hide(i);g.isMenuVisible=0;if(!j){g.collapse(1)}if(g.element){g.element.hide()}if(h=c.get(g.id)){c.removeClass(h.firstChild,g.classPrefix+"ItemActive")}g.onHideMenu.dispatch(g)},add:function(i){var g=this,h;i=g.parent(i);if(g.isRendered&&(h=c.get("menu_"+g.id))){g._add(c.select("tbody",h)[0],i)}return i},collapse:function(g){this.parent(g);this.hideMenu(1)},remove:function(g){c.remove(g.id);this.destroy();return this.parent(g)},destroy:function(){var g=this,h=c.get("menu_"+g.id);if(g.keyboardNav){g.keyboardNav.destroy()}a.remove(h,"mouseover",g.mouseOverFunc);a.remove(c.select("a",h),"focus",g.mouseOverFunc);a.remove(h,"click",g.mouseClickFunc);a.remove(h,"keydown",g._keyHandler);if(g.element){g.element.remove()}c.remove(h)},renderNode:function(){var i=this,j=i.settings,l,h,k,g;g=c.create("div",{role:"listbox",id:"menu_"+i.id,"class":j["class"],style:"position:absolute;left:0;top:0;z-index:200000;outline:0"});if(i.settings.parent){c.setAttrib(g,"aria-parent","menu_"+i.settings.parent.id)}k=c.add(g,"div",{role:"presentation",id:"menu_"+i.id+"_co","class":i.classPrefix+(j["class"]?" "+j["class"]:"")});i.element=new b("menu_"+i.id,{blocker:1,container:j.container});if(j.menu_line){c.add(k,"span",{"class":i.classPrefix+"Line"})}l=c.add(k,"table",{role:"presentation",id:"menu_"+i.id+"_tbl",border:0,cellPadding:0,cellSpacing:0});h=c.add(l,"tbody");f(i.items,function(m){i._add(h,m)});i.rendered=true;return g},_setupKeyboardNav:function(){var i,h,g=this;i=c.get("menu_"+g.id);h=c.select("a[role=option]","menu_"+g.id);h.splice(0,0,i);g.keyboardNav=new e.ui.KeyboardNavigation({root:"menu_"+g.id,items:h,onCancel:function(){g.hideMenu()},enableUpDown:true});i.focus()},_keyHandler:function(g){var h=this,i;switch(g.keyCode){case 37:if(h.settings.parent){h.hideMenu();h.settings.parent.focus();a.cancel(g)}break;case 39:if(h.mouseOverFunc){h.mouseOverFunc(g)}break}},_add:function(j,h){var i,q=h.settings,p,l,k,m=this.classPrefix,g;if(q.separator){l=c.add(j,"tr",{id:h.id,"class":m+"ItemSeparator"});c.add(l,"td",{"class":m+"ItemSeparator"});if(i=l.previousSibling){c.addClass(i,"mceLast")}return}i=l=c.add(j,"tr",{id:h.id,"class":m+"Item "+m+"ItemEnabled"});i=k=c.add(i,q.titleItem?"th":"td");i=p=c.add(i,"a",{id:h.id+"_aria",role:q.titleItem?"presentation":"option",href:"javascript:;",onclick:"return false;",onmousedown:"return false;"});if(q.parent){c.setAttrib(p,"aria-haspopup","true");c.setAttrib(p,"aria-owns","menu_"+h.id)}c.addClass(k,q["class"]);g=c.add(i,"span",{"class":"mceIcon"+(q.icon?" mce_"+q.icon:"")});if(q.icon_src){c.add(g,"img",{src:q.icon_src})}i=c.add(i,q.element||"span",{"class":"mceText",title:h.settings.title},h.settings.title);if(h.settings.style){if(typeof h.settings.style=="function"){h.settings.style=h.settings.style()}c.setAttrib(i,"style",h.settings.style)}if(j.childNodes.length==1){c.addClass(l,"mceFirst")}if((i=l.previousSibling)&&c.hasClass(i,m+"ItemSeparator")){c.addClass(l,"mceFirst")}if(h.collapse){c.addClass(l,m+"ItemSub")}if(i=l.previousSibling){c.removeClass(i,"mceLast")}c.addClass(l,"mceLast")}})})(tinymce);(function(b){var a=b.DOM;b.create("tinymce.ui.Button:tinymce.ui.Control",{Button:function(e,d,c){this.parent(e,d,c);this.classPrefix="mceButton"},renderHTML:function(){var f=this.classPrefix,e=this.settings,d,c;c=a.encode(e.label||"");d='<a role="button" id="'+this.id+'" href="javascript:;" class="'+f+" "+f+"Enabled "+e["class"]+(c?" "+f+"Labeled":"")+'" onmousedown="return false;" onclick="return false;" aria-labelledby="'+this.id+'_voice" title="'+a.encode(e.title)+'">';if(e.image&&!(this.editor&&this.editor.forcedHighContrastMode)){d+='<span class="mceIcon '+e["class"]+'"><img class="mceIcon" src="'+e.image+'" alt="'+a.encode(e.title)+'" /></span>'+(c?'<span class="'+f+'Label">'+c+"</span>":"")}else{d+='<span class="mceIcon '+e["class"]+'"></span>'+(c?'<span class="'+f+'Label">'+c+"</span>":"")}d+='<span class="mceVoiceLabel mceIconOnly" style="display: none;" id="'+this.id+'_voice">'+e.title+"</span>";d+="</a>";return d},postRender:function(){var d=this,e=d.settings,c;if(b.isIE&&d.editor){b.dom.Event.add(d.id,"mousedown",function(f){var g=d.editor.selection.getNode().nodeName;c=g==="IMG"?d.editor.selection.getBookmark():null})}b.dom.Event.add(d.id,"click",function(f){if(!d.isDisabled()){if(b.isIE&&d.editor&&c!==null){d.editor.selection.moveToBookmark(c)}return e.onclick.call(e.scope,f)}});b.dom.Event.add(d.id,"keyup",function(f){if(!d.isDisabled()&&f.keyCode==b.VK.SPACEBAR){return e.onclick.call(e.scope,f)}})}})})(tinymce);(function(e){var d=e.DOM,b=e.dom.Event,f=e.each,a=e.util.Dispatcher,c;e.create("tinymce.ui.ListBox:tinymce.ui.Control",{ListBox:function(j,i,g){var h=this;h.parent(j,i,g);h.items=[];h.onChange=new a(h);h.onPostRender=new a(h);h.onAdd=new a(h);h.onRenderMenu=new e.util.Dispatcher(this);h.classPrefix="mceListBox";h.marked={}},select:function(h){var g=this,j,i;g.marked={};if(h==c){return g.selectByIndex(-1)}if(h&&typeof(h)=="function"){i=h}else{i=function(k){return k==h}}if(h!=g.selectedValue){f(g.items,function(l,k){if(i(l.value)){j=1;g.selectByIndex(k);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(g){var i=this,j,k,h;i.marked={};if(g!=i.selectedIndex){j=d.get(i.id+"_text");h=d.get(i.id+"_voiceDesc");k=i.items[g];if(k){i.selectedValue=k.value;i.selectedIndex=g;d.setHTML(j,d.encode(k.title));d.setHTML(h,i.settings.title+" - "+k.title);d.removeClass(j,"mceTitle");d.setAttrib(i.id,"aria-valuenow",k.title)}else{d.setHTML(j,d.encode(i.settings.title));d.setHTML(h,d.encode(i.settings.title));d.addClass(j,"mceTitle");i.selectedValue=i.selectedIndex=null;d.setAttrib(i.id,"aria-valuenow",i.settings.title)}j=0}},mark:function(g){this.marked[g]=true},add:function(j,g,i){var h=this;i=i||{};i=e.extend(i,{title:j,value:g});h.items.push(i);h.onAdd.dispatch(h,i)},getLength:function(){return this.items.length},renderHTML:function(){var j="",g=this,i=g.settings,k=g.classPrefix;j='<span role="listbox" aria-haspopup="true" aria-labelledby="'+g.id+'_voiceDesc" aria-describedby="'+g.id+'_voiceDesc"><table role="presentation" tabindex="0" id="'+g.id+'" cellpadding="0" cellspacing="0" class="'+k+" "+k+"Enabled"+(i["class"]?(" "+i["class"]):"")+'"><tbody><tr>';j+="<td>"+d.createHTML("span",{id:g.id+"_voiceDesc","class":"voiceLabel",style:"display:none;"},g.settings.title);j+=d.createHTML("a",{id:g.id+"_text",tabindex:-1,href:"javascript:;","class":"mceText",onclick:"return false;",onmousedown:"return false;"},d.encode(g.settings.title))+"</td>";j+="<td>"+d.createHTML("a",{id:g.id+"_open",tabindex:-1,href:"javascript:;","class":"mceOpen",onclick:"return false;",onmousedown:"return false;"},'<span><span style="display:none;" class="mceIconOnly" aria-hidden="true">\u25BC</span></span>')+"</td>";j+="</tr></tbody></table></span>";return j},showMenu:function(){var h=this,j,i=d.get(this.id),g;if(h.isDisabled()||h.items.length===0){return}if(h.menu&&h.menu.isMenuVisible){return h.hideMenu()}if(!h.isMenuRendered){h.renderMenu();h.isMenuRendered=true}j=d.getPos(i);g=h.menu;g.settings.offset_x=j.x;g.settings.offset_y=j.y;g.settings.keyboard_focus=!e.isOpera;f(h.items,function(k){if(g.items[k.id]){g.items[k.id].setSelected(0)}});f(h.items,function(k){if(g.items[k.id]&&h.marked[k.value]){g.items[k.id].setSelected(1)}if(k.value===h.selectedValue){g.items[k.id].setSelected(1)}});g.showMenu(0,i.clientHeight);b.add(d.doc,"mousedown",h.hideMenu,h);d.addClass(h.id,h.classPrefix+"Selected")},hideMenu:function(h){var g=this;if(g.menu&&g.menu.isMenuVisible){d.removeClass(g.id,g.classPrefix+"Selected");if(h&&h.type=="mousedown"&&(h.target.id==g.id+"_text"||h.target.id==g.id+"_open")){return}if(!h||!d.getParent(h.target,".mceMenu")){d.removeClass(g.id,g.classPrefix+"Selected");b.remove(d.doc,"mousedown",g.hideMenu,g);g.menu.hideMenu()}}},renderMenu:function(){var h=this,g;g=h.settings.control_manager.createDropMenu(h.id+"_menu",{menu_line:1,"class":h.classPrefix+"Menu mceNoIcons",max_width:250,max_height:150});g.onHideMenu.add(function(){h.hideMenu();h.focus()});g.add({title:h.settings.title,"class":"mceMenuItemTitle",onclick:function(){if(h.settings.onselect("")!==false){h.select("")}}});f(h.items,function(i){if(i.value===c){g.add({title:i.title,role:"option","class":"mceMenuItemTitle",onclick:function(){if(h.settings.onselect("")!==false){h.select("")}}})}else{i.id=d.uniqueId();i.role="option";i.onclick=function(){if(h.settings.onselect(i.value)!==false){h.select(i.value)}};g.add(i)}});h.onRenderMenu.dispatch(h,g);h.menu=g},postRender:function(){var g=this,h=g.classPrefix;b.add(g.id,"click",g.showMenu,g);b.add(g.id,"keydown",function(i){if(i.keyCode==32){g.showMenu(i);b.cancel(i)}});b.add(g.id,"focus",function(){if(!g._focused){g.keyDownHandler=b.add(g.id,"keydown",function(i){if(i.keyCode==40){g.showMenu();b.cancel(i)}});g.keyPressHandler=b.add(g.id,"keypress",function(j){var i;if(j.keyCode==13){i=g.selectedValue;g.selectedValue=null;b.cancel(j);g.settings.onselect(i)}})}g._focused=1});b.add(g.id,"blur",function(){b.remove(g.id,"keydown",g.keyDownHandler);b.remove(g.id,"keypress",g.keyPressHandler);g._focused=0});if(e.isIE6||!d.boxModel){b.add(g.id,"mouseover",function(){if(!d.hasClass(g.id,h+"Disabled")){d.addClass(g.id,h+"Hover")}});b.add(g.id,"mouseout",function(){if(!d.hasClass(g.id,h+"Disabled")){d.removeClass(g.id,h+"Hover")}})}g.onPostRender.dispatch(g,d.get(g.id))},destroy:function(){this.parent();b.clear(this.id+"_text");b.clear(this.id+"_open")}})})(tinymce);(function(e){var d=e.DOM,b=e.dom.Event,f=e.each,a=e.util.Dispatcher,c;e.create("tinymce.ui.NativeListBox:tinymce.ui.ListBox",{NativeListBox:function(h,g){this.parent(h,g);this.classPrefix="mceNativeListBox"},setDisabled:function(g){d.get(this.id).disabled=g;this.setAriaProperty("disabled",g)},isDisabled:function(){return d.get(this.id).disabled},select:function(h){var g=this,j,i;if(h==c){return g.selectByIndex(-1)}if(h&&typeof(h)=="function"){i=h}else{i=function(k){return k==h}}if(h!=g.selectedValue){f(g.items,function(l,k){if(i(l.value)){j=1;g.selectByIndex(k);return false}});if(!j){g.selectByIndex(-1)}}},selectByIndex:function(g){d.get(this.id).selectedIndex=g+1;this.selectedValue=this.items[g]?this.items[g].value:null},add:function(k,h,g){var j,i=this;g=g||{};g.value=h;if(i.isRendered()){d.add(d.get(this.id),"option",g,k)}j={title:k,value:h,attribs:g};i.items.push(j);i.onAdd.dispatch(i,j)},getLength:function(){return this.items.length},renderHTML:function(){var i,g=this;i=d.createHTML("option",{value:""},"-- "+g.settings.title+" --");f(g.items,function(h){i+=d.createHTML("option",{value:h.value},h.title)});i=d.createHTML("select",{id:g.id,"class":"mceNativeListBox","aria-labelledby":g.id+"_aria"},i);i+=d.createHTML("span",{id:g.id+"_aria",style:"display: none"},g.settings.title);return i},postRender:function(){var h=this,i,j=true;h.rendered=true;function g(l){var k=h.items[l.target.selectedIndex-1];if(k&&(k=k.value)){h.onChange.dispatch(h,k);if(h.settings.onselect){h.settings.onselect(k)}}}b.add(h.id,"change",g);b.add(h.id,"keydown",function(l){var k;b.remove(h.id,"change",i);j=false;k=b.add(h.id,"blur",function(){if(j){return}j=true;b.add(h.id,"change",g);b.remove(h.id,"blur",k)});if(e.isWebKit&&(l.keyCode==37||l.keyCode==39)){return b.prevent(l)}if(l.keyCode==13||l.keyCode==32){g(l);return b.cancel(l)}});h.onPostRender.dispatch(h,d.get(h.id))}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create("tinymce.ui.MenuButton:tinymce.ui.Button",{MenuButton:function(g,f,e){this.parent(g,f,e);this.onRenderMenu=new c.util.Dispatcher(this);f.menu_container=f.menu_container||b.doc.body},showMenu:function(){var g=this,j,i,h=b.get(g.id),f;if(g.isDisabled()){return}if(!g.isMenuRendered){g.renderMenu();g.isMenuRendered=true}if(g.isMenuVisible){return g.hideMenu()}j=b.getPos(g.settings.menu_container);i=b.getPos(h);f=g.menu;f.settings.offset_x=i.x;f.settings.offset_y=i.y;f.settings.vp_offset_x=i.x;f.settings.vp_offset_y=i.y;f.settings.keyboard_focus=g._focused;f.showMenu(0,h.firstChild.clientHeight);a.add(b.doc,"mousedown",g.hideMenu,g);g.setState("Selected",1);g.isMenuVisible=1},renderMenu:function(){var f=this,e;e=f.settings.control_manager.createDropMenu(f.id+"_menu",{menu_line:1,"class":this.classPrefix+"Menu",icons:f.settings.icons});e.onHideMenu.add(function(){f.hideMenu();f.focus()});f.onRenderMenu.dispatch(f,e);f.menu=e},hideMenu:function(g){var f=this;if(g&&g.type=="mousedown"&&b.getParent(g.target,function(h){return h.id===f.id||h.id===f.id+"_open"})){return}if(!g||!b.getParent(g.target,".mceMenu")){f.setState("Selected",0);a.remove(b.doc,"mousedown",f.hideMenu,f);if(f.menu){f.menu.hideMenu()}}f.isMenuVisible=0},postRender:function(){var e=this,f=e.settings;a.add(e.id,"click",function(){if(!e.isDisabled()){if(f.onclick){f.onclick(e.value)}e.showMenu()}})}})})(tinymce);(function(c){var b=c.DOM,a=c.dom.Event,d=c.each;c.create("tinymce.ui.SplitButton:tinymce.ui.MenuButton",{SplitButton:function(g,f,e){this.parent(g,f,e);this.classPrefix="mceSplitButton"},renderHTML:function(){var i,f=this,g=f.settings,e;i="<tbody><tr>";if(g.image){e=b.createHTML("img ",{src:g.image,role:"presentation","class":"mceAction "+g["class"]})}else{e=b.createHTML("span",{"class":"mceAction "+g["class"]},"")}e+=b.createHTML("span",{"class":"mceVoiceLabel mceIconOnly",id:f.id+"_voice",style:"display:none;"},g.title);i+="<td >"+b.createHTML("a",{role:"button",id:f.id+"_action",tabindex:"-1",href:"javascript:;","class":"mceAction "+g["class"],onclick:"return false;",onmousedown:"return false;",title:g.title},e)+"</td>";e=b.createHTML("span",{"class":"mceOpen "+g["class"]},'<span style="display:none;" class="mceIconOnly" aria-hidden="true">\u25BC</span>');i+="<td >"+b.createHTML("a",{role:"button",id:f.id+"_open",tabindex:"-1",href:"javascript:;","class":"mceOpen "+g["class"],onclick:"return false;",onmousedown:"return false;",title:g.title},e)+"</td>";i+="</tr></tbody>";i=b.createHTML("table",{role:"presentation","class":"mceSplitButton mceSplitButtonEnabled "+g["class"],cellpadding:"0",cellspacing:"0",title:g.title},i);return b.createHTML("div",{id:f.id,role:"button",tabindex:"0","aria-labelledby":f.id+"_voice","aria-haspopup":"true"},i)},postRender:function(){var e=this,g=e.settings,f;if(g.onclick){f=function(h){if(!e.isDisabled()){g.onclick(e.value);a.cancel(h)}};a.add(e.id+"_action","click",f);a.add(e.id,["click","keydown"],function(h){var k=32,m=14,i=13,j=38,l=40;if((h.keyCode===32||h.keyCode===13||h.keyCode===14)&&!h.altKey&&!h.ctrlKey&&!h.metaKey){f();a.cancel(h)}else{if(h.type==="click"||h.keyCode===l){e.showMenu();a.cancel(h)}}})}a.add(e.id+"_open","click",function(h){e.showMenu();a.cancel(h)});a.add([e.id,e.id+"_open"],"focus",function(){e._focused=1});a.add([e.id,e.id+"_open"],"blur",function(){e._focused=0});if(c.isIE6||!b.boxModel){a.add(e.id,"mouseover",function(){if(!b.hasClass(e.id,"mceSplitButtonDisabled")){b.addClass(e.id,"mceSplitButtonHover")}});a.add(e.id,"mouseout",function(){if(!b.hasClass(e.id,"mceSplitButtonDisabled")){b.removeClass(e.id,"mceSplitButtonHover")}})}},destroy:function(){this.parent();a.clear(this.id+"_action");a.clear(this.id+"_open");a.clear(this.id)}})})(tinymce);(function(d){var c=d.DOM,a=d.dom.Event,b=d.is,e=d.each;d.create("tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton",{ColorSplitButton:function(i,h,f){var g=this;g.parent(i,h,f);g.settings=h=d.extend({colors:"000000,993300,333300,003300,003366,000080,333399,333333,800000,FF6600,808000,008000,008080,0000FF,666699,808080,FF0000,FF9900,99CC00,339966,33CCCC,3366FF,800080,999999,FF00FF,FFCC00,FFFF00,00FF00,00FFFF,00CCFF,993366,C0C0C0,FF99CC,FFCC99,FFFF99,CCFFCC,CCFFFF,99CCFF,CC99FF,FFFFFF",grid_width:8,default_color:"#888888"},g.settings);g.onShowMenu=new d.util.Dispatcher(g);g.onHideMenu=new d.util.Dispatcher(g);g.value=h.default_color},showMenu:function(){var f=this,g,j,i,h;if(f.isDisabled()){return}if(!f.isMenuRendered){f.renderMenu();f.isMenuRendered=true}if(f.isMenuVisible){return f.hideMenu()}i=c.get(f.id);c.show(f.id+"_menu");c.addClass(i,"mceSplitButtonSelected");h=c.getPos(i);c.setStyles(f.id+"_menu",{left:h.x,top:h.y+i.firstChild.clientHeight,zIndex:200000});i=0;a.add(c.doc,"mousedown",f.hideMenu,f);f.onShowMenu.dispatch(f);if(f._focused){f._keyHandler=a.add(f.id+"_menu","keydown",function(k){if(k.keyCode==27){f.hideMenu()}});c.select("a",f.id+"_menu")[0].focus()}f.keyboardNav=new d.ui.KeyboardNavigation({root:f.id+"_menu",items:c.select("a",f.id+"_menu"),onCancel:function(){f.hideMenu();f.focus()}});f.keyboardNav.focus();f.isMenuVisible=1},hideMenu:function(g){var f=this;if(f.isMenuVisible){if(g&&g.type=="mousedown"&&c.getParent(g.target,function(h){return h.id===f.id+"_open"})){return}if(!g||!c.getParent(g.target,".mceSplitButtonMenu")){c.removeClass(f.id,"mceSplitButtonSelected");a.remove(c.doc,"mousedown",f.hideMenu,f);a.remove(f.id+"_menu","keydown",f._keyHandler);c.hide(f.id+"_menu")}f.isMenuVisible=0;f.onHideMenu.dispatch();f.keyboardNav.destroy()}},renderMenu:function(){var p=this,h,k=0,q=p.settings,g,j,l,o,f;o=c.add(q.menu_container,"div",{role:"listbox",id:p.id+"_menu","class":q.menu_class+" "+q["class"],style:"position:absolute;left:0;top:-1000px;"});h=c.add(o,"div",{"class":q["class"]+" mceSplitButtonMenu"});c.add(h,"span",{"class":"mceMenuLine"});g=c.add(h,"table",{role:"presentation","class":"mceColorSplitMenu"});j=c.add(g,"tbody");k=0;e(b(q.colors,"array")?q.colors:q.colors.split(","),function(m){m=m.replace(/^#/,"");if(!k--){l=c.add(j,"tr");k=q.grid_width-1}g=c.add(l,"td");var i={href:"javascript:;",style:{backgroundColor:"#"+m},title:p.editor.getLang("colors."+m,m),"data-mce-color":"#"+m};if(!d.isIE){i.role="option"}g=c.add(g,"a",i);if(p.editor.forcedHighContrastMode){g=c.add(g,"canvas",{width:16,height:16,"aria-hidden":"true"});if(g.getContext&&(f=g.getContext("2d"))){f.fillStyle="#"+m;f.fillRect(0,0,16,16)}else{c.remove(g)}}});if(q.more_colors_func){g=c.add(j,"tr");g=c.add(g,"td",{colspan:q.grid_width,"class":"mceMoreColors"});g=c.add(g,"a",{role:"option",id:p.id+"_more",href:"javascript:;",onclick:"return false;","class":"mceMoreColors"},q.more_colors_title);a.add(g,"click",function(i){q.more_colors_func.call(q.more_colors_scope||this);return a.cancel(i)})}c.addClass(h,"mceColorSplitMenu");a.add(p.id+"_menu","mousedown",function(i){return a.cancel(i)});a.add(p.id+"_menu","click",function(i){var m;i=c.getParent(i.target,"a",j);if(i&&i.nodeName.toLowerCase()=="a"&&(m=i.getAttribute("data-mce-color"))){p.setColor(m)}return false});return o},setColor:function(f){this.displayColor(f);this.hideMenu();this.settings.onselect(f)},displayColor:function(g){var f=this;c.setStyle(f.id+"_preview","backgroundColor",g);f.value=g},postRender:function(){var f=this,g=f.id;f.parent();c.add(g+"_action","div",{id:g+"_preview","class":"mceColorPreview"});c.setStyle(f.id+"_preview","backgroundColor",f.value)},destroy:function(){var f=this;f.parent();a.clear(f.id+"_menu");a.clear(f.id+"_more");c.remove(f.id+"_menu");if(f.keyboardNav){f.keyboardNav.destroy()}}})})(tinymce);(function(b){var d=b.DOM,c=b.each,a=b.dom.Event;b.create("tinymce.ui.ToolbarGroup:tinymce.ui.Container",{renderHTML:function(){var f=this,i=[],e=f.controls,j=b.each,g=f.settings;i.push('<div id="'+f.id+'" role="group" aria-labelledby="'+f.id+'_voice">');i.push("<span role='application'>");i.push('<span id="'+f.id+'_voice" class="mceVoiceLabel" style="display:none;">'+d.encode(g.name)+"</span>");j(e,function(h){i.push(h.renderHTML())});i.push("</span>");i.push("</div>");return i.join("")},focus:function(){var e=this;d.get(e.id).focus()},postRender:function(){var f=this,e=[];c(f.controls,function(g){c(g.controls,function(h){if(h.id){e.push(h)}})});f.keyNav=new b.ui.KeyboardNavigation({root:f.id,items:e,onCancel:function(){if(b.isWebKit){d.get(f.editor.id+"_ifr").focus()}f.editor.focus()},excludeFromTabOrder:!f.settings.tab_focus_toolbar})},destroy:function(){var e=this;e.parent();e.keyNav.destroy();a.clear(e.id)}})})(tinymce);(function(a){var c=a.DOM,b=a.each;a.create("tinymce.ui.Toolbar:tinymce.ui.Container",{renderHTML:function(){var m=this,f="",j,k,n=m.settings,e,d,g,l;l=m.controls;for(e=0;e<l.length;e++){k=l[e];d=l[e-1];g=l[e+1];if(e===0){j="mceToolbarStart";if(k.Button){j+=" mceToolbarStartButton"}else{if(k.SplitButton){j+=" mceToolbarStartSplitButton"}else{if(k.ListBox){j+=" mceToolbarStartListBox"}}}f+=c.createHTML("td",{"class":j},c.createHTML("span",null,"<!-- IE -->"))}if(d&&k.ListBox){if(d.Button||d.SplitButton){f+=c.createHTML("td",{"class":"mceToolbarEnd"},c.createHTML("span",null,"<!-- IE -->"))}}if(c.stdMode){f+='<td style="position: relative">'+k.renderHTML()+"</td>"}else{f+="<td>"+k.renderHTML()+"</td>"}if(g&&k.ListBox){if(g.Button||g.SplitButton){f+=c.createHTML("td",{"class":"mceToolbarStart"},c.createHTML("span",null,"<!-- IE -->"))}}}j="mceToolbarEnd";if(k.Button){j+=" mceToolbarEndButton"}else{if(k.SplitButton){j+=" mceToolbarEndSplitButton"}else{if(k.ListBox){j+=" mceToolbarEndListBox"}}}f+=c.createHTML("td",{"class":j},c.createHTML("span",null,"<!-- IE -->"));return c.createHTML("table",{id:m.id,"class":"mceToolbar"+(n["class"]?" "+n["class"]:""),cellpadding:"0",cellspacing:"0",align:m.settings.align||"",role:"presentation",tabindex:"-1"},"<tbody><tr>"+f+"</tr></tbody>")}})})(tinymce);(function(b){var a=b.util.Dispatcher,c=b.each;b.create("tinymce.AddOnManager",{AddOnManager:function(){var d=this;d.items=[];d.urls={};d.lookup={};d.onAdd=new a(d)},get:function(d){if(this.lookup[d]){return this.lookup[d].instance}else{return undefined}},dependencies:function(e){var d;if(this.lookup[e]){d=this.lookup[e].dependencies}return d||[]},requireLangPack:function(e){var d=b.settings;if(d&&d.language&&d.language_load!==false){b.ScriptLoader.add(this.urls[e]+"/langs/"+d.language+".js")}},add:function(f,e,d){this.items.push(e);this.lookup[f]={instance:e,dependencies:d};this.onAdd.dispatch(this,f,e);return e},createUrl:function(d,e){if(typeof e==="object"){return e}else{return{prefix:d.prefix,resource:e,suffix:d.suffix}}},addComponents:function(f,d){var e=this.urls[f];b.each(d,function(g){b.ScriptLoader.add(e+"/"+g)})},load:function(j,f,d,h){var g=this,e=f;function i(){var k=g.dependencies(j);b.each(k,function(m){var l=g.createUrl(f,m);g.load(l.resource,l,undefined,undefined)});if(d){if(h){d.call(h)}else{d.call(b.ScriptLoader)}}}if(g.urls[j]){return}if(typeof f==="object"){e=f.prefix+f.resource+f.suffix}if(e.indexOf("/")!==0&&e.indexOf("://")==-1){e=b.baseURL+"/"+e}g.urls[j]=e.substring(0,e.lastIndexOf("/"));if(g.lookup[j]){i()}else{b.ScriptLoader.add(e,i,h)}}});b.PluginManager=new b.AddOnManager();b.ThemeManager=new b.AddOnManager()}(tinymce));(function(j){var g=j.each,d=j.extend,k=j.DOM,i=j.dom.Event,f=j.ThemeManager,b=j.PluginManager,e=j.explode,h=j.util.Dispatcher,a,c=0;j.documentBaseURL=window.location.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");if(!/[\/\\]$/.test(j.documentBaseURL)){j.documentBaseURL+="/"}j.baseURL=new j.util.URI(j.documentBaseURL).toAbsolute(j.baseURL);j.baseURI=new j.util.URI(j.baseURL);j.onBeforeUnload=new h(j);i.add(window,"beforeunload",function(l){j.onBeforeUnload.dispatch(j,l)});j.onAddEditor=new h(j);j.onRemoveEditor=new h(j);j.EditorManager=d(j,{editors:[],i18n:{},activeEditor:null,init:function(x){var v=this,o,n=j.ScriptLoader,u,l=[],r;function q(t){var s=t.id;if(!s){s=t.name;if(s&&!k.get(s)){s=t.name}else{s=k.uniqueId()}t.setAttribute("id",s)}return s}function m(z,A,t){var y=z[A];if(!y){return}if(j.is(y,"string")){t=y.replace(/\.\w+$/,"");t=t?j.resolve(t):0;y=j.resolve(y)}return y.apply(t||this,Array.prototype.slice.call(arguments,2))}function p(t,s){return s.constructor===RegExp?s.test(t.className):k.hasClass(t,s)}v.settings=x;i.bind(window,"ready",function(){var s,t;m(x,"onpageload");switch(x.mode){case"exact":s=x.elements||"";if(s.length>0){g(e(s),function(y){if(k.get(y)){r=new j.Editor(y,x);l.push(r);r.render(1)}else{g(document.forms,function(z){g(z.elements,function(A){if(A.name===y){y="mce_editor_"+c++;k.setAttrib(A,"id",y);r=new j.Editor(y,x);l.push(r);r.render(1)}})})}})}break;case"textareas":case"specific_textareas":g(k.select("textarea"),function(y){if(x.editor_deselector&&p(y,x.editor_deselector)){return}if(!x.editor_selector||p(y,x.editor_selector)){r=new j.Editor(q(y),x);l.push(r);r.render(1)}});break;default:if(x.types){g(x.types,function(y){g(k.select(y.selector),function(A){var z=new j.Editor(q(A),j.extend({},x,y));l.push(z);z.render(1)})})}else{if(x.selector){g(k.select(x.selector),function(z){var y=new j.Editor(q(z),x);l.push(y);y.render(1)})}}}if(x.oninit){s=t=0;g(l,function(y){t++;if(!y.initialized){y.onInit.add(function(){s++;if(s==t){m(x,"oninit")}})}else{s++}if(s==t){m(x,"oninit")}})}})},get:function(l){if(l===a){return this.editors}if(!this.editors.hasOwnProperty(l)){return a}return this.editors[l]},getInstanceById:function(l){return this.get(l)},add:function(m){var l=this,n=l.editors;n[m.id]=m;n.push(m);l._setActive(m);l.onAddEditor.dispatch(l,m);if(j.adapter){j.adapter.patchEditor(m)}return m},remove:function(n){var m=this,l,o=m.editors;if(!o[n.id]){return null}delete o[n.id];for(l=0;l<o.length;l++){if(o[l]==n){o.splice(l,1);break}}if(m.activeEditor==n){m._setActive(o[0])}n.destroy();m.onRemoveEditor.dispatch(m,n);return n},execCommand:function(r,p,o){var q=this,n=q.get(o),l;function m(){n.destroy();l.detachEvent("onunload",m);l=l.tinyMCE=l.tinymce=null}switch(r){case"mceFocus":n.focus();return true;case"mceAddEditor":case"mceAddControl":if(!q.get(o)){new j.Editor(o,q.settings).render()}return true;case"mceAddFrameControl":l=o.window;l.tinyMCE=tinyMCE;l.tinymce=j;j.DOM.doc=l.document;j.DOM.win=l;n=new j.Editor(o.element_id,o);n.render();if(j.isIE){l.attachEvent("onunload",m)}o.page_window=null;return true;case"mceRemoveEditor":case"mceRemoveControl":if(n){n.remove()}return true;case"mceToggleEditor":if(!n){q.execCommand("mceAddControl",0,o);return true}if(n.isHidden()){n.show()}else{n.hide()}return true}if(q.activeEditor){return q.activeEditor.execCommand(r,p,o)}return false},execInstanceCommand:function(p,o,n,m){var l=this.get(p);if(l){return l.execCommand(o,n,m)}return false},triggerSave:function(){g(this.editors,function(l){l.save()})},addI18n:function(n,q){var l,m=this.i18n;if(!j.is(n,"string")){g(n,function(r,p){g(r,function(t,s){g(t,function(v,u){if(s==="common"){m[p+"."+u]=v}else{m[p+"."+s+"."+u]=v}})})})}else{g(q,function(r,p){m[n+"."+p]=r})}},_setActive:function(l){this.selectedInstance=this.activeEditor=l}})})(tinymce);(function(k){var l=k.DOM,j=k.dom.Event,f=k.extend,i=k.each,a=k.isGecko,b=k.isIE,e=k.isWebKit,d=k.is,h=k.ThemeManager,c=k.PluginManager,g=k.explode;k.create("tinymce.Editor",{Editor:function(p,o){var m=this,n=true;m.settings=o=f({id:p,language:"en",theme:"advanced",skin:"default",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:k.documentBaseURL,add_form_submit_trigger:n,submit_patch:n,add_unload_trigger:n,convert_urls:n,relative_urls:n,remove_script_host:n,table_inline_editing:false,object_resizing:n,accessibility_focus:n,doctype:k.isIE6?'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">':"<!DOCTYPE>",visual:n,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%",apply_source_formatting:n,directionality:"ltr",forced_root_block:"p",hidden_input:n,padd_empty_editor:n,render_ui:n,indentation:"30px",fix_table_elements:n,inline_styles:n,convert_fonts_to_spans:n,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,figure,option,optgroup,datalist",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,option,optgroup,datalist",validate:n,entity_encoding:"named",url_converter:m.convertURL,url_converter_scope:m,ie7_compat:n},o);m.id=m.editorId=p;m.isNotDirty=false;m.plugins={};m.documentBaseURI=new k.util.URI(o.document_base_url||k.documentBaseURL,{base_uri:tinyMCE.baseURI});m.baseURI=k.baseURI;m.contentCSS=[];m.contentStyles=[];m.setupEvents();m.execCommands={};m.queryStateCommands={};m.queryValueCommands={};m.execCallback("setup",m)},render:function(o){var p=this,q=p.settings,r=p.id,m=k.ScriptLoader;if(!j.domLoaded){j.add(window,"ready",function(){p.render()});return}tinyMCE.settings=q;if(!p.getElement()){return}if(k.isIDevice&&!k.isIOS5){return}if(!/TEXTAREA|INPUT/i.test(p.getElement().nodeName)&&q.hidden_input&&l.getParent(r,"form")){l.insertAfter(l.create("input",{type:"hidden",name:r}),r)}if(!q.content_editable){p.orgVisibility=p.getElement().style.visibility;p.getElement().style.visibility="hidden"}if(k.WindowManager){p.windowManager=new k.WindowManager(p)}if(q.encoding=="xml"){p.onGetContent.add(function(s,t){if(t.save){t.content=l.encode(t.content)}})}if(q.add_form_submit_trigger){p.onSubmit.addToTop(function(){if(p.initialized){p.save();p.isNotDirty=1}})}if(q.add_unload_trigger){p._beforeUnload=tinyMCE.onBeforeUnload.add(function(){if(p.initialized&&!p.destroyed&&!p.isHidden()){p.save({format:"raw",no_events:true})}})}k.addUnload(p.destroy,p);if(q.submit_patch){p.onBeforeRenderUI.add(function(){var s=p.getElement().form;if(!s){return}if(s._mceOldSubmit){return}if(!s.submit.nodeType&&!s.submit.length){p.formElement=s;s._mceOldSubmit=s.submit;s.submit=function(){k.triggerSave();p.isNotDirty=1;return p.formElement._mceOldSubmit(p.formElement)}}s=null})}function n(){if(q.language&&q.language_load!==false){m.add(k.baseURL+"/langs/"+q.language+".js")}if(q.theme&&typeof q.theme!="function"&&q.theme.charAt(0)!="-"&&!h.urls[q.theme]){h.load(q.theme,"themes/"+q.theme+"/editor_template"+k.suffix+".js")}i(g(q.plugins),function(t){if(t&&!c.urls[t]){if(t.charAt(0)=="-"){t=t.substr(1,t.length);var s=c.dependencies(t);i(s,function(v){var u={prefix:"plugins/",resource:v,suffix:"/editor_plugin"+k.suffix+".js"};v=c.createUrl(u,v);c.load(v.resource,v)})}else{if(t=="safari"){return}c.load(t,{prefix:"plugins/",resource:t,suffix:"/editor_plugin"+k.suffix+".js"})}}});m.loadQueue(function(){if(!p.removed){p.init()}})}n()},init:function(){var q,G=this,H=G.settings,D,y,z,C=G.getElement(),p,m,E,v,B,F,x,r=[];k.add(G);H.aria_label=H.aria_label||l.getAttrib(C,"aria-label",G.getLang("aria.rich_text_area"));if(H.theme){if(typeof H.theme!="function"){H.theme=H.theme.replace(/-/,"");p=h.get(H.theme);G.theme=new p();if(G.theme.init){G.theme.init(G,h.urls[H.theme]||k.documentBaseURL.replace(/\/$/,""))}}else{G.theme=H.theme}}function A(s){var t=c.get(s),o=c.urls[s]||k.documentBaseURL.replace(/\/$/,""),n;if(t&&k.inArray(r,s)===-1){i(c.dependencies(s),function(u){A(u)});n=new t(G,o);G.plugins[s]=n;if(n.init){n.init(G,o);r.push(s)}}}i(g(H.plugins.replace(/\-/g,"")),A);if(H.popup_css!==false){if(H.popup_css){H.popup_css=G.documentBaseURI.toAbsolute(H.popup_css)}else{H.popup_css=G.baseURI.toAbsolute("themes/"+H.theme+"/skins/"+H.skin+"/dialog.css")}}if(H.popup_css_add){H.popup_css+=","+G.documentBaseURI.toAbsolute(H.popup_css_add)}G.controlManager=new k.ControlManager(G);G.onBeforeRenderUI.dispatch(G,G.controlManager);if(H.render_ui&&G.theme){G.orgDisplay=C.style.display;if(typeof H.theme!="function"){D=H.width||C.style.width||C.offsetWidth;y=H.height||C.style.height||C.offsetHeight;z=H.min_height||100;F=/^[0-9\.]+(|px)$/i;if(F.test(""+D)){D=Math.max(parseInt(D,10)+(p.deltaWidth||0),100)}if(F.test(""+y)){y=Math.max(parseInt(y,10)+(p.deltaHeight||0),z)}p=G.theme.renderUI({targetNode:C,width:D,height:y,deltaWidth:H.delta_width,deltaHeight:H.delta_height});l.setStyles(p.sizeContainer||p.editorContainer,{width:D,height:y});y=(p.iframeHeight||y)+(typeof(y)=="number"?(p.deltaHeight||0):"");if(y<z){y=z}}else{p=H.theme(G,C);if(p.editorContainer.nodeType){p.editorContainer=p.editorContainer.id=p.editorContainer.id||G.id+"_parent"}if(p.iframeContainer.nodeType){p.iframeContainer=p.iframeContainer.id=p.iframeContainer.id||G.id+"_iframecontainer"}y=p.iframeHeight||C.offsetHeight;if(b){G.onInit.add(function(n){n.dom.bind(n.getBody(),"beforedeactivate keydown",function(){n.lastIERng=n.selection.getRng()})})}}G.editorContainer=p.editorContainer}if(H.content_css){i(g(H.content_css),function(n){G.contentCSS.push(G.documentBaseURI.toAbsolute(n))})}if(H.content_style){G.contentStyles.push(H.content_style)}if(H.content_editable){C=q=p=null;return G.initContentBody()}if(document.domain&&location.hostname!=document.domain){k.relaxedDomain=document.domain}G.iframeHTML=H.doctype+'<html><head xmlns="http://www.w3.org/1999/xhtml">';if(H.document_base_url!=k.documentBaseURL){G.iframeHTML+='<base href="'+G.documentBaseURI.getURI()+'" />'}if(k.isIE8){if(H.ie7_compat){G.iframeHTML+='<meta http-equiv="X-UA-Compatible" content="IE=7" />'}else{G.iframeHTML+='<meta http-equiv="X-UA-Compatible" content="IE=edge" />'}}G.iframeHTML+='<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';for(x=0;x<G.contentCSS.length;x++){G.iframeHTML+='<link type="text/css" rel="stylesheet" href="'+G.contentCSS[x]+'" />'}G.contentCSS=[];v=H.body_id||"tinymce";if(v.indexOf("=")!=-1){v=G.getParam("body_id","","hash");v=v[G.id]||v}B=H.body_class||"";if(B.indexOf("=")!=-1){B=G.getParam("body_class","","hash");B=B[G.id]||""}G.iframeHTML+='</head><body id="'+v+'" class="mceContentBody '+B+'" onload="window.parent.tinyMCE.get(\''+G.id+"').onLoad.dispatch();\"><br></body></html>";if(k.relaxedDomain&&(b||(k.isOpera&&parseFloat(opera.version())<11))){E='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinyMCE.get("'+G.id+'");document.write(ed.iframeHTML);document.close();ed.initContentBody();})()'}q=l.add(p.iframeContainer,"iframe",{id:G.id+"_ifr",src:E||'javascript:""',frameBorder:"0",allowTransparency:"true",title:H.aria_label,style:{width:"100%",height:y,display:"block"}});G.contentAreaContainer=p.iframeContainer;if(p.editorContainer){l.get(p.editorContainer).style.display=G.orgDisplay}C.style.visibility=G.orgVisibility;l.get(G.id).style.display="none";l.setAttrib(G.id,"aria-hidden",true);if(!k.relaxedDomain||!E){G.initContentBody()}C=q=p=null},initContentBody:function(){var n=this,p=n.settings,q=l.get(n.id),r=n.getDoc(),o,m,s;if((!b||!k.relaxedDomain)&&!p.content_editable){r.open();r.write(n.iframeHTML);r.close();if(k.relaxedDomain){r.domain=k.relaxedDomain}}if(p.content_editable){l.addClass(q,"mceContentBody");n.contentDocument=r=p.content_document||document;n.contentWindow=p.content_window||window;n.bodyElement=q;p.content_document=p.content_window=null}m=n.getBody();m.disabled=true;if(!p.readonly){m.contentEditable=n.getParam("content_editable_state",true)}m.disabled=false;n.schema=new k.html.Schema(p);n.dom=new k.dom.DOMUtils(r,{keep_values:true,url_converter:n.convertURL,url_converter_scope:n,hex_colors:p.force_hex_style_colors,class_filter:p.class_filter,update_styles:true,root_element:p.content_editable?n.id:null,schema:n.schema});n.parser=new k.html.DomParser(p,n.schema);n.parser.addAttributeFilter("src,href,style",function(t,u){var v=t.length,y,A=n.dom,z,x;while(v--){y=t[v];z=y.attr(u);x="data-mce-"+u;if(!y.attributes.map[x]){if(u==="style"){y.attr(x,A.serializeStyle(A.parseStyle(z),y.name))}else{y.attr(x,n.convertURL(z,u,y.name))}}}});n.parser.addNodeFilter("script",function(t,u){var v=t.length,x;while(v--){x=t[v];x.attr("type","mce-"+(x.attr("type")||"text/javascript"))}});n.parser.addNodeFilter("#cdata",function(t,u){var v=t.length,x;while(v--){x=t[v];x.type=8;x.name="#comment";x.value="[CDATA["+x.value+"]]"}});n.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(u,v){var x=u.length,y,t=n.schema.getNonEmptyElements();while(x--){y=u[x];if(y.isEmpty(t)){y.empty().append(new k.html.Node("br",1)).shortEnded=true}}});n.serializer=new k.dom.Serializer(p,n.dom,n.schema);n.selection=new k.dom.Selection(n.dom,n.getWin(),n.serializer,n);n.formatter=new k.Formatter(n);n.undoManager=new k.UndoManager(n);n.forceBlocks=new k.ForceBlocks(n);n.enterKey=new k.EnterKey(n);n.editorCommands=new k.EditorCommands(n);n.onExecCommand.add(function(t,u){if(!/^(FontName|FontSize)$/.test(u)){n.nodeChanged()}});n.serializer.onPreProcess.add(function(t,u){return n.onPreProcess.dispatch(n,u,t)});n.serializer.onPostProcess.add(function(t,u){return n.onPostProcess.dispatch(n,u,t)});n.onPreInit.dispatch(n);if(!p.browser_spellcheck&&!p.gecko_spellcheck){r.body.spellcheck=false}if(!p.readonly){n.bindNativeEvents()}n.controlManager.onPostRender.dispatch(n,n.controlManager);n.onPostRender.dispatch(n);n.quirks=k.util.Quirks(n);if(p.directionality){m.dir=p.directionality}if(p.nowrap){m.style.whiteSpace="nowrap"}if(p.protect){n.onBeforeSetContent.add(function(t,u){i(p.protect,function(v){u.content=u.content.replace(v,function(x){return"<!--mce:protected "+escape(x)+"-->"})})})}n.onSetContent.add(function(){n.addVisual(n.getBody())});if(p.padd_empty_editor){n.onPostProcess.add(function(t,u){u.content=u.content.replace(/^(<p[^>]*>( | |\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/,"")})}n.load({initial:true,format:"html"});n.startContent=n.getContent({format:"raw"});n.initialized=true;n.onInit.dispatch(n);n.execCallback("setupcontent_callback",n.id,m,r);n.execCallback("init_instance_callback",n);n.focus(true);n.nodeChanged({initial:true});if(n.contentStyles.length>0){s="";i(n.contentStyles,function(t){s+=t+"\r\n"});n.dom.addStyle(s)}i(n.contentCSS,function(t){n.dom.loadCSS(t)});if(p.auto_focus){setTimeout(function(){var t=k.get(p.auto_focus);t.selection.select(t.getBody(),1);t.selection.collapse(1);t.getBody().focus();t.getWin().focus()},100)}q=r=m=null},focus:function(p){var o,u=this,t=u.selection,q=u.settings.content_editable,n,r,s=u.getDoc(),m;if(!p){if(u.lastIERng){t.setRng(u.lastIERng)}n=t.getRng();if(n.item){r=n.item(0)}u._refreshContentEditable();if(!q){u.getWin().focus()}if(k.isGecko||q){m=u.getBody();if(m.setActive){m.setActive()}else{m.focus()}if(q){t.normalize()}}if(r&&r.ownerDocument==s){n=s.body.createControlRange();n.addElement(r);n.select()}}if(k.activeEditor!=u){if((o=k.activeEditor)!=null){o.onDeactivate.dispatch(o,u)}u.onActivate.dispatch(u,o)}k._setActive(u)},execCallback:function(q){var m=this,p=m.settings[q],o;if(!p){return}if(m.callbackLookup&&(o=m.callbackLookup[q])){p=o.func;o=o.scope}if(d(p,"string")){o=p.replace(/\.\w+$/,"");o=o?k.resolve(o):0;p=k.resolve(p);m.callbackLookup=m.callbackLookup||{};m.callbackLookup[q]={func:p,scope:o}}return p.apply(o||m,Array.prototype.slice.call(arguments,1))},translate:function(m){var o=this.settings.language||"en",n=k.i18n;if(!m){return""}return n[o+"."+m]||m.replace(/\{\#([^\}]+)\}/g,function(q,p){return n[o+"."+p]||"{#"+p+"}"})},getLang:function(o,m){return k.i18n[(this.settings.language||"en")+"."+o]||(d(m)?m:"{#"+o+"}")},getParam:function(t,q,m){var r=k.trim,p=d(this.settings[t])?this.settings[t]:q,s;if(m==="hash"){s={};if(d(p,"string")){i(p.indexOf("=")>0?p.split(/[;,](?![^=;,]*(?:[;,]|$))/):p.split(","),function(n){n=n.split("=");if(n.length>1){s[r(n[0])]=r(n[1])}else{s[r(n[0])]=r(n)}})}else{s=p}return s}return p},nodeChanged:function(q){var m=this,n=m.selection,p;if(m.initialized){q=q||{};p=n.getStart()||m.getBody();p=b&&p.ownerDocument!=m.getDoc()?m.getBody():p;q.parents=[];m.dom.getParent(p,function(o){if(o.nodeName=="BODY"){return true}q.parents.push(o)});m.onNodeChange.dispatch(m,q?q.controlManager||m.controlManager:m.controlManager,p,n.isCollapsed(),q)}},addButton:function(n,o){var m=this;m.buttons=m.buttons||{};m.buttons[n]=o},addCommand:function(m,o,n){this.execCommands[m]={func:o,scope:n||this}},addQueryStateHandler:function(m,o,n){this.queryStateCommands[m]={func:o,scope:n||this}},addQueryValueHandler:function(m,o,n){this.queryValueCommands[m]={func:o,scope:n||this}},addShortcut:function(o,q,m,p){var n=this,r;if(n.settings.custom_shortcuts===false){return false}n.shortcuts=n.shortcuts||{};if(d(m,"string")){r=m;m=function(){n.execCommand(r,false,null)}}if(d(m,"object")){r=m;m=function(){n.execCommand(r[0],r[1],r[2])}}i(g(o),function(s){var t={func:m,scope:p||this,desc:n.translate(q),alt:false,ctrl:false,shift:false};i(g(s,"+"),function(u){switch(u){case"alt":case"ctrl":case"shift":t[u]=true;break;default:t.charCode=u.charCodeAt(0);t.keyCode=u.toUpperCase().charCodeAt(0)}});n.shortcuts[(t.ctrl?"ctrl":"")+","+(t.alt?"alt":"")+","+(t.shift?"shift":"")+","+t.keyCode]=t});return true},execCommand:function(u,r,x,m){var p=this,q=0,v,n;if(!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(u)&&(!m||!m.skip_focus)){p.focus()}m=f({},m);p.onBeforeExecCommand.dispatch(p,u,r,x,m);if(m.terminate){return false}if(p.execCallback("execcommand_callback",p.id,p.selection.getNode(),u,r,x)){p.onExecCommand.dispatch(p,u,r,x,m);return true}if(v=p.execCommands[u]){n=v.func.call(v.scope,r,x);if(n!==true){p.onExecCommand.dispatch(p,u,r,x,m);return n}}i(p.plugins,function(o){if(o.execCommand&&o.execCommand(u,r,x)){p.onExecCommand.dispatch(p,u,r,x,m);q=1;return false}});if(q){return true}if(p.theme&&p.theme.execCommand&&p.theme.execCommand(u,r,x)){p.onExecCommand.dispatch(p,u,r,x,m);return true}if(p.editorCommands.execCommand(u,r,x)){p.onExecCommand.dispatch(p,u,r,x,m);return true}p.getDoc().execCommand(u,r,x);p.onExecCommand.dispatch(p,u,r,x,m)},queryCommandState:function(q){var n=this,r,p;if(n._isHidden()){return}if(r=n.queryStateCommands[q]){p=r.func.call(r.scope);if(p!==true){return p}}r=n.editorCommands.queryCommandState(q);if(r!==-1){return r}try{return this.getDoc().queryCommandState(q)}catch(m){}},queryCommandValue:function(r){var n=this,q,p;if(n._isHidden()){return}if(q=n.queryValueCommands[r]){p=q.func.call(q.scope);if(p!==true){return p}}q=n.editorCommands.queryCommandValue(r);if(d(q)){return q}try{return this.getDoc().queryCommandValue(r)}catch(m){}},show:function(){var m=this;l.show(m.getContainer());l.hide(m.id);m.load()},hide:function(){var m=this,n=m.getDoc();if(b&&n){n.execCommand("SelectAll")}m.save();l.hide(m.getContainer());l.setStyle(m.id,"display",m.orgDisplay)},isHidden:function(){return !l.isHidden(this.id)},setProgressState:function(m,n,p){this.onSetProgressState.dispatch(this,m,n,p);return m},load:function(q){var m=this,p=m.getElement(),n;if(p){q=q||{};q.load=true;n=m.setContent(d(p.value)?p.value:p.innerHTML,q);q.element=p;if(!q.no_events){m.onLoadContent.dispatch(m,q)}q.element=p=null;return n}},save:function(r){var m=this,q=m.getElement(),n,p;if(!q||!m.initialized){return}r=r||{};r.save=true;r.element=q;n=r.content=m.getContent(r);if(!r.no_events){m.onSaveContent.dispatch(m,r)}n=r.content;if(!/TEXTAREA|INPUT/i.test(q.nodeName)){q.innerHTML=n;if(p=l.getParent(m.id,"form")){i(p.elements,function(o){if(o.name==m.id){o.value=n;return false}})}}else{q.value=n}r.element=q=null;return n},setContent:function(r,p){var o=this,n,m=o.getBody(),q;p=p||{};p.format=p.format||"html";p.set=true;p.content=r;if(!p.no_events){o.onBeforeSetContent.dispatch(o,p)}r=p.content;if(!k.isIE&&(r.length===0||/^\s+$/.test(r))){q=o.settings.forced_root_block;if(q){r="<"+q+'><br data-mce-bogus="1"></'+q+">"}else{r='<br data-mce-bogus="1">'}m.innerHTML=r;o.selection.select(m,true);o.selection.collapse(true);return}if(p.format!=="raw"){r=new k.html.Serializer({},o.schema).serialize(o.parser.parse(r))}p.content=k.trim(r);o.dom.setHTML(m,p.content);if(!p.no_events){o.onSetContent.dispatch(o,p)}if(!o.settings.content_editable||document.activeElement===o.getBody()){o.selection.normalize()}return p.content},getContent:function(o){var n=this,p,m=n.getBody();o=o||{};o.format=o.format||"html";o.get=true;o.getInner=true;if(!o.no_events){n.onBeforeGetContent.dispatch(n,o)}if(o.format=="raw"){p=m.innerHTML}else{if(o.format=="text"){p=m.innerText||m.textContent}else{p=n.serializer.serialize(m,o)}}if(o.format!="text"){o.content=k.trim(p)}else{o.content=p}if(!o.no_events){n.onGetContent.dispatch(n,o)}return o.content},isDirty:function(){var m=this;return k.trim(m.startContent)!=k.trim(m.getContent({format:"raw",no_events:1}))&&!m.isNotDirty},getContainer:function(){var m=this;if(!m.container){m.container=l.get(m.editorContainer||m.id+"_parent")}return m.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return l.get(this.settings.content_element||this.id)},getWin:function(){var m=this,n;if(!m.contentWindow){n=l.get(m.id+"_ifr");if(n){m.contentWindow=n.contentWindow}}return m.contentWindow},getDoc:function(){var m=this,n;if(!m.contentDocument){n=m.getWin();if(n){m.contentDocument=n.document}}return m.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(o,n,q){var m=this,p=m.settings;if(p.urlconverter_callback){return m.execCallback("urlconverter_callback",o,q,true,n)}if(!p.convert_urls||(q&&q.nodeName=="LINK")||o.indexOf("file:")===0){return o}if(p.relative_urls){return m.documentBaseURI.toRelative(o)}o=m.documentBaseURI.toAbsolute(o,p.remove_script_host);return o},addVisual:function(q){var n=this,o=n.settings,p=n.dom,m;q=q||n.getBody();if(!d(n.hasVisual)){n.hasVisual=o.visual}i(p.select("table,a",q),function(s){var r;switch(s.nodeName){case"TABLE":m=o.visual_table_class||"mceItemTable";r=p.getAttrib(s,"border");if(!r||r=="0"){if(n.hasVisual){p.addClass(s,m)}else{p.removeClass(s,m)}}return;case"A":if(!p.getAttrib(s,"href",false)){r=p.getAttrib(s,"name")||s.id;m="mceItemAnchor";if(r){if(n.hasVisual){p.addClass(s,m)}else{p.removeClass(s,m)}}}return}});n.onVisualAid.dispatch(n,q,n.hasVisual)},remove:function(){var m=this,o=m.getContainer(),n=m.getDoc();if(!m.removed){m.removed=1;if(b&&n){n.execCommand("SelectAll")}m.save();l.setStyle(m.id,"display",m.orgDisplay);if(!m.settings.content_editable){j.unbind(m.getWin());j.unbind(m.getDoc())}j.unbind(m.getBody());j.clear(o);m.execCallback("remove_instance_callback",m);m.onRemove.dispatch(m);m.onExecCommand.listeners=[];k.remove(m);l.remove(o)}},destroy:function(n){var m=this;if(m.destroyed){return}if(a){j.unbind(m.getDoc());j.unbind(m.getWin());j.unbind(m.getBody())}if(!n){k.removeUnload(m.destroy);tinyMCE.onBeforeUnload.remove(m._beforeUnload);if(m.theme&&m.theme.destroy){m.theme.destroy()}m.controlManager.destroy();m.selection.destroy();m.dom.destroy()}if(m.formElement){m.formElement.submit=m.formElement._mceOldSubmit;m.formElement._mceOldSubmit=null}m.contentAreaContainer=m.formElement=m.container=m.settings.content_element=m.bodyElement=m.contentDocument=m.contentWindow=null;if(m.selection){m.selection=m.selection.win=m.selection.dom=m.selection.dom.doc=null}m.destroyed=1},_refreshContentEditable:function(){var n=this,m,o;if(n._isHidden()){m=n.getBody();o=m.parentNode;o.removeChild(m);o.appendChild(m);m.focus()}},_isHidden:function(){var m;if(!a){return 0}m=this.selection.getSel();return(!m||!m.rangeCount||m.rangeCount===0)}})})(tinymce);(function(a){var b=a.each;a.Editor.prototype.setupEvents=function(){var c=this,d=c.settings;b(["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){c[e]=new a.util.Dispatcher(c)});if(d.cleanup_callback){c.onBeforeSetContent.add(function(e,f){f.content=e.execCallback("cleanup_callback","insert_to_editor",f.content,f)});c.onPreProcess.add(function(e,f){if(f.set){e.execCallback("cleanup_callback","insert_to_editor_dom",f.node,f)}if(f.get){e.execCallback("cleanup_callback","get_from_editor_dom",f.node,f)}});c.onPostProcess.add(function(e,f){if(f.set){f.content=e.execCallback("cleanup_callback","insert_to_editor",f.content,f)}if(f.get){f.content=e.execCallback("cleanup_callback","get_from_editor",f.content,f)}})}if(d.save_callback){c.onGetContent.add(function(e,f){if(f.save){f.content=e.execCallback("save_callback",e.id,f.content,e.getBody())}})}if(d.handle_event_callback){c.onEvent.add(function(f,g,h){if(c.execCallback("handle_event_callback",g,f,h)===false){g.preventDefault();g.stopPropagation()}})}if(d.handle_node_change_callback){c.onNodeChange.add(function(f,e,g){f.execCallback("handle_node_change_callback",f.id,g,-1,-1,true,f.selection.isCollapsed())})}if(d.save_callback){c.onSaveContent.add(function(e,g){var f=e.execCallback("save_callback",e.id,g.content,e.getBody());if(f){g.content=f}})}if(d.onchange_callback){c.onChange.add(function(f,e){f.execCallback("onchange_callback",f,e)})}};a.Editor.prototype.bindNativeEvents=function(){var l=this,f,d=l.settings,e=l.dom,h;h={mouseup:"onMouseUp",mousedown:"onMouseDown",click:"onClick",keyup:"onKeyUp",keydown:"onKeyDown",keypress:"onKeyPress",submit:"onSubmit",reset:"onReset",contextmenu:"onContextMenu",dblclick:"onDblClick",paste:"onPaste"};function c(i,m){var n=i.type;if(l.removed){return}if(l.onEvent.dispatch(l,i,m)!==false){l[h[i.fakeType||i.type]].dispatch(l,i,m)}}function j(i){l.focus(true)}function k(i,m){if(m.keyCode!=65||!a.VK.metaKeyPressed(m)){l.selection.normalize()}l.nodeChanged()}b(h,function(m,n){var i=d.content_editable?l.getBody():l.getDoc();switch(n){case"contextmenu":e.bind(i,n,c);break;case"paste":e.bind(l.getBody(),n,c);break;case"submit":case"reset":e.bind(l.getElement().form||a.DOM.getParent(l.id,"form"),n,c);break;default:e.bind(i,n,c)}});e.bind(d.content_editable?l.getBody():(a.isGecko?l.getDoc():l.getWin()),"focus",function(i){l.focus(true)});if(d.content_editable&&a.isOpera){e.bind(l.getBody(),"click",j);e.bind(l.getBody(),"keydown",j)}l.onMouseUp.add(k);l.onKeyUp.add(function(i,n){var m=n.keyCode;if((m>=33&&m<=36)||(m>=37&&m<=40)||m==13||m==45||m==46||m==8||(a.isMac&&(m==91||m==93))||n.ctrlKey){k(i,n)}});l.onReset.add(function(){l.setContent(l.startContent,{format:"raw"})});function g(m,i){if(m.altKey||m.ctrlKey||m.metaKey){b(l.shortcuts,function(n){var o=a.isMac?m.metaKey:m.ctrlKey;if(n.ctrl!=o||n.alt!=m.altKey||n.shift!=m.shiftKey){return}if(m.keyCode==n.keyCode||(m.charCode&&m.charCode==n.charCode)){m.preventDefault();if(i){n.func.call(n.scope)}return true}})}}l.onKeyUp.add(function(i,m){g(m)});l.onKeyPress.add(function(i,m){g(m)});l.onKeyDown.add(function(i,m){g(m,true)});if(a.isOpera){l.onClick.add(function(i,m){m.preventDefault()})}}})(tinymce);(function(d){var e=d.each,b,a=true,c=false;d.EditorCommands=function(n){var m=n.dom,p=n.selection,j={state:{},exec:{},value:{}},k=n.settings,q=n.formatter,o;function r(z,y,x){var v;z=z.toLowerCase();if(v=j.exec[z]){v(z,y,x);return a}return c}function l(x){var v;x=x.toLowerCase();if(v=j.state[x]){return v(x)}return -1}function h(x){var v;x=x.toLowerCase();if(v=j.value[x]){return v(x)}return c}function u(v,x){x=x||"exec";e(v,function(z,y){e(y.toLowerCase().split(","),function(A){j[x][A]=z})})}d.extend(this,{execCommand:r,queryCommandState:l,queryCommandValue:h,addCommands:u});function f(y,x,v){if(x===b){x=c}if(v===b){v=null}return n.getDoc().execCommand(y,x,v)}function t(v){return q.match(v)}function s(v,x){q.toggle(v,x?{value:x}:b)}function i(v){o=p.getBookmark(v)}function g(){p.moveToBookmark(o)}u({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){n.undoManager.add()},"Cut,Copy,Paste":function(z){var y=n.getDoc(),v;try{f(z)}catch(x){v=a}if(v||!y.queryCommandSupported(z)){if(d.isGecko){n.windowManager.confirm(n.getLang("clipboard_msg"),function(A){if(A){open("http://www.mozilla.org/editor/midasdemo/securityprefs.html","_blank")}})}else{n.windowManager.alert(n.getLang("clipboard_no_support"))}}},unlink:function(v){if(p.isCollapsed()){p.select(p.getNode())}f(v);p.collapse(c)},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(v){var x=v.substring(7);e("left,center,right,full".split(","),function(y){if(x!=y){q.remove("align"+y)}});s("align"+x);r("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(y){var v,x;f(y);v=m.getParent(p.getNode(),"ol,ul");if(v){x=v.parentNode;if(/^(H[1-6]|P|ADDRESS|PRE)$/.test(x.nodeName)){i();m.split(x,v);g()}}},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(v){s(v)},"ForeColor,HiliteColor,FontName":function(y,x,v){s(y,v)},FontSize:function(z,y,x){var v,A;if(x>=1&&x<=7){A=d.explode(k.font_size_style_values);v=d.explode(k.font_size_classes);if(v){x=v[x-1]||x}else{x=A[x-1]||x}}s(z,x)},RemoveFormat:function(v){q.remove(v)},mceBlockQuote:function(v){s("blockquote")},FormatBlock:function(y,x,v){return s(v||"p")},mceCleanup:function(){var v=p.getBookmark();n.setContent(n.getContent({cleanup:a}),{cleanup:a});p.moveToBookmark(v)},mceRemoveNode:function(z,y,x){var v=x||p.getNode();if(v!=n.getBody()){i();n.dom.remove(v,a);g()}},mceSelectNodeDepth:function(z,y,x){var v=0;m.getParent(p.getNode(),function(A){if(A.nodeType==1&&v++==x){p.select(A);return c}},n.getBody())},mceSelectNode:function(y,x,v){p.select(v)},mceInsertContent:function(B,I,K){var y,J,E,z,F,G,D,C,L,x,A,M,v,H;y=n.parser;J=new d.html.Serializer({},n.schema);v='<span id="mce_marker" data-mce-type="bookmark">\uFEFF</span>';G={content:K,format:"html"};p.onBeforeSetContent.dispatch(p,G);K=G.content;if(K.indexOf("{$caret}")==-1){K+="{$caret}"}K=K.replace(/\{\$caret\}/,v);if(!p.isCollapsed()){n.getDoc().execCommand("Delete",false,null)}E=p.getNode();G={context:E.nodeName.toLowerCase()};F=y.parse(K,G);A=F.lastChild;if(A.attr("id")=="mce_marker"){D=A;for(A=A.prev;A;A=A.walk(true)){if(A.type==3||!m.isBlock(A.name)){A.parent.insert(D,A,A.name==="br");break}}}if(!G.invalid){K=J.serialize(F);A=E.firstChild;M=E.lastChild;if(!A||(A===M&&A.nodeName==="BR")){m.setHTML(E,K)}else{p.setContent(K)}}else{p.setContent(v);E=p.getNode();z=n.getBody();if(E.nodeType==9){E=A=z}else{A=E}while(A!==z){E=A;A=A.parentNode}K=E==z?z.innerHTML:m.getOuterHTML(E);K=J.serialize(y.parse(K.replace(/<span (id="mce_marker"|id=mce_marker).+?<\/span>/i,function(){return J.serialize(F)})));if(E==z){m.setHTML(z,K)}else{m.setOuterHTML(E,K)}}D=m.get("mce_marker");C=m.getRect(D);L=m.getViewPort(n.getWin());if((C.y+C.h>L.y+L.h||C.y<L.y)||(C.x>L.x+L.w||C.x<L.x)){H=d.isIE?n.getDoc().documentElement:n.getBody();H.scrollLeft=C.x;H.scrollTop=C.y-L.h+25}x=m.createRng();A=D.previousSibling;if(A&&A.nodeType==3){x.setStart(A,A.nodeValue.length)}else{x.setStartBefore(D);x.setEndBefore(D)}m.remove(D);p.setRng(x);p.onSetContent.dispatch(p,G);n.addVisual()},mceInsertRawHTML:function(y,x,v){p.setContent("tiny_mce_marker");n.setContent(n.getContent().replace(/tiny_mce_marker/g,function(){return v}))},mceToggleFormat:function(y,x,v){s(v)},mceSetContent:function(y,x,v){n.setContent(v)},"Indent,Outdent":function(z){var x,v,y;x=k.indentation;v=/[a-z%]+$/i.exec(x);x=parseInt(x);if(!l("InsertUnorderedList")&&!l("InsertOrderedList")){if(!k.forced_root_block&&!m.getParent(p.getNode(),m.isBlock)){q.apply("div")}e(p.getSelectedBlocks(),function(A){if(z=="outdent"){y=Math.max(0,parseInt(A.style.paddingLeft||0)-x);m.setStyle(A,"paddingLeft",y?y+v:"")}else{m.setStyle(A,"paddingLeft",(parseInt(A.style.paddingLeft||0)+x)+v)}})}else{f(z)}},mceRepaint:function(){var x;if(d.isGecko){try{i(a);if(p.getSel()){p.getSel().selectAllChildren(n.getBody())}p.collapse(a);g()}catch(v){}}},mceToggleFormat:function(y,x,v){q.toggle(v)},InsertHorizontalRule:function(){n.execCommand("mceInsertContent",false,"<hr />")},mceToggleVisualAid:function(){n.hasVisual=!n.hasVisual;n.addVisual()},mceReplaceContent:function(y,x,v){n.execCommand("mceInsertContent",false,v.replace(/\{\$selection\}/g,p.getContent({format:"text"})))},mceInsertLink:function(z,y,x){var v;if(typeof(x)=="string"){x={href:x}}v=m.getParent(p.getNode(),"a");x.href=x.href.replace(" ","%20");if(!v||!x.href){q.remove("link")}if(x.href){q.apply("link",x,v)}},selectAll:function(){var x=m.getRoot(),v=m.createRng();if(p.getRng().setStart){v.setStart(x,0);v.setEnd(x,x.childNodes.length);p.setRng(v)}else{f("SelectAll")}}});u({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(z){var x="align"+z.substring(7);var v=p.isCollapsed()?[m.getParent(p.getNode(),m.isBlock)]:p.getSelectedBlocks();var y=d.map(v,function(A){return !!q.matchNode(A,x)});return d.inArray(y,a)!==-1},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(v){return t(v)},mceBlockQuote:function(){return t("blockquote")},Outdent:function(){var v;if(k.inline_styles){if((v=m.getParent(p.getStart(),m.isBlock))&&parseInt(v.style.paddingLeft)>0){return a}if((v=m.getParent(p.getEnd(),m.isBlock))&&parseInt(v.style.paddingLeft)>0){return a}}return l("InsertUnorderedList")||l("InsertOrderedList")||(!k.inline_styles&&!!m.getParent(p.getNode(),"BLOCKQUOTE"))},"InsertUnorderedList,InsertOrderedList":function(x){var v=m.getParent(p.getNode(),"ul,ol");return v&&(x==="insertunorderedlist"&&v.tagName==="UL"||x==="insertorderedlist"&&v.tagName==="OL")}},"state");u({"FontSize,FontName":function(y){var x=0,v;if(v=m.getParent(p.getNode(),"span")){if(y=="fontsize"){x=v.style.fontSize}else{x=v.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase()}}return x}},"value");u({Undo:function(){n.undoManager.undo()},Redo:function(){n.undoManager.redo()}})}})(tinymce);(function(b){var a=b.util.Dispatcher;b.UndoManager=function(h){var l,i=0,e=[],g,k,j,f;function c(){return b.trim(h.getContent({format:"raw",no_events:1}).replace(/<span[^>]+data-mce-bogus[^>]+>[\u200B\uFEFF]+<\/span>/g,""))}function d(){l.typing=false;l.add()}onBeforeAdd=new a(l);k=new a(l);j=new a(l);f=new a(l);k.add(function(m,n){if(m.hasUndo()){return h.onChange.dispatch(h,n,m)}});j.add(function(m,n){return h.onUndo.dispatch(h,n,m)});f.add(function(m,n){return h.onRedo.dispatch(h,n,m)});h.onInit.add(function(){l.add()});h.onBeforeExecCommand.add(function(m,p,o,q,n){if(p!="Undo"&&p!="Redo"&&p!="mceRepaint"&&(!n||!n.skip_undo)){l.beforeChange()}});h.onExecCommand.add(function(m,p,o,q,n){if(p!="Undo"&&p!="Redo"&&p!="mceRepaint"&&(!n||!n.skip_undo)){l.add()}});h.onSaveContent.add(d);h.dom.bind(h.dom.getRoot(),"dragend",d);h.dom.bind(h.getBody(),"focusout",function(m){if(!h.removed&&l.typing){d()}});h.onKeyUp.add(function(m,o){var n=o.keyCode;if((n>=33&&n<=36)||(n>=37&&n<=40)||n==45||n==13||o.ctrlKey){d()}});h.onKeyDown.add(function(m,o){var n=o.keyCode;if((n>=33&&n<=36)||(n>=37&&n<=40)||n==45){if(l.typing){d()}return}if((n<16||n>20)&&n!=224&&n!=91&&!l.typing){l.beforeChange();l.typing=true;l.add()}});h.onMouseDown.add(function(m,n){if(l.typing){d()}});h.addShortcut("ctrl+z","undo_desc","Undo");h.addShortcut("ctrl+y","redo_desc","Redo");l={data:e,typing:false,onBeforeAdd:onBeforeAdd,onAdd:k,onUndo:j,onRedo:f,beforeChange:function(){g=h.selection.getBookmark(2,true)},add:function(p){var m,n=h.settings,o;p=p||{};p.content=c();l.onBeforeAdd.dispatch(l,p);o=e[i];if(o&&o.content==p.content){return null}if(e[i]){e[i].beforeBookmark=g}if(n.custom_undo_redo_levels){if(e.length>n.custom_undo_redo_levels){for(m=0;m<e.length-1;m++){e[m]=e[m+1]}e.length--;i=e.length}}p.bookmark=h.selection.getBookmark(2,true);if(i<e.length-1){e.length=i+1}e.push(p);i=e.length-1;l.onAdd.dispatch(l,p);h.isNotDirty=0;return p},undo:function(){var n,m;if(l.typing){l.add();l.typing=false}if(i>0){n=e[--i];h.setContent(n.content,{format:"raw"});h.selection.moveToBookmark(n.beforeBookmark);l.onUndo.dispatch(l,n)}return n},redo:function(){var m;if(i<e.length-1){m=e[++i];h.setContent(m.content,{format:"raw"});h.selection.moveToBookmark(m.bookmark);l.onRedo.dispatch(l,m)}return m},clear:function(){e=[];i=0;l.typing=false},hasUndo:function(){return i>0||this.typing},hasRedo:function(){return i<e.length-1&&!this.typing}};return l}})(tinymce);tinymce.ForceBlocks=function(c){var b=c.settings,e=c.dom,a=c.selection,d=c.schema.getBlockElements();function f(){var j=a.getStart(),h=c.getBody(),g,k,o,s,q,i,l,m=-16777215,p,r;if(!j||j.nodeType!==1||!b.forced_root_block){return}while(j&&j!=h){if(d[j.nodeName]){return}j=j.parentNode}g=a.getRng();if(g.setStart){k=g.startContainer;o=g.startOffset;s=g.endContainer;q=g.endOffset}else{if(g.item){j=g.item(0);g=c.getDoc().body.createTextRange();g.moveToElementText(j)}r=g.parentElement().ownerDocument===c.getDoc();tmpRng=g.duplicate();tmpRng.collapse(true);o=tmpRng.move("character",m)*-1;if(!tmpRng.collapsed){tmpRng=g.duplicate();tmpRng.collapse(false);q=(tmpRng.move("character",m)*-1)-o}}j=h.firstChild;while(j){if(j.nodeType===3||(j.nodeType==1&&!d[j.nodeName])){if(j.nodeType===3&&j.nodeValue.length==0){l=j;j=j.nextSibling;e.remove(l);continue}if(!i){i=e.create(b.forced_root_block);j.parentNode.insertBefore(i,j);p=true}l=j;j=j.nextSibling;i.appendChild(l)}else{i=null;j=j.nextSibling}}if(p){if(g.setStart){g.setStart(k,o);g.setEnd(s,q);a.setRng(g)}else{if(r){try{g=c.getDoc().body.createTextRange();g.moveToElementText(h);g.collapse(true);g.moveStart("character",o);if(q>0){g.moveEnd("character",q)}g.select()}catch(n){}}}c.nodeChanged()}}if(b.forced_root_block){c.onKeyUp.add(f);c.onNodeChange.add(f)}};(function(c){var b=c.DOM,a=c.dom.Event,d=c.each,e=c.extend;c.create("tinymce.ControlManager",{ControlManager:function(f,j){var h=this,g;j=j||{};h.editor=f;h.controls={};h.onAdd=new c.util.Dispatcher(h);h.onPostRender=new c.util.Dispatcher(h);h.prefix=j.prefix||f.id+"_";h._cls={};h.onPostRender.add(function(){d(h.controls,function(i){i.postRender()})})},get:function(f){return this.controls[this.prefix+f]||this.controls[f]},setActive:function(h,f){var g=null;if(g=this.get(h)){g.setActive(f)}return g},setDisabled:function(h,f){var g=null;if(g=this.get(h)){g.setDisabled(f)}return g},add:function(g){var f=this;if(g){f.controls[g.id]=g;f.onAdd.dispatch(g,f)}return g},createControl:function(j){var o,k,g,h=this,m=h.editor,n,f;if(!h.controlFactories){h.controlFactories=[];d(m.plugins,function(i){if(i.createControl){h.controlFactories.push(i)}})}n=h.controlFactories;for(k=0,g=n.length;k<g;k++){o=n[k].createControl(j,h);if(o){return h.add(o)}}if(j==="|"||j==="separator"){return h.createSeparator()}if(m.buttons&&(o=m.buttons[j])){return h.createButton(j,o)}return h.add(o)},createDropMenu:function(f,n,h){var m=this,i=m.editor,j,g,k,l;n=e({"class":"mceDropDown",constrain:i.settings.constrain_menus},n);n["class"]=n["class"]+" "+i.getParam("skin")+"Skin";if(k=i.getParam("skin_variant")){n["class"]+=" "+i.getParam("skin")+"Skin"+k.substring(0,1).toUpperCase()+k.substring(1)}n["class"]+=i.settings.directionality=="rtl"?" mceRtl":"";f=m.prefix+f;l=h||m._cls.dropmenu||c.ui.DropMenu;j=m.controls[f]=new l(f,n);j.onAddItem.add(function(r,q){var p=q.settings;p.title=i.getLang(p.title,p.title);if(!p.onclick){p.onclick=function(o){if(p.cmd){i.execCommand(p.cmd,p.ui||false,p.value)}}}});i.onRemove.add(function(){j.destroy()});if(c.isIE){j.onShowMenu.add(function(){i.focus();g=i.selection.getBookmark(1)});j.onHideMenu.add(function(){if(g){i.selection.moveToBookmark(g);g=0}})}return m.add(j)},createListBox:function(f,n,h){var l=this,j=l.editor,i,k,m;if(l.get(f)){return null}n.title=j.translate(n.title);n.scope=n.scope||j;if(!n.onselect){n.onselect=function(o){j.execCommand(n.cmd,n.ui||false,o||n.value)}}n=e({title:n.title,"class":"mce_"+f,scope:n.scope,control_manager:l},n);f=l.prefix+f;function g(o){return o.settings.use_accessible_selects&&!c.isGecko}if(j.settings.use_native_selects||g(j)){k=new c.ui.NativeListBox(f,n)}else{m=h||l._cls.listbox||c.ui.ListBox;k=new m(f,n,j)}l.controls[f]=k;if(c.isWebKit){k.onPostRender.add(function(p,o){a.add(o,"mousedown",function(){j.bookmark=j.selection.getBookmark(1)});a.add(o,"focus",function(){j.selection.moveToBookmark(j.bookmark);j.bookmark=null})})}if(k.hideMenu){j.onMouseDown.add(k.hideMenu,k)}return l.add(k)},createButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.label=g.translate(i.label);i.scope=i.scope||g;if(!i.onclick&&!i.menu_button){i.onclick=function(){g.execCommand(i.cmd,i.ui||false,i.value)}}i=e({title:i.title,"class":"mce_"+m,unavailable_prefix:g.getLang("unavailable",""),scope:i.scope,control_manager:h},i);m=h.prefix+m;if(i.menu_button){f=l||h._cls.menubutton||c.ui.MenuButton;k=new f(m,i,g);g.onMouseDown.add(k.hideMenu,k)}else{f=h._cls.button||c.ui.Button;k=new f(m,i,g)}return h.add(k)},createMenuButton:function(h,f,g){f=f||{};f.menu_button=1;return this.createButton(h,f,g)},createSplitButton:function(m,i,l){var h=this,g=h.editor,j,k,f;if(h.get(m)){return null}i.title=g.translate(i.title);i.scope=i.scope||g;if(!i.onclick){i.onclick=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}if(!i.onselect){i.onselect=function(n){g.execCommand(i.cmd,i.ui||false,n||i.value)}}i=e({title:i.title,"class":"mce_"+m,scope:i.scope,control_manager:h},i);m=h.prefix+m;f=l||h._cls.splitbutton||c.ui.SplitButton;k=h.add(new f(m,i,g));g.onMouseDown.add(k.hideMenu,k);return k},createColorSplitButton:function(f,n,h){var l=this,j=l.editor,i,k,m,g;if(l.get(f)){return null}n.title=j.translate(n.title);n.scope=n.scope||j;if(!n.onclick){n.onclick=function(o){if(c.isIE){g=j.selection.getBookmark(1)}j.execCommand(n.cmd,n.ui||false,o||n.value)}}if(!n.onselect){n.onselect=function(o){j.execCommand(n.cmd,n.ui||false,o||n.value)}}n=e({title:n.title,"class":"mce_"+f,menu_class:j.getParam("skin")+"Skin",scope:n.scope,more_colors_title:j.getLang("more_colors")},n);f=l.prefix+f;m=h||l._cls.colorsplitbutton||c.ui.ColorSplitButton;k=new m(f,n,j);j.onMouseDown.add(k.hideMenu,k);j.onRemove.add(function(){k.destroy()});if(c.isIE){k.onShowMenu.add(function(){j.focus();g=j.selection.getBookmark(1)});k.onHideMenu.add(function(){if(g){j.selection.moveToBookmark(g);g=0}})}return l.add(k)},createToolbar:function(k,h,j){var i,g=this,f;k=g.prefix+k;f=j||g._cls.toolbar||c.ui.Toolbar;i=new f(k,h,g.editor);if(g.get(k)){return null}return g.add(i)},createToolbarGroup:function(k,h,j){var i,g=this,f;k=g.prefix+k;f=j||this._cls.toolbarGroup||c.ui.ToolbarGroup;i=new f(k,h,g.editor);if(g.get(k)){return null}return g.add(i)},createSeparator:function(g){var f=g||this._cls.separator||c.ui.Separator;return new f()},setControlType:function(g,f){return this._cls[g.toLowerCase()]=f},destroy:function(){d(this.controls,function(f){f.destroy()});this.controls=null}})})(tinymce);(function(d){var a=d.util.Dispatcher,e=d.each,c=d.isIE,b=d.isOpera;d.create("tinymce.WindowManager",{WindowManager:function(f){var g=this;g.editor=f;g.onOpen=new a(g);g.onClose=new a(g);g.params={};g.features={}},open:function(z,h){var v=this,k="",n,m,i=v.editor.settings.dialog_type=="modal",q,o,j,g=d.DOM.getViewPort(),r;z=z||{};h=h||{};o=b?g.w:screen.width;j=b?g.h:screen.height;z.name=z.name||"mc_"+new Date().getTime();z.width=parseInt(z.width||320);z.height=parseInt(z.height||240);z.resizable=true;z.left=z.left||parseInt(o/2)-(z.width/2);z.top=z.top||parseInt(j/2)-(z.height/2);h.inline=false;h.mce_width=z.width;h.mce_height=z.height;h.mce_auto_focus=z.auto_focus;if(i){if(c){z.center=true;z.help=false;z.dialogWidth=z.width+"px";z.dialogHeight=z.height+"px";z.scroll=z.scrollbars||false}}e(z,function(p,f){if(d.is(p,"boolean")){p=p?"yes":"no"}if(!/^(name|url)$/.test(f)){if(c&&i){k+=(k?";":"")+f+":"+p}else{k+=(k?",":"")+f+"="+p}}});v.features=z;v.params=h;v.onOpen.dispatch(v,z,h);r=z.url||z.file;r=d._addVer(r);try{if(c&&i){q=1;window.showModalDialog(r,window,k)}else{q=window.open(r,z.name,k)}}catch(l){}if(!q){alert(v.editor.getLang("popup_blocked"))}},close:function(f){f.close();this.onClose.dispatch(this)},createInstance:function(i,h,g,m,l,k){var j=d.resolve(i);return new j(h,g,m,l,k)},confirm:function(h,f,i,g){g=g||window;f.call(i||this,g.confirm(this._decode(this.editor.getLang(h,h))))},alert:function(h,f,j,g){var i=this;g=g||window;g.alert(i._decode(i.editor.getLang(h,h)));if(f){f.call(j||i)}},resizeBy:function(f,g,h){h.resizeBy(f,g)},_decode:function(f){return d.DOM.decode(f).replace(/\\n/g,"\n")}})}(tinymce));(function(a){a.Formatter=function(aa){var Q={},T=a.each,c=aa.dom,r=aa.selection,t=a.dom.TreeWalker,N=new a.dom.RangeUtils(c),d=aa.schema.isValidChild,A=a.isArray,H=c.isBlock,m=aa.settings.forced_root_block,s=c.nodeIndex,G="\uFEFF",e=/^(src|href|style)$/,X=false,C=true,P,D,x=c.getContentEditable;function I(ab){return !!aa.schema.getTextBlocks()[ab.toLowerCase()]}function n(ac,ab){return c.getParents(ac,ab,c.getRoot())}function b(ab){return ab.nodeType===1&&ab.id==="_mce_caret"}function j(){l({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(ab){return true},onformat:function(ad,ab,ac){T(ac,function(af,ae){c.setAttrib(ad,ae,af)})}},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}]});T("p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp".split(/\s/),function(ab){l(ab,{block:ab,remove:"all"})});l(aa.settings.formats)}function W(){aa.addShortcut("ctrl+b","bold_desc","Bold");aa.addShortcut("ctrl+i","italic_desc","Italic");aa.addShortcut("ctrl+u","underline_desc","Underline");for(var ab=1;ab<=6;ab++){aa.addShortcut("ctrl+"+ab,"",["FormatBlock",false,"h"+ab])}aa.addShortcut("ctrl+7","",["FormatBlock",false,"p"]);aa.addShortcut("ctrl+8","",["FormatBlock",false,"div"]);aa.addShortcut("ctrl+9","",["FormatBlock",false,"address"])}function V(ab){return ab?Q[ab]:Q}function l(ab,ac){if(ab){if(typeof(ab)!=="string"){T(ab,function(ae,ad){l(ad,ae)})}else{ac=ac.length?ac:[ac];T(ac,function(ad){if(ad.deep===D){ad.deep=!ad.selector}if(ad.split===D){ad.split=!ad.selector||ad.inline}if(ad.remove===D&&ad.selector&&!ad.inline){ad.remove="none"}if(ad.selector&&ad.inline){ad.mixed=true;ad.block_expand=true}if(typeof(ad.classes)==="string"){ad.classes=ad.classes.split(/\s+/)}});Q[ab]=ac}}}var i=function(ac){var ab;aa.dom.getParent(ac,function(ad){ab=aa.dom.getStyle(ad,"text-decoration");return ab&&ab!=="none"});return ab};var L=function(ab){var ac;if(ab.nodeType===1&&ab.parentNode&&ab.parentNode.nodeType===1){ac=i(ab.parentNode);if(aa.dom.getStyle(ab,"color")&&ac){aa.dom.setStyle(ab,"text-decoration",ac)}else{if(aa.dom.getStyle(ab,"textdecoration")===ac){aa.dom.setStyle(ab,"text-decoration",null)}}}};function Y(ae,al,ag){var ah=V(ae),am=ah[0],ak,ac,aj,ai=r.isCollapsed();function ab(aq,ap){ap=ap||am;if(aq){if(ap.onformat){ap.onformat(aq,ap,al,ag)}T(ap.styles,function(at,ar){c.setStyle(aq,ar,q(at,al))});T(ap.attributes,function(at,ar){c.setAttrib(aq,ar,q(at,al))});T(ap.classes,function(ar){ar=q(ar,al);if(!c.hasClass(aq,ar)){c.addClass(aq,ar)}})}}function af(){function ar(ay,aw){var ax=new t(aw);for(ag=ax.current();ag;ag=ax.prev()){if(ag.childNodes.length>1||ag==ay||ag.tagName=="BR"){return ag}}}var aq=aa.selection.getRng();var av=aq.startContainer;var ap=aq.endContainer;if(av!=ap&&aq.endOffset===0){var au=ar(av,ap);var at=au.nodeType==3?au.length:au.childNodes.length;aq.setEnd(au,at)}return aq}function ad(at,ay,aw,av,aq){var ap=[],ar=-1,ax,aA=-1,au=-1,az;T(at.childNodes,function(aC,aB){if(aC.nodeName==="UL"||aC.nodeName==="OL"){ar=aB;ax=aC;return false}});T(at.childNodes,function(aC,aB){if(aC.nodeName==="SPAN"&&c.getAttrib(aC,"data-mce-type")=="bookmark"){if(aC.id==ay.id+"_start"){aA=aB}else{if(aC.id==ay.id+"_end"){au=aB}}}});if(ar<=0||(aA<ar&&au>ar)){T(a.grep(at.childNodes),aq);return 0}else{az=c.clone(aw,X);T(a.grep(at.childNodes),function(aC,aB){if((aA<ar&&aB<ar)||(aA>ar&&aB>ar)){ap.push(aC);aC.parentNode.removeChild(aC)}});if(aA<ar){at.insertBefore(az,ax)}else{if(aA>ar){at.insertBefore(az,ax.nextSibling)}}av.push(az);T(ap,function(aB){az.appendChild(aB)});return az}}function an(aq,at,aw){var ap=[],av,ar,au=true;av=am.inline||am.block;ar=c.create(av);ab(ar);N.walk(aq,function(ax){var ay;function az(aA){var aF,aD,aB,aC,aE;aE=au;aF=aA.nodeName.toLowerCase();aD=aA.parentNode.nodeName.toLowerCase();if(aA.nodeType===1&&x(aA)){aE=au;au=x(aA)==="true";aC=true}if(g(aF,"br")){ay=0;if(am.block){c.remove(aA)}return}if(am.wrapper&&y(aA,ae,al)){ay=0;return}if(au&&!aC&&am.block&&!am.wrapper&&I(aF)){aA=c.rename(aA,av);ab(aA);ap.push(aA);ay=0;return}if(am.selector){T(ah,function(aG){if("collapsed" in aG&&aG.collapsed!==ai){return}if(c.is(aA,aG.selector)&&!b(aA)){ab(aA,aG);aB=true}});if(!am.inline||aB){ay=0;return}}if(au&&!aC&&d(av,aF)&&d(aD,av)&&!(!aw&&aA.nodeType===3&&aA.nodeValue.length===1&&aA.nodeValue.charCodeAt(0)===65279)&&!b(aA)){if(!ay){ay=c.clone(ar,X);aA.parentNode.insertBefore(ay,aA);ap.push(ay)}ay.appendChild(aA)}else{if(aF=="li"&&at){ay=ad(aA,at,ar,ap,az)}else{ay=0;T(a.grep(aA.childNodes),az);if(aC){au=aE}ay=0}}}T(ax,az)});if(am.wrap_links===false){T(ap,function(ax){function ay(aC){var aB,aA,az;if(aC.nodeName==="A"){aA=c.clone(ar,X);ap.push(aA);az=a.grep(aC.childNodes);for(aB=0;aB<az.length;aB++){aA.appendChild(az[aB])}aC.appendChild(aA)}T(a.grep(aC.childNodes),ay)}ay(ax)})}T(ap,function(az){var ax;function aA(aC){var aB=0;T(aC.childNodes,function(aD){if(!f(aD)&&!K(aD)){aB++}});return aB}function ay(aB){var aD,aC;T(aB.childNodes,function(aE){if(aE.nodeType==1&&!K(aE)&&!b(aE)){aD=aE;return X}});if(aD&&h(aD,am)){aC=c.clone(aD,X);ab(aC);c.replace(aC,aB,C);c.remove(aD,1)}return aC||aB}ax=aA(az);if((ap.length>1||!H(az))&&ax===0){c.remove(az,1);return}if(am.inline||am.wrapper){if(!am.exact&&ax===1){az=ay(az)}T(ah,function(aB){T(c.select(aB.inline,az),function(aD){var aC;if(aB.wrap_links===false){aC=aD.parentNode;do{if(aC.nodeName==="A"){return}}while(aC=aC.parentNode)}Z(aB,al,aD,aB.exact?aD:null)})});if(y(az.parentNode,ae,al)){c.remove(az,1);az=0;return C}if(am.merge_with_parents){c.getParent(az.parentNode,function(aB){if(y(aB,ae,al)){c.remove(az,1);az=0;return C}})}if(az&&am.merge_siblings!==false){az=u(E(az),az);az=u(az,E(az,C))}}})}if(am){if(ag){if(ag.nodeType){ac=c.createRng();ac.setStartBefore(ag);ac.setEndAfter(ag);an(p(ac,ah),null,true)}else{an(ag,null,true)}}else{if(!ai||!am.inline||c.select("td.mceSelected,th.mceSelected").length){var ao=aa.selection.getNode();if(!m&&ah[0].defaultBlock&&!c.getParent(ao,c.isBlock)){Y(ah[0].defaultBlock)}aa.selection.setRng(af());ak=r.getBookmark();an(p(r.getRng(C),ah),ak);if(am.styles&&(am.styles.color||am.styles.textDecoration)){a.walk(ao,L,"childNodes");L(ao)}r.moveToBookmark(ak);R(r.getRng(C));aa.nodeChanged()}else{U("apply",ae,al)}}}}function B(ad,am,af){var ag=V(ad),ao=ag[0],ak,aj,ac,al=true;function ae(av){var au,at,ar,aq,ax,aw;if(av.nodeType===3){return}if(av.nodeType===1&&x(av)){ax=al;al=x(av)==="true";aw=true}au=a.grep(av.childNodes);if(al&&!aw){for(at=0,ar=ag.length;at<ar;at++){if(Z(ag[at],am,av,av)){break}}}if(ao.deep){if(au.length){for(at=0,ar=au.length;at<ar;at++){ae(au[at])}if(aw){al=ax}}}}function ah(aq){var ar;T(n(aq.parentNode).reverse(),function(at){var au;if(!ar&&at.id!="_start"&&at.id!="_end"){au=y(at,ad,am);if(au&&au.split!==false){ar=at}}});return ar}function ab(au,aq,aw,az){var aA,ay,ax,at,av,ar;if(au){ar=au.parentNode;for(aA=aq.parentNode;aA&&aA!=ar;aA=aA.parentNode){ay=c.clone(aA,X);for(av=0;av<ag.length;av++){if(Z(ag[av],am,ay,ay)){ay=0;break}}if(ay){if(ax){ay.appendChild(ax)}if(!at){at=ay}ax=ay}}if(az&&(!ao.mixed||!H(au))){aq=c.split(au,aq)}if(ax){aw.parentNode.insertBefore(ax,aw);at.appendChild(aw)}}return aq}function an(aq){return ab(ah(aq),aq,aq,true)}function ai(at){var ar=c.get(at?"_start":"_end"),aq=ar[at?"firstChild":"lastChild"];if(K(aq)){aq=aq[at?"firstChild":"lastChild"]}c.remove(ar,true);return aq}function ap(aq){var at,au,ar;aq=p(aq,ag,C);if(ao.split){at=M(aq,C);au=M(aq);if(at!=au){if(/^(TR|TD)$/.test(at.nodeName)&&at.firstChild){at=(at.nodeName=="TD"?at.firstChild:at.firstChild.firstChild)||at}at=S(at,"span",{id:"_start","data-mce-type":"bookmark"});au=S(au,"span",{id:"_end","data-mce-type":"bookmark"});an(at);an(au);at=ai(C);au=ai()}else{at=au=an(at)}aq.startContainer=at.parentNode;aq.startOffset=s(at);aq.endContainer=au.parentNode;aq.endOffset=s(au)+1}N.walk(aq,function(av){T(av,function(aw){ae(aw);if(aw.nodeType===1&&aa.dom.getStyle(aw,"text-decoration")==="underline"&&aw.parentNode&&i(aw.parentNode)==="underline"){Z({deep:false,exact:true,inline:"span",styles:{textDecoration:"underline"}},null,aw)}})})}if(af){if(af.nodeType){ac=c.createRng();ac.setStartBefore(af);ac.setEndAfter(af);ap(ac)}else{ap(af)}return}if(!r.isCollapsed()||!ao.inline||c.select("td.mceSelected,th.mceSelected").length){ak=r.getBookmark();ap(r.getRng(C));r.moveToBookmark(ak);if(ao.inline&&k(ad,am,r.getStart())){R(r.getRng(true))}aa.nodeChanged()}else{U("remove",ad,am)}}function F(ac,ae,ad){var ab=V(ac);if(k(ac,ae,ad)&&(!("toggle" in ab[0])||ab[0].toggle)){B(ac,ae,ad)}else{Y(ac,ae,ad)}}function y(ac,ab,ah,af){var ad=V(ab),ai,ag,ae;function aj(an,ap,aq){var am,ao,ak=ap[aq],al;if(ap.onmatch){return ap.onmatch(an,ap,aq)}if(ak){if(ak.length===D){for(am in ak){if(ak.hasOwnProperty(am)){if(aq==="attributes"){ao=c.getAttrib(an,am)}else{ao=O(an,am)}if(af&&!ao&&!ap.exact){return}if((!af||ap.exact)&&!g(ao,q(ak[am],ah))){return}}}}else{for(al=0;al<ak.length;al++){if(aq==="attributes"?c.getAttrib(an,ak[al]):O(an,ak[al])){return ap}}}}return ap}if(ad&&ac){for(ag=0;ag<ad.length;ag++){ai=ad[ag];if(h(ac,ai)&&aj(ac,ai,"attributes")&&aj(ac,ai,"styles")){if(ae=ai.classes){for(ag=0;ag<ae.length;ag++){if(!c.hasClass(ac,ae[ag])){return}}}return ai}}}}function k(ad,af,ae){var ac;function ab(ag){ag=c.getParent(ag,function(ah){return !!y(ah,ad,af,true)});return y(ag,ad,af)}if(ae){return ab(ae)}ae=r.getNode();if(ab(ae)){return C}ac=r.getStart();if(ac!=ae){if(ab(ac)){return C}}return X}function v(ai,ah){var af,ag=[],ae={},ad,ac,ab;af=r.getStart();c.getParent(af,function(al){var ak,aj;for(ak=0;ak<ai.length;ak++){aj=ai[ak];if(!ae[aj]&&y(al,aj,ah)){ae[aj]=true;ag.push(aj)}}},c.getRoot());return ag}function z(af){var ah=V(af),ae,ad,ag,ac,ab;if(ah){ae=r.getStart();ad=n(ae);for(ac=ah.length-1;ac>=0;ac--){ab=ah[ac].selector;if(!ab){return C}for(ag=ad.length-1;ag>=0;ag--){if(c.is(ad[ag],ab)){return C}}}}return X}function J(ab,ae,ac){var ad;if(!P){P={};ad={};aa.onNodeChange.addToTop(function(ag,af,ai){var ah=n(ai),aj={};T(P,function(ak,al){T(ah,function(am){if(y(am,al,{},ak.similar)){if(!ad[al]){T(ak,function(an){an(true,{node:am,format:al,parents:ah})});ad[al]=ak}aj[al]=ak;return false}})});T(ad,function(ak,al){if(!aj[al]){delete ad[al];T(ak,function(am){am(false,{node:ai,format:al,parents:ah})})}})})}T(ab.split(","),function(af){if(!P[af]){P[af]=[];P[af].similar=ac}P[af].push(ae)});return this}a.extend(this,{get:V,register:l,apply:Y,remove:B,toggle:F,match:k,matchAll:v,matchNode:y,canApply:z,formatChanged:J});j();W();function h(ab,ac){if(g(ab,ac.inline)){return C}if(g(ab,ac.block)){return C}if(ac.selector){return c.is(ab,ac.selector)}}function g(ac,ab){ac=ac||"";ab=ab||"";ac=""+(ac.nodeName||ac);ab=""+(ab.nodeName||ab);return ac.toLowerCase()==ab.toLowerCase()}function O(ac,ab){var ad=c.getStyle(ac,ab);if(ab=="color"||ab=="backgroundColor"){ad=c.toHex(ad)}if(ab=="fontWeight"&&ad==700){ad="bold"}return""+ad}function q(ab,ac){if(typeof(ab)!="string"){ab=ab(ac)}else{if(ac){ab=ab.replace(/%(\w+)/g,function(ae,ad){return ac[ad]||ae})}}return ab}function f(ab){return ab&&ab.nodeType===3&&/^([\t \r\n]+|)$/.test(ab.nodeValue)}function S(ad,ac,ab){var ae=c.create(ac,ab);ad.parentNode.insertBefore(ae,ad);ae.appendChild(ad);return ae}function p(ab,am,ae){var ap,an,ah,al,ad=ab.startContainer,ai=ab.startOffset,ar=ab.endContainer,ak=ab.endOffset;function ao(aA){var au,ax,az,aw,av,at;au=ax=aA?ad:ar;av=aA?"previousSibling":"nextSibling";at=c.getRoot();function ay(aB){return aB.nodeName=="BR"&&aB.getAttribute("data-mce-bogus")&&!aB.nextSibling}if(au.nodeType==3&&!f(au)){if(aA?ai>0:ak<au.nodeValue.length){return au}}for(;;){if(!am[0].block_expand&&H(ax)){return ax}for(aw=ax[av];aw;aw=aw[av]){if(!K(aw)&&!f(aw)&&!ay(aw)){return ax}}if(ax.parentNode==at){au=ax;break}ax=ax.parentNode}return au}function ag(at,au){if(au===D){au=at.nodeType===3?at.length:at.childNodes.length}while(at&&at.hasChildNodes()){at=at.childNodes[au];if(at){au=at.nodeType===3?at.length:at.childNodes.length}}return{node:at,offset:au}}if(ad.nodeType==1&&ad.hasChildNodes()){an=ad.childNodes.length-1;ad=ad.childNodes[ai>an?an:ai];if(ad.nodeType==3){ai=0}}if(ar.nodeType==1&&ar.hasChildNodes()){an=ar.childNodes.length-1;ar=ar.childNodes[ak>an?an:ak-1];if(ar.nodeType==3){ak=ar.nodeValue.length}}function aq(au){var at=au;while(at){if(at.nodeType===1&&x(at)){return x(at)==="false"?at:au}at=at.parentNode}return au}function aj(au,ay,aA){var ax,av,az,at;function aw(aC,aE){var aF,aB,aD=aC.nodeValue;if(typeof(aE)=="undefined"){aE=aA?aD.length:0}if(aA){aF=aD.lastIndexOf(" ",aE);aB=aD.lastIndexOf("\u00a0",aE);aF=aF>aB?aF:aB;if(aF!==-1&&!ae){aF++}}else{aF=aD.indexOf(" ",aE);aB=aD.indexOf("\u00a0",aE);aF=aF!==-1&&(aB===-1||aF<aB)?aF:aB}return aF}if(au.nodeType===3){az=aw(au,ay);if(az!==-1){return{container:au,offset:az}}at=au}ax=new t(au,c.getParent(au,H)||aa.getBody());while(av=ax[aA?"prev":"next"]()){if(av.nodeType===3){at=av;az=aw(av);if(az!==-1){return{container:av,offset:az}}}else{if(H(av)){break}}}if(at){if(aA){ay=0}else{ay=at.length}return{container:at,offset:ay}}}function af(au,at){var av,aw,ay,ax;if(au.nodeType==3&&au.nodeValue.length===0&&au[at]){au=au[at]}av=n(au);for(aw=0;aw<av.length;aw++){for(ay=0;ay<am.length;ay++){ax=am[ay];if("collapsed" in ax&&ax.collapsed!==ab.collapsed){continue}if(c.is(av[aw],ax.selector)){return av[aw]}}}return au}function ac(au,at,aw){var av;if(!am[0].wrapper){av=c.getParent(au,am[0].block)}if(!av){av=c.getParent(au.nodeType==3?au.parentNode:au,I)}if(av&&am[0].wrapper){av=n(av,"ul,ol").reverse()[0]||av}if(!av){av=au;while(av[at]&&!H(av[at])){av=av[at];if(g(av,"br")){break}}}return av||au}ad=aq(ad);ar=aq(ar);if(K(ad.parentNode)||K(ad)){ad=K(ad)?ad:ad.parentNode;ad=ad.nextSibling||ad;if(ad.nodeType==3){ai=0}}if(K(ar.parentNode)||K(ar)){ar=K(ar)?ar:ar.parentNode;ar=ar.previousSibling||ar;if(ar.nodeType==3){ak=ar.length}}if(am[0].inline){if(ab.collapsed){al=aj(ad,ai,true);if(al){ad=al.container;ai=al.offset}al=aj(ar,ak);if(al){ar=al.container;ak=al.offset}}ah=ag(ar,ak);if(ah.node){while(ah.node&&ah.offset===0&&ah.node.previousSibling){ah=ag(ah.node.previousSibling)}if(ah.node&&ah.offset>0&&ah.node.nodeType===3&&ah.node.nodeValue.charAt(ah.offset-1)===" "){if(ah.offset>1){ar=ah.node;ar.splitText(ah.offset-1)}}}}if(am[0].inline||am[0].block_expand){if(!am[0].inline||(ad.nodeType!=3||ai===0)){ad=ao(true)}if(!am[0].inline||(ar.nodeType!=3||ak===ar.nodeValue.length)){ar=ao()}}if(am[0].selector&&am[0].expand!==X&&!am[0].inline){ad=af(ad,"previousSibling");ar=af(ar,"nextSibling")}if(am[0].block||am[0].selector){ad=ac(ad,"previousSibling");ar=ac(ar,"nextSibling");if(am[0].block){if(!H(ad)){ad=ao(true)}if(!H(ar)){ar=ao()}}}if(ad.nodeType==1){ai=s(ad);ad=ad.parentNode}if(ar.nodeType==1){ak=s(ar)+1;ar=ar.parentNode}return{startContainer:ad,startOffset:ai,endContainer:ar,endOffset:ak}}function Z(ah,ag,ae,ab){var ad,ac,af;if(!h(ae,ah)){return X}if(ah.remove!="all"){T(ah.styles,function(aj,ai){aj=q(aj,ag);if(typeof(ai)==="number"){ai=aj;ab=0}if(!ab||g(O(ab,ai),aj)){c.setStyle(ae,ai,"")}af=1});if(af&&c.getAttrib(ae,"style")==""){ae.removeAttribute("style");ae.removeAttribute("data-mce-style")}T(ah.attributes,function(ak,ai){var aj;ak=q(ak,ag);if(typeof(ai)==="number"){ai=ak;ab=0}if(!ab||g(c.getAttrib(ab,ai),ak)){if(ai=="class"){ak=c.getAttrib(ae,ai);if(ak){aj="";T(ak.split(/\s+/),function(al){if(/mce\w+/.test(al)){aj+=(aj?" ":"")+al}});if(aj){c.setAttrib(ae,ai,aj);return}}}if(ai=="class"){ae.removeAttribute("className")}if(e.test(ai)){ae.removeAttribute("data-mce-"+ai)}ae.removeAttribute(ai)}});T(ah.classes,function(ai){ai=q(ai,ag);if(!ab||c.hasClass(ab,ai)){c.removeClass(ae,ai)}});ac=c.getAttribs(ae);for(ad=0;ad<ac.length;ad++){if(ac[ad].nodeName.indexOf("_")!==0){return X}}}if(ah.remove!="none"){o(ae,ah);return C}}function o(ad,ae){var ab=ad.parentNode,ac;function af(ah,ag,ai){ah=E(ah,ag,ai);return !ah||(ah.nodeName=="BR"||H(ah))}if(ae.block){if(!m){if(H(ad)&&!H(ab)){if(!af(ad,X)&&!af(ad.firstChild,C,1)){ad.insertBefore(c.create("br"),ad.firstChild)}if(!af(ad,C)&&!af(ad.lastChild,X,1)){ad.appendChild(c.create("br"))}}}else{if(ab==c.getRoot()){if(!ae.list_block||!g(ad,ae.list_block)){T(a.grep(ad.childNodes),function(ag){if(d(m,ag.nodeName.toLowerCase())){if(!ac){ac=S(ag,m)}else{ac.appendChild(ag)}}else{ac=0}})}}}}if(ae.selector&&ae.inline&&!g(ae.inline,ad)){return}c.remove(ad,1)}function E(ac,ab,ad){if(ac){ab=ab?"nextSibling":"previousSibling";for(ac=ad?ac:ac[ab];ac;ac=ac[ab]){if(ac.nodeType==1||!f(ac)){return ac}}}}function K(ab){return ab&&ab.nodeType==1&&ab.getAttribute("data-mce-type")=="bookmark"}function u(af,ae){var ab,ad,ac;function ah(ak,aj){if(ak.nodeName!=aj.nodeName){return X}function ai(am){var an={};T(c.getAttribs(am),function(ao){var ap=ao.nodeName.toLowerCase();if(ap.indexOf("_")!==0&&ap!=="style"){an[ap]=c.getAttrib(am,ap)}});return an}function al(ap,ao){var an,am;for(am in ap){if(ap.hasOwnProperty(am)){an=ao[am];if(an===D){return X}if(ap[am]!=an){return X}delete ao[am]}}for(am in ao){if(ao.hasOwnProperty(am)){return X}}return C}if(!al(ai(ak),ai(aj))){return X}if(!al(c.parseStyle(c.getAttrib(ak,"style")),c.parseStyle(c.getAttrib(aj,"style")))){return X}return C}function ag(aj,ai){for(ad=aj;ad;ad=ad[ai]){if(ad.nodeType==3&&ad.nodeValue.length!==0){return aj}if(ad.nodeType==1&&!K(ad)){return ad}}return aj}if(af&&ae){af=ag(af,"previousSibling");ae=ag(ae,"nextSibling");if(ah(af,ae)){for(ad=af.nextSibling;ad&&ad!=ae;){ac=ad;ad=ad.nextSibling;af.appendChild(ac)}c.remove(ae);T(a.grep(ae.childNodes),function(ai){af.appendChild(ai)});return af}}return ae}function I(ab){return/^(h[1-6]|p|div|pre|address|dl|dt|dd)$/.test(ab)}function M(ac,ag){var ab,af,ad,ae;ab=ac[ag?"startContainer":"endContainer"];af=ac[ag?"startOffset":"endOffset"];if(ab.nodeType==1){ad=ab.childNodes.length-1;if(!ag&&af){af--}ab=ab.childNodes[af>ad?ad:af]}if(ab.nodeType===3&&ag&&af>=ab.nodeValue.length){ab=new t(ab,aa.getBody()).next()||ab}if(ab.nodeType===3&&!ag&&af===0){ab=new t(ab,aa.getBody()).prev()||ab}return ab}function U(ak,ab,ai){var al="_mce_caret",ac=aa.settings.caret_debug;function ad(ap){var ao=c.create("span",{id:al,"data-mce-bogus":true,style:ac?"color:red":""});if(ap){ao.appendChild(aa.getDoc().createTextNode(G))}return ao}function aj(ap,ao){while(ap){if((ap.nodeType===3&&ap.nodeValue!==G)||ap.childNodes.length>1){return false}if(ao&&ap.nodeType===1){ao.push(ap)}ap=ap.firstChild}return true}function ag(ao){while(ao){if(ao.id===al){return ao}ao=ao.parentNode}}function af(ao){var ap;if(ao){ap=new t(ao,ao);for(ao=ap.current();ao;ao=ap.next()){if(ao.nodeType===3){return ao}}}}function ae(aq,ap){var ar,ao;if(!aq){aq=ag(r.getStart());if(!aq){while(aq=c.get(al)){ae(aq,false)}}}else{ao=r.getRng(true);if(aj(aq)){if(ap!==false){ao.setStartBefore(aq);ao.setEndBefore(aq)}c.remove(aq)}else{ar=af(aq);if(ar.nodeValue.charAt(0)===G){ar=ar.deleteData(0,1)}c.remove(aq,1)}r.setRng(ao)}}function ah(){var aq,ao,av,au,ar,ap,at;aq=r.getRng(true);au=aq.startOffset;ap=aq.startContainer;at=ap.nodeValue;ao=ag(r.getStart());if(ao){av=af(ao)}if(at&&au>0&&au<at.length&&/\w/.test(at.charAt(au))&&/\w/.test(at.charAt(au-1))){ar=r.getBookmark();aq.collapse(true);aq=p(aq,V(ab));aq=N.split(aq);Y(ab,ai,aq);r.moveToBookmark(ar)}else{if(!ao||av.nodeValue!==G){ao=ad(true);av=ao.firstChild;aq.insertNode(ao);au=1;Y(ab,ai,ao)}else{Y(ab,ai,ao)}r.setCursorLocation(av,au)}}function am(){var ao=r.getRng(true),ap,ar,av,au,aq,ay,ax=[],at,aw;ap=ao.startContainer;ar=ao.startOffset;aq=ap;if(ap.nodeType==3){if(ar!=ap.nodeValue.length||ap.nodeValue===G){au=true}aq=aq.parentNode}while(aq){if(y(aq,ab,ai)){ay=aq;break}if(aq.nextSibling){au=true}ax.push(aq);aq=aq.parentNode}if(!ay){return}if(au){av=r.getBookmark();ao.collapse(true);ao=p(ao,V(ab),true);ao=N.split(ao);B(ab,ai,ao);r.moveToBookmark(av)}else{aw=ad();aq=aw;for(at=ax.length-1;at>=0;at--){aq.appendChild(c.clone(ax[at],false));aq=aq.firstChild}aq.appendChild(c.doc.createTextNode(G));aq=aq.firstChild;c.insertAfter(aw,ay);r.setCursorLocation(aq,1)}}function an(){var ap,ao,aq;ao=ag(r.getStart());if(ao&&!c.isEmpty(ao)){a.walk(ao,function(ar){if(ar.nodeType==1&&ar.id!==al&&!c.isEmpty(ar)){c.setAttrib(ar,"data-mce-bogus",null)}},"childNodes")}}if(!self._hasCaretEvents){aa.onBeforeGetContent.addToTop(function(){var ao=[],ap;if(aj(ag(r.getStart()),ao)){ap=ao.length;while(ap--){c.setAttrib(ao[ap],"data-mce-bogus","1")}}});a.each("onMouseUp onKeyUp".split(" "),function(ao){aa[ao].addToTop(function(){ae();an()})});aa.onKeyDown.addToTop(function(ao,aq){var ap=aq.keyCode;if(ap==8||ap==37||ap==39){ae(ag(r.getStart()))}an()});r.onSetContent.add(an);self._hasCaretEvents=true}if(ak=="apply"){ah()}else{am()}}function R(ac){var ab=ac.startContainer,ai=ac.startOffset,ae,ah,ag,ad,af;if(ab.nodeType==3&&ai>=ab.nodeValue.length){ai=s(ab);ab=ab.parentNode;ae=true}if(ab.nodeType==1){ad=ab.childNodes;ab=ad[Math.min(ai,ad.length-1)];ah=new t(ab,c.getParent(ab,c.isBlock));if(ai>ad.length-1||ae){ah.next()}for(ag=ah.current();ag;ag=ah.next()){if(ag.nodeType==3&&!f(ag)){af=c.create("a",null,G);ag.parentNode.insertBefore(af,ag);ac.setStart(ag,0);r.setRng(ac);c.remove(af);return}}}}}})(tinymce);tinymce.onAddEditor.add(function(e,a){var d,h,g,c=a.settings;function b(j,i){e.each(i,function(l,k){if(l){g.setStyle(j,k,l)}});g.rename(j,"span")}function f(i,j){g=i.dom;if(c.convert_fonts_to_spans){e.each(g.select("font,u,strike",j.node),function(k){d[k.nodeName.toLowerCase()](a.dom,k)})}}if(c.inline_styles){h=e.explode(c.font_size_legacy_values);d={font:function(j,i){b(i,{backgroundColor:i.style.backgroundColor,color:i.color,fontFamily:i.face,fontSize:h[parseInt(i.size,10)-1]})},u:function(j,i){b(i,{textDecoration:"underline"})},strike:function(j,i){b(i,{textDecoration:"line-through"})}};a.onPreProcess.add(f);a.onSetContent.add(f);a.onInit.add(function(){a.selection.onSetContent.add(f)})}});(function(b){var a=b.dom.TreeWalker;b.EnterKey=function(f){var i=f.dom,e=f.selection,d=f.settings,h=f.undoManager,c=f.schema.getNonEmptyElements();function g(A){var v=e.getRng(true),G,j,z,u,p,M,B,o,k,n,t,J,x,C;function E(N){return N&&i.isBlock(N)&&!/^(TD|TH|CAPTION|FORM)$/.test(N.nodeName)&&!/^(fixed|absolute)/i.test(N.style.position)&&i.getContentEditable(N)!=="true"}function F(O){var N;if(b.isIE&&i.isBlock(O)){N=e.getRng();O.appendChild(i.create("span",null,"\u00a0"));e.select(O);O.lastChild.outerHTML="";e.setRng(N)}}function y(P){var O=P,Q=[],N;while(O=O.firstChild){if(i.isBlock(O)){return}if(O.nodeType==1&&!c[O.nodeName.toLowerCase()]){Q.push(O)}}N=Q.length;while(N--){O=Q[N];if(!O.hasChildNodes()||(O.firstChild==O.lastChild&&O.firstChild.nodeValue==="")){i.remove(O)}else{if(O.nodeName=="A"&&(O.innerText||O.textContent)===" "){i.remove(O)}}}}function m(O){var T,R,N,U,S,Q=O,P;N=i.createRng();if(O.hasChildNodes()){T=new a(O,O);while(R=T.current()){if(R.nodeType==3){N.setStart(R,0);N.setEnd(R,0);break}if(c[R.nodeName.toLowerCase()]){N.setStartBefore(R);N.setEndBefore(R);break}Q=R;R=T.next()}if(!R){N.setStart(Q,0);N.setEnd(Q,0)}}else{if(O.nodeName=="BR"){if(O.nextSibling&&i.isBlock(O.nextSibling)){if(!M||M<9){P=i.create("br");O.parentNode.insertBefore(P,O)}N.setStartBefore(O);N.setEndBefore(O)}else{N.setStartAfter(O);N.setEndAfter(O)}}else{N.setStart(O,0);N.setEnd(O,0)}}e.setRng(N);i.remove(P);S=i.getViewPort(f.getWin());U=i.getPos(O).y;if(U<S.y||U+25>S.y+S.h){f.getWin().scrollTo(0,U<S.y?U:U-S.h+25)}}function r(O){var P=z,R,Q,N;R=O||t=="TABLE"?i.create(O||x):p.cloneNode(false);N=R;if(d.keep_styles!==false){do{if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(P.nodeName)){if(P.id=="_mce_caret"){continue}Q=P.cloneNode(false);i.setAttrib(Q,"id","");if(R.hasChildNodes()){Q.appendChild(R.firstChild);R.appendChild(Q)}else{N=Q;R.appendChild(Q)}}}while(P=P.parentNode)}if(!b.isIE){N.innerHTML='<br data-mce-bogus="1">'}return R}function q(Q){var P,O,N;if(z.nodeType==3&&(Q?u>0:u<z.nodeValue.length)){return false}if(z.parentNode==p&&C&&!Q){return true}if(Q&&z.nodeType==1&&z==p.firstChild){return true}if(z.nodeName==="TABLE"||(z.previousSibling&&z.previousSibling.nodeName=="TABLE")){return(C&&!Q)||(!C&&Q)}P=new a(z,p);if(z.nodeType==3){if(Q&&u==0){P.prev()}else{if(!Q&&u==z.nodeValue.length){P.next()}}}while(O=P.current()){if(O.nodeType===1){if(!O.getAttribute("data-mce-bogus")){N=O.nodeName.toLowerCase();if(c[N]&&N!=="br"){return false}}}else{if(O.nodeType===3&&!/^[ \t\r\n]*$/.test(O.nodeValue)){return false}}if(Q){P.prev()}else{P.next()}}return true}function l(N,T){var U,S,P,R,Q,O=x||"P";S=i.getParent(N,i.isBlock);if(!S||!E(S)){S=S||j;if(!S.hasChildNodes()){U=i.create(O);S.appendChild(U);v.setStart(U,0);v.setEnd(U,0);return U}R=N;while(R.parentNode!=S){R=R.parentNode}while(R&&!i.isBlock(R)){P=R;R=R.previousSibling}if(P){U=i.create(O);P.parentNode.insertBefore(U,P);R=P;while(R&&!i.isBlock(R)){Q=R.nextSibling;U.appendChild(R);R=Q}v.setStart(N,T);v.setEnd(N,T)}}return N}function H(){function N(P){var O=n[P?"firstChild":"lastChild"];while(O){if(O.nodeType==1){break}O=O[P?"nextSibling":"previousSibling"]}return O===p}o=x?r(x):i.create("BR");if(N(true)&&N()){i.replace(o,n)}else{if(N(true)){n.parentNode.insertBefore(o,n)}else{if(N()){i.insertAfter(o,n);F(o)}else{G=v.cloneRange();G.setStartAfter(p);G.setEndAfter(n);k=G.extractContents();i.insertAfter(k,n);i.insertAfter(o,n)}}}i.remove(p);m(o);h.add()}function D(){var O=new a(z,p),N;while(N=O.current()){if(N.nodeName=="BR"){return true}N=O.next()}}function L(){var P,O,N;if(z&&z.nodeType==3&&u>=z.nodeValue.length){if(!b.isIE&&!D()){P=i.create("br");v.insertNode(P);v.setStartAfter(P);v.setEndAfter(P);O=true}}P=i.create("br");v.insertNode(P);if(b.isIE&&t=="PRE"&&(!M||M<8)){P.parentNode.insertBefore(i.doc.createTextNode("\r"),P)}N=i.create("span",{}," ");P.parentNode.insertBefore(N,P);e.scrollIntoView(N);i.remove(N);if(!O){v.setStartAfter(P);v.setEndAfter(P)}else{v.setStartBefore(P);v.setEndBefore(P)}e.setRng(v);h.add()}function s(N){do{if(N.nodeType===3){N.nodeValue=N.nodeValue.replace(/^[\r\n]+/,"")}N=N.firstChild}while(N)}function K(P){var N=i.getRoot(),O,Q;O=P;while(O!==N&&i.getContentEditable(O)!=="false"){if(i.getContentEditable(O)==="true"){Q=O}O=O.parentNode}return O!==N?Q:N}function I(O){var N;if(!b.isIE){O.normalize();N=O.lastChild;if(!N||(/^(left|right)$/gi.test(i.getStyle(N,"float",true)))){i.add(O,"br")}}}if(!v.collapsed){f.execCommand("Delete");return}if(A.isDefaultPrevented()){return}z=v.startContainer;u=v.startOffset;x=(d.force_p_newlines?"p":"")||d.forced_root_block;x=x?x.toUpperCase():"";M=i.doc.documentMode;B=A.shiftKey;if(z.nodeType==1&&z.hasChildNodes()){C=u>z.childNodes.length-1;z=z.childNodes[Math.min(u,z.childNodes.length-1)]||z;if(C&&z.nodeType==3){u=z.nodeValue.length}else{u=0}}j=K(z);if(!j){return}h.beforeChange();if(!i.isBlock(j)&&j!=i.getRoot()){if(!x||B){L()}return}if((x&&!B)||(!x&&B)){z=l(z,u)}p=i.getParent(z,i.isBlock);n=p?i.getParent(p.parentNode,i.isBlock):null;t=p?p.nodeName.toUpperCase():"";J=n?n.nodeName.toUpperCase():"";if(J=="LI"&&!A.ctrlKey){p=n;t=J}if(t=="LI"){if(!x&&B){L();return}if(i.isEmpty(p)){if(/^(UL|OL|LI)$/.test(n.parentNode.nodeName)){return false}H();return}}if(t=="PRE"&&d.br_in_pre!==false){if(!B){L();return}}else{if((!x&&!B&&t!="LI")||(x&&B)){L();return}}x=x||"P";if(q()){if(/^(H[1-6]|PRE)$/.test(t)&&J!="HGROUP"){o=r(x)}else{o=r()}if(d.end_container_on_empty_block&&E(n)&&i.isEmpty(p)){o=i.split(n,p)}else{i.insertAfter(o,p)}m(o)}else{if(q(true)){o=p.parentNode.insertBefore(r(),p);F(o)}else{G=v.cloneRange();G.setEndAfter(p);k=G.extractContents();s(k);o=k.firstChild;i.insertAfter(k,p);y(o);I(p);m(o)}}i.setAttrib(o,"id","");h.add()}f.onKeyDown.add(function(k,j){if(j.keyCode==13){if(g(j)!==false){j.preventDefault()}}})}})(tinymce); \ No newline at end of file diff --git a/tiny_mce_popup.js b/tiny_mce_popup.js index f859d24e6a6788d5890a02f76f96c81ff2749580..bb8e58c88a6b86169d25a1b15ea6be5a8031d6f0 100644 --- a/tiny_mce_popup.js +++ b/tiny_mce_popup.js @@ -2,4 +2,4 @@ // Uncomment and change this document.domain value if you are loading the script cross subdomains // document.domain = 'moxiecode.com'; -var tinymce=null,tinyMCEPopup,tinyMCE;tinyMCEPopup={init:function(){var b=this,a,c;a=b.getWin();tinymce=a.tinymce;tinyMCE=a.tinyMCE;b.editor=tinymce.EditorManager.activeEditor;b.params=b.editor.windowManager.params;b.features=b.editor.windowManager.features;b.dom=b.editor.windowManager.createInstance("tinymce.dom.DOMUtils",document);if(b.features.popup_css!==false){b.dom.loadCSS(b.features.popup_css||b.editor.settings.popup_css)}b.listeners=[];b.onInit={add:function(e,d){b.listeners.push({func:e,scope:d})}};b.isWindow=!b.getWindowArg("mce_inline");b.id=b.getWindowArg("mce_window_id");b.editor.windowManager.onOpen.dispatch(b.editor.windowManager,window)},getWin:function(){return(!window.frameElement&&window.dialogArguments)||opener||parent||top},getWindowArg:function(c,b){var a=this.params[c];return tinymce.is(a)?a:b},getParam:function(b,a){return this.editor.getParam(b,a)},getLang:function(b,a){return this.editor.getLang(b,a)},execCommand:function(d,c,e,b){b=b||{};b.skip_focus=1;this.restoreSelection();return this.editor.execCommand(d,c,e,b)},resizeToInnerSize:function(){var a=this;setTimeout(function(){var b=a.dom.getViewPort(window);a.editor.windowManager.resizeBy(a.getWindowArg("mce_width")-b.w,a.getWindowArg("mce_height")-b.h,a.id||window)},10)},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark(1)},restoreSelection:function(){var a=tinyMCEPopup;if(!a.isWindow&&tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},requireLangPack:function(){var b=this,a=b.getWindowArg("plugin_url")||b.getWindowArg("theme_url");if(a&&b.editor.settings.language&&b.features.translate_i18n!==false&&b.editor.settings.language_load!==false){a+="/langs/"+b.editor.settings.language+"_dlg.js";if(!tinymce.ScriptLoader.isDone(a)){document.write('<script type="text/javascript" src="'+tinymce._addVer(a)+'"><\/script>');tinymce.ScriptLoader.markDone(a)}}},pickColor:function(b,a){this.execCommand("mceColorPicker",true,{color:document.getElementById(a).value,func:function(e){document.getElementById(a).value=e;try{document.getElementById(a).onchange()}catch(d){}}})},openBrowser:function(a,c,b){tinyMCEPopup.restoreSelection();this.editor.execCallback("file_browser_callback",a,document.getElementById(a).value,c,window)},confirm:function(b,a,c){this.editor.windowManager.confirm(b,a,c,window)},alert:function(b,a,c){this.editor.windowManager.alert(b,a,c,window)},close:function(){var a=this;function b(){a.editor.windowManager.close(window);tinymce=tinyMCE=a.editor=a.params=a.dom=a.dom.doc=null}if(tinymce.isOpera){a.getWin().setTimeout(b,0)}else{b()}},_restoreSelection:function(){var a=window.event.srcElement;if(a.nodeName=="INPUT"&&(a.type=="submit"||a.type=="button")){tinyMCEPopup.restoreSelection()}},_onDOMLoaded:function(){var b=tinyMCEPopup,d=document.title,e,c,a;if(b.domLoaded){return}b.domLoaded=1;if(b.features.translate_i18n!==false){c=document.body.innerHTML;if(tinymce.isIE){c=c.replace(/ (value|title|alt)=([^"][^\s>]+)/gi,' $1="$2"')}document.dir=b.editor.getParam("directionality","");if((a=b.editor.translate(c))&&a!=c){document.body.innerHTML=a}if((a=b.editor.translate(d))&&a!=d){document.title=d=a}}if(!b.editor.getParam("browser_preferred_colors",false)||!b.isWindow){b.dom.addClass(document.body,"forceColors")}document.body.style.display="";if(tinymce.isIE){document.attachEvent("onmouseup",tinyMCEPopup._restoreSelection);b.dom.add(b.dom.select("head")[0],"base",{target:"_self"})}b.restoreSelection();b.resizeToInnerSize();if(!b.isWindow){b.editor.windowManager.setTitle(window,d)}else{window.focus()}if(!tinymce.isIE&&!b.isWindow){tinymce.dom.Event._add(document,"focus",function(){b.editor.windowManager.focus(b.id)})}tinymce.each(b.dom.select("select"),function(f){f.onkeydown=tinyMCEPopup._accessHandler});tinymce.each(b.listeners,function(f){f.func.call(f.scope,b.editor)});if(b.getWindowArg("mce_auto_focus",true)){window.focus();tinymce.each(document.forms,function(g){tinymce.each(g.elements,function(f){if(b.dom.hasClass(f,"mceFocus")&&!f.disabled){f.focus();return false}})})}document.onkeyup=tinyMCEPopup._closeWinKeyHandler},_accessHandler:function(a){a=a||window.event;if(a.keyCode==13||a.keyCode==32){a=a.target||a.srcElement;if(a.onchange){a.onchange()}return tinymce.dom.Event.cancel(a)}},_closeWinKeyHandler:function(a){a=a||window.event;if(a.keyCode==27){tinyMCEPopup.close()}},_wait:function(){if(document.attachEvent){document.attachEvent("onreadystatechange",function(){if(document.readyState==="complete"){document.detachEvent("onreadystatechange",arguments.callee);tinyMCEPopup._onDOMLoaded()}});if(document.documentElement.doScroll&&window==window.top){(function(){if(tinyMCEPopup.domLoaded){return}try{document.documentElement.doScroll("left")}catch(a){setTimeout(arguments.callee,0);return}tinyMCEPopup._onDOMLoaded()})()}document.attachEvent("onload",tinyMCEPopup._onDOMLoaded)}else{if(document.addEventListener){window.addEventListener("DOMContentLoaded",tinyMCEPopup._onDOMLoaded,false);window.addEventListener("load",tinyMCEPopup._onDOMLoaded,false)}}}};tinyMCEPopup.init();tinyMCEPopup._wait(); \ No newline at end of file +var tinymce=null,tinyMCEPopup,tinyMCE;tinyMCEPopup={init:function(){var b=this,a,c;a=b.getWin();tinymce=a.tinymce;tinyMCE=a.tinyMCE;b.editor=tinymce.EditorManager.activeEditor;b.params=b.editor.windowManager.params;b.features=b.editor.windowManager.features;b.dom=b.editor.windowManager.createInstance("tinymce.dom.DOMUtils",document,{ownEvents:true,proxy:tinyMCEPopup._eventProxy});b.dom.bind(window,"ready",b._onDOMLoaded,b);if(b.features.popup_css!==false){b.dom.loadCSS(b.features.popup_css||b.editor.settings.popup_css)}b.listeners=[];b.onInit={add:function(e,d){b.listeners.push({func:e,scope:d})}};b.isWindow=!b.getWindowArg("mce_inline");b.id=b.getWindowArg("mce_window_id");b.editor.windowManager.onOpen.dispatch(b.editor.windowManager,window)},getWin:function(){return(!window.frameElement&&window.dialogArguments)||opener||parent||top},getWindowArg:function(c,b){var a=this.params[c];return tinymce.is(a)?a:b},getParam:function(b,a){return this.editor.getParam(b,a)},getLang:function(b,a){return this.editor.getLang(b,a)},execCommand:function(d,c,e,b){b=b||{};b.skip_focus=1;this.restoreSelection();return this.editor.execCommand(d,c,e,b)},resizeToInnerSize:function(){var a=this;setTimeout(function(){var b=a.dom.getViewPort(window);a.editor.windowManager.resizeBy(a.getWindowArg("mce_width")-b.w,a.getWindowArg("mce_height")-b.h,a.id||window)},10)},executeOnLoad:function(s){this.onInit.add(function(){eval(s)})},storeSelection:function(){this.editor.windowManager.bookmark=tinyMCEPopup.editor.selection.getBookmark(1)},restoreSelection:function(){var a=tinyMCEPopup;if(!a.isWindow&&tinymce.isIE){a.editor.selection.moveToBookmark(a.editor.windowManager.bookmark)}},requireLangPack:function(){var b=this,a=b.getWindowArg("plugin_url")||b.getWindowArg("theme_url");if(a&&b.editor.settings.language&&b.features.translate_i18n!==false&&b.editor.settings.language_load!==false){a+="/langs/"+b.editor.settings.language+"_dlg.js";if(!tinymce.ScriptLoader.isDone(a)){document.write('<script type="text/javascript" src="'+tinymce._addVer(a)+'"><\/script>');tinymce.ScriptLoader.markDone(a)}}},pickColor:function(b,a){this.execCommand("mceColorPicker",true,{color:document.getElementById(a).value,func:function(e){document.getElementById(a).value=e;try{document.getElementById(a).onchange()}catch(d){}}})},openBrowser:function(a,c,b){tinyMCEPopup.restoreSelection();this.editor.execCallback("file_browser_callback",a,document.getElementById(a).value,c,window)},confirm:function(b,a,c){this.editor.windowManager.confirm(b,a,c,window)},alert:function(b,a,c){this.editor.windowManager.alert(b,a,c,window)},close:function(){var a=this;function b(){a.editor.windowManager.close(window);tinymce=tinyMCE=a.editor=a.params=a.dom=a.dom.doc=null}if(tinymce.isOpera){a.getWin().setTimeout(b,0)}else{b()}},_restoreSelection:function(){var a=window.event.srcElement;if(a.nodeName=="INPUT"&&(a.type=="submit"||a.type=="button")){tinyMCEPopup.restoreSelection()}},_onDOMLoaded:function(){var b=tinyMCEPopup,d=document.title,e,c,a;if(b.features.translate_i18n!==false){c=document.body.innerHTML;if(tinymce.isIE){c=c.replace(/ (value|title|alt)=([^"][^\s>]+)/gi,' $1="$2"')}document.dir=b.editor.getParam("directionality","");if((a=b.editor.translate(c))&&a!=c){document.body.innerHTML=a}if((a=b.editor.translate(d))&&a!=d){document.title=d=a}}if(!b.editor.getParam("browser_preferred_colors",false)||!b.isWindow){b.dom.addClass(document.body,"forceColors")}document.body.style.display="";if(tinymce.isIE){document.attachEvent("onmouseup",tinyMCEPopup._restoreSelection);b.dom.add(b.dom.select("head")[0],"base",{target:"_self"})}b.restoreSelection();b.resizeToInnerSize();if(!b.isWindow){b.editor.windowManager.setTitle(window,d)}else{window.focus()}if(!tinymce.isIE&&!b.isWindow){b.dom.bind(document,"focus",function(){b.editor.windowManager.focus(b.id)})}tinymce.each(b.dom.select("select"),function(f){f.onkeydown=tinyMCEPopup._accessHandler});tinymce.each(b.listeners,function(f){f.func.call(f.scope,b.editor)});if(b.getWindowArg("mce_auto_focus",true)){window.focus();tinymce.each(document.forms,function(g){tinymce.each(g.elements,function(f){if(b.dom.hasClass(f,"mceFocus")&&!f.disabled){f.focus();return false}})})}document.onkeyup=tinyMCEPopup._closeWinKeyHandler},_accessHandler:function(a){a=a||window.event;if(a.keyCode==13||a.keyCode==32){var b=a.target||a.srcElement;if(b.onchange){b.onchange()}return tinymce.dom.Event.cancel(a)}},_closeWinKeyHandler:function(a){a=a||window.event;if(a.keyCode==27){tinyMCEPopup.close()}},_eventProxy:function(a){return function(b){tinyMCEPopup.dom.events.callNativeHandler(a,b)}}};tinyMCEPopup.init(); \ No newline at end of file diff --git a/tiny_mce_src.js b/tiny_mce_src.js index 64feb6663762f61f030fb01d3f7abf8f816900ac..757cf4261b9087241eab6927052c9a8254612c59 100644 --- a/tiny_mce_src.js +++ b/tiny_mce_src.js @@ -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 : '4.9', + minorVersion : '5.8', - releaseDate : '2012-02-23', + releaseDate : '2012-11-20', _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,14 +105,18 @@ is : function(o, t) { if (!t) - return o !== undefined; + return o !== undef; - if (t == 'array' && (o.hasOwnProperty && o instanceof Array)) + if (t == 'array' && tinymce.isArray(o)) return true; return typeof(o) == t; }, + isArray: Array.isArray || function(obj) { + return Object.prototype.toString.call(obj) === "[object Array]"; + }, + makeMap : function(items, delim, map) { var i; @@ -137,7 +143,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) @@ -157,56 +163,6 @@ }, - map : function(a, f) { - var o = []; - - tinymce.each(a, function(v) { - o.push(f(v)); - }); - - return o; - }, - - grep : function(a, f) { - var o = []; - - tinymce.each(a, function(v) { - if (!f || f(v)) - o.push(v); - }); - - return o; - }, - - inArray : function(a, v) { - var i, l; - - if (a) { - for (i = 0, l = a.length; i < l; i++) { - if (a[i] === v) - return i; - } - } - - return -1; - }, - - extend : function(o, e) { - var i, l, a = arguments; - - for (i = 1, l = a.length; i < l; i++) { - e = a[i]; - - tinymce.each(e, function(v, n) { - if (v !== undefined) - o[n] = v; - }); - } - - return o; - }, - - trim : function(s) { return (s ? '' + s : '').replace(whiteSpaceRe, ''); }, @@ -346,69 +302,69 @@ }, addUnload : function(f, s) { - var t = this; + var t = this, unload; - f = {func : f, scope : s || this}; + unload = function() { + var li = t.unloads, o, n; - if (!t.unloads) { - function unload() { - var li = t.unloads, o, n; + if (li) { + // Call unload handlers + for (n in li) { + o = li[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 + } - 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); - // 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; - // Destroy references - t.unloads = o = li = w = unload = 0; + // Run garbarge collector on IE + if (win.CollectGarbage) + CollectGarbage(); + } + }; - // Run garbarge collector on IE - if (win.CollectGarbage) - CollectGarbage(); - } - }; + function fakeUnload() { + var d = document; - function fakeUnload() { - var d = document; + function stop() { + // Prevent memory leak + d.detachEvent('onstop', stop); - // 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(); - // Call unload handler - if (unload) - unload(); + d = 0; + }; - 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); - // Fire unload when the currently loading page is stopped + // 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.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); - } - }; + d.detachEvent('onstop', stop); + }, 0); + } + }; + + f = {func : f, scope : s || this}; + if (!t.unloads) { // Attach unload handler if (win.attachEvent) { win.attachEvent('onunload', unload); @@ -439,7 +395,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 +425,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]); @@ -492,56 +452,374 @@ })(window); +(function($, tinymce) { + var is = tinymce.is, attrRegExp = /^(href|src|style)$/i, undef; + + // jQuery is undefined + if (!$ && window.console) { + return console.log("Load jQuery first!"); + } + + // Stick jQuery into the tinymce namespace + tinymce.$ = $; + + // Setup adapter + tinymce.adapter = { + patchEditor : function(editor) { + var fn = $.fn; + + // Adapt the css function to make sure that the data-mce-style + // attribute gets updated with the new style information + function css(name, value) { + var self = this; + + // Remove data-mce-style when set operation occurs + if (value) + self.removeAttr('data-mce-style'); + + return fn.css.apply(self, arguments); + }; + + // Apapt the attr function to make sure that it uses the data-mce- prefixed variants + function attr(name, value) { + var self = this; + + // Update/retrive data-mce- attribute variants + if (attrRegExp.test(name)) { + if (value !== undef) { + // Use TinyMCE behavior when setting the specifc attributes + self.each(function(i, node) { + editor.dom.setAttrib(node, name, value); + }); + + return self; + } else + return self.attr('data-mce-' + name); + } + + // Default behavior + return fn.attr.apply(self, arguments); + }; + + // Patch various jQuery functions to handle tinymce specific attribute and content behavior + // we don't patch the jQuery.fn directly since it will most likely break compatibility + // with other jQuery logic on the page. Only instances created by TinyMCE should be patched. + function patch(jq) { + // Patch some functions, only patch the object once + if (jq.css !== css) { + // Patch css/attr to use the data-mce- prefixed attribute variants + jq.css = css; + jq.attr = attr; + + jq.tinymce = editor; + + // Each pushed jQuery instance needs to be patched + // as well for example when traversing the DOM + jq.pushStack = function() { + return patch(fn.pushStack.apply(this, arguments)); + }; + } + + return jq; + }; + + // Add a $ function on each editor instance this one is scoped for the editor document object + // this way you can do chaining like this tinymce.get(0).$('p').append('text').css('color', 'red'); + editor.$ = function(selector, scope) { + var doc = editor.getDoc(); + + return patch($(selector || doc, doc || scope)); + }; + } + }; + + // Patch in core NS functions + tinymce.extend = $.extend; + tinymce.extend(tinymce, { + map : $.map, + grep : function(a, f) {return $.grep(a, f || function(){return 1;});}, + inArray : function(a, v) {return $.inArray(v, a || []);} + + /* Didn't iterate stylesheets + each : function(o, cb, s) { + if (!o) + return 0; + + var r = 1; + + $.each(o, function(nr, el){ + if (cb.call(s, el, nr, o) === false) { + r = 0; + return false; + } + }); + + return r; + }*/ + }); + + // Patch in functions in various clases + // Add a "#ifndefjquery" statement around each core API function you add below + var patches = { + 'tinymce.dom.DOMUtils' : { + /* + addClass : function(e, c) { + if (is(e, 'array') && is(e[0], 'string')) + e = e.join(',#'); + return (e && $(is(e, 'string') ? '#' + e : e) + .addClass(c) + .attr('class')) || false; + }, + + hasClass : function(n, c) { + return $(is(n, 'string') ? '#' + n : n).hasClass(c); + }, + + removeClass : function(e, c) { + if (!e) + return false; + + var r = []; + + $(is(e, 'string') ? '#' + e : e) + .removeClass(c) + .each(function(){ + r.push(this.className); + }); + + return r.length == 1 ? r[0] : r; + }, + */ + + select : function(pattern, scope) { + var t = this; + + return $.find(pattern, t.get(scope) || t.get(t.settings.root_element) || t.doc, []); + }, + + is : function(n, patt) { + return $(this.get(n)).is(patt); + } + + /* + show : function(e) { + if (is(e, 'array') && is(e[0], 'string')) + e = e.join(',#'); + + $(is(e, 'string') ? '#' + e : e).css('display', 'block'); + }, + + hide : function(e) { + if (is(e, 'array') && is(e[0], 'string')) + e = e.join(',#'); + + $(is(e, 'string') ? '#' + e : e).css('display', 'none'); + }, + + isHidden : function(e) { + return $(is(e, 'string') ? '#' + e : e).is(':hidden'); + }, + + insertAfter : function(n, e) { + return $(is(e, 'string') ? '#' + e : e).after(n); + }, + + replace : function(o, n, k) { + n = $(is(n, 'string') ? '#' + n : n); + + if (k) + n.children().appendTo(o); + + n.replaceWith(o); + }, + + setStyle : function(n, na, v) { + if (is(n, 'array') && is(n[0], 'string')) + n = n.join(',#'); + + $(is(n, 'string') ? '#' + n : n).css(na, v); + }, + + getStyle : function(n, na, c) { + return $(is(n, 'string') ? '#' + n : n).css(na); + }, + + setStyles : function(e, o) { + if (is(e, 'array') && is(e[0], 'string')) + e = e.join(',#'); + $(is(e, 'string') ? '#' + e : e).css(o); + }, + + setAttrib : function(e, n, v) { + var t = this, s = t.settings; + + if (is(e, 'array') && is(e[0], 'string')) + e = e.join(',#'); + + e = $(is(e, 'string') ? '#' + e : e); + + switch (n) { + case "style": + e.each(function(i, v){ + if (s.keep_values) + $(v).attr('data-mce-style', v); + + v.style.cssText = v; + }); + break; + + case "class": + e.each(function(){ + this.className = v; + }); + break; + + case "src": + case "href": + e.each(function(i, v){ + if (s.keep_values) { + if (s.url_converter) + v = s.url_converter.call(s.url_converter_scope || t, v, n, v); + + t.setAttrib(v, 'data-mce-' + n, v); + } + }); + + break; + } + + if (v !== null && v.length !== 0) + e.attr(n, '' + v); + else + e.removeAttr(n); + }, + + setAttribs : function(e, o) { + var t = this; + + $.each(o, function(n, v){ + t.setAttrib(e,n,v); + }); + } + */ + } + +/* + 'tinymce.dom.Event' : { + add : function (o, n, f, s) { + var lo, cb; + + cb = function(e) { + e.target = e.target || this; + f.call(s || this, e); + }; + + if (is(o, 'array') && is(o[0], 'string')) + o = o.join(',#'); + o = $(is(o, 'string') ? '#' + o : o); + if (n == 'init') { + o.ready(cb, s); + } else { + if (s) { + o.bind(n, s, cb); + } else { + o.bind(n, cb); + } + } + + lo = this._jqLookup || (this._jqLookup = []); + lo.push({func : f, cfunc : cb}); + + return cb; + }, + + remove : function(o, n, f) { + // Find cfunc + $(this._jqLookup).each(function() { + if (this.func === f) + f = this.cfunc; + }); + + if (is(o, 'array') && is(o[0], 'string')) + o = o.join(',#'); + + $(is(o, 'string') ? '#' + o : o).unbind(n,f); + + return true; + } + } +*/ + }; + + // Patch functions after a class is created + tinymce.onCreate = function(ty, c, p) { + tinymce.extend(p, patches[c]); + }; +})(window.jQuery, tinymce); + + 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}; + + // 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 cb; + 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 +849,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 +867,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 +914,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 +934,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 +965,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 +1000,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 +1115,7 @@ tinymce.create('tinymce.util.Dispatcher', { if (b == -1) { b = c.indexOf(p); - if (b != 0) + if (b !== 0) return null; } else b += 2; @@ -851,19 +1136,19 @@ tinymce.create('tinymce.util.Dispatcher', { ((s) ? "; secure" : ""); }, - remove : function(n, p) { - var d = new Date(); + remove : function(name, path, domain) { + var date = new Date(); - d.setTime(d.getTime() - 1000); + date.setTime(date.getTime() - 1000); - this.set(n, '', d, p, d); + this.set(name, '', date, path, domain); } }); })(); (function() { function serialize(o, quote) { - var i, v, t; + var i, v, t, name; quote = quote || '"'; @@ -892,7 +1177,7 @@ tinymce.create('tinymce.util.Dispatcher', { } if (t == 'object') { - if (o.hasOwnProperty && o instanceof Array) { + if (o.hasOwnProperty && Object.prototype.toString.call(o) === '[object Array]') { for (i=0, v = '['; i<o.length; i++) v += (i > 0 ? ',' : '') + serialize(o[i], quote); @@ -901,9 +1186,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 +1216,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 +1261,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(); @@ -1042,121 +1327,198 @@ tinymce.create('static tinymce.util.XHR', { }()); (function(tinymce){ tinymce.VK = { - DELETE: 46, BACKSPACE: 8, + DELETE: 46, + DOWN: 40, ENTER: 13, + LEFT: 37, + RIGHT: 39, + SPACEBAR: 32, TAB: 9, - SPACEBAR: 32, UP: 38, - DOWN: 40, + modifierPressed: function (e) { return e.shiftKey || e.ctrlKey || e.altKey; + }, + + metaKeyPressed: function(e) { + // Check if ctrl or meta key is pressed also check if alt is false for Polish users + return tinymce.isMac ? e.metaKey : 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, parser = editor.parser, serializer = editor.serializer, each = tinymce.each; - function cleanupStylesWhenDeleting(ed) { - var dom = ed.dom, selection = ed.selection; + function setEditorCommandState(cmd, state) { + try { + editor.getDoc().execCommand(cmd, false, state); + } catch (ex) { + // Ignore + } + } - ed.onKeyDown.add(function(ed, e) { - var rng, blockElm, node, clonedSpan, isDelete; + function getDocumentMode() { + var documentMode = editor.getDoc().documentMode; - isDelete = e.keyCode == DELETE; - if ((isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) { - e.preventDefault(); - rng = selection.getRng(); + return documentMode ? documentMode : 6; + }; - // Find root block - blockElm = dom.getParent(rng.startContainer, dom.isBlock); + function isDefaultPrevented(e) { + return e.isDefaultPrevented(); + }; - // On delete clone the root span of the next block element - if (isDelete) - blockElm = dom.getNext(blockElm, dom.isBlock); + function cleanupStylesWhenDeleting() { + function removeMergedFormatSpans(isDelete) { + var rng, blockElm, node, clonedSpan; - // 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; + rng = selection.getRng(); - // Ignore empty text nodes - while (node && node.nodeType == 3 && node.nodeValue.length == 0) - node = node.nextSibling; + // Find root block + blockElm = dom.getParent(rng.startContainer, dom.isBlock); - if (node && node.nodeName === 'SPAN') { - clonedSpan = node.cloneNode(false); - } + // 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; } - // Do the backspace/delete action - ed.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null); + if (node && node.nodeName === 'SPAN') { + clonedSpan = node.cloneNode(false); + } + } - // 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(); + each(dom.select('span', blockElm), function(span) { + span.setAttribute('data-mce-mark', '1'); + }); - if (clonedSpan) { - dom.replace(clonedSpan.cloneNode(false), span, true); - } else { - dom.remove(span, true); - } + // Do the backspace/delete action + editor.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); + each(dom.select('span', blockElm), function(span) { + var bm = selection.getBookmark(); + + if (clonedSpan) { + dom.replace(clonedSpan.cloneNode(false), span, true); + } else if (!span.getAttribute('data-mce-mark')) { + dom.remove(span, true); + } else { + span.removeAttribute('data-mce-mark'); + } + + // Restore the selection + selection.moveToBookmark(bm); + }); + } + + editor.onKeyDown.add(function(editor, e) { + var isDelete; + + isDelete = e.keyCode == DELETE; + if (!isDefaultPrevented(e) && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) { + e.preventDefault(); + removeMergedFormatSpans(isDelete); } }); - }; - - function emptyEditorWhenDeleting(ed) { + editor.addCommand('Delete', function() {removeMergedFormatSpans();}); + }; + + function emptyEditorWhenDeleting() { function serializeRng(rng) { - var body = ed.dom.create("body"); + var body = dom.create("body"); var contents = rng.cloneContents(); body.appendChild(contents); - return ed.selection.serializer.serialize(body, {format: 'html'}); + return selection.serializer.serialize(body, {format: 'html'}); } function allContentsSelected(rng) { var selection = serializeRng(rng); - var allRng = ed.dom.createRng(); - allRng.selectNode(ed.getBody()); + var allRng = dom.createRng(); + allRng.selectNode(editor.getBody()); var allSelection = serializeRng(allRng); return selection === allSelection; } - 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(); - e.preventDefault(); - } - } - }); - - }; + editor.onKeyDown.add(function(editor, e) { + var keyCode = e.keyCode, isCollapsed; - function inputMethodFocus(ed) { - ed.dom.bind(ed.getDoc(), 'focusin', function() { - ed.selection.setRng(ed.selection.getRng()); - }); - }; + // Empty the editor if it's needed for example backspace at <p><b>|</b></p> + if (!isDefaultPrevented(e) && (keyCode == DELETE || keyCode == BACKSPACE)) { + isCollapsed = editor.selection.isCollapsed(); - 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(); + // Selection is collapsed but the editor isn't empty + if (isCollapsed && !dom.isEmpty(editor.getBody())) { + return; + } + + // IE deletes all contents correctly when everything is selected + if (tinymce.isIE && !isCollapsed) { + return; + } + + // Selection isn't collapsed but not all the contents is selected + if (!isCollapsed && !allContentsSelected(editor.selection.getRng())) { + return; + } + + // Manually empty the editor + editor.setContent(''); + editor.selection.setCursorLocation(editor.getBody(), 0); + editor.nodeChanged(); + } + }); + }; + + function selectAll() { + editor.onKeyDown.add(function(editor, e) { + if (!isDefaultPrevented(e) && e.keyCode == 65 && VK.metaKeyPressed(e)) { + e.preventDefault(); + editor.execCommand('SelectAll'); + } + }); + }; + + 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() { + editor.onKeyDown.add(function(editor, e) { + if (!isDefaultPrevented(e) && 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); } } @@ -1164,13 +1526,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) { - if (e.target.nodeName === "HTML") { - var body = ed.getBody(); + editor.onMouseDown.add(function(editor, e) { + if (!isDefaultPrevented(e) && e.target.nodeName === "HTML") { + var body = editor.getBody(); // Blur the body it's focused but not correctly focused body.blur(); @@ -1184,6181 +1546,6421 @@ 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 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; + function removeStylesWhenDeletingAccrossBlockElements() { + function getAttributeApplyFunction() { + var template = dom.getAttribs(selection.getStart().cloneNode(false)); + + return function() { + var target = selection.getStart(); + + if (target !== editor.getBody()) { + dom.setAttrib(target, "style", null); + + each(template, function(attr) { + target.setAttributeNode(attr.cloneNode(true)); + }); + } + }; + } + + function isSelectionAcrossElements() { + return !selection.isCollapsed() && dom.getParent(selection.getStart(), dom.isBlock) != dom.getParent(selection.getEnd(), dom.isBlock); + } + + function blockEvent(editor, e) { + e.preventDefault(); + return false; + } + + editor.onKeyPress.add(function(editor, e) { + var applyAttributes; + + if (!isDefaultPrevented(e) && (e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) { + applyAttributes = getAttributeApplyFunction(); + editor.getDoc().execCommand('delete', false, null); + applyAttributes(); + e.preventDefault(); + return false; } + }); + + dom.bind(editor.getDoc(), 'cut', function(e) { + var applyAttributes; + + if (!isDefaultPrevented(e) && isSelectionAcrossElements()) { + applyAttributes = getAttributeApplyFunction(); + editor.onKeyUp.addToTop(blockEvent); - 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'); - } + applyAttributes(); + editor.onKeyUp.remove(blockEvent); }, 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"); } - - tinymce.create('tinymce.util.Quirks', { - Quirks: function(ed) { - // WebKit - if (tinymce.isWebKit) { - cleanupStylesWhenDeleting(ed); - emptyEditorWhenDeleting(ed); - inputMethodFocus(ed); - selectControlElements(ed); - // iOS - if (tinymce.isIDevice) { - selectionChangeNodeChanged(ed); + function disableBackspaceIntoATable() { + editor.onKeyDown.add(function(editor, e) { + if (!isDefaultPrevented(e) && 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); + } } } + }) + } - // IE - if (tinymce.isIE) { - removeHrOnBackspace(ed); - emptyEditorWhenDeleting(ed); - ensureBodyHasRoleApplication(ed); - removeStylesOnPTagsInheritedFromHeadingTag(ed) - } - - // Gecko - if (tinymce.isGecko) { - removeHrOnBackspace(ed); - focusBody(ed); - } + function addNewLinesBeforeBrInPre() { + // IE8+ rendering mode does the right thing with BR in PRE + if (getDocumentMode() > 7) { + return; } - }); -})(tinymce); - -(function(tinymce) { - var namedEntities, baseEntities, reverseEntities, - attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, - textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, - rawCharsRegExp = /[<>&\"\']/g, - entityRegExp = /&(#x|#)?([\w]+);/g, - asciiMap = { - 128 : "\u20AC", 130 : "\u201A", 131 : "\u0192", 132 : "\u201E", 133 : "\u2026", 134 : "\u2020", - 135 : "\u2021", 136 : "\u02C6", 137 : "\u2030", 138 : "\u0160", 139 : "\u2039", 140 : "\u0152", - 142 : "\u017D", 145 : "\u2018", 146 : "\u2019", 147 : "\u201C", 148 : "\u201D", 149 : "\u2022", - 150 : "\u2013", 151 : "\u2014", 152 : "\u02DC", 153 : "\u2122", 154 : "\u0161", 155 : "\u203A", - 156 : "\u0153", 158 : "\u017E", 159 : "\u0178" - }; - - // Raw entities - baseEntities = { - '\"' : '"', // Needs to be escaped since the YUI compressor would otherwise break the code - "'" : ''', - '<' : '<', - '>' : '>', - '&' : '&' - }; - // Reverse lookup table for raw entities - reverseEntities = { - '<' : '<', - '>' : '>', - '&' : '&', - '"' : '"', - ''' : "'" - }; + // 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('RespectVisibilityInDesign', true); + editor.contentStyles.push('.mceHideBrInPre pre br {display: none}'); + dom.addClass(editor.getBody(), 'mceHideBrInPre'); - // Decodes text by using the browser - function nativeDecode(text) { - var elm; + // Adds a \n before all BR elements in PRE to get them visual + parser.addNodeFilter('pre', function(nodes, name) { + var i = nodes.length, brNodes, j, brElm, sibling; - elm = document.createElement("div"); - elm.innerHTML = text; + while (i--) { + brNodes = nodes[i].getAll('br'); + j = brNodes.length; + while (j--) { + brElm = brNodes[j]; + + // Add \n before BR in PRE elements on older IE:s so the new lines get rendered + sibling = brElm.prev; + if (sibling && sibling.type === 3 && sibling.value.charAt(sibling.value - 1) != '\n') { + sibling.value += '\n'; + } else { + brElm.parent.insert(new tinymce.html.Node('#text', 3), brElm, true).value = '\n'; + } + } + } + }); - return elm.textContent || elm.innerText || text; - }; + // Removes any \n before BR elements in PRE since other browsers and in contentEditable=false mode they will be visible + serializer.addNodeFilter('pre', function(nodes, name) { + var i = nodes.length, brNodes, j, brElm, sibling; - // Build a two way lookup table for the entities - function buildEntitiesLookup(items, radix) { - var i, chr, entity, lookup = {}; + while (i--) { + brNodes = nodes[i].getAll('br'); + j = brNodes.length; + while (j--) { + brElm = brNodes[j]; + sibling = brElm.prev; + if (sibling && sibling.type == 3) { + sibling.value = sibling.value.replace(/\r?\n$/, ''); + } + } + } + }); + } - if (items) { - items = items.split(','); - radix = radix || 10; + function removePreSerializedStylesWhenSelectingControls() { + dom.bind(editor.getBody(), 'mouseup', function(e) { + var value, node = selection.getNode(); - // Build entities lookup table - for (i = 0; i < items.length; i += 2) { - chr = String.fromCharCode(parseInt(items[i], radix)); + // 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', ''); + } - // Only add non base entities - if (!baseEntities[chr]) { - entity = '&' + items[i + 1] + ';'; - lookup[chr] = entity; - lookup[entity] = chr; + // 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', ''); } } + }); + } - return lookup; - } - }; + function keepInlineElementOnDeleteBackspace() { + editor.onKeyDown.add(function(editor, e) { + var isDelete, rng, container, offset, brElm, sibling, collapsed; - // Unpack entities lookup where the numbers are in radix 32 to reduce the size - namedEntities = buildEntitiesLookup( - '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + - '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + - '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + - '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + - '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + - '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + - '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + - '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + - '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + - '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + - 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + - 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + - 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + - 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + - 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + - '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + - '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + - '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + - '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + - '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + - 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + - '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); + isDelete = e.keyCode == DELETE; + if (!isDefaultPrevented(e) && (isDelete || e.keyCode == BACKSPACE) && !VK.modifierPressed(e)) { + rng = selection.getRng(); + container = rng.startContainer; + offset = rng.startOffset; + collapsed = rng.collapsed; - tinymce.html = tinymce.html || {}; + // 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(); - tinymce.html.Entities = { - encodeRaw : function(text, attr) { - return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { - return baseEntities[chr] || chr; - }); - }, + // Prevent default logic since it's broken + e.preventDefault(); - encodeAllRaw : function(text) { - return ('' + text).replace(rawCharsRegExp, function(chr) { - return baseEntities[chr] || chr; - }); - }, + // 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); - encodeNumeric : function(text, attr) { - return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { - // Multi byte sequence convert it to a single entity - if (chr.length > 1) - return '&#' + (((chr.charCodeAt(0) - 0xD800) * 0x400) + (chr.charCodeAt(1) - 0xDC00) + 0x10000) + ';'; + // Do the browser delete + editor.getDoc().execCommand(isDelete ? 'ForwardDelete' : 'Delete', false, null); - return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';'; - }); - }, + // 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); + } - encodeNamed : function(text, attr, entities) { - entities = entities || namedEntities; + // Remove the temp element we inserted + dom.remove('__tmp'); + } + } + }); + } - return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { - return baseEntities[chr] || entities[chr] || chr; - }); - }, + function removeBlockQuoteOnBackSpace() { + // Add block quote deletion handler + editor.onKeyDown.add(function(editor, e) { + var rng, container, offset, root, parent; - getEncodeFunc : function(name, entities) { - var Entities = tinymce.html.Entities; + if (isDefaultPrevented(e) || e.keyCode != VK.BACKSPACE) { + return; + } - entities = buildEntitiesLookup(entities) || namedEntities; + rng = selection.getRng(); + container = rng.startContainer; + offset = rng.startOffset; + root = dom.getRoot(); + parent = container; - function encodeNamedAndNumeric(text, attr) { - return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { - return baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr; - }); - }; + if (!rng.collapsed || offset !== 0) { + return; + } - function encodeCustomNamed(text, attr) { - return Entities.encodeNamed(text, attr, entities); - }; + while (parent && parent.parentNode && parent.parentNode.firstChild == parent && parent.parentNode != root) { + parent = parent.parentNode; + } - // Replace + with , to be compatible with previous TinyMCE versions - name = tinymce.makeMap(name.replace(/\+/g, ',')); + // Is the cursor at the beginning of a blockquote? + if (parent.tagName === 'BLOCKQUOTE') { + // Remove the blockquote + editor.formatter.toggle('blockquote', null, parent); - // Named and numeric encoder - if (name.named && name.numeric) - return encodeNamedAndNumeric; + // Move the caret to the beginning of container + rng = dom.createRng(); + rng.setStart(container, 0); + rng.setEnd(container, 0); + selection.setRng(rng); + } + }); + }; - // Named encoder - if (name.named) { - // Custom names - if (entities) - return encodeCustomNamed; + function setGeckoEditingOptions() { + function setOpts() { + editor._refreshContentEditable(); - return Entities.encodeNamed; + setEditorCommandState("StyleWithCSS", false); + setEditorCommandState("enableInlineTableEditing", false); + + if (!settings.object_resizing) { + setEditorCommandState("enableObjectResizing", false); } + }; - // Numeric - if (name.numeric) - return Entities.encodeNumeric; + if (!settings.readonly) { + editor.onBeforeExecCommand.add(setOpts); + editor.onMouseDown.add(setOpts); + } + }; - // Raw encoder - return Entities.encodeRaw; - }, + function addBrAfterLastLinks() { + function fixLinks(editor, o) { + each(dom.select('a'), function(node) { + var parentNode = node.parentNode, root = dom.getRoot(); - decode : function(text) { - return text.replace(entityRegExp, function(all, numeric, value) { - if (numeric) { - value = parseInt(value, numeric.length === 2 ? 16 : 10); + if (parentNode.lastChild === node) { + while (parentNode && !dom.isBlock(parentNode)) { + if (parentNode.parentNode.lastChild !== parentNode || parentNode === root) { + return; + } - // Support upper UTF - if (value > 0xFFFF) { - value -= 0x10000; + parentNode = parentNode.parentNode; + } - return String.fromCharCode(0xD800 + (value >> 10), 0xDC00 + (value & 0x3FF)); - } else - return asciiMap[value] || String.fromCharCode(value); + dom.add(parentNode, 'br', {'data-mce-bogus' : 1}); } - - return reverseEntities[all] || namedEntities[all] || nativeDecode(all); }); - } - }; -})(tinymce); + }; -tinymce.html.Styles = function(settings, schema) { - var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi, - urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi, - styleRegExp = /\s*([^:]+):\s*([^;]+);?/g, - trimRightRegExp = /\s+$/, - urlColorRegExp = /rgb/, - undef, i, encodingLookup = {}, encodingItems; + editor.onExecCommand.add(function(editor, cmd) { + if (cmd === 'CreateLink') { + fixLinks(editor); + } + }); - settings = settings || {}; + editor.onSetContent.add(selection.onSetContent.add(fixLinks)); + }; - encodingItems = '\\" \\\' \\; \\: ; : \uFEFF'.split(' '); - for (i = 0; i < encodingItems.length; i++) { - encodingLookup[encodingItems[i]] = '\uFEFF' + i; - encodingLookup['\uFEFF' + i] = encodingItems[i]; + function setDefaultBlockType() { + if (settings.forced_root_block) { + editor.onInit.add(function() { + setEditorCommandState('DefaultParagraphSeparator', settings.forced_root_block); + }); + } } - function toHex(match, r, g, b) { - function hex(val) { - val = parseInt(val).toString(16); - - return val.length > 1 ? val : '0' + val; // 0 -> 00 + function removeGhostSelection() { + function repaint(sender, args) { + if (!sender || !args.initial) { + editor.execCommand('mceRepaint'); + } }; - return '#' + hex(r) + hex(g) + hex(b); + editor.onUndo.add(repaint); + editor.onRedo.add(repaint); + editor.onSetContent.add(repaint); }; - return { - toHex : function(color) { - return color.replace(rgbRegExp, toHex); - }, - - parse : function(css) { - var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope || this; - - function compress(prefix, suffix) { - var top, right, bottom, left; - - // Get values and check it it needs compressing - top = styles[prefix + '-top' + suffix]; - if (!top) - return; + function deleteControlItemOnBackSpace() { + editor.onKeyDown.add(function(editor, e) { + var rng; - right = styles[prefix + '-right' + suffix]; - if (top != right) - return; + if (!isDefaultPrevented(e) && e.keyCode == BACKSPACE) { + rng = editor.getDoc().selection.createRange(); + if (rng && rng.item) { + e.preventDefault(); + editor.undoManager.beforeChange(); + dom.remove(rng.item(0)); + editor.undoManager.add(); + } + } + }); + }; - bottom = styles[prefix + '-bottom' + suffix]; - if (right != bottom) - return; + function renderEmptyBlocksFix() { + var emptyBlocksCSS; - left = styles[prefix + '-left' + suffix]; - if (bottom != left) - return; + // IE10+ + if (getDocumentMode() >= 10) { + emptyBlocksCSS = ''; + each('p div h1 h2 h3 h4 h5 h6'.split(' '), function(name, i) { + emptyBlocksCSS += (i > 0 ? ',' : '') + name + ':empty'; + }); - // Compress - styles[prefix + suffix] = left; - delete styles[prefix + '-top' + suffix]; - delete styles[prefix + '-right' + suffix]; - delete styles[prefix + '-bottom' + suffix]; - delete styles[prefix + '-left' + suffix]; - }; + editor.contentStyles.push(emptyBlocksCSS + '{padding-right: 1px !important}'); + } + }; - function canCompress(key) { - var value = styles[key], i; + function fakeImageResize() { + var selectedElmX, selectedElmY, selectedElm, selectedElmGhost, selectedHandle, startX, startY, startW, startH, ratio, + resizeHandles, width, height, rootDocument = document, editableDoc = editor.getDoc(); - if (!value || value.indexOf(' ') < 0) - return; + if (!settings.object_resizing || settings.webkit_fake_resize === false) { + return; + } - value = value.split(' '); - i = value.length; - while (i--) { - if (value[i] !== value[0]) - return false; - } + // Try disabling object resizing if WebKit implements resizing in the future + setEditorCommandState("enableObjectResizing", false); + + // Details about each resize handle how to scale etc + resizeHandles = { + // Name: x multiplier, y multiplier, delta size x, delta size y + n: [.5, 0, 0, -1], + e: [1, .5, 1, 0], + s: [.5, 1, 0, 1], + w: [0, .5, -1, 0], + nw: [0, 0, -1, -1], + ne: [1, 0, 1, -1], + se: [1, 1, 1, 1], + sw : [0, 1, -1, 1] + }; - styles[key] = value[0]; + function resizeElement(e) { + var deltaX, deltaY; - return true; - }; + // Calc new width/height + deltaX = e.screenX - startX; + deltaY = e.screenY - startY; - function compress2(target, a, b, c) { - if (!canCompress(a)) - return; + // Calc new size + width = deltaX * selectedHandle[2] + startW; + height = deltaY * selectedHandle[3] + startH; - if (!canCompress(b)) - return; + // Never scale down lower than 5 pixels + width = width < 5 ? 5 : width; + height = height < 5 ? 5 : height; - if (!canCompress(c)) - return; + // Constrain proportions when modifier key is pressed or if the nw, ne, sw, se corners are moved on an image + if (VK.modifierPressed(e) || (selectedElm.nodeName == "IMG" && selectedHandle[2] * selectedHandle[3] !== 0)) { + width = Math.round(height / ratio); + height = Math.round(width * ratio); + } - // Compress - styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c]; - delete styles[a]; - delete styles[b]; - delete styles[c]; - }; + // Update ghost size + dom.setStyles(selectedElmGhost, { + width: width, + height: height + }); - // Encodes the specified string by replacing all \" \' ; : with _<num> - function encode(str) { - isEncoded = true; + // Update ghost X position if needed + if (selectedHandle[2] < 0 && selectedElmGhost.clientWidth <= width) { + dom.setStyle(selectedElmGhost, 'left', selectedElmX + (startW - width)); + } - return encodingLookup[str]; - }; + // Update ghost Y position if needed + if (selectedHandle[3] < 0 && selectedElmGhost.clientHeight <= height) { + dom.setStyle(selectedElmGhost, 'top', selectedElmY + (startH - height)); + } + } - // Decodes the specified string by replacing all _<num> with it's original value \" \' etc - // It will also decode the \" \' if keep_slashes is set to fale or omitted - function decode(str, keep_slashes) { - if (isEncoded) { - str = str.replace(/\uFEFF[0-9]/g, function(str) { - return encodingLookup[str]; - }); + function endResize() { + function setSizeProp(name, value) { + if (value) { + // Resize by using style or attribute + if (selectedElm.style[name] || !editor.schema.isValid(selectedElm.nodeName.toLowerCase(), name)) { + dom.setStyle(selectedElm, name, value); + } else { + dom.setAttrib(selectedElm, name, value); + } } - - if (!keep_slashes) - str = str.replace(/\\([\'\";:])/g, "$1"); - - return str; } - if (css) { - // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing - css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) { - return str.replace(/[;:]/g, encode); - }); - - // Parse styles - while (matches = styleRegExp.exec(css)) { - name = matches[1].replace(trimRightRegExp, '').toLowerCase(); - value = matches[2].replace(trimRightRegExp, ''); - - if (name && value.length > 0) { - // Opera will produce 700 instead of bold in their style values - if (name === 'font-weight' && value === '700') - value = 'bold'; - else if (name === 'color' || name === 'background-color') // Lowercase colors like RED - value = value.toLowerCase(); + // Set width/height properties + setSizeProp('width', width); + setSizeProp('height', height); - // Convert RGB colors to HEX - value = value.replace(rgbRegExp, toHex); + dom.unbind(editableDoc, 'mousemove', resizeElement); + dom.unbind(editableDoc, 'mouseup', endResize); - // Convert URLs and force them into url('value') format - value = value.replace(urlOrStrRegExp, function(match, url, url2, url3, str, str2) { - str = str || str2; + if (rootDocument != editableDoc) { + dom.unbind(rootDocument, 'mousemove', resizeElement); + dom.unbind(rootDocument, 'mouseup', endResize); + } - if (str) { - str = decode(str); + // Remove ghost and update resize handle positions + dom.remove(selectedElmGhost); + showResizeRect(selectedElm); + } - // Force strings into single quote format - return "'" + str.replace(/\'/g, "\\'") + "'"; - } + function showResizeRect(targetElm) { + var position, targetWidth, targetHeight; - url = decode(url || url2 || url3); + hideResizeRect(); - // Convert the URL to relative/absolute depending on config - if (urlConverter) - url = urlConverter.call(urlConverterScope, url, 'style'); + // Get position and size of target + position = dom.getPos(targetElm); + selectedElmX = position.x; + selectedElmY = position.y; + targetWidth = targetElm.offsetWidth; + targetHeight = targetElm.offsetHeight; - // Output new URL format - return "url('" + url.replace(/\'/g, "\\'") + "')"; - }); + // Reset width/height if user selects a new image/table + if (selectedElm != targetElm) { + selectedElm = targetElm; + width = height = 0; + } - styles[name] = isEncoded ? decode(value, true) : value; - } + each(resizeHandles, function(handle, name) { + var handleElm; - styleRegExp.lastIndex = matches.index + matches[0].length; - } + // Get existing or render resize handle + handleElm = dom.get('mceResizeHandle' + name); + if (!handleElm) { + handleElm = dom.add(editableDoc.documentElement, 'div', { + id: 'mceResizeHandle' + name, + 'class': 'mceResizeHandle', + style: 'cursor:' + name + '-resize; margin:0; padding:0' + }); - // Compress the styles to reduce it's size for example IE will expand styles - compress("border", ""); - compress("border", "-width"); - compress("border", "-color"); - compress("border", "-style"); - compress("padding", ""); - compress("margin", ""); - compress2('border', 'border-width', 'border-style', 'border-color'); + dom.bind(handleElm, 'mousedown', function(e) { + e.preventDefault(); - // Remove pointless border, IE produces these - if (styles.border === 'medium none') - delete styles.border; - } + endResize(); - return styles; - }, + startX = e.screenX; + startY = e.screenY; + startW = selectedElm.clientWidth; + startH = selectedElm.clientHeight; + ratio = startH / startW; + selectedHandle = handle; - serialize : function(styles, element_name) { - var css = '', name, value; + selectedElmGhost = selectedElm.cloneNode(true); + dom.addClass(selectedElmGhost, 'mceClonedResizable'); + dom.setStyles(selectedElmGhost, { + left: selectedElmX, + top: selectedElmY, + margin: 0 + }); - function serializeStyles(name) { - var styleList, i, l, value; + editableDoc.documentElement.appendChild(selectedElmGhost); - styleList = schema.styles[name]; - if (styleList) { - for (i = 0, l = styleList.length; i < l; i++) { - name = styleList[i]; - value = styles[name]; + dom.bind(editableDoc, 'mousemove', resizeElement); + dom.bind(editableDoc, 'mouseup', endResize); - if (value !== undef && value.length > 0) - css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; - } + if (rootDocument != editableDoc) { + dom.bind(rootDocument, 'mousemove', resizeElement); + dom.bind(rootDocument, 'mouseup', endResize); + } + }); + } else { + dom.show(handleElm); } - }; - // Serialize styles according to schema - if (element_name && schema && schema.styles) { - // Serialize global styles and element specific styles - serializeStyles('*'); - serializeStyles(element_name); - } else { - // Output the styles in the order they are inside the object - for (name in styles) { - value = styles[name]; + // Position element + dom.setStyles(handleElm, { + left: (targetWidth * handle[0] + selectedElmX) - (handleElm.offsetWidth / 2), + top: (targetHeight * handle[1] + selectedElmY) - (handleElm.offsetHeight / 2) + }); + }); - if (value !== undef && value.length > 0) - css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; - } + // Only add resize rectangle on WebKit and only on images + if (!tinymce.isOpera && selectedElm.nodeName == "IMG") { + selectedElm.setAttribute('data-mce-selected', '1'); } - - return css; } - }; -}; - -(function(tinymce) { - var transitional = {}, boolAttrMap, blockElementsMap, shortEndedElementsMap, nonEmptyElementsMap, customElementsMap = {}, - defaultWhiteSpaceElementsMap, selfClosingElementsMap, makeMap = tinymce.makeMap, each = tinymce.each; - function split(str, delim) { - return str.split(delim || ','); - }; + function hideResizeRect() { + if (selectedElm) { + selectedElm.removeAttribute('data-mce-selected'); + } - function unpack(lookup, data) { - var key, elements = {}; + for (var name in resizeHandles) { + dom.hide('mceResizeHandle' + name); + } + } - function replace(value) { - return value.replace(/[A-Z]+/g, function(key) { - return replace(lookup[key]); + // Add CSS for resize handles, cloned element and selected + editor.contentStyles.push( + '.mceResizeHandle {' + + 'position: absolute;' + + 'border: 1px solid black;' + + 'background: #FFF;' + + 'width: 5px;' + + 'height: 5px;' + + 'z-index: 10000' + + '}' + + '.mceResizeHandle:hover {' + + 'background: #000' + + '}' + + 'img[data-mce-selected] {' + + 'outline: 1px solid black' + + '}' + + 'img.mceClonedResizable, table.mceClonedResizable {' + + 'position: absolute;' + + 'outline: 1px dashed black;' + + 'opacity: .5;' + + 'z-index: 10000' + + '}' + ); + + function updateResizeRect() { + var controlElm = dom.getParent(selection.getNode(), 'table,img'); + + // Remove data-mce-selected from all elements since they might have been copied using Ctrl+c/v + each(dom.select('img[data-mce-selected]'), function(img) { + img.removeAttribute('data-mce-selected'); }); - }; - // Unpack lookup - for (key in lookup) { - if (lookup.hasOwnProperty(key)) - lookup[key] = replace(lookup[key]); + if (controlElm) { + showResizeRect(controlElm); + } else { + hideResizeRect(); + } } - // Unpack and parse data into object map - replace(data).replace(/#/g, '#text').replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g, function(str, name, attributes, children) { - attributes = split(attributes, '|'); + // Show/hide resize rect when image is selected + editor.onNodeChange.add(updateResizeRect); - elements[name] = { - attributes : makeMap(attributes), - attributesOrder : attributes, - children : makeMap(children, '|', {'#comment' : {}}) + // Fixes WebKit quirk where it returns IMG on getNode if caret is after last image in container + dom.bind(editableDoc, 'selectionchange', updateResizeRect); + + // Remove the internal attribute when serializing the DOM + editor.serializer.addAttributeFilter('data-mce-selected', function(nodes, name) { + var i = nodes.length; + + while (i--) { + nodes[i].attr(name, null); } }); + } - return elements; - }; - - // Build a lookup table for block elements both lowercase and uppercase - blockElementsMap = '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'; - blockElementsMap = makeMap(blockElementsMap, ',', makeMap(blockElementsMap.toUpperCase())); - - // This is the XHTML 1.0 transitional elements with it's attributes and children packed to reduce it's size - transitional = unpack({ - Z : 'H|K|N|O|P', - Y : 'X|form|R|Q', - ZG : 'E|span|width|align|char|charoff|valign', - X : 'p|T|div|U|W|isindex|fieldset|table', - ZF : 'E|align|char|charoff|valign', - W : 'pre|hr|blockquote|address|center|noframes', - ZE : 'abbr|axis|headers|scope|rowspan|colspan|align|char|charoff|valign|nowrap|bgcolor|width|height', - ZD : '[E][S]', - U : 'ul|ol|dl|menu|dir', - ZC : 'p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q', - T : 'h1|h2|h3|h4|h5|h6', - ZB : 'X|S|Q', - S : 'R|P', - ZA : 'a|G|J|M|O|P', - R : 'a|H|K|N|O', - Q : 'noscript|P', - P : 'ins|del|script', - O : 'input|select|textarea|label|button', - N : 'M|L', - M : 'em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym', - L : 'sub|sup', - K : 'J|I', - J : 'tt|i|b|u|s|strike', - I : 'big|small|font|basefont', - H : 'G|F', - G : 'br|span|bdo', - F : 'object|applet|img|map|iframe', - E : 'A|B|C', - D : 'accesskey|tabindex|onfocus|onblur', - C : 'onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup', - B : 'lang|xml:lang|dir', - A : 'id|class|style|title' - }, 'script[id|charset|type|language|src|defer|xml:space][]' + - 'style[B|id|type|media|title|xml:space][]' + - 'object[E|declare|classid|codebase|data|type|codetype|archive|standby|width|height|usemap|name|tabindex|align|border|hspace|vspace][#|param|Y]' + - 'param[id|name|value|valuetype|type][]' + - 'p[E|align][#|S]' + - 'a[E|D|charset|type|name|href|hreflang|rel|rev|shape|coords|target][#|Z]' + - 'br[A|clear][]' + - 'span[E][#|S]' + - 'bdo[A|C|B][#|S]' + - 'applet[A|codebase|archive|code|object|alt|name|width|height|align|hspace|vspace][#|param|Y]' + - 'h1[E|align][#|S]' + - 'img[E|src|alt|name|longdesc|width|height|usemap|ismap|align|border|hspace|vspace][]' + - 'map[B|C|A|name][X|form|Q|area]' + - 'h2[E|align][#|S]' + - 'iframe[A|longdesc|name|src|frameborder|marginwidth|marginheight|scrolling|align|width|height][#|Y]' + - 'h3[E|align][#|S]' + - 'tt[E][#|S]' + - 'i[E][#|S]' + - 'b[E][#|S]' + - 'u[E][#|S]' + - 's[E][#|S]' + - 'strike[E][#|S]' + - 'big[E][#|S]' + - 'small[E][#|S]' + - 'font[A|B|size|color|face][#|S]' + - 'basefont[id|size|color|face][]' + - 'em[E][#|S]' + - 'strong[E][#|S]' + - 'dfn[E][#|S]' + - 'code[E][#|S]' + - 'q[E|cite][#|S]' + - 'samp[E][#|S]' + - 'kbd[E][#|S]' + - 'var[E][#|S]' + - 'cite[E][#|S]' + - 'abbr[E][#|S]' + - 'acronym[E][#|S]' + - 'sub[E][#|S]' + - 'sup[E][#|S]' + - 'input[E|D|type|name|value|checked|disabled|readonly|size|maxlength|src|alt|usemap|onselect|onchange|accept|align][]' + - 'select[E|name|size|multiple|disabled|tabindex|onfocus|onblur|onchange][optgroup|option]' + - 'optgroup[E|disabled|label][option]' + - 'option[E|selected|disabled|label|value][]' + - 'textarea[E|D|name|rows|cols|disabled|readonly|onselect|onchange][]' + - 'label[E|for|accesskey|onfocus|onblur][#|S]' + - 'button[E|D|name|value|type|disabled][#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]' + - 'h4[E|align][#|S]' + - 'ins[E|cite|datetime][#|Y]' + - 'h5[E|align][#|S]' + - 'del[E|cite|datetime][#|Y]' + - 'h6[E|align][#|S]' + - 'div[E|align][#|Y]' + - 'ul[E|type|compact][li]' + - 'li[E|type|value][#|Y]' + - 'ol[E|type|compact|start][li]' + - 'dl[E|compact][dt|dd]' + - 'dt[E][#|S]' + - 'dd[E][#|Y]' + - 'menu[E|compact][li]' + - 'dir[E|compact][li]' + - 'pre[E|width|xml:space][#|ZA]' + - 'hr[E|align|noshade|size|width][]' + - 'blockquote[E|cite][#|Y]' + - 'address[E][#|S|p]' + - 'center[E][#|Y]' + - 'noframes[E][#|Y]' + - 'isindex[A|B|prompt][]' + - 'fieldset[E][#|legend|Y]' + - 'legend[E|accesskey|align][#|S]' + - 'table[E|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor][caption|col|colgroup|thead|tfoot|tbody|tr]' + - 'caption[E|align][#|S]' + - 'col[ZG][]' + - 'colgroup[ZG][col]' + - 'thead[ZF][tr]' + - 'tr[ZF|bgcolor][th|td]' + - 'th[E|ZE][#|Y]' + - 'form[E|action|method|name|enctype|onsubmit|onreset|accept|accept-charset|target][#|X|R|Q]' + - 'noscript[E][#|Y]' + - 'td[E|ZE][#|Y]' + - 'tfoot[ZF][tr]' + - 'tbody[ZF][tr]' + - 'area[E|D|shape|coords|href|nohref|alt|target][]' + - 'base[id|href|target][]' + - 'body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]' - ); - - boolAttrMap = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,autoplay,loop,controls'); - shortEndedElementsMap = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source'); - nonEmptyElementsMap = tinymce.extend(makeMap('td,th,iframe,video,audio,object'), shortEndedElementsMap); - defaultWhiteSpaceElementsMap = makeMap('pre,script,style,textarea'); - selfClosingElementsMap = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); + function keepNoScriptContents() { + if (getDocumentMode() < 9) { + parser.addNodeFilter('noscript', function(nodes) { + var i = nodes.length, node, textNode; - tinymce.html.Schema = function(settings) { - var self = this, elements = {}, children = {}, patternElements = [], validStyles, whiteSpaceElementsMap; + while (i--) { + node = nodes[i]; + textNode = node.firstChild; - settings = settings || {}; + if (textNode) { + node.attr('data-mce-innertext', textNode.value); + } + } + }); - // Allow all elements and attributes if verify_html is set to false - if (settings.verify_html === false) - settings.valid_elements = '*[*]'; + serializer.addNodeFilter('noscript', function(nodes) { + var i = nodes.length, node, textNode, value; - // Build styles list - if (settings.valid_styles) { - validStyles = {}; + while (i--) { + node = nodes[i]; + textNode = nodes[i].firstChild; - // Convert styles into a rule list - each(settings.valid_styles, function(value, key) { - validStyles[key] = tinymce.explode(value); + if (textNode) { + textNode.value = tinymce.html.Entities.decode(textNode.value); + } else { + // Old IE can't retain noscript value so an attribute is used to store it + value = node.attributes.map['data-mce-innertext']; + if (value) { + node.attr('data-mce-innertext', null); + textNode = new tinymce.html.Node('#text', 3); + textNode.value = value; + textNode.raw = true; + node.append(textNode); + } + } + } }); } + } - whiteSpaceElementsMap = settings.whitespace_elements ? makeMap(settings.whitespace_elements) : defaultWhiteSpaceElementsMap; + // All browsers + disableBackspaceIntoATable(); + removeBlockQuoteOnBackSpace(); + emptyEditorWhenDeleting(); + + // WebKit + if (tinymce.isWebKit) { + keepInlineElementOnDeleteBackspace(); + cleanupStylesWhenDeleting(); + inputMethodFocus(); + selectControlElements(); + setDefaultBlockType(); + + // iOS + if (tinymce.isIDevice) { + selectionChangeNodeChanged(); + } else { + fakeImageResize(); + selectAll(); + } + } - // Converts a wildcard expression string to a regexp for example *a will become /.*a/. - function patternToRegExp(str) { - return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$'); + // IE + if (tinymce.isIE) { + removeHrOnBackspace(); + ensureBodyHasRoleApplication(); + addNewLinesBeforeBrInPre(); + removePreSerializedStylesWhenSelectingControls(); + deleteControlItemOnBackSpace(); + renderEmptyBlocksFix(); + keepNoScriptContents(); + } + + // Gecko + if (tinymce.isGecko) { + removeHrOnBackspace(); + focusBody(); + removeStylesWhenDeletingAccrossBlockElements(); + setGeckoEditingOptions(); + addBrAfterLastLinks(); + removeGhostSelection(); + } + + // Opera + if (tinymce.isOpera) { + fakeImageResize(); + } +}; +(function(tinymce) { + var namedEntities, baseEntities, reverseEntities, + attrsCharsRegExp = /[&<>\"\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + textCharsRegExp = /[<>&\u007E-\uD7FF\uE000-\uFFEF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, + rawCharsRegExp = /[<>&\"\']/g, + entityRegExp = /&(#x|#)?([\w]+);/g, + asciiMap = { + 128 : "\u20AC", 130 : "\u201A", 131 : "\u0192", 132 : "\u201E", 133 : "\u2026", 134 : "\u2020", + 135 : "\u2021", 136 : "\u02C6", 137 : "\u2030", 138 : "\u0160", 139 : "\u2039", 140 : "\u0152", + 142 : "\u017D", 145 : "\u2018", 146 : "\u2019", 147 : "\u201C", 148 : "\u201D", 149 : "\u2022", + 150 : "\u2013", 151 : "\u2014", 152 : "\u02DC", 153 : "\u2122", 154 : "\u0161", 155 : "\u203A", + 156 : "\u0153", 158 : "\u017E", 159 : "\u0178" }; - // Parses the specified valid_elements string and adds to the current rules - // This function is a bit hard to read since it's heavily optimized for speed - 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 = /^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/, - attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/, - hasPatternsRegExp = /[*?+]/; + // Raw entities + baseEntities = { + '\"' : '"', // Needs to be escaped since the YUI compressor would otherwise break the code + "'" : ''', + '<' : '<', + '>' : '>', + '&' : '&' + }; - if (valid_elements) { - // Split valid elements into an array with rules - valid_elements = split(valid_elements); + // Reverse lookup table for raw entities + reverseEntities = { + '<' : '<', + '>' : '>', + '&' : '&', + '"' : '"', + ''' : "'" + }; - if (elements['@']) { - globalAttributes = elements['@'].attributes; - globalAttributesOrder = elements['@'].attributesOrder; - } + // Decodes text by using the browser + function nativeDecode(text) { + var elm; - // Loop all rules - for (ei = 0, el = valid_elements.length; ei < el; ei++) { - // Parse element rule - matches = elementRuleRegExp.exec(valid_elements[ei]); - if (matches) { - // Setup local names for matches - prefix = matches[1]; - elementName = matches[2]; - outputName = matches[3]; - attrData = matches[4]; + elm = document.createElement("div"); + elm.innerHTML = text; - // Create new attributes and attributesOrder - attributes = {}; - attributesOrder = []; + return elm.textContent || elm.innerText || text; + }; - // Create the new element - element = { - attributes : attributes, - attributesOrder : attributesOrder - }; + // Build a two way lookup table for the entities + function buildEntitiesLookup(items, radix) { + var i, chr, entity, lookup = {}; - // Padd empty elements prefix - if (prefix === '#') - element.paddEmpty = true; + if (items) { + items = items.split(','); + radix = radix || 10; - // Remove empty elements prefix - if (prefix === '-') - element.removeEmpty = true; + // Build entities lookup table + for (i = 0; i < items.length; i += 2) { + chr = String.fromCharCode(parseInt(items[i], radix)); - // Copy attributes from global rule into current rule - if (globalAttributes) { - for (key in globalAttributes) - attributes[key] = globalAttributes[key]; + // Only add non base entities + if (!baseEntities[chr]) { + entity = '&' + items[i + 1] + ';'; + lookup[chr] = entity; + lookup[entity] = chr; + } + } - attributesOrder.push.apply(attributesOrder, globalAttributesOrder); - } + return lookup; + } + }; - // Attributes defined - if (attrData) { - attrData = split(attrData, '|'); - for (ai = 0, al = attrData.length; ai < al; ai++) { - matches = attrRuleRegExp.exec(attrData[ai]); - if (matches) { - attr = {}; - attrType = matches[1]; - attrName = matches[2].replace(/::/g, ':'); - prefix = matches[3]; - value = matches[4]; + // Unpack entities lookup where the numbers are in radix 32 to reduce the size + namedEntities = buildEntitiesLookup( + '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' + + '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' + + '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' + + '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' + + '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' + + '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' + + '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' + + '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' + + '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' + + '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' + + 'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' + + 'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' + + 't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' + + 'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' + + 'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' + + '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' + + '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' + + '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' + + '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' + + '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' + + 'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' + + '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); - // Required - if (attrType === '!') { - element.attributesRequired = element.attributesRequired || []; - element.attributesRequired.push(attrName); - attr.required = true; - } + tinymce.html = tinymce.html || {}; - // Denied from global - if (attrType === '-') { - delete attributes[attrName]; - attributesOrder.splice(tinymce.inArray(attributesOrder, attrName), 1); - continue; - } + tinymce.html.Entities = { + encodeRaw : function(text, attr) { + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + return baseEntities[chr] || chr; + }); + }, - // Default value - if (prefix) { - // Default value - if (prefix === '=') { - element.attributesDefault = element.attributesDefault || []; - element.attributesDefault.push({name: attrName, value: value}); - attr.defaultValue = value; - } + encodeAllRaw : function(text) { + return ('' + text).replace(rawCharsRegExp, function(chr) { + return baseEntities[chr] || chr; + }); + }, - // Forced value - if (prefix === ':') { - element.attributesForced = element.attributesForced || []; - element.attributesForced.push({name: attrName, value: value}); - attr.forcedValue = value; - } + encodeNumeric : function(text, attr) { + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + // Multi byte sequence convert it to a single entity + if (chr.length > 1) + return '&#' + (((chr.charCodeAt(0) - 0xD800) * 0x400) + (chr.charCodeAt(1) - 0xDC00) + 0x10000) + ';'; - // Required values - if (prefix === '<') - attr.validValues = makeMap(value, '?'); - } + return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';'; + }); + }, - // Check for attribute patterns - if (hasPatternsRegExp.test(attrName)) { - element.attributePatterns = element.attributePatterns || []; - attr.pattern = patternToRegExp(attrName); - element.attributePatterns.push(attr); - } else { - // Add attribute to order list if it doesn't already exist - if (!attributes[attrName]) - attributesOrder.push(attrName); + encodeNamed : function(text, attr, entities) { + entities = entities || namedEntities; - attributes[attrName] = attr; - } - } - } - } + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + return baseEntities[chr] || entities[chr] || chr; + }); + }, - // Global rule, store away these for later usage - if (!globalAttributes && elementName == '@') { - globalAttributes = attributes; - globalAttributesOrder = attributesOrder; - } + getEncodeFunc : function(name, entities) { + var Entities = tinymce.html.Entities; - // Handle substitute elements such as b/strong - if (outputName) { - element.outputName = elementName; - elements[outputName] = element; - } + entities = buildEntitiesLookup(entities) || namedEntities; - // Add pattern or exact element - if (hasPatternsRegExp.test(elementName)) { - element.pattern = patternToRegExp(elementName); - patternElements.push(element); - } else - elements[elementName] = element; - } - } + function encodeNamedAndNumeric(text, attr) { + return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) { + return baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr; + }); + }; + + function encodeCustomNamed(text, attr) { + return Entities.encodeNamed(text, attr, entities); + }; + + // Replace + with , to be compatible with previous TinyMCE versions + name = tinymce.makeMap(name.replace(/\+/g, ',')); + + // Named and numeric encoder + if (name.named && name.numeric) + return encodeNamedAndNumeric; + + // Named encoder + if (name.named) { + // Custom names + if (entities) + return encodeCustomNamed; + + return Entities.encodeNamed; } - }; - function setValidElements(valid_elements) { - elements = {}; - patternElements = []; + // Numeric + if (name.numeric) + return Entities.encodeNumeric; - addValidElements(valid_elements); + // Raw encoder + return Entities.encodeRaw; + }, - each(transitional, function(element, name) { - children[name] = element.children; + decode : function(text) { + return text.replace(entityRegExp, function(all, numeric, value) { + if (numeric) { + value = parseInt(value, numeric.length === 2 ? 16 : 10); + + // Support upper UTF + if (value > 0xFFFF) { + value -= 0x10000; + + return String.fromCharCode(0xD800 + (value >> 10), 0xDC00 + (value & 0x3FF)); + } else + return asciiMap[value] || String.fromCharCode(value); + } + + return reverseEntities[all] || namedEntities[all] || nativeDecode(all); }); + } + }; +})(tinymce); + +tinymce.html.Styles = function(settings, schema) { + var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi, + urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi, + styleRegExp = /\s*([^:]+):\s*([^;]+);?/g, + trimRightRegExp = /\s+$/, + urlColorRegExp = /rgb/, + undef, i, encodingLookup = {}, encodingItems; + + settings = settings || {}; + + encodingItems = '\\" \\\' \\; \\: ; : \uFEFF'.split(' '); + for (i = 0; i < encodingItems.length; i++) { + encodingLookup[encodingItems[i]] = '\uFEFF' + i; + encodingLookup['\uFEFF' + i] = encodingItems[i]; + } + + function toHex(match, r, g, b) { + function hex(val) { + val = parseInt(val).toString(16); + + return val.length > 1 ? val : '0' + val; // 0 -> 00 }; - // Adds custom non HTML elements to the schema - function addCustomElements(custom_elements) { - var customElementRegExp = /^(~)?(.+)$/; + return '#' + hex(r) + hex(g) + hex(b); + }; - if (custom_elements) { - each(split(custom_elements), function(rule) { - var matches = customElementRegExp.exec(rule), - inline = matches[1] === '~', - cloneName = inline ? 'span' : 'div', - name = matches[2]; + return { + toHex : function(color) { + return color.replace(rgbRegExp, toHex); + }, - children[name] = children[cloneName]; - customElementsMap[name] = cloneName; + parse : function(css) { + var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope || this; - // If it's not marked as inline then add it to valid block elements - if (!inline) - blockElementsMap[name] = {}; + function compress(prefix, suffix) { + var top, right, bottom, left; - // Add custom elements at span/div positions - each(children, function(element, child) { - if (element[cloneName]) - element[name] = element[cloneName]; + // Get values and check it it needs compressing + top = styles[prefix + '-top' + suffix]; + if (!top) + return; + + right = styles[prefix + '-right' + suffix]; + if (top != right) + return; + + bottom = styles[prefix + '-bottom' + suffix]; + if (right != bottom) + return; + + left = styles[prefix + '-left' + suffix]; + if (bottom != left) + return; + + // Compress + styles[prefix + suffix] = left; + delete styles[prefix + '-top' + suffix]; + delete styles[prefix + '-right' + suffix]; + delete styles[prefix + '-bottom' + suffix]; + delete styles[prefix + '-left' + suffix]; + }; + + function canCompress(key) { + var value = styles[key], i; + + if (!value || value.indexOf(' ') < 0) + return; + + value = value.split(' '); + i = value.length; + while (i--) { + if (value[i] !== value[0]) + return false; + } + + styles[key] = value[0]; + + return true; + }; + + function compress2(target, a, b, c) { + if (!canCompress(a)) + return; + + if (!canCompress(b)) + return; + + if (!canCompress(c)) + return; + + // Compress + styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c]; + delete styles[a]; + delete styles[b]; + delete styles[c]; + }; + + // Encodes the specified string by replacing all \" \' ; : with _<num> + function encode(str) { + isEncoded = true; + + return encodingLookup[str]; + }; + + // Decodes the specified string by replacing all _<num> with it's original value \" \' etc + // It will also decode the \" \' if keep_slashes is set to fale or omitted + function decode(str, keep_slashes) { + if (isEncoded) { + str = str.replace(/\uFEFF[0-9]/g, function(str) { + return encodingLookup[str]; }); + } + + if (!keep_slashes) + 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 + css = css.replace(/\\[\"\';:\uFEFF]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) { + return str.replace(/[;:]/g, encode); }); - } - }; - // Adds valid children to the schema object - function addValidChildren(valid_children) { - var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/; + // Parse styles + while (matches = styleRegExp.exec(css)) { + name = matches[1].replace(trimRightRegExp, '').toLowerCase(); + value = matches[2].replace(trimRightRegExp, ''); + + if (name && value.length > 0) { + // Opera will produce 700 instead of bold in their style values + if (name === 'font-weight' && value === '700') + value = 'bold'; + else if (name === 'color' || name === 'background-color') // Lowercase colors like RED + value = value.toLowerCase(); - if (valid_children) { - each(split(valid_children), function(rule) { - var matches = childRuleRegExp.exec(rule), parent, prefix; + // Convert RGB colors to HEX + value = value.replace(rgbRegExp, toHex); - if (matches) { - prefix = matches[1]; + // Convert URLs and force them into url('value') format + value = value.replace(urlOrStrRegExp, processUrl); + styles[name] = isEncoded ? decode(value, true) : value; + } - // Add/remove items from default - if (prefix) - parent = children[matches[2]]; - else - parent = children[matches[2]] = {'#comment' : {}}; + styleRegExp.lastIndex = matches.index + matches[0].length; + } - parent = children[matches[2]]; + // Compress the styles to reduce it's size for example IE will expand styles + compress("border", ""); + compress("border", "-width"); + compress("border", "-color"); + compress("border", "-style"); + compress("padding", ""); + compress("margin", ""); + compress2('border', 'border-width', 'border-style', 'border-color'); - each(split(matches[3], '|'), function(child) { - if (prefix === '-') - delete parent[child]; - else - parent[child] = {}; - }); - } - }); + // Remove pointless border, IE produces these + if (styles.border === 'medium none') + delete styles.border; } - }; - function getElementRule(name) { - var element = elements[name], i; + return styles; + }, - // Exact match found - if (element) - return element; + serialize : function(styles, element_name) { + var css = '', name, value; - // No exact match then try the patterns - i = patternElements.length; - while (i--) { - element = patternElements[i]; + function serializeStyles(name) { + var styleList, i, l, value; - if (element.pattern.test(name)) - return element; + styleList = schema.styles[name]; + if (styleList) { + for (i = 0, l = styleList.length; i < l; i++) { + name = styleList[i]; + value = styles[name]; + + if (value !== undef && value.length > 0) + css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; + } + } + }; + + // Serialize styles according to schema + if (element_name && schema && schema.styles) { + // Serialize global styles and element specific styles + serializeStyles('*'); + serializeStyles(element_name); + } else { + // Output the styles in the order they are inside the object + for (name in styles) { + value = styles[name]; + + if (value !== undef && value.length > 0) + css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';'; + } } - }; - if (!settings.valid_elements) { - // No valid elements defined then clone the elements from the transitional spec - each(transitional, function(element, name) { - elements[name] = { - attributes : element.attributes, - attributesOrder : element.attributesOrder - }; + return css; + } + }; +}; - children[name] = element.children; - }); +(function(tinymce) { + var mapCache = {}, makeMap = tinymce.makeMap, each = tinymce.each; - // Switch these - each(split('strong/b,em/i'), function(item) { - item = split(item, '/'); - elements[item[1]].outputName = item[0]; - }); + function split(str, delim) { + return str.split(delim || ','); + }; - // Add default alt attribute for images - elements.img.attributesDefault = [{name: 'alt', value: ''}]; + function unpack(lookup, data) { + var key, elements = {}; - // Remove these if they are empty by default - each(split('ol,ul,sub,sup,blockquote,span,font,a,table,tbody,tr'), function(name) { - elements[name].removeEmpty = true; + function replace(value) { + return value.replace(/[A-Z]+/g, function(key) { + return replace(lookup[key]); }); + }; - // Padd these by default - each(split('p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption'), function(name) { - elements[name].paddEmpty = true; - }); - } else - setValidElements(settings.valid_elements); + // Unpack lookup + for (key in lookup) { + if (lookup.hasOwnProperty(key)) + lookup[key] = replace(lookup[key]); + } - addCustomElements(settings.custom_elements); - addValidChildren(settings.valid_children); - addValidElements(settings.extended_valid_elements); + // Unpack and parse data into object map + replace(data).replace(/#/g, '#text').replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g, function(str, name, attributes, children) { + attributes = split(attributes, '|'); - // Todo: Remove this when we fix list handling to be valid - addValidChildren('+ol[ul|ol],+ul[ul|ol]'); + elements[name] = { + attributes : makeMap(attributes), + attributesOrder : attributes, + children : makeMap(children, '|', {'#comment' : {}}) + } + }); - // If the user didn't allow span only allow internal spans - if (!getElementRule('span')) - addValidElements('span[!data-mce-type|*]'); + return elements; + }; - // Delete invalid elements - if (settings.invalid_elements) { - tinymce.each(tinymce.explode(settings.invalid_elements), function(item) { - if (elements[item]) - delete elements[item]; - }); + function getHTML5() { + var html5 = mapCache.html5; + + if (!html5) { + html5 = mapCache.html5 = unpack({ + A : 'id|accesskey|class|dir|draggable|item|hidden|itemprop|role|spellcheck|style|subject|title|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup', + B : '#|a|abbr|area|audio|b|bdo|br|button|canvas|cite|code|command|datalist|del|dfn|em|embed|i|iframe|img|input|ins|kbd|keygen|label|link|map|mark|meta|' + + 'meter|noscript|object|output|progress|q|ruby|samp|script|select|small|span|strong|sub|sup|svg|textarea|time|var|video|wbr', + C : '#|a|abbr|area|address|article|aside|audio|b|bdo|blockquote|br|button|canvas|cite|code|command|datalist|del|details|dfn|dialog|div|dl|em|embed|fieldset|' + + 'figure|footer|form|h1|h2|h3|h4|h5|h6|header|hgroup|hr|i|iframe|img|input|ins|kbd|keygen|label|link|map|mark|menu|meta|meter|nav|noscript|ol|object|output|' + + 'p|pre|progress|q|ruby|samp|script|section|select|small|span|strong|style|sub|sup|svg|table|textarea|time|ul|var|video' + }, 'html[A|manifest][body|head]' + + 'head[A][base|command|link|meta|noscript|script|style|title]' + + 'title[A][#]' + + 'base[A|href|target][]' + + 'link[A|href|rel|media|type|sizes][]' + + 'meta[A|http-equiv|name|content|charset][]' + + 'style[A|type|media|scoped][#]' + + 'script[A|charset|type|src|defer|async][#]' + + 'noscript[A][C]' + + 'body[A][C]' + + 'section[A][C]' + + 'nav[A][C]' + + 'article[A][C]' + + 'aside[A][C]' + + 'h1[A][B]' + + 'h2[A][B]' + + 'h3[A][B]' + + 'h4[A][B]' + + 'h5[A][B]' + + 'h6[A][B]' + + 'hgroup[A][h1|h2|h3|h4|h5|h6]' + + 'header[A][C]' + + 'footer[A][C]' + + 'address[A][C]' + + 'p[A][B]' + + 'br[A][]' + + 'pre[A][B]' + + 'dialog[A][dd|dt]' + + 'blockquote[A|cite][C]' + + 'ol[A|start|reversed][li]' + + 'ul[A][li]' + + 'li[A|value][C]' + + 'dl[A][dd|dt]' + + 'dt[A][B]' + + 'dd[A][C]' + + 'a[A|href|target|ping|rel|media|type][B]' + + 'em[A][B]' + + 'strong[A][B]' + + 'small[A][B]' + + 'cite[A][B]' + + 'q[A|cite][B]' + + 'dfn[A][B]' + + 'abbr[A][B]' + + 'code[A][B]' + + 'var[A][B]' + + 'samp[A][B]' + + 'kbd[A][B]' + + 'sub[A][B]' + + 'sup[A][B]' + + 'i[A][B]' + + 'b[A][B]' + + 'mark[A][B]' + + 'progress[A|value|max][B]' + + 'meter[A|value|min|max|low|high|optimum][B]' + + 'time[A|datetime][B]' + + 'ruby[A][B|rt|rp]' + + 'rt[A][B]' + + 'rp[A][B]' + + 'bdo[A][B]' + + 'span[A][B]' + + 'ins[A|cite|datetime][B]' + + 'del[A|cite|datetime][B]' + + '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][]' + + 'object[A|data|type|height|width|usemap|name|form|classid][param]' + + 'param[A|name|value][]' + + 'details[A|open][C|legend]' + + 'command[A|type|label|icon|disabled|checked|radiogroup][]' + + 'menu[A|type|label][C|li]' + + 'legend[A][C|B]' + + 'div[A][C]' + + 'source[A|src|type|media][]' + + 'audio[A|src|autobuffer|autoplay|loop|controls][source]' + + 'video[A|src|autobuffer|autoplay|loop|controls|width|height|poster][source]' + + 'hr[A][]' + + 'form[A|accept-charset|action|autocomplete|enctype|method|name|novalidate|target][C]' + + 'fieldset[A|disabled|form|name][C|legend]' + + 'label[A|form|for][B]' + + 'input[A|type|accept|alt|autocomplete|autofocus|checked|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|height|list|max|maxlength|min|' + + 'multiple|pattern|placeholder|readonly|required|size|src|step|width|files|value|name][]' + + 'button[A|autofocus|disabled|form|formaction|formenctype|formmethod|formnovalidate|formtarget|name|value|type][B]' + + 'select[A|autofocus|disabled|form|multiple|name|size][option|optgroup]' + + 'datalist[A][B|option]' + + 'optgroup[A|disabled|label][option]' + + 'option[A|disabled|selected|label|value][]' + + 'textarea[A|autofocus|disabled|form|maxlength|name|placeholder|readonly|required|rows|cols|wrap][]' + + 'keygen[A|autofocus|challenge|disabled|form|keytype|name][]' + + 'output[A|for|form|name][B]' + + 'canvas[A|width|height][]' + + 'map[A|name][B|C]' + + 'area[A|shape|coords|href|alt|target|media|rel|ping|type][]' + + 'mathml[A][]' + + 'svg[A][]' + + 'table[A|border][caption|colgroup|thead|tfoot|tbody|tr]' + + 'caption[A][C]' + + 'colgroup[A|span][col]' + + 'col[A|span][]' + + 'thead[A][tr]' + + 'tfoot[A][tr]' + + 'tbody[A][tr]' + + 'tr[A][th|td]' + + 'th[A|headers|rowspan|colspan|scope][B]' + + 'td[A|headers|rowspan|colspan][C]' + + 'wbr[A][]' + ); } - self.children = children; - - self.styles = validStyles; + return html5; + }; - self.getBoolAttrs = function() { - return boolAttrMap; - }; + function getHTML4() { + var html4 = mapCache.html4; + + if (!html4) { + // This is the XHTML 1.0 transitional elements with it's attributes and children packed to reduce it's size + html4 = mapCache.html4 = unpack({ + Z : 'H|K|N|O|P', + Y : 'X|form|R|Q', + ZG : 'E|span|width|align|char|charoff|valign', + X : 'p|T|div|U|W|isindex|fieldset|table', + ZF : 'E|align|char|charoff|valign', + W : 'pre|hr|blockquote|address|center|noframes', + ZE : 'abbr|axis|headers|scope|rowspan|colspan|align|char|charoff|valign|nowrap|bgcolor|width|height', + ZD : '[E][S]', + U : 'ul|ol|dl|menu|dir', + ZC : 'p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q', + T : 'h1|h2|h3|h4|h5|h6', + ZB : 'X|S|Q', + S : 'R|P', + ZA : 'a|G|J|M|O|P', + R : 'a|H|K|N|O', + Q : 'noscript|P', + P : 'ins|del|script', + O : 'input|select|textarea|label|button', + N : 'M|L', + M : 'em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym', + L : 'sub|sup', + K : 'J|I', + J : 'tt|i|b|u|s|strike', + I : 'big|small|font|basefont', + H : 'G|F', + G : 'br|span|bdo', + F : 'object|applet|img|map|iframe', + E : 'A|B|C', + D : 'accesskey|tabindex|onfocus|onblur', + C : 'onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup', + B : 'lang|xml:lang|dir', + A : 'id|class|style|title' + }, 'script[id|charset|type|language|src|defer|xml:space][]' + + 'style[B|id|type|media|title|xml:space][]' + + 'object[E|declare|classid|codebase|data|type|codetype|archive|standby|width|height|usemap|name|tabindex|align|border|hspace|vspace][#|param|Y]' + + 'param[id|name|value|valuetype|type][]' + + 'p[E|align][#|S]' + + 'a[E|D|charset|type|name|href|hreflang|rel|rev|shape|coords|target][#|Z]' + + 'br[A|clear][]' + + 'span[E][#|S]' + + 'bdo[A|C|B][#|S]' + + 'applet[A|codebase|archive|code|object|alt|name|width|height|align|hspace|vspace][#|param|Y]' + + 'h1[E|align][#|S]' + + 'img[E|src|alt|name|longdesc|width|height|usemap|ismap|align|border|hspace|vspace][]' + + 'map[B|C|A|name][X|form|Q|area]' + + 'h2[E|align][#|S]' + + 'iframe[A|longdesc|name|src|frameborder|marginwidth|marginheight|scrolling|align|width|height][#|Y]' + + 'h3[E|align][#|S]' + + 'tt[E][#|S]' + + 'i[E][#|S]' + + 'b[E][#|S]' + + 'u[E][#|S]' + + 's[E][#|S]' + + 'strike[E][#|S]' + + 'big[E][#|S]' + + 'small[E][#|S]' + + 'font[A|B|size|color|face][#|S]' + + 'basefont[id|size|color|face][]' + + 'em[E][#|S]' + + 'strong[E][#|S]' + + 'dfn[E][#|S]' + + 'code[E][#|S]' + + 'q[E|cite][#|S]' + + 'samp[E][#|S]' + + 'kbd[E][#|S]' + + 'var[E][#|S]' + + 'cite[E][#|S]' + + 'abbr[E][#|S]' + + 'acronym[E][#|S]' + + 'sub[E][#|S]' + + 'sup[E][#|S]' + + 'input[E|D|type|name|value|checked|disabled|readonly|size|maxlength|src|alt|usemap|onselect|onchange|accept|align][]' + + 'select[E|name|size|multiple|disabled|tabindex|onfocus|onblur|onchange][optgroup|option]' + + 'optgroup[E|disabled|label][option]' + + 'option[E|selected|disabled|label|value][]' + + 'textarea[E|D|name|rows|cols|disabled|readonly|onselect|onchange][]' + + 'label[E|for|accesskey|onfocus|onblur][#|S]' + + 'button[E|D|name|value|type|disabled][#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]' + + 'h4[E|align][#|S]' + + 'ins[E|cite|datetime][#|Y]' + + 'h5[E|align][#|S]' + + 'del[E|cite|datetime][#|Y]' + + 'h6[E|align][#|S]' + + 'div[E|align][#|Y]' + + 'ul[E|type|compact][li]' + + 'li[E|type|value][#|Y]' + + 'ol[E|type|compact|start][li]' + + 'dl[E|compact][dt|dd]' + + 'dt[E][#|S]' + + 'dd[E][#|Y]' + + 'menu[E|compact][li]' + + 'dir[E|compact][li]' + + 'pre[E|width|xml:space][#|ZA]' + + 'hr[E|align|noshade|size|width][]' + + 'blockquote[E|cite][#|Y]' + + 'address[E][#|S|p]' + + 'center[E][#|Y]' + + 'noframes[E][#|Y]' + + 'isindex[A|B|prompt][]' + + 'fieldset[E][#|legend|Y]' + + 'legend[E|accesskey|align][#|S]' + + 'table[E|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor][caption|col|colgroup|thead|tfoot|tbody|tr]' + + 'caption[E|align][#|S]' + + 'col[ZG][]' + + 'colgroup[ZG][col]' + + 'thead[ZF][tr]' + + 'tr[ZF|bgcolor][th|td]' + + 'th[E|ZE][#|Y]' + + 'form[E|action|method|name|enctype|onsubmit|onreset|accept|accept-charset|target][#|X|R|Q]' + + 'noscript[E][#|Y]' + + 'td[E|ZE][#|Y]' + + 'tfoot[ZF][tr]' + + 'tbody[ZF][tr]' + + 'area[E|D|shape|coords|href|nohref|alt|target][]' + + 'base[id|href|target][]' + + 'body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]' + ); + } - self.getBlockElements = function() { - return blockElementsMap; - }; + return html4; + }; - self.getShortEndedElements = function() { - return shortEndedElementsMap; - }; + tinymce.html.Schema = function(settings) { + var self = this, elements = {}, children = {}, patternElements = [], validStyles, schemaItems; + var whiteSpaceElementsMap, selfClosingElementsMap, shortEndedElementsMap, boolAttrMap, blockElementsMap, nonEmptyElementsMap, customElementsMap = {}; - self.getSelfClosingElements = function() { - return selfClosingElementsMap; - }; + // Creates an lookup table map object for the specified option or the default value + function createLookupTable(option, default_value, extend) { + var value = settings[option]; - self.getNonEmptyElements = function() { - return nonEmptyElementsMap; - }; + if (!value) { + // Get cached default map or make it if needed + value = mapCache[option]; - self.getWhiteSpaceElements = function() { - return whiteSpaceElementsMap; - }; + if (!value) { + value = makeMap(default_value, ' ', makeMap(default_value.toUpperCase(), ' ')); + value = tinymce.extend(value, extend); - self.isValidChild = function(name, child) { - var parent = children[name]; + mapCache[option] = value; + } + } else { + // Create custom map + value = makeMap(value, ',', makeMap(value.toUpperCase(), ' ')); + } - return !!(parent && parent[child]); + return value; }; - self.getElementRule = getElementRule; + settings = settings || {}; + schemaItems = settings.schema == "html5" ? getHTML5() : getHTML4(); - self.getCustomElements = function() { - return customElementsMap; - }; + // Allow all elements and attributes if verify_html is set to false + if (settings.verify_html === false) + settings.valid_elements = '*[*]'; - self.addValidElements = addValidElements; + // Build styles list + if (settings.valid_styles) { + validStyles = {}; - self.setValidElements = setValidElements; + // Convert styles into a rule list + each(settings.valid_styles, function(value, key) { + validStyles[key] = tinymce.explode(value); + }); + } - self.addCustomElements = addCustomElements; + // Setup map objects + whiteSpaceElementsMap = createLookupTable('whitespace_elements', 'pre script noscript style textarea'); + selfClosingElementsMap = createLookupTable('self_closing_elements', 'colgroup dd dt li option p td tfoot th thead tr'); + shortEndedElementsMap = createLookupTable('short_ended_elements', 'area base basefont br col frame hr img input isindex link meta param embed source wbr'); + boolAttrMap = createLookupTable('boolean_attributes', 'checked compact declare defer disabled ismap multiple nohref noresize noshade nowrap readonly selected autoplay loop controls'); + nonEmptyElementsMap = createLookupTable('non_empty_elements', 'td th iframe video audio object', shortEndedElementsMap); + textBlockElementsMap = createLookupTable('text_block_elements', 'h1 h2 h3 h4 h5 h6 p div address pre form ' + + 'blockquote center dir fieldset header footer article section hgroup aside nav figure'); + blockElementsMap = createLookupTable('block_elements', 'hr table tbody thead tfoot ' + + 'th tr td li ol ul caption dl dt dd noscript menu isindex samp option datalist select optgroup', textBlockElementsMap); - self.addValidChildren = addValidChildren; - }; + // Converts a wildcard expression string to a regexp for example *a will become /.*a/. + function patternToRegExp(str) { + return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$'); + }; - // Expose boolMap and blockElementMap as static properties for usage in DOMUtils - tinymce.html.Schema.boolAttrMap = boolAttrMap; - tinymce.html.Schema.blockElementsMap = blockElementsMap; -})(tinymce); + // Parses the specified valid_elements string and adds to the current rules + // This function is a bit hard to read since it's heavily optimized for speed + 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 = /^([#+\-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/, + attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/, + hasPatternsRegExp = /[*?+]/; -(function(tinymce) { - tinymce.html.SaxParser = function(settings, schema) { - var self = this, noop = function() {}; + if (valid_elements) { + // Split valid elements into an array with rules + valid_elements = split(valid_elements); - settings = settings || {}; - self.schema = schema = schema || new tinymce.html.Schema(); + if (elements['@']) { + globalAttributes = elements['@'].attributes; + globalAttributesOrder = elements['@'].attributesOrder; + } - if (settings.fix_self_closing !== false) - settings.fix_self_closing = true; + // Loop all rules + for (ei = 0, el = valid_elements.length; ei < el; ei++) { + // Parse element rule + matches = elementRuleRegExp.exec(valid_elements[ei]); + if (matches) { + // Setup local names for matches + prefix = matches[1]; + elementName = matches[2]; + outputName = matches[3]; + attrData = matches[4]; - // Add handler functions from settings and setup default handlers - tinymce.each('comment cdata text start end pi doctype'.split(' '), function(name) { - if (name) - self[name] = settings[name] || noop; - }); + // Create new attributes and attributesOrder + attributes = {}; + attributesOrder = []; - self.parse = function(html) { - var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name, isInternalElement, removeInternalElements, - shortEndedElements, fillAttrsMap, isShortEnded, validate, elementRule, isValidElement, attr, attribsValue, invalidPrefixRegExp, - validAttributesMap, validAttributePatterns, attributesRequired, attributesDefault, attributesForced, selfClosing, - tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0, decode = tinymce.html.Entities.decode, fixSelfClosing, isIE; + // Create the new element + element = { + attributes : attributes, + attributesOrder : attributesOrder + }; - function processEndTag(name) { - var pos, i; + // Padd empty elements prefix + if (prefix === '#') + element.paddEmpty = true; - // Find position of parent of the same type - pos = stack.length; - while (pos--) { - if (stack[pos].name === name) - break; - } + // Remove empty elements prefix + if (prefix === '-') + element.removeEmpty = true; - // Found parent - if (pos >= 0) { - // Close all the open elements - for (i = stack.length - 1; i >= pos; i--) { - name = stack[i]; + // Copy attributes from global rule into current rule + if (globalAttributes) { + for (key in globalAttributes) + attributes[key] = globalAttributes[key]; - if (name.valid) - self.end(name.name); - } + attributesOrder.push.apply(attributesOrder, globalAttributesOrder); + } - // Remove the open elements from the stack - stack.length = pos; - } - }; + // Attributes defined + if (attrData) { + attrData = split(attrData, '|'); + for (ai = 0, al = attrData.length; ai < al; ai++) { + matches = attrRuleRegExp.exec(attrData[ai]); + if (matches) { + attr = {}; + attrType = matches[1]; + attrName = matches[2].replace(/::/g, ':'); + prefix = matches[3]; + value = matches[4]; - // Precompile RegExps and map objects - tokenRegExp = new RegExp('<(?:' + - '(?:!--([\\w\\W]*?)-->)|' + // Comment - '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + // CDATA - '(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE - '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI - '(?:\\/([^>]+)>)|' + // End element - '(?:([^\\s\\/<>]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/)>)' + // Start element - ')', 'g'); + // Required + if (attrType === '!') { + element.attributesRequired = element.attributesRequired || []; + element.attributesRequired.push(attrName); + attr.required = true; + } - attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g; - specialElements = { - 'script' : /<\/script[^>]*>/gi, - 'style' : /<\/style[^>]*>/gi, - 'noscript' : /<\/noscript[^>]*>/gi - }; + // Denied from global + if (attrType === '-') { + delete attributes[attrName]; + attributesOrder.splice(tinymce.inArray(attributesOrder, attrName), 1); + continue; + } - // Setup lookup tables for empty elements and boolean attributes - shortEndedElements = schema.getShortEndedElements(); - selfClosing = schema.getSelfClosingElements(); - fillAttrsMap = schema.getBoolAttrs(); - validate = settings.validate; - removeInternalElements = settings.remove_internals; - fixSelfClosing = settings.fix_self_closing; - isIE = tinymce.isIE; - invalidPrefixRegExp = /^:/; + // Default value + if (prefix) { + // Default value + if (prefix === '=') { + element.attributesDefault = element.attributesDefault || []; + element.attributesDefault.push({name: attrName, value: value}); + attr.defaultValue = value; + } - while (matches = tokenRegExp.exec(html)) { - // Text - if (index < matches.index) - self.text(decode(html.substr(index, matches.index - index))); + // Forced value + if (prefix === ':') { + element.attributesForced = element.attributesForced || []; + element.attributesForced.push({name: attrName, value: value}); + attr.forcedValue = value; + } - if (value = matches[6]) { // End element - value = value.toLowerCase(); + // Required values + if (prefix === '<') + attr.validValues = makeMap(value, '?'); + } - // IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements - if (isIE && invalidPrefixRegExp.test(value)) - value = value.substr(1); + // Check for attribute patterns + if (hasPatternsRegExp.test(attrName)) { + element.attributePatterns = element.attributePatterns || []; + attr.pattern = patternToRegExp(attrName); + element.attributePatterns.push(attr); + } else { + // Add attribute to order list if it doesn't already exist + if (!attributes[attrName]) + attributesOrder.push(attrName); - processEndTag(value); - } else if (value = matches[7]) { // Start element - value = value.toLowerCase(); + attributes[attrName] = attr; + } + } + } + } - // IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements - if (isIE && invalidPrefixRegExp.test(value)) - value = value.substr(1); + // Global rule, store away these for later usage + if (!globalAttributes && elementName == '@') { + globalAttributes = attributes; + globalAttributesOrder = attributesOrder; + } - isShortEnded = value in shortEndedElements; + // Handle substitute elements such as b/strong + if (outputName) { + element.outputName = elementName; + elements[outputName] = element; + } - // Is self closing tag for example an <li> after an open <li> - if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) - processEndTag(value); + // Add pattern or exact element + if (hasPatternsRegExp.test(elementName)) { + element.pattern = patternToRegExp(elementName); + patternElements.push(element); + } else + elements[elementName] = element; + } + } + } + }; - // Validate element - if (!validate || (elementRule = schema.getElementRule(value))) { - isValidElement = true; + function setValidElements(valid_elements) { + elements = {}; + patternElements = []; - // Grab attributes map and patters when validation is enabled - if (validate) { - validAttributesMap = elementRule.attributes; - validAttributePatterns = elementRule.attributePatterns; - } + addValidElements(valid_elements); - // Parse attributes - if (attribsValue = matches[8]) { - isInternalElement = attribsValue.indexOf('data-mce-type') !== -1; // Check if the element is an internal element + each(schemaItems, function(element, name) { + children[name] = element.children; + }); + }; - // If the element has internal attributes then remove it if we are told to do so - if (isInternalElement && removeInternalElements) - isValidElement = false; + // Adds custom non HTML elements to the schema + function addCustomElements(custom_elements) { + var customElementRegExp = /^(~)?(.+)$/; - attrList = []; - attrList.map = {}; + if (custom_elements) { + each(split(custom_elements), function(rule) { + var matches = customElementRegExp.exec(rule), + inline = matches[1] === '~', + cloneName = inline ? 'span' : 'div', + name = matches[2]; - attribsValue.replace(attrRegExp, function(match, name, value, val2, val3) { - var attrRule, i; + children[name] = children[cloneName]; + customElementsMap[name] = cloneName; - name = name.toLowerCase(); - value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute + // If it's not marked as inline then add it to valid block elements + if (!inline) { + blockElementsMap[name.toUpperCase()] = {}; + blockElementsMap[name] = {}; + } - // Validate name and value - if (validate && !isInternalElement && name.indexOf('data-') !== 0) { - attrRule = validAttributesMap[name]; + // Add elements clone if needed + if (!elements[name]) { + elements[name] = elements[cloneName]; + } - // Find rule by pattern matching - if (!attrRule && validAttributePatterns) { - i = validAttributePatterns.length; - while (i--) { - attrRule = validAttributePatterns[i]; - if (attrRule.pattern.test(name)) - break; - } + // Add custom elements at span/div positions + each(children, function(element, child) { + if (element[cloneName]) + element[name] = element[cloneName]; + }); + }); + } + }; - // No rule matched - if (i === -1) - attrRule = null; - } + // Adds valid children to the schema object + function addValidChildren(valid_children) { + var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/; - // No attribute rule found - if (!attrRule) - return; + if (valid_children) { + each(split(valid_children), function(rule) { + var matches = childRuleRegExp.exec(rule), parent, prefix; - // Validate value - if (attrRule.validValues && !(value in attrRule.validValues)) - return; - } + if (matches) { + prefix = matches[1]; - // Add attribute to list and map - attrList.map[name] = value; - attrList.push({ - name: name, - value: value - }); - }); - } else { - attrList = []; - attrList.map = {}; - } + // Add/remove items from default + if (prefix) + parent = children[matches[2]]; + else + parent = children[matches[2]] = {'#comment' : {}}; - // Process attributes if validation is enabled - if (validate && !isInternalElement) { - attributesRequired = elementRule.attributesRequired; - attributesDefault = elementRule.attributesDefault; - attributesForced = elementRule.attributesForced; + parent = children[matches[2]]; - // Handle forced attributes - if (attributesForced) { - i = attributesForced.length; - while (i--) { - attr = attributesForced[i]; - name = attr.name; - attrValue = attr.value; + each(split(matches[3], '|'), function(child) { + if (prefix === '-') + delete parent[child]; + else + parent[child] = {}; + }); + } + }); + } + }; - if (attrValue === '{$uid}') - attrValue = 'mce_' + idCount++; + function getElementRule(name) { + var element = elements[name], i; - attrList.map[name] = attrValue; - attrList.push({name: name, value: attrValue}); - } - } + // Exact match found + if (element) + return element; - // Handle default attributes - if (attributesDefault) { - i = attributesDefault.length; - while (i--) { - attr = attributesDefault[i]; - name = attr.name; + // No exact match then try the patterns + i = patternElements.length; + while (i--) { + element = patternElements[i]; - if (!(name in attrList.map)) { - attrValue = attr.value; + if (element.pattern.test(name)) + return element; + } + }; - if (attrValue === '{$uid}') - attrValue = 'mce_' + idCount++; + if (!settings.valid_elements) { + // No valid elements defined then clone the elements from the schema spec + each(schemaItems, function(element, name) { + elements[name] = { + attributes : element.attributes, + attributesOrder : element.attributesOrder + }; - attrList.map[name] = attrValue; - attrList.push({name: name, value: attrValue}); - } - } - } + children[name] = element.children; + }); - // Handle required attributes - if (attributesRequired) { - i = attributesRequired.length; - while (i--) { - if (attributesRequired[i] in attrList.map) - break; - } + // Switch these on HTML4 + if (settings.schema != "html5") { + each(split('strong/b,em/i'), function(item) { + item = split(item, '/'); + elements[item[1]].outputName = item[0]; + }); + } - // None of the required attributes where found - if (i === -1) - isValidElement = false; - } + // Add default alt attribute for images + elements.img.attributesDefault = [{name: 'alt', value: ''}]; - // Invalidate element if it's marked as bogus - if (attrList.map['data-mce-bogus']) - isValidElement = false; - } + // Remove these if they are empty by default + each(split('ol,ul,sub,sup,blockquote,span,font,a,table,tbody,tr,strong,em,b,i'), function(name) { + if (elements[name]) { + elements[name].removeEmpty = true; + } + }); - if (isValidElement) - self.start(value, attrList, isShortEnded); - } else - isValidElement = false; + // Padd these by default + each(split('p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption'), function(name) { + elements[name].paddEmpty = true; + }); + } else + setValidElements(settings.valid_elements); - // Treat script, noscript and style a bit different since they may include code that looks like elements - if (endRegExp = specialElements[value]) { - endRegExp.lastIndex = index = matches.index + matches[0].length; + addCustomElements(settings.custom_elements); + addValidChildren(settings.valid_children); + addValidElements(settings.extended_valid_elements); - if (matches = endRegExp.exec(html)) { - if (isValidElement) - text = html.substr(index, matches.index - index); + // Todo: Remove this when we fix list handling to be valid + addValidChildren('+ol[ul|ol],+ul[ul|ol]'); - index = matches.index + matches[0].length; - } else { - text = html.substr(index); - index = html.length; - } + // Delete invalid elements + if (settings.invalid_elements) { + tinymce.each(tinymce.explode(settings.invalid_elements), function(item) { + if (elements[item]) + delete elements[item]; + }); + } - if (isValidElement && text.length > 0) - self.text(text, true); + // If the user didn't allow span only allow internal spans + if (!getElementRule('span')) + addValidElements('span[!data-mce-type|*]'); - if (isValidElement) - self.end(value); + self.children = children; - tokenRegExp.lastIndex = index; - continue; - } + self.styles = validStyles; - // Push value on to stack - if (!isShortEnded) { - if (!attribsValue || attribsValue.indexOf('/') != attribsValue.length - 1) - stack.push({name: value, valid: isValidElement}); - else if (isValidElement) - self.end(value); - } - } else if (value = matches[1]) { // Comment - self.comment(value); - } else if (value = matches[2]) { // CDATA - self.cdata(value); - } else if (value = matches[3]) { // DOCTYPE - self.doctype(value); - } else if (value = matches[4]) { // PI - self.pi(value, matches[5]); - } + self.getBoolAttrs = function() { + return boolAttrMap; + }; - index = matches.index + matches[0].length; - } + self.getBlockElements = function() { + return blockElementsMap; + }; - // Text - if (index < html.length) - self.text(decode(html.substr(index))); + self.getTextBlockElements = function() { + return textBlockElementsMap; + }; - // Close any open elements - for (i = stack.length - 1; i >= 0; i--) { - value = stack[i]; + self.getShortEndedElements = function() { + return shortEndedElementsMap; + }; - if (value.valid) - self.end(value.name); - } + self.getSelfClosingElements = function() { + return selfClosingElementsMap; }; - } -})(tinymce); -(function(tinymce) { - var whiteSpaceRegExp = /^[ \t\r\n]*$/, typeLookup = { - '#text' : 3, - '#comment' : 8, - '#cdata' : 4, - '#pi' : 7, - '#doctype' : 10, - '#document-fragment' : 11 - }; + self.getNonEmptyElements = function() { + return nonEmptyElementsMap; + }; - // Walks the tree left/right - function walk(node, root_node, prev) { - var sibling, parent, startName = prev ? 'lastChild' : 'firstChild', siblingName = prev ? 'prev' : 'next'; + self.getWhiteSpaceElements = function() { + return whiteSpaceElementsMap; + }; - // Walk into nodes if it has a start - if (node[startName]) - return node[startName]; + self.isValidChild = function(name, child) { + var parent = children[name]; - // Return the sibling if it has one - if (node !== root_node) { - sibling = node[siblingName]; + return !!(parent && parent[child]); + }; - if (sibling) - return sibling; + self.isValid = function(name, attr) { + var attrPatterns, i, rule = getElementRule(name); - // Walk up the parents to look for siblings - for (parent = node.parent; parent && parent !== root_node; parent = parent.parent) { - sibling = parent[siblingName]; + // Check if it's a valid element + if (rule) { + if (attr) { + // Check if attribute name exists + if (rule.attributes[attr]) { + return true; + } - if (sibling) - return sibling; + // Check if attribute matches a regexp pattern + attrPatterns = rule.attributePatterns; + if (attrPatterns) { + i = attrPatterns.length; + while (i--) { + if (attrPatterns[i].pattern.test(name)) { + return true; + } + } + } + } else { + return true; + } } - } - }; - function Node(name, type) { - this.name = name; - this.type = type; + // No match + return false; + }; + + self.getElementRule = getElementRule; - if (type === 1) { - this.attributes = []; - this.attributes.map = {}; - } - } + self.getCustomElements = function() { + return customElementsMap; + }; - tinymce.extend(Node.prototype, { - replace : function(node) { - var self = this; + self.addValidElements = addValidElements; - if (node.parent) - node.remove(); + self.setValidElements = setValidElements; - self.insert(node, self); - self.remove(); + self.addCustomElements = addCustomElements; - return self; - }, + self.addValidChildren = addValidChildren; - attr : function(name, value) { - var self = this, attrs, i, undef; + self.elements = elements; + }; +})(tinymce); - if (typeof name !== "string") { - for (i in name) - self.attr(i, name[i]); +(function(tinymce) { + tinymce.html.SaxParser = function(settings, schema) { + var self = this, noop = function() {}; - return self; - } + settings = settings || {}; + self.schema = schema = schema || new tinymce.html.Schema(); - if (attrs = self.attributes) { - if (value !== undef) { - // Remove attribute - if (value === null) { - if (name in attrs.map) { - delete attrs.map[name]; + if (settings.fix_self_closing !== false) + settings.fix_self_closing = true; - i = attrs.length; - while (i--) { - if (attrs[i].name === name) { - attrs = attrs.splice(i, 1); - return self; - } - } - } + // Add handler functions from settings and setup default handlers + tinymce.each('comment cdata text start end pi doctype'.split(' '), function(name) { + if (name) + self[name] = settings[name] || noop; + }); - return self; - } + self.parse = function(html) { + var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name, isInternalElement, removeInternalElements, + shortEndedElements, fillAttrsMap, isShortEnded, validate, elementRule, isValidElement, attr, attribsValue, invalidPrefixRegExp, + validAttributesMap, validAttributePatterns, attributesRequired, attributesDefault, attributesForced, selfClosing, + tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0, decode = tinymce.html.Entities.decode, fixSelfClosing, isIE; + + function processEndTag(name) { + var pos, i; + + // Find position of parent of the same type + pos = stack.length; + while (pos--) { + if (stack[pos].name === name) + break; + } - // Set attribute - if (name in attrs.map) { - // Set attribute - i = attrs.length; - while (i--) { - if (attrs[i].name === name) { - attrs[i].value = value; - break; - } - } - } else - attrs.push({name: name, value: value}); + // Found parent + if (pos >= 0) { + // Close all the open elements + for (i = stack.length - 1; i >= pos; i--) { + name = stack[i]; - attrs.map[name] = value; + if (name.valid) + self.end(name.name); + } - return self; - } else { - return attrs.map[name]; + // Remove the open elements from the stack + stack.length = pos; } - } - }, + }; - clone : function() { - var self = this, clone = new Node(self.name, self.type), i, l, selfAttrs, selfAttr, cloneAttrs; + function parseAttribute(match, name, value, val2, val3) { + var attrRule, i; - // Clone element attributes - if (selfAttrs = self.attributes) { - cloneAttrs = []; - cloneAttrs.map = {}; + name = name.toLowerCase(); + value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute - for (i = 0, l = selfAttrs.length; i < l; i++) { - selfAttr = selfAttrs[i]; + // Validate name and value + if (validate && !isInternalElement && name.indexOf('data-') !== 0) { + attrRule = validAttributesMap[name]; - // Clone everything except id - if (selfAttr.name !== 'id') { - cloneAttrs[cloneAttrs.length] = {name: selfAttr.name, value: selfAttr.value}; - cloneAttrs.map[selfAttr.name] = selfAttr.value; + // 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; } - clone.attributes = cloneAttrs; - } + // Add attribute to list and map + attrList.map[name] = value; + attrList.push({ + name: name, + value: value + }); + }; - clone.value = self.value; - clone.shortEnded = self.shortEnded; + // Precompile RegExps and map objects + tokenRegExp = new RegExp('<(?:' + + '(?:!--([\\w\\W]*?)-->)|' + // Comment + '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + // CDATA + '(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE + '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI + '(?:\\/([^>]+)>)|' + // End element + '(?:([A-Za-z0-9\\-\\:\\.]+)((?:\\s+[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*|\\/|\\s+)>)' + // Start element + ')', 'g'); - return clone; - }, + attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:[^\"])*)\")|(?:\'((?:[^\'])*)\')|([^>\s]+)))?/g; + specialElements = { + 'script' : /<\/script[^>]*>/gi, + 'style' : /<\/style[^>]*>/gi, + 'noscript' : /<\/noscript[^>]*>/gi + }; - wrap : function(wrapper) { - var self = this; + // Setup lookup tables for empty elements and boolean attributes + shortEndedElements = schema.getShortEndedElements(); + selfClosing = settings.self_closing_elements || schema.getSelfClosingElements(); + fillAttrsMap = schema.getBoolAttrs(); + validate = settings.validate; + removeInternalElements = settings.remove_internals; + fixSelfClosing = settings.fix_self_closing; + isIE = tinymce.isIE; + invalidPrefixRegExp = /^:/; - self.parent.insert(wrapper, self); - wrapper.append(self); + while (matches = tokenRegExp.exec(html)) { + // Text + if (index < matches.index) + self.text(decode(html.substr(index, matches.index - index))); - return self; - }, + if (value = matches[6]) { // End element + value = value.toLowerCase(); - unwrap : function() { - var self = this, node, next; + // IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements + if (isIE && invalidPrefixRegExp.test(value)) + value = value.substr(1); - for (node = self.firstChild; node; ) { - next = node.next; - self.insert(node, self, true); - node = next; - } + processEndTag(value); + } else if (value = matches[7]) { // Start element + value = value.toLowerCase(); - self.remove(); - }, + // IE will add a ":" in front of elements it doesn't understand like custom elements or HTML5 elements + if (isIE && invalidPrefixRegExp.test(value)) + value = value.substr(1); - remove : function() { - var self = this, parent = self.parent, next = self.next, prev = self.prev; + isShortEnded = value in shortEndedElements; - if (parent) { - if (parent.firstChild === self) { - parent.firstChild = next; + // Is self closing tag for example an <li> after an open <li> + if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value) + processEndTag(value); - if (next) - next.prev = null; - } else { - prev.next = next; - } + // Validate element + if (!validate || (elementRule = schema.getElementRule(value))) { + isValidElement = true; - if (parent.lastChild === self) { - parent.lastChild = prev; + // Grab attributes map and patters when validation is enabled + if (validate) { + validAttributesMap = elementRule.attributes; + validAttributePatterns = elementRule.attributePatterns; + } - if (prev) - prev.next = null; - } else { - next.prev = prev; - } + // Parse attributes + if (attribsValue = matches[8]) { + isInternalElement = attribsValue.indexOf('data-mce-type') !== -1; // Check if the element is an internal element - self.parent = self.next = self.prev = null; - } + // If the element has internal attributes then remove it if we are told to do so + if (isInternalElement && removeInternalElements) + isValidElement = false; - return self; - }, + attrList = []; + attrList.map = {}; - append : function(node) { - var self = this, last; + attribsValue.replace(attrRegExp, parseAttribute); + } else { + attrList = []; + attrList.map = {}; + } - if (node.parent) - node.remove(); + // Process attributes if validation is enabled + if (validate && !isInternalElement) { + attributesRequired = elementRule.attributesRequired; + attributesDefault = elementRule.attributesDefault; + attributesForced = elementRule.attributesForced; - last = self.lastChild; - if (last) { - last.next = node; - node.prev = last; - self.lastChild = node; - } else - self.lastChild = self.firstChild = node; + // Handle forced attributes + if (attributesForced) { + i = attributesForced.length; + while (i--) { + attr = attributesForced[i]; + name = attr.name; + attrValue = attr.value; - node.parent = self; + if (attrValue === '{$uid}') + attrValue = 'mce_' + idCount++; - return node; - }, + attrList.map[name] = attrValue; + attrList.push({name: name, value: attrValue}); + } + } - insert : function(node, ref_node, before) { - var parent; + // Handle default attributes + if (attributesDefault) { + i = attributesDefault.length; + while (i--) { + attr = attributesDefault[i]; + name = attr.name; - if (node.parent) - node.remove(); + if (!(name in attrList.map)) { + attrValue = attr.value; - parent = ref_node.parent || this; + if (attrValue === '{$uid}') + attrValue = 'mce_' + idCount++; - if (before) { - if (ref_node === parent.firstChild) - parent.firstChild = node; - else - ref_node.prev.next = node; + attrList.map[name] = attrValue; + attrList.push({name: name, value: attrValue}); + } + } + } - node.prev = ref_node.prev; - node.next = ref_node; - ref_node.prev = node; - } else { - if (ref_node === parent.lastChild) - parent.lastChild = node; - else - ref_node.next.prev = node; + // Handle required attributes + if (attributesRequired) { + i = attributesRequired.length; + while (i--) { + if (attributesRequired[i] in attrList.map) + break; + } - node.next = ref_node.next; - node.prev = ref_node; - ref_node.next = node; - } + // None of the required attributes where found + if (i === -1) + isValidElement = false; + } - node.parent = parent; + // Invalidate element if it's marked as bogus + if (attrList.map['data-mce-bogus']) + isValidElement = false; + } - return node; - }, + if (isValidElement) + self.start(value, attrList, isShortEnded); + } else + isValidElement = false; - getAll : function(name) { - var self = this, node, collection = []; + // Treat script, noscript and style a bit different since they may include code that looks like elements + if (endRegExp = specialElements[value]) { + endRegExp.lastIndex = index = matches.index + matches[0].length; - for (node = self.firstChild; node; node = walk(node, self)) { - if (node.name === name) - collection.push(node); - } + if (matches = endRegExp.exec(html)) { + if (isValidElement) + text = html.substr(index, matches.index - index); - return collection; - }, + index = matches.index + matches[0].length; + } else { + text = html.substr(index); + index = html.length; + } - empty : function() { - var self = this, nodes, i, node; + if (isValidElement && text.length > 0) + self.text(text, true); - // Remove all children - if (self.firstChild) { - nodes = []; + if (isValidElement) + self.end(value); - // Collect the children - for (node = self.firstChild; node; node = walk(node, self)) - nodes.push(node); + tokenRegExp.lastIndex = index; + continue; + } - // Remove the children - i = nodes.length; - while (i--) { - node = nodes[i]; - node.parent = node.firstChild = node.lastChild = node.next = node.prev = null; + // Push value on to stack + if (!isShortEnded) { + if (!attribsValue || attribsValue.indexOf('/') != attribsValue.length - 1) + stack.push({name: value, valid: isValidElement}); + else if (isValidElement) + self.end(value); + } + } else if (value = matches[1]) { // Comment + self.comment(value); + } else if (value = matches[2]) { // CDATA + self.cdata(value); + } else if (value = matches[3]) { // DOCTYPE + self.doctype(value); + } else if (value = matches[4]) { // PI + self.pi(value, matches[5]); } - } - - self.firstChild = self.lastChild = null; - return self; - }, + index = matches.index + matches[0].length; + } - isEmpty : function(elements) { - var self = this, node = self.firstChild, i, name; + // Text + if (index < html.length) + self.text(decode(html.substr(index))); - if (node) { - do { - if (node.type === 1) { - // Ignore bogus elements - if (node.attributes.map['data-mce-bogus']) - continue; + // Close any open elements + for (i = stack.length - 1; i >= 0; i--) { + value = stack[i]; - // Keep empty elements like <img /> - if (elements[node.name]) - return false; + if (value.valid) + self.end(value.name); + } + }; + } +})(tinymce); - // Keep elements with data attributes or name attribute like <a name="1"></a> - i = node.attributes.length; - while (i--) { - name = node.attributes[i].name; - if (name === "name" || name.indexOf('data-') === 0) - return false; - } - } +(function(tinymce) { + var whiteSpaceRegExp = /^[ \t\r\n]*$/, typeLookup = { + '#text' : 3, + '#comment' : 8, + '#cdata' : 4, + '#pi' : 7, + '#doctype' : 10, + '#document-fragment' : 11 + }; - // Keep comments - if (node.type === 8) - return false; - - // Keep non whitespace text nodes - if ((node.type === 3 && !whiteSpaceRegExp.test(node.value))) - return false; - } while (node = walk(node, self)); - } + // Walks the tree left/right + function walk(node, root_node, prev) { + var sibling, parent, startName = prev ? 'lastChild' : 'firstChild', siblingName = prev ? 'prev' : 'next'; - return true; - }, + // Walk into nodes if it has a start + if (node[startName]) + return node[startName]; - walk : function(prev) { - return walk(this, null, prev); - } - }); + // Return the sibling if it has one + if (node !== root_node) { + sibling = node[siblingName]; - tinymce.extend(Node, { - create : function(name, attrs) { - var node, attrName; + if (sibling) + return sibling; - // Create node - node = new Node(name, typeLookup[name] || 1); + // Walk up the parents to look for siblings + for (parent = node.parent; parent && parent !== root_node; parent = parent.parent) { + sibling = parent[siblingName]; - // Add attributes if needed - if (attrs) { - for (attrName in attrs) - node.attr(attrName, attrs[attrName]); + if (sibling) + return sibling; } - - return node; } - }); + }; - tinymce.html.Node = Node; -})(tinymce); + function Node(name, type) { + this.name = name; + this.type = type; -(function(tinymce) { - var Node = tinymce.html.Node; + if (type === 1) { + this.attributes = []; + this.attributes.map = {}; + } + } - tinymce.html.DomParser = function(settings, schema) { - var self = this, nodeFilters = {}, attributeFilters = [], matchedNodes = {}, matchedAttributes = {}; + tinymce.extend(Node.prototype, { + replace : function(node) { + var self = this; - settings = settings || {}; - settings.validate = "validate" in settings ? settings.validate : true; - settings.root_name = settings.root_name || 'body'; - self.schema = schema = schema || new tinymce.html.Schema(); + if (node.parent) + node.remove(); - function fixInvalidChildren(nodes) { - var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i, - childClone, nonEmptyElements, nonSplitableElements, sibling, nextNode; + self.insert(node, self); + self.remove(); - nonSplitableElements = tinymce.makeMap('tr,td,th,tbody,thead,tfoot,table'); - nonEmptyElements = schema.getNonEmptyElements(); + return self; + }, - for (ni = 0; ni < nodes.length; ni++) { - node = nodes[ni]; + attr : function(name, value) { + var self = this, attrs, i, undef; - // Already removed - if (!node.parent) - continue; + if (typeof name !== "string") { + for (i in name) + self.attr(i, name[i]); - // Get list of all parent nodes until we find a valid parent to stick the child into - parents = [node]; - for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) - parents.push(parent); + return self; + } - // Found a suitable parent - if (parent && parents.length > 1) { - // Reverse the array since it makes looping easier - parents.reverse(); + if (attrs = self.attributes) { + if (value !== undef) { + // Remove attribute + if (value === null) { + if (name in attrs.map) { + delete attrs.map[name]; - // Clone the related parent and insert that after the moved node - newParent = currentNode = self.filterNode(parents[0].clone()); + i = attrs.length; + while (i--) { + if (attrs[i].name === name) { + attrs = attrs.splice(i, 1); + return self; + } + } + } - // Start cloning and moving children on the left side of the target node - for (i = 0; i < parents.length - 1; i++) { - if (schema.isValidChild(currentNode.name, parents[i].name)) { - tempNode = self.filterNode(parents[i].clone()); - currentNode.append(tempNode); - } else - tempNode = currentNode; + return self; + } - for (childNode = parents[i].firstChild; childNode && childNode != parents[i + 1]; ) { - nextNode = childNode.next; - tempNode.append(childNode); - childNode = nextNode; + // Set attribute + if (name in attrs.map) { + // Set attribute + i = attrs.length; + while (i--) { + if (attrs[i].name === name) { + attrs[i].value = value; + break; + } } + } else + attrs.push({name: name, value: value}); - currentNode = tempNode; - } + attrs.map[name] = value; - if (!newParent.isEmpty(nonEmptyElements)) { - parent.insert(newParent, parents[0], true); - parent.insert(node, newParent); - } else { - parent.insert(node, parents[0], true); - } + return self; + } else { + return attrs.map[name]; + } + } + }, - // Check if the element is empty by looking through it's contents and special treatment for <p><br /></p> - parent = parents[0]; - if (parent.isEmpty(nonEmptyElements) || parent.firstChild === parent.lastChild && parent.firstChild.name === 'br') { - parent.empty().remove(); - } - } else if (node.parent) { - // If it's an LI try to find a UL/OL for it or wrap it - if (node.name === 'li') { - sibling = node.prev; - if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { - sibling.append(node); - continue; - } + clone : function() { + var self = this, clone = new Node(self.name, self.type), i, l, selfAttrs, selfAttr, cloneAttrs; - sibling = node.next; - if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { - sibling.insert(node, sibling.firstChild, true); - continue; - } + // Clone element attributes + if (selfAttrs = self.attributes) { + cloneAttrs = []; + cloneAttrs.map = {}; - node.wrap(self.filterNode(new Node('ul', 1))); - continue; - } + for (i = 0, l = selfAttrs.length; i < l; i++) { + selfAttr = selfAttrs[i]; - // Try wrapping the element in a DIV - if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) { - node.wrap(self.filterNode(new Node('div', 1))); - } else { - // We failed wrapping it, then remove or unwrap it - if (node.name === 'style' || node.name === 'script') - node.empty().remove(); - else - node.unwrap(); + // Clone everything except id + if (selfAttr.name !== 'id') { + cloneAttrs[cloneAttrs.length] = {name: selfAttr.name, value: selfAttr.value}; + cloneAttrs.map[selfAttr.name] = selfAttr.value; } } + + clone.attributes = cloneAttrs; } - }; - self.filterNode = function(node) { - var i, name, list; + clone.value = self.value; + clone.shortEnded = self.shortEnded; - // Run element filters - if (name in nodeFilters) { - list = matchedNodes[name]; + return clone; + }, - if (list) - list.push(node); - else - matchedNodes[name] = [node]; - } + wrap : function(wrapper) { + var self = this; - // Run attribute filters - i = attributeFilters.length; - while (i--) { - name = attributeFilters[i].name; + self.parent.insert(wrapper, self); + wrapper.append(self); - if (name in node.attributes.map) { - list = matchedAttributes[name]; + return self; + }, - if (list) - list.push(node); - else - matchedAttributes[name] = [node]; - } + unwrap : function() { + var self = this, node, next; + + for (node = self.firstChild; node; ) { + next = node.next; + self.insert(node, self, true); + node = next; } - return node; - }; + self.remove(); + }, - self.addNodeFilter = function(name, callback) { - tinymce.each(tinymce.explode(name), function(name) { - var list = nodeFilters[name]; + remove : function() { + var self = this, parent = self.parent, next = self.next, prev = self.prev; - if (!list) - nodeFilters[name] = list = []; + if (parent) { + if (parent.firstChild === self) { + parent.firstChild = next; - list.push(callback); - }); - }; + if (next) + next.prev = null; + } else { + prev.next = next; + } - self.addAttributeFilter = function(name, callback) { - tinymce.each(tinymce.explode(name), function(name) { - var i; + if (parent.lastChild === self) { + parent.lastChild = prev; - for (i = 0; i < attributeFilters.length; i++) { - if (attributeFilters[i].name === name) { - attributeFilters[i].callbacks.push(callback); - return; - } + if (prev) + prev.next = null; + } else { + next.prev = prev; } - attributeFilters.push({name: name, callbacks: [callback]}); - }); - }; + self.parent = self.next = self.prev = null; + } - self.parse = function(html, args) { - var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate, - blockElements, startWhiteSpaceRegExp, invalidChildren = [], - endWhiteSpaceRegExp, allWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName; + return self; + }, - args = args || {}; - matchedNodes = {}; - matchedAttributes = {}; - blockElements = tinymce.extend(tinymce.makeMap('script,style,head,html,body,title,meta,param'), schema.getBlockElements()); - nonEmptyElements = schema.getNonEmptyElements(); - children = schema.children; - validate = settings.validate; - rootBlockName = "forced_root_block" in args ? args.forced_root_block : settings.forced_root_block; + append : function(node) { + var self = this, last; - whiteSpaceElements = schema.getWhiteSpaceElements(); - startWhiteSpaceRegExp = /^[ \t\r\n]+/; - endWhiteSpaceRegExp = /[ \t\r\n]+$/; - allWhiteSpaceRegExp = /[ \t\r\n]+/g; + if (node.parent) + node.remove(); - function addRootBlocks() { - var node = rootNode.firstChild, next, rootBlockNode; + last = self.lastChild; + if (last) { + last.next = node; + node.prev = last; + self.lastChild = node; + } else + self.lastChild = self.firstChild = node; - while (node) { - next = node.next; + node.parent = self; - if (node.type == 3 || (node.type == 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type'))) { - if (!rootBlockNode) { - // Create a new root block element - rootBlockNode = createNode(rootBlockName, 1); - rootNode.insert(rootBlockNode, node); - rootBlockNode.append(node); - } else - rootBlockNode.append(node); - } else { - rootBlockNode = null; - } + return node; + }, - node = next; - }; - }; + insert : function(node, ref_node, before) { + var parent; - function createNode(name, type) { - var node = new Node(name, type), list; + if (node.parent) + node.remove(); - if (name in nodeFilters) { - list = matchedNodes[name]; + parent = ref_node.parent || this; - if (list) - list.push(node); - else - matchedNodes[name] = [node]; - } + if (before) { + if (ref_node === parent.firstChild) + parent.firstChild = node; + else + ref_node.prev.next = node; - return node; - }; + node.prev = ref_node.prev; + node.next = ref_node; + ref_node.prev = node; + } else { + if (ref_node === parent.lastChild) + parent.lastChild = node; + else + ref_node.next.prev = node; - function removeWhitespaceBefore(node) { - var textNode, textVal, sibling; + node.next = ref_node.next; + node.prev = ref_node; + ref_node.next = node; + } - for (textNode = node.prev; textNode && textNode.type === 3; ) { - textVal = textNode.value.replace(endWhiteSpaceRegExp, ''); + node.parent = parent; - if (textVal.length > 0) { - textNode.value = textVal; - textNode = textNode.prev; - } else { - sibling = textNode.prev; - textNode.remove(); - textNode = sibling; - } - } - }; + return node; + }, - parser = new tinymce.html.SaxParser({ - validate : validate, - fix_self_closing : !validate, // Let the DOM parser handle <li> in <li> or <p> in <p> for better results + getAll : function(name) { + var self = this, node, collection = []; - cdata: function(text) { - node.append(createNode('#cdata', 4)).value = text; - }, + for (node = self.firstChild; node; node = walk(node, self)) { + if (node.name === name) + collection.push(node); + } - text: function(text, raw) { - var textNode; + return collection; + }, - // Trim all redundant whitespace on non white space elements - if (!whiteSpaceElements[node.name]) { - text = text.replace(allWhiteSpaceRegExp, ' '); + empty : function() { + var self = this, nodes, i, node; - if (node.lastChild && blockElements[node.lastChild.name]) - text = text.replace(startWhiteSpaceRegExp, ''); - } + // Remove all children + if (self.firstChild) { + nodes = []; - // Do we need to create the node - if (text.length !== 0) { - textNode = createNode('#text', 3); - textNode.raw = !!raw; - node.append(textNode).value = text; - } - }, + // Collect the children + for (node = self.firstChild; node; node = walk(node, self)) + nodes.push(node); - comment: function(text) { - node.append(createNode('#comment', 8)).value = text; - }, + // Remove the children + i = nodes.length; + while (i--) { + node = nodes[i]; + node.parent = node.firstChild = node.lastChild = node.next = node.prev = null; + } + } - pi: function(name, text) { - node.append(createNode(name, 7)).value = text; - removeWhitespaceBefore(node); - }, + self.firstChild = self.lastChild = null; + + return self; + }, + + isEmpty : function(elements) { + var self = this, node = self.firstChild, i, name; - doctype: function(text) { - var newNode; - - newNode = node.append(createNode('#doctype', 10)); - newNode.value = text; - removeWhitespaceBefore(node); - }, + if (node) { + do { + if (node.type === 1) { + // Ignore bogus elements + if (node.attributes.map['data-mce-bogus']) + continue; - start: function(name, attrs, empty) { - var newNode, attrFiltersLen, elementRule, textNode, attrName, text, sibling, parent; + // Keep empty elements like <img /> + if (elements[node.name]) + return false; - elementRule = validate ? schema.getElementRule(name) : {}; - if (elementRule) { - newNode = createNode(elementRule.outputName || name, 1); - newNode.attributes = attrs; - newNode.shortEnded = empty; + // Keep elements with data attributes or name attribute like <a name="1"></a> + i = node.attributes.length; + while (i--) { + name = node.attributes[i].name; + if (name === "name" || name.indexOf('data-mce-') === 0) + return false; + } + } - node.append(newNode); + // Keep comments + if (node.type === 8) + return false; + + // Keep non whitespace text nodes + if ((node.type === 3 && !whiteSpaceRegExp.test(node.value))) + return false; + } while (node = walk(node, self)); + } - // Check if node is valid child of the parent node is the child is - // unknown we don't collect it since it's probably a custom element - parent = children[node.name]; - if (parent && children[newNode.name] && !parent[newNode.name]) - invalidChildren.push(newNode); + return true; + }, - attrFiltersLen = attributeFilters.length; - while (attrFiltersLen--) { - attrName = attributeFilters[attrFiltersLen].name; + walk : function(prev) { + return walk(this, null, prev); + } + }); - if (attrName in attrs.map) { - list = matchedAttributes[attrName]; + tinymce.extend(Node, { + create : function(name, attrs) { + var node, attrName; - if (list) - list.push(newNode); - else - matchedAttributes[attrName] = [newNode]; - } - } + // Create node + node = new Node(name, typeLookup[name] || 1); - // Trim whitespace before block - if (blockElements[name]) - removeWhitespaceBefore(newNode); + // Add attributes if needed + if (attrs) { + for (attrName in attrs) + node.attr(attrName, attrs[attrName]); + } - // Change current node if the element wasn't empty i.e not <br /> or <img /> - if (!empty) - node = newNode; - } - }, + return node; + } + }); - end: function(name) { - var textNode, elementRule, text, sibling, tempNode; + tinymce.html.Node = Node; +})(tinymce); - elementRule = validate ? schema.getElementRule(name) : {}; - if (elementRule) { - if (blockElements[name]) { - if (!whiteSpaceElements[node.name]) { - // Trim whitespace at beginning of block - for (textNode = node.firstChild; textNode && textNode.type === 3; ) { - text = textNode.value.replace(startWhiteSpaceRegExp, ''); +(function(tinymce) { + var Node = tinymce.html.Node; - if (text.length > 0) { - textNode.value = text; - textNode = textNode.next; - } else { - sibling = textNode.next; - textNode.remove(); - textNode = sibling; - } - } + tinymce.html.DomParser = function(settings, schema) { + var self = this, nodeFilters = {}, attributeFilters = [], matchedNodes = {}, matchedAttributes = {}; - // Trim whitespace at end of block - for (textNode = node.lastChild; textNode && textNode.type === 3; ) { - text = textNode.value.replace(endWhiteSpaceRegExp, ''); + settings = settings || {}; + settings.validate = "validate" in settings ? settings.validate : true; + settings.root_name = settings.root_name || 'body'; + self.schema = schema = schema || new tinymce.html.Schema(); - if (text.length > 0) { - textNode.value = text; - textNode = textNode.prev; - } else { - sibling = textNode.prev; - textNode.remove(); - textNode = sibling; - } - } - } + function fixInvalidChildren(nodes) { + var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i, + childClone, nonEmptyElements, nonSplitableElements, textBlockElements, sibling, nextNode; - // Trim start white space - textNode = node.prev; - if (textNode && textNode.type === 3) { - text = textNode.value.replace(startWhiteSpaceRegExp, ''); + nonSplitableElements = tinymce.makeMap('tr,td,th,tbody,thead,tfoot,table'); + nonEmptyElements = schema.getNonEmptyElements(); + textBlockElements = schema.getTextBlockElements(); - if (text.length > 0) - textNode.value = text; - else - textNode.remove(); - } - } + for (ni = 0; ni < nodes.length; ni++) { + node = nodes[ni]; - // Handle empty nodes - if (elementRule.removeEmpty || elementRule.paddEmpty) { - if (node.isEmpty(nonEmptyElements)) { - if (elementRule.paddEmpty) - node.empty().append(new Node('#text', '3')).value = '\u00a0'; - else { - // Leave nodes that have a name like <a name="name"> - if (!node.attributes.map.name) { - tempNode = node.parent; - node.empty().remove(); - node = tempNode; - return; - } - } - } + // Already removed or fixed + if (!node.parent || node.fixed) + continue; + + // If the invalid element is a text block and the text block is within a parent LI element + // Then unwrap the first text block and convert other sibling text blocks to LI elements similar to Word/Open Office + if (textBlockElements[node.name] && node.parent.name == 'li') { + // Move sibling text blocks after LI element + sibling = node.next; + while (sibling) { + if (textBlockElements[sibling.name]) { + sibling.name = 'li'; + sibling.fixed = true; + node.parent.insert(sibling, node.parent); + } else { + break; } - node = node.parent; + sibling = sibling.next; } + + // Unwrap current text block + node.unwrap(node); + continue; } - }, schema); - rootNode = node = new Node(args.context || settings.root_name, 11); + // Get list of all parent nodes until we find a valid parent to stick the child into + parents = [node]; + for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent) + parents.push(parent); - parser.parse(html); + // Found a suitable parent + if (parent && parents.length > 1) { + // Reverse the array since it makes looping easier + parents.reverse(); - // Fix invalid children or report invalid children in a contextual parsing - if (validate && invalidChildren.length) { - if (!args.context) - fixInvalidChildren(invalidChildren); - else - args.invalid = true; - } + // Clone the related parent and insert that after the moved node + newParent = currentNode = self.filterNode(parents[0].clone()); - // Wrap nodes in the root into block elements if the root is body - if (rootBlockName && rootNode.name == 'body') - addRootBlocks(); + // Start cloning and moving children on the left side of the target node + for (i = 0; i < parents.length - 1; i++) { + if (schema.isValidChild(currentNode.name, parents[i].name)) { + tempNode = self.filterNode(parents[i].clone()); + currentNode.append(tempNode); + } else + tempNode = currentNode; - // Run filters only when the contents is valid - if (!args.invalid) { - // Run node filters - for (name in matchedNodes) { - list = nodeFilters[name]; - nodes = matchedNodes[name]; + for (childNode = parents[i].firstChild; childNode && childNode != parents[i + 1]; ) { + nextNode = childNode.next; + tempNode.append(childNode); + childNode = nextNode; + } - // Remove already removed children - fi = nodes.length; - while (fi--) { - if (!nodes[fi].parent) - nodes.splice(fi, 1); + currentNode = tempNode; } - for (i = 0, l = list.length; i < l; i++) - list[i](nodes, name, args); - } - - // Run attribute filters - for (i = 0, l = attributeFilters.length; i < l; i++) { - list = attributeFilters[i]; + if (!newParent.isEmpty(nonEmptyElements)) { + parent.insert(newParent, parents[0], true); + parent.insert(node, newParent); + } else { + parent.insert(node, parents[0], true); + } - if (list.name in matchedAttributes) { - nodes = matchedAttributes[list.name]; + // Check if the element is empty by looking through it's contents and special treatment for <p><br /></p> + parent = parents[0]; + if (parent.isEmpty(nonEmptyElements) || parent.firstChild === parent.lastChild && parent.firstChild.name === 'br') { + parent.empty().remove(); + } + } else if (node.parent) { + // If it's an LI try to find a UL/OL for it or wrap it + if (node.name === 'li') { + sibling = node.prev; + if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { + sibling.append(node); + continue; + } - // Remove already removed children - fi = nodes.length; - while (fi--) { - if (!nodes[fi].parent) - nodes.splice(fi, 1); + sibling = node.next; + if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) { + sibling.insert(node, sibling.firstChild, true); + continue; } - for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) - list.callbacks[fi](nodes, list.name, args); + node.wrap(self.filterNode(new Node('ul', 1))); + continue; + } + + // Try wrapping the element in a DIV + if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) { + node.wrap(self.filterNode(new Node('div', 1))); + } else { + // We failed wrapping it, then remove or unwrap it + if (node.name === 'style' || node.name === 'script') + node.empty().remove(); + else + node.unwrap(); } } } - - return rootNode; }; - // Remove <br> at end of block elements Gecko and WebKit injects BR elements to - // make it possible to place the caret inside empty blocks. This logic tries to remove - // 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; - - // Remove brs from body element as well - blockElements.body = 1; - - // Must loop forwards since it will otherwise remove all brs in <p>a<br><br><br></p> - for (i = 0; i < l; i++) { - node = nodes[i]; - 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 - // excluding bookmarks since they are invisible - prev = node.prev; - while (prev) { - prevName = prev.name; + self.filterNode = function(node) { + var i, name, list; - // Ignore bookmarks - if (prevName !== "span" || prev.attr('data-mce-type') !== 'bookmark') { - // Found a non BR element - if (prevName !== "br") - break; - - // Found another br it's a <br><br> structure then don't remove anything - if (prevName === 'br') { - node = null; - break; - } - } + // Run element filters + if (name in nodeFilters) { + list = matchedNodes[name]; - prev = prev.prev; - } + if (list) + list.push(node); + else + matchedNodes[name] = [node]; + } - if (node) { - node.remove(); + // Run attribute filters + i = attributeFilters.length; + while (i--) { + name = attributeFilters[i].name; - // Is the parent to be considered empty after we removed the BR - if (parent.isEmpty(nonEmptyElements)) { - elementRule = schema.getElementRule(parent.name); + if (name in node.attributes.map) { + list = matchedAttributes[name]; - // Remove or padd the element depending on schema rule - if (elementRule) { - if (elementRule.removeEmpty) - parent.remove(); - else if (elementRule.paddEmpty) - parent.empty().append(new tinymce.html.Node('#text', 3)).value = '\u00a0'; - } - } - } - } + if (list) + list.push(node); + else + matchedAttributes[name] = [node]; } - }); - } - } -})(tinymce); - -tinymce.html.Writer = function(settings) { - var html = [], indent, indentBefore, indentAfter, encode, htmlOutput; + } - settings = settings || {}; - indent = settings.indent; - indentBefore = tinymce.makeMap(settings.indent_before || ''); - indentAfter = tinymce.makeMap(settings.indent_after || ''); - encode = tinymce.html.Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities); - htmlOutput = settings.element_format == "html"; + return node; + }; - return { - start: function(name, attrs, empty) { - var i, l, attr, value; + self.addNodeFilter = function(name, callback) { + tinymce.each(tinymce.explode(name), function(name) { + var list = nodeFilters[name]; - if (indent && indentBefore[name] && html.length > 0) { - value = html[html.length - 1]; + if (!list) + nodeFilters[name] = list = []; - if (value.length > 0 && value !== '\n') - html.push('\n'); - } + list.push(callback); + }); + }; - html.push('<', name); + self.addAttributeFilter = function(name, callback) { + tinymce.each(tinymce.explode(name), function(name) { + var i; - if (attrs) { - for (i = 0, l = attrs.length; i < l; i++) { - attr = attrs[i]; - html.push(' ', attr.name, '="', encode(attr.value, true), '"'); + for (i = 0; i < attributeFilters.length; i++) { + if (attributeFilters[i].name === name) { + attributeFilters[i].callbacks.push(callback); + return; + } } - } - if (!empty || htmlOutput) - html[html.length] = '>'; - else - html[html.length] = ' />'; + attributeFilters.push({name: name, callbacks: [callback]}); + }); + }; - if (empty && indent && indentAfter[name] && html.length > 0) { - value = html[html.length - 1]; + self.parse = function(html, args) { + var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate, + blockElements, startWhiteSpaceRegExp, invalidChildren = [], isInWhiteSpacePreservedElement, + endWhiteSpaceRegExp, allWhiteSpaceRegExp, isAllWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements, rootBlockName; - if (value.length > 0 && value !== '\n') - html.push('\n'); - } - }, + args = args || {}; + matchedNodes = {}; + matchedAttributes = {}; + blockElements = tinymce.extend(tinymce.makeMap('script,style,head,html,body,title,meta,param'), schema.getBlockElements()); + nonEmptyElements = schema.getNonEmptyElements(); + children = schema.children; + validate = settings.validate; + rootBlockName = "forced_root_block" in args ? args.forced_root_block : settings.forced_root_block; - end: function(name) { - var value; + whiteSpaceElements = schema.getWhiteSpaceElements(); + startWhiteSpaceRegExp = /^[ \t\r\n]+/; + endWhiteSpaceRegExp = /[ \t\r\n]+$/; + allWhiteSpaceRegExp = /[ \t\r\n]+/g; + isAllWhiteSpaceRegExp = /^[ \t\r\n]+$/; - /*if (indent && indentBefore[name] && html.length > 0) { - value = html[html.length - 1]; + function addRootBlocks() { + var node = rootNode.firstChild, next, rootBlockNode; - if (value.length > 0 && value !== '\n') - html.push('\n'); - }*/ + while (node) { + next = node.next; - html.push('</', name, '>'); + if (node.type == 3 || (node.type == 1 && node.name !== 'p' && !blockElements[node.name] && !node.attr('data-mce-type'))) { + if (!rootBlockNode) { + // Create a new root block element + rootBlockNode = createNode(rootBlockName, 1); + rootNode.insert(rootBlockNode, node); + rootBlockNode.append(node); + } else + rootBlockNode.append(node); + } else { + rootBlockNode = null; + } - if (indent && indentAfter[name] && html.length > 0) { - value = html[html.length - 1]; + node = next; + }; + }; - if (value.length > 0 && value !== '\n') - html.push('\n'); - } - }, + function createNode(name, type) { + var node = new Node(name, type), list; - text: function(text, raw) { - if (text.length > 0) - html[html.length] = raw ? text : encode(text); - }, + if (name in nodeFilters) { + list = matchedNodes[name]; - cdata: function(text) { - html.push('<![CDATA[', text, ']]>'); - }, + if (list) + list.push(node); + else + matchedNodes[name] = [node]; + } - comment: function(text) { - html.push('<!--', text, '-->'); - }, + return node; + }; - pi: function(name, text) { - if (text) - html.push('<?', name, ' ', text, '?>'); - else - html.push('<?', name, '?>'); + function removeWhitespaceBefore(node) { + var textNode, textVal, sibling; - if (indent) - html.push('\n'); - }, + for (textNode = node.prev; textNode && textNode.type === 3; ) { + textVal = textNode.value.replace(endWhiteSpaceRegExp, ''); - doctype: function(text) { - html.push('<!DOCTYPE', text, '>', indent ? '\n' : ''); - }, + if (textVal.length > 0) { + textNode.value = textVal; + textNode = textNode.prev; + } else { + sibling = textNode.prev; + textNode.remove(); + textNode = sibling; + } + } + }; - reset: function() { - html.length = 0; - }, + function cloneAndExcludeBlocks(input) { + var name, output = {}; - getContent: function() { - return html.join('').replace(/\n$/, ''); - } - }; -}; + for (name in input) { + if (name !== 'li' && name != 'p') { + output[name] = input[name]; + } + } -(function(tinymce) { - tinymce.html.Serializer = function(settings, schema) { - var self = this, writer = new tinymce.html.Writer(settings); + return output; + }; - settings = settings || {}; - settings.validate = "validate" in settings ? settings.validate : true; + parser = new tinymce.html.SaxParser({ + validate : validate, - self.schema = schema = schema || new tinymce.html.Schema(); - self.writer = writer; + // Exclude P and LI from DOM parsing since it's treated better by the DOM parser + self_closing_elements: cloneAndExcludeBlocks(schema.getSelfClosingElements()), - self.serialize = function(node) { - var handlers, validate; + cdata: function(text) { + node.append(createNode('#cdata', 4)).value = text; + }, - validate = settings.validate; + text: function(text, raw) { + var textNode; - handlers = { - // #text - 3: function(node, raw) { - writer.text(node.value, node.raw); - }, + // Trim all redundant whitespace on non white space elements + if (!isInWhiteSpacePreservedElement) { + text = text.replace(allWhiteSpaceRegExp, ' '); - // #comment - 8: function(node) { - writer.comment(node.value); - }, + if (node.lastChild && blockElements[node.lastChild.name]) + text = text.replace(startWhiteSpaceRegExp, ''); + } - // Processing instruction - 7: function(node) { - writer.pi(node.name, node.value); + // Do we need to create the node + if (text.length !== 0) { + textNode = createNode('#text', 3); + textNode.raw = !!raw; + node.append(textNode).value = text; + } }, - // Doctype - 10: function(node) { - writer.doctype(node.value); + comment: function(text) { + node.append(createNode('#comment', 8)).value = text; }, - // CDATA - 4: function(node) { - writer.cdata(node.value); + pi: function(name, text) { + node.append(createNode(name, 7)).value = text; + removeWhitespaceBefore(node); }, - // Document fragment - 11: function(node) { - if ((node = node.firstChild)) { - do { - walk(node); - } while (node = node.next); - } - } - }; + doctype: function(text) { + var newNode; + + newNode = node.append(createNode('#doctype', 10)); + newNode.value = text; + removeWhitespaceBefore(node); + }, - writer.reset(); + start: function(name, attrs, empty) { + var newNode, attrFiltersLen, elementRule, textNode, attrName, text, sibling, parent; - function walk(node) { - var handler = handlers[node.type], name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule; + elementRule = validate ? schema.getElementRule(name) : {}; + if (elementRule) { + newNode = createNode(elementRule.outputName || name, 1); + newNode.attributes = attrs; + newNode.shortEnded = empty; - if (!handler) { - name = node.name; - isEmpty = node.shortEnded; - attrs = node.attributes; + node.append(newNode); - // Sort attributes - if (validate && attrs && attrs.length > 1) { - sortedAttrs = []; - sortedAttrs.map = {}; + // Check if node is valid child of the parent node is the child is + // unknown we don't collect it since it's probably a custom element + parent = children[node.name]; + if (parent && children[newNode.name] && !parent[newNode.name]) + invalidChildren.push(newNode); - elementRule = schema.getElementRule(node.name); - for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) { - attrName = elementRule.attributesOrder[i]; + attrFiltersLen = attributeFilters.length; + while (attrFiltersLen--) { + attrName = attributeFilters[attrFiltersLen].name; if (attrName in attrs.map) { - attrValue = attrs.map[attrName]; - sortedAttrs.map[attrName] = attrValue; - sortedAttrs.push({name: attrName, value: attrValue}); + list = matchedAttributes[attrName]; + + if (list) + list.push(newNode); + else + matchedAttributes[attrName] = [newNode]; } } - for (i = 0, l = attrs.length; i < l; i++) { - attrName = attrs[i].name; + // Trim whitespace before block + if (blockElements[name]) + removeWhitespaceBefore(newNode); - if (!(attrName in sortedAttrs.map)) { - attrValue = attrs.map[attrName]; - sortedAttrs.map[attrName] = attrValue; - sortedAttrs.push({name: attrName, value: attrValue}); - } - } + // Change current node if the element wasn't empty i.e not <br /> or <img /> + if (!empty) + node = newNode; - attrs = sortedAttrs; + // Check if we are inside a whitespace preserved element + if (!isInWhiteSpacePreservedElement && whiteSpaceElements[name]) { + isInWhiteSpacePreservedElement = true; + } } + }, - writer.start(node.name, attrs, isEmpty); + end: function(name) { + var textNode, elementRule, text, sibling, tempNode; - if (!isEmpty) { - if ((node = node.firstChild)) { - do { - walk(node); - } while (node = node.next); - } + elementRule = validate ? schema.getElementRule(name) : {}; + if (elementRule) { + if (blockElements[name]) { + if (!isInWhiteSpacePreservedElement) { + // Trim whitespace of the first node in a block + textNode = node.firstChild; + if (textNode && textNode.type === 3) { + text = textNode.value.replace(startWhiteSpaceRegExp, ''); - writer.end(name); - } - } else - handler(node); - } + // Any characters left after trim or should we remove it + if (text.length > 0) { + textNode.value = text; + textNode = textNode.next; + } else { + sibling = textNode.next; + textNode.remove(); + textNode = sibling; + } - // Serialize element and treat all non elements as fragments - if (node.type == 1 && !settings.inner) - walk(node); - else - handlers[11](node); + // Remove any pure whitespace siblings + while (textNode && textNode.type === 3) { + text = textNode.value; + sibling = textNode.next; - return writer.getContent(); - }; - } -})(tinymce); + if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) { + textNode.remove(); + textNode = sibling; + } -(function(tinymce) { - // Shorten names - var each = tinymce.each, - is = tinymce.is, - isWebKit = tinymce.isWebKit, - isIE = tinymce.isIE, - Entities = tinymce.html.Entities, - simpleSelectorRe = /^([a-z0-9],?)+$/i, - blockElementsMap = tinymce.html.Schema.blockElementsMap, - whiteSpaceRegExp = /^[ \t\r\n]*$/; + textNode = sibling; + } + } - tinymce.create('tinymce.dom.DOMUtils', { - doc : null, - root : null, - files : null, - pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/, - props : { - "for" : "htmlFor", - "class" : "className", - className : "className", - checked : "checked", - disabled : "disabled", - maxlength : "maxLength", - readonly : "readOnly", - selected : "selected", - value : "value", - id : "id", - name : "name", - type : "type" - }, + // Trim whitespace of the last node in a block + textNode = node.lastChild; + if (textNode && textNode.type === 3) { + text = textNode.value.replace(endWhiteSpaceRegExp, ''); - DOMUtils : function(d, s) { - var t = this, globalStyle, name; + // Any characters left after trim or should we remove it + if (text.length > 0) { + textNode.value = text; + textNode = textNode.prev; + } else { + sibling = textNode.prev; + textNode.remove(); + textNode = sibling; + } - t.doc = d; - t.win = window; - t.files = {}; - t.cssFlicker = false; - t.counter = 0; - t.stdMode = !tinymce.isIE || d.documentMode >= 8; - t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat" || t.stdMode; - t.hasOuterHTML = "outerHTML" in d.createElement("a"); + // Remove any pure whitespace siblings + while (textNode && textNode.type === 3) { + text = textNode.value; + sibling = textNode.prev; - t.settings = s = tinymce.extend({ - keep_values : false, - hex_colors : 1 - }, s); - - t.schema = s.schema; - t.styles = new tinymce.html.Styles({ - url_converter : s.url_converter, - url_converter_scope : s.url_converter_scope - }, s.schema); + if (text.length === 0 || isAllWhiteSpaceRegExp.test(text)) { + textNode.remove(); + textNode = sibling; + } - // Fix IE6SP2 flicker and check it failed for pre SP2 - if (tinymce.isIE6) { - try { - d.execCommand('BackgroundImageCache', false, true); - } catch (e) { - t.cssFlicker = true; - } - } + textNode = sibling; + } + } + } - if (isIE && s.schema) { - // Add missing HTML 4/5 elements to IE - ('abbr article aside audio canvas ' + - 'details figcaption figure footer ' + - 'header hgroup mark menu meter nav ' + - 'output progress section summary ' + - 'time video').replace(/\w+/g, function(name) { - d.createElement(name); - }); + // Trim start white space + // Removed due to: #5424 + /*textNode = node.prev; + if (textNode && textNode.type === 3) { + text = textNode.value.replace(startWhiteSpaceRegExp, ''); - // Create all custom elements - for (name in s.schema.getCustomElements()) { - d.createElement(name); + if (text.length > 0) + textNode.value = text; + else + textNode.remove(); + }*/ + } + + // Check if we exited a whitespace preserved element + if (isInWhiteSpacePreservedElement && whiteSpaceElements[name]) { + isInWhiteSpacePreservedElement = false; + } + + // Handle empty nodes + if (elementRule.removeEmpty || elementRule.paddEmpty) { + if (node.isEmpty(nonEmptyElements)) { + if (elementRule.paddEmpty) + node.empty().append(new Node('#text', '3')).value = '\u00a0'; + else { + // Leave nodes that have a name like <a name="name"> + if (!node.attributes.map.name && !node.attributes.map.id) { + tempNode = node.parent; + node.empty().remove(); + node = tempNode; + return; + } + } + } + } + + node = node.parent; + } } + }, schema); + + rootNode = node = new Node(args.context || settings.root_name, 11); + + parser.parse(html); + + // Fix invalid children or report invalid children in a contextual parsing + if (validate && invalidChildren.length) { + if (!args.context) + fixInvalidChildren(invalidChildren); + else + args.invalid = true; } - tinymce.addUnload(t.destroy, t); - }, + // Wrap nodes in the root into block elements if the root is body + if (rootBlockName && rootNode.name == 'body') + addRootBlocks(); + + // Run filters only when the contents is valid + if (!args.invalid) { + // Run node filters + for (name in matchedNodes) { + list = nodeFilters[name]; + nodes = matchedNodes[name]; - getRoot : function() { - var t = this, s = t.settings; + // Remove already removed children + fi = nodes.length; + while (fi--) { + if (!nodes[fi].parent) + nodes.splice(fi, 1); + } - return (s && t.get(s.root_element)) || t.doc.body; - }, + for (i = 0, l = list.length; i < l; i++) + list[i](nodes, name, args); + } - getViewPort : function(w) { - var d, b; + // Run attribute filters + for (i = 0, l = attributeFilters.length; i < l; i++) { + list = attributeFilters[i]; - w = !w ? this.win : w; - d = w.document; - b = this.boxModel ? d.documentElement : d.body; + if (list.name in matchedAttributes) { + nodes = matchedAttributes[list.name]; - // Returns viewport size excluding scrollbars - return { - x : w.pageXOffset || b.scrollLeft, - y : w.pageYOffset || b.scrollTop, - w : w.innerWidth || b.clientWidth, - h : w.innerHeight || b.clientHeight - }; - }, + // Remove already removed children + fi = nodes.length; + while (fi--) { + if (!nodes[fi].parent) + nodes.splice(fi, 1); + } - getRect : function(e) { - var p, t = this, sr; + for (fi = 0, fl = list.callbacks.length; fi < fl; fi++) + list.callbacks[fi](nodes, list.name, args); + } + } + } - e = t.get(e); - p = t.getPos(e); - sr = t.getSize(e); + return rootNode; + }; - return { - x : p.x, - y : p.y, - w : sr.w, - h : sr.h - }; - }, + // Remove <br> at end of block elements Gecko and WebKit injects BR elements to + // make it possible to place the caret inside empty blocks. This logic tries to remove + // 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 = tinymce.extend({}, schema.getBlockElements()), + nonEmptyElements = schema.getNonEmptyElements(), parent, lastParent, prev, prevName; - getSize : function(e) { - var t = this, w, h; + // Remove brs from body element as well + blockElements.body = 1; - e = t.get(e); - w = t.getStyle(e, 'width'); - h = t.getStyle(e, 'height'); + // Must loop forwards since it will otherwise remove all brs in <p>a<br><br><br></p> + for (i = 0; i < l; i++) { + node = nodes[i]; + parent = node.parent; - // Non pixel value, then force offset/clientWidth - if (w.indexOf('px') === -1) - w = 0; + if (blockElements[node.parent.name] && node === parent.lastChild) { + // 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) { + prevName = prev.name; - // Non pixel value, then force offset/clientWidth - if (h.indexOf('px') === -1) - h = 0; + // Ignore bookmarks + if (prevName !== "span" || prev.attr('data-mce-type') !== 'bookmark') { + // Found a non BR element + if (prevName !== "br") + break; + + // Found another br it's a <br><br> structure then don't remove anything + if (prevName === 'br') { + node = null; + break; + } + } - return { - w : parseInt(w) || e.offsetWidth || e.clientWidth, - h : parseInt(h) || e.offsetHeight || e.clientHeight - }; - }, + prev = prev.prev; + } - getParent : function(n, f, r) { - return this.getParents(n, f, r, false); - }, + if (node) { + node.remove(); - getParents : function(n, f, r, c) { - var t = this, na, se = t.settings, o = []; + // Is the parent to be considered empty after we removed the BR + if (parent.isEmpty(nonEmptyElements)) { + elementRule = schema.getElementRule(parent.name); - n = t.get(n); - c = c === undefined; + // Remove or padd the element depending on schema rule + if (elementRule) { + if (elementRule.removeEmpty) + parent.remove(); + else if (elementRule.paddEmpty) + parent.empty().append(new tinymce.html.Node('#text', 3)).value = '\u00a0'; + } + } + } + } 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 (se.strict_root) - r = r || t.getRoot(); + if (blockElements[parent.name]) { + break; + } - // Wrap node name as func - if (is(f, 'string')) { - na = f; + parent = parent.parent; + } - if (f === '*') { - f = function(n) {return n.nodeType == 1;}; - } else { - f = function(n) { - return t.is(n, na); - }; + if (lastParent === parent) { + textNode = new tinymce.html.Node('#text', 3); + textNode.value = '\u00a0'; + node.replace(textNode); + } + } } - } + }); + } - while (n) { - if (n == r || !n.nodeType || n.nodeType === 9) - break; + // Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included. + if (!settings.allow_html_in_named_anchor) { + self.addAttributeFilter('id,name', function(nodes, name) { + var i = nodes.length, sibling, prevSibling, parent, node; - if (!f || f(n)) { - if (c) - o.push(n); - else - return n; + while (i--) { + node = nodes[i]; + if (node.name === 'a' && node.firstChild && !node.attr('href')) { + parent = node.parent; + + // Move children after current node + sibling = node.lastChild; + do { + prevSibling = sibling.prev; + parent.insert(sibling, node); + sibling = prevSibling; + } while (sibling); + } } + }); + } + } +})(tinymce); - n = n.parentNode; - } +tinymce.html.Writer = function(settings) { + var html = [], indent, indentBefore, indentAfter, encode, htmlOutput; - return c ? o : null; - }, + settings = settings || {}; + indent = settings.indent; + indentBefore = tinymce.makeMap(settings.indent_before || ''); + indentAfter = tinymce.makeMap(settings.indent_after || ''); + encode = tinymce.html.Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities); + htmlOutput = settings.element_format == "html"; - get : function(e) { - var n; + return { + start: function(name, attrs, empty) { + var i, l, attr, value; - if (e && this.doc && typeof(e) == 'string') { - n = e; - e = this.doc.getElementById(e); + if (indent && indentBefore[name] && html.length > 0) { + value = html[html.length - 1]; - // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick - if (e && e.id !== n) - return this.doc.getElementsByName(n)[1]; + if (value.length > 0 && value !== '\n') + html.push('\n'); } - return e; - }, - - getNext : function(node, selector) { - return this._findSib(node, selector, 'nextSibling'); - }, + html.push('<', name); - getPrev : function(node, selector) { - return this._findSib(node, selector, 'previousSibling'); - }, + if (attrs) { + for (i = 0, l = attrs.length; i < l; i++) { + attr = attrs[i]; + html.push(' ', attr.name, '="', encode(attr.value, true), '"'); + } + } + if (!empty || htmlOutput) + html[html.length] = '>'; + else + html[html.length] = ' />'; - select : function(pa, s) { - var t = this; + if (empty && indent && indentAfter[name] && html.length > 0) { + value = html[html.length - 1]; - return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []); + if (value.length > 0 && value !== '\n') + html.push('\n'); + } }, - is : function(n, selector) { - var i; + end: function(name) { + var value; - // If it isn't an array then try to do some simple selectors instead of Sizzle for to boost performance - if (n.length === undefined) { - // Simple all selector - if (selector === '*') - return n.nodeType == 1; + /*if (indent && indentBefore[name] && html.length > 0) { + value = html[html.length - 1]; - // Simple selector just elements - if (simpleSelectorRe.test(selector)) { - selector = selector.toLowerCase().split(/,/); - n = n.nodeName.toLowerCase(); + if (value.length > 0 && value !== '\n') + html.push('\n'); + }*/ - for (i = selector.length - 1; i >= 0; i--) { - if (selector[i] == n) - return true; - } + html.push('</', name, '>'); - return false; - } - } + if (indent && indentAfter[name] && html.length > 0) { + value = html[html.length - 1]; - return tinymce.dom.Sizzle.matches(selector, n.nodeType ? [n] : n).length > 0; + if (value.length > 0 && value !== '\n') + html.push('\n'); + } }, - - add : function(p, n, a, h, c) { - var t = this; - - return this.run(p, function(p) { - var e, k; - - e = is(n, 'string') ? t.doc.createElement(n) : n; - t.setAttribs(e, a); - - if (h) { - if (h.nodeType) - e.appendChild(h); - else - t.setHTML(e, h); - } - - return !c ? p.appendChild(e) : e; - }); + text: function(text, raw) { + if (text.length > 0) + html[html.length] = raw ? text : encode(text); }, - create : function(n, a, h) { - return this.add(this.doc.createElement(n), n, a, h, 1); + cdata: function(text) { + html.push('<![CDATA[', text, ']]>'); }, - createHTML : function(n, a, h) { - var o = '', t = this, k; - - o += '<' + n; + comment: function(text) { + html.push('<!--', text, '-->'); + }, - for (k in a) { - if (a.hasOwnProperty(k)) - o += ' ' + k + '="' + t.encode(a[k]) + '"'; - } + pi: function(name, text) { + if (text) + html.push('<?', name, ' ', text, '?>'); + else + html.push('<?', name, '?>'); - // A call to tinymce.is doesn't work for some odd reason on IE9 possible bug inside their JS runtime - if (typeof(h) != "undefined") - return o + '>' + h + '</' + n + '>'; + if (indent) + html.push('\n'); + }, - return o + ' />'; + doctype: function(text) { + html.push('<!DOCTYPE', text, '>', indent ? '\n' : ''); }, - remove : function(node, keep_children) { - return this.run(node, function(node) { - var child, parent = node.parentNode; + reset: function() { + html.length = 0; + }, - if (!parent) - return null; + getContent: function() { + return html.join('').replace(/\n$/, ''); + } + }; +}; - if (keep_children) { - while (child = node.firstChild) { - // IE 8 will crash if you don't remove completely empty text nodes - if (!tinymce.isIE || child.nodeType !== 3 || child.nodeValue) - parent.insertBefore(child, node); - else - node.removeChild(child); - } - } +(function(tinymce) { + tinymce.html.Serializer = function(settings, schema) { + var self = this, writer = new tinymce.html.Writer(settings); - return parent.removeChild(node); - }); - }, + settings = settings || {}; + settings.validate = "validate" in settings ? settings.validate : true; - setStyle : function(n, na, v) { - var t = this; + self.schema = schema = schema || new tinymce.html.Schema(); + self.writer = writer; - return t.run(n, function(e) { - var s, i; + self.serialize = function(node) { + var handlers, validate; - s = e.style; + validate = settings.validate; - // Camelcase it, if needed - na = na.replace(/-(\D)/g, function(a, b){ - return b.toUpperCase(); - }); + handlers = { + // #text + 3: function(node, raw) { + writer.text(node.value, node.raw); + }, - // Default px suffix on these - if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v))) - v += 'px'; + // #comment + 8: function(node) { + writer.comment(node.value); + }, - switch (na) { - case 'opacity': - // IE specific opacity - if (isIE) { - s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")"; + // Processing instruction + 7: function(node) { + writer.pi(node.name, node.value); + }, - if (!n.currentStyle || !n.currentStyle.hasLayout) - s.display = 'inline-block'; - } + // Doctype + 10: function(node) { + writer.doctype(node.value); + }, - // Fix for older browsers - s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || ''; - break; + // CDATA + 4: function(node) { + writer.cdata(node.value); + }, - case 'float': - isIE ? s.styleFloat = v : s.cssFloat = v; - break; - - default: - s[na] = v || ''; + // Document fragment + 11: function(node) { + if ((node = node.firstChild)) { + do { + walk(node); + } while (node = node.next); + } } + }; - // Force update of the style data - if (t.settings.update_styles) - t.setAttrib(e, 'data-mce-style'); - }); - }, + writer.reset(); - getStyle : function(n, na, c) { - n = this.get(n); + function walk(node) { + var handler = handlers[node.type], name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule; - if (!n) - return; + if (!handler) { + name = node.name; + isEmpty = node.shortEnded; + attrs = node.attributes; - // Gecko - if (this.doc.defaultView && c) { - // Remove camelcase - na = na.replace(/[A-Z]/g, function(a){ - return '-' + a; - }); + // Sort attributes + if (validate && attrs && attrs.length > 1) { + sortedAttrs = []; + sortedAttrs.map = {}; - try { - return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na); - } catch (ex) { - // Old safari might fail - return null; - } - } + elementRule = schema.getElementRule(node.name); + for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) { + attrName = elementRule.attributesOrder[i]; - // Camelcase it, if needed - na = na.replace(/-(\D)/g, function(a, b){ - return b.toUpperCase(); - }); + if (attrName in attrs.map) { + attrValue = attrs.map[attrName]; + sortedAttrs.map[attrName] = attrValue; + sortedAttrs.push({name: attrName, value: attrValue}); + } + } - if (na == 'float') - na = isIE ? 'styleFloat' : 'cssFloat'; + for (i = 0, l = attrs.length; i < l; i++) { + attrName = attrs[i].name; - // IE & Opera - if (n.currentStyle && c) - return n.currentStyle[na]; + if (!(attrName in sortedAttrs.map)) { + attrValue = attrs.map[attrName]; + sortedAttrs.map[attrName] = attrValue; + sortedAttrs.push({name: attrName, value: attrValue}); + } + } - return n.style ? n.style[na] : undefined; - }, + attrs = sortedAttrs; + } - setStyles : function(e, o) { - var t = this, s = t.settings, ol; + writer.start(node.name, attrs, isEmpty); - ol = s.update_styles; - s.update_styles = 0; + if (!isEmpty) { + if ((node = node.firstChild)) { + do { + walk(node); + } while (node = node.next); + } - each(o, function(v, n) { - t.setStyle(e, n, v); - }); + writer.end(name); + } + } else + handler(node); + } - // Update style info - s.update_styles = ol; - if (s.update_styles) - t.setAttrib(e, s.cssText); - }, + // Serialize element and treat all non elements as fragments + if (node.type == 1 && !settings.inner) + walk(node); + else + handlers[11](node); - removeAllAttribs: function(e) { - return this.run(e, function(e) { - var i, attrs = e.attributes; - for (i = attrs.length - 1; i >= 0; i--) { - e.removeAttributeNode(attrs.item(i)); - } - }); - }, + return writer.getContent(); + }; + } +})(tinymce); - setAttrib : function(e, n, v) { - var t = this; +// JSLint defined globals +/*global tinymce:false, window:false */ - // Whats the point - if (!e || !n) - return; +tinymce.dom = {}; - // Strict XML mode - if (t.settings.strict) - n = n.toLowerCase(); +(function(namespace, expando) { + var w3cEventModel = !!document.addEventListener; - return this.run(e, function(e) { - var s = t.settings; - var originalValue = e.getAttribute(n); - if (v !== null) { - switch (n) { - case "style": - if (!is(v, 'string')) { - each(v, function(v, n) { - t.setStyle(e, n, v); - }); + function addEvent(target, name, callback, capture) { + if (target.addEventListener) { + target.addEventListener(name, callback, capture || false); + } else if (target.attachEvent) { + target.attachEvent('on' + name, callback); + } + } - return; - } + function removeEvent(target, name, callback, capture) { + if (target.removeEventListener) { + target.removeEventListener(name, callback, capture || false); + } else if (target.detachEvent) { + target.detachEvent('on' + name, callback); + } + } - // No mce_style for elements with these since they might get resized by the user - if (s.keep_values) { - if (v && !t._isRes(v)) - e.setAttribute('data-mce-style', v, 2); - else - e.removeAttribute('data-mce-style', 2); - } + function fix(original_event, data) { + var name, event = data || {}; - e.style.cssText = v; - break; + // Dummy function that gets replaced on the delegation state functions + function returnFalse() { + return false; + } - case "class": - e.className = v || ''; // Fix IE null bug - break; + // Dummy function that gets replaced on the delegation state functions + function returnTrue() { + return true; + } - case "src": - case "href": - if (s.keep_values) { - if (s.url_converter) - v = s.url_converter.call(s.url_converter_scope || t, v, n, e); + // Copy all properties from the original event + for (name in original_event) { + // layerX/layerY is deprecated in Chrome and produces a warning + if (name !== "layerX" && name !== "layerY") { + event[name] = original_event[name]; + } + } - t.setAttrib(e, 'data-mce-' + n, v, 2); - } + // Normalize target IE uses srcElement + if (!event.target) { + event.target = event.srcElement || document; + } - break; + // Add preventDefault method + event.preventDefault = function() { + event.isDefaultPrevented = returnTrue; - case "shape": - e.setAttribute('data-mce-style', v); - break; - } + // Execute preventDefault on the original event object + if (original_event) { + if (original_event.preventDefault) { + original_event.preventDefault(); + } else { + original_event.returnValue = false; // IE } - if (is(v) && v !== null && v.length !== 0) - e.setAttribute(n, '' + v, 2); - else - e.removeAttribute(n, 2); + } + }; - // fire onChangeAttrib event for attributes that have changed - if (tinyMCE.activeEditor && originalValue != v) { - var ed = tinyMCE.activeEditor; - ed.onSetAttrib.dispatch(ed, e, n, v); + // Add stopPropagation + event.stopPropagation = function() { + event.isPropagationStopped = returnTrue; + + // Execute stopPropagation on the original event object + if (original_event) { + if (original_event.stopPropagation) { + original_event.stopPropagation(); + } else { + original_event.cancelBubble = true; // IE } - }); - }, + } + }; - setAttribs : function(e, o) { - var t = this; + // Add stopImmediatePropagation + event.stopImmediatePropagation = function() { + event.isImmediatePropagationStopped = returnTrue; + event.stopPropagation(); + }; - return this.run(e, function(e) { - each(o, function(v, n) { - t.setAttrib(e, n, v); - }); - }); - }, + // Add event delegation states + if (!event.isDefaultPrevented) { + event.isDefaultPrevented = returnFalse; + event.isPropagationStopped = returnFalse; + event.isImmediatePropagationStopped = returnFalse; + } - getAttrib : function(e, n, dv) { - var v, t = this, undef; + return event; + } - e = t.get(e); + function bindOnReady(win, callback, event_utils) { + var doc = win.document, event = {type: 'ready'}; - if (!e || e.nodeType !== 1) - return dv === undef ? false : dv; + // Gets called when the DOM is ready + function readyHandler() { + if (!event_utils.domLoaded) { + event_utils.domLoaded = true; + callback(event); + } + } - if (!is(dv)) - dv = ''; + // Page already loaded then fire it directly + if (doc.readyState == "complete") { + readyHandler(); + return; + } - // Try the mce variant for these - if (/^(src|href|style|coords|shape)$/.test(n)) { - v = e.getAttribute("data-mce-" + n); + // Use W3C method + if (w3cEventModel) { + addEvent(win, 'DOMContentLoaded', readyHandler); + } else { + // Use IE method + addEvent(doc, "readystatechange", function() { + if (doc.readyState === "complete") { + removeEvent(doc, "readystatechange", arguments.callee); + readyHandler(); + } + }); - if (v) - return v; - } + // Wait until we can scroll, when we can the DOM is initialized + if (doc.documentElement.doScroll && win === win.top) { + (function() { + try { + // If IE is used, use the trick by Diego Perini licensed under MIT by request to the author. + // http://javascript.nwbox.com/IEContentLoaded/ + doc.documentElement.doScroll("left"); + } catch (ex) { + setTimeout(arguments.callee, 0); + return; + } - if (isIE && t.props[n]) { - v = e[t.props[n]]; - v = v && v.nodeValue ? v.nodeValue : v; + readyHandler(); + })(); } + } - if (!v) - v = e.getAttribute(n, 2); + // Fallback if any of the above methods should fail for some odd reason + addEvent(win, 'load', readyHandler); + } - // Check boolean attribs - if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) { - if (e[t.props[n]] === true && v === '') - return n; + function EventUtils(proxy) { + var self = this, events = {}, count, isFocusBlurBound, hasFocusIn, hasMouseEnterLeave, mouseEnterLeave; - return v ? n : ''; - } + hasMouseEnterLeave = "onmouseenter" in document.documentElement; + hasFocusIn = "onfocusin" in document.documentElement; + mouseEnterLeave = {mouseenter: 'mouseover', mouseleave: 'mouseout'}; + count = 1; - // Inner input elements will override attributes on form elements - if (e.nodeName === "FORM" && e.getAttributeNode(n)) - return e.getAttributeNode(n).nodeValue; + // State if the DOMContentLoaded was executed or not + self.domLoaded = false; + self.events = events; - if (n === 'style') { - v = v || e.style.cssText; + function executeHandlers(evt, id) { + var callbackList, i, l, callback; - if (v) { - v = t.serializeStyle(t.parseStyle(v), e.nodeName); + callbackList = events[id][evt.type]; + if (callbackList) { + for (i = 0, l = callbackList.length; i < l; i++) { + callback = callbackList[i]; + + // Check if callback exists might be removed if a unbind is called inside the callback + if (callback && callback.func.call(callback.scope, evt) === false) { + evt.preventDefault(); + } - if (t.settings.keep_values && !t._isRes(v)) - e.setAttribute('data-mce-style', v); + // Should we stop propagation to immediate listeners + if (evt.isImmediatePropagationStopped()) { + return; + } } } + } - // Remove Apple and WebKit stuff - if (isWebKit && n === "class" && v) - v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, ''); + self.bind = function(target, names, callback, scope) { + var id, callbackList, i, name, fakeName, nativeHandler, capture, win = window; - // Handle IE issues - if (isIE) { - switch (n) { - case 'rowspan': - case 'colspan': - // IE returns 1 as default value - if (v === 1) - v = ''; + // Native event handler function patches the event and executes the callbacks for the expando + function defaultNativeHandler(evt) { + executeHandlers(fix(evt || win.event), id); + } - break; + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return; + } - case 'size': - // IE returns +0 as default value for size - if (v === '+0' || v === 20 || v === 0) - v = ''; + // Create or get events id for the target + if (!target[expando]) { + id = count++; + target[expando] = id; + events[id] = {}; + } else { + id = target[expando]; - break; + if (!events[id]) { + events[id] = {}; + } + } - case 'width': - case 'height': - case 'vspace': - case 'checked': - case 'disabled': - case 'readonly': - if (v === 0) - v = ''; + // Setup the specified scope or use the target as a default + scope = scope || target; - break; + // Split names and bind each event, enables you to bind multiple events with one call + names = names.split(' '); + i = names.length; + while (i--) { + name = names[i]; + nativeHandler = defaultNativeHandler; + fakeName = capture = false; - case 'hspace': - // IE returns -1 as default value - if (v === -1) - v = ''; + // Use ready instead of DOMContentLoaded + if (name === "DOMContentLoaded") { + name = "ready"; + } - break; + // DOM is already ready + if ((self.domLoaded || target.readyState == 'complete') && name === "ready") { + self.domLoaded = true; + callback.call(scope, fix({type: name})); + continue; + } - case 'maxlength': - case 'tabindex': - // IE returns default value - if (v === 32768 || v === 2147483647 || v === '32768') - v = ''; + // Handle mouseenter/mouseleaver + if (!hasMouseEnterLeave) { + fakeName = mouseEnterLeave[name]; - break; + if (fakeName) { + nativeHandler = function(evt) { + var current, related; - case 'multiple': - case 'compact': - case 'noshade': - case 'nowrap': - if (v === 65535) - return n; + current = evt.currentTarget; + related = evt.relatedTarget; - return dv; + // Check if related is inside the current target if it's not then the event should be ignored since it's a mouseover/mouseout inside the element + if (related && current.contains) { + // Use contains for performance + related = current.contains(related); + } else { + while (related && related !== current) { + related = related.parentNode; + } + } - case 'shape': - v = v.toLowerCase(); - break; + // Fire fake event + if (!related) { + evt = fix(evt || win.event); + evt.type = evt.type === 'mouseout' ? 'mouseleave' : 'mouseenter'; + evt.target = current; + executeHandlers(evt, id); + } + }; + } + } - default: - // IE has odd anonymous function for event attributes - if (n.indexOf('on') === 0 && v) - v = tinymce._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1', '' + v); + // Fake bubbeling of focusin/focusout + if (!hasFocusIn && (name === "focusin" || name === "focusout")) { + capture = true; + fakeName = name === "focusin" ? "focus" : "blur"; + nativeHandler = function(evt) { + evt = fix(evt || win.event); + evt.type = evt.type === 'focus' ? 'focusin' : 'focusout'; + executeHandlers(evt, id); + }; + } + + // Setup callback list and bind native event + callbackList = events[id][name]; + if (!callbackList) { + events[id][name] = callbackList = [{func: callback, scope: scope}]; + callbackList.fakeName = fakeName; + callbackList.capture = capture; + + // Add the nativeHandler to the callback list so that we can later unbind it + callbackList.nativeHandler = nativeHandler; + if (!w3cEventModel) { + callbackList.proxyHandler = proxy(id); + } + + // Check if the target has native events support + if (name === "ready") { + bindOnReady(target, nativeHandler, self); + } else { + addEvent(target, fakeName || name, w3cEventModel ? nativeHandler : callbackList.proxyHandler, capture); + } + } else { + // If it already has an native handler then just push the callback + callbackList.push({func: callback, scope: scope}); } } - return (v !== undef && v !== null && v !== '') ? '' + v : dv; - }, + target = callbackList = 0; // Clean memory for IE - getPos : function(n, ro) { - var t = this, x = 0, y = 0, e, d = t.doc, r; + return callback; + }; - n = t.get(n); - ro = ro || d.body; + self.unbind = function(target, names, callback) { + var id, callbackList, i, ci, name, eventMap; - if (n) { - // Use getBoundingClientRect if it exists since it's faster than looping offset nodes - if (n.getBoundingClientRect) { - n = n.getBoundingClientRect(); - e = t.boxModel ? d.documentElement : d.body; + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return self; + } - // Add scroll offsets from documentElement or body since IE with the wrong box model will use d.body and so do WebKit - // Also remove the body/documentelement clientTop/clientLeft on IE 6, 7 since they offset the position - x = n.left + (d.documentElement.scrollLeft || d.body.scrollLeft) - e.clientTop; - y = n.top + (d.documentElement.scrollTop || d.body.scrollTop) - e.clientLeft; + // Unbind event or events if the target has the expando + id = target[expando]; + if (id) { + eventMap = events[id]; - return {x : x, y : y}; + // Specific callback + if (names) { + names = names.split(' '); + i = names.length; + while (i--) { + name = names[i]; + callbackList = eventMap[name]; + + // Unbind the event if it exists in the map + if (callbackList) { + // Remove specified callback + if (callback) { + ci = callbackList.length; + while (ci--) { + if (callbackList[ci].func === callback) { + callbackList.splice(ci, 1); + } + } + } + + // Remove all callbacks if there isn't a specified callback or there is no callbacks left + if (!callback || callbackList.length === 0) { + delete eventMap[name]; + removeEvent(target, callbackList.fakeName || name, w3cEventModel ? callbackList.nativeHandler : callbackList.proxyHandler, callbackList.capture); + } + } + } + } else { + // All events for a specific element + for (name in eventMap) { + callbackList = eventMap[name]; + removeEvent(target, callbackList.fakeName || name, w3cEventModel ? callbackList.nativeHandler : callbackList.proxyHandler, callbackList.capture); + } + + eventMap = {}; } - r = n; - while (r && r != ro && r.nodeType) { - x += r.offsetLeft || 0; - y += r.offsetTop || 0; - r = r.offsetParent; + // Check if object is empty, if it isn't then we won't remove the expando map + for (name in eventMap) { + return self; } - r = n.parentNode; - while (r && r != ro && r.nodeType) { - x -= r.scrollLeft || 0; - y -= r.scrollTop || 0; - r = r.parentNode; + // Delete event object + delete events[id]; + + // Remove expando from target + try { + // IE will fail here since it can't delete properties from window + delete target[expando]; + } catch (ex) { + // IE will set it to null + target[expando] = null; } } - return {x : x, y : y}; - }, + return self; + }; - parseStyle : function(st) { - return this.styles.parse(st); - }, + self.fire = function(target, name, args) { + var id, event; - serializeStyle : function(o, name) { - return this.styles.serialize(o, name); - }, + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return self; + } - loadCSS : function(u) { - var t = this, d = t.doc, head; + // Build event object by patching the args + event = fix(null, args); + event.type = name; + + do { + // Found an expando that means there is listeners to execute + id = target[expando]; + if (id) { + executeHandlers(event, id); + } + + // Walk up the DOM + target = target.parentNode || target.ownerDocument || target.defaultView || target.parentWindow; + } while (target && !event.isPropagationStopped()); + + return self; + }; + + self.clean = function(target) { + var i, children, unbind = self.unbind; + + // Don't bind to text nodes or comments + if (!target || target.nodeType === 3 || target.nodeType === 8) { + return self; + } + + // Unbind any element on the specificed target + if (target[expando]) { + unbind(target); + } + + // Target doesn't have getElementsByTagName it's probably a window object then use it's document to find the children + if (!target.getElementsByTagName) { + target = target.document; + } + + // Remove events from each child element + if (target && target.getElementsByTagName) { + unbind(target); + + children = target.getElementsByTagName('*'); + i = children.length; + while (i--) { + target = children[i]; - if (!u) - u = ''; + if (target[expando]) { + unbind(target); + } + } + } - head = t.select('head')[0]; + return self; + }; - each(u.split(','), function(u) { - var link; + self.callNativeHandler = function(id, evt) { + if (events) { + events[id][evt.type].nativeHandler(evt); + } + }; - if (t.files[u]) - return; + self.destory = function() { + events = {}; + }; - t.files[u] = true; - link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)}); + // Legacy function calls - // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug - // This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading - // It's ugly but it seems to work fine. - if (isIE && d.documentMode && d.recalc) { - link.onload = function() { - if (d.recalc) - d.recalc(); + self.add = function(target, events, func, scope) { + // Old API supported direct ID assignment + if (typeof(target) === "string") { + target = document.getElementById(target); + } - link.onload = null; - }; - } + // Old API supported multiple targets + if (target && target instanceof Array) { + var i = target.length; - head.appendChild(link); - }); - }, + while (i--) { + self.add(target[i], events, func, scope); + } - addClass : function(e, c) { - return this.run(e, function(e) { - var o; + return; + } - if (!c) - return 0; + // Old API called ready init + if (events === "init") { + events = "ready"; + } - if (this.hasClass(e, c)) - return e.className; + return self.bind(target, events instanceof Array ? events.join(' ') : events, func, scope); + }; - o = this.removeClass(e, c); + self.remove = function(target, events, func, scope) { + if (!target) { + return self; + } - return e.className = (o != '' ? (o + ' ') : '') + c; - }); - }, + // Old API supported direct ID assignment + if (typeof(target) === "string") { + target = document.getElementById(target); + } - removeClass : function(e, c) { - var t = this, re; + // Old API supported multiple targets + if (target instanceof Array) { + var i = target.length; - return t.run(e, function(e) { - var v; + while (i--) { + self.remove(target[i], events, func, scope); + } - if (t.hasClass(e, c)) { - if (!re) - re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g"); + return self; + } - v = e.className.replace(re, ' '); - v = tinymce.trim(v != ' ' ? v : ''); + return self.unbind(target, events instanceof Array ? events.join(' ') : events, func); + }; - e.className = v; + self.clear = function(target) { + // Old API supported direct ID assignment + if (typeof(target) === "string") { + target = document.getElementById(target); + } - // Empty class attr - if (!v) { - e.removeAttribute('class'); - e.removeAttribute('className'); - } + return self.clean(target); + }; - return v; - } + self.cancel = function(e) { + if (e) { + self.prevent(e); + self.stop(e); + } - return e.className; - }); - }, + return false; + }; - hasClass : function(n, c) { - n = this.get(n); + self.prevent = function(e) { + if (!e.preventDefault) { + e = fix(e); + } - if (!n || !c) - return false; + e.preventDefault(); - return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1; - }, + return false; + }; - show : function(e) { - return this.setStyle(e, 'display', 'block'); - }, + self.stop = function(e) { + if (!e.stopPropagation) { + e = fix(e); + } - hide : function(e) { - return this.setStyle(e, 'display', 'none'); - }, + e.stopPropagation(); - isHidden : function(e) { - e = this.get(e); + return false; + }; + } - return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none'; - }, + namespace.EventUtils = EventUtils; - uniqueId : function(p) { - return (!p ? 'mce_' : p) + (this.counter++); - }, + namespace.Event = new EventUtils(function(id) { + return function(evt) { + tinymce.dom.Event.callNativeHandler(id, evt); + }; + }); - setHTML : function(element, html) { - var self = this; + // Bind ready event when tinymce script is loaded + namespace.Event.bind(window, 'ready', function() {}); - return self.run(element, function(element) { - if (isIE) { - // Remove all child nodes, IE keeps empty text nodes in DOM - while (element.firstChild) - element.removeChild(element.firstChild); + namespace = 0; +})(tinymce.dom, 'data-mce-expando'); // Namespace and expando - try { - // IE will remove comments from the beginning - // unless you padd the contents with something - element.innerHTML = '<br />' + html; - element.removeChild(element.firstChild); - } catch (ex) { - // IE sometimes produces an unknown runtime error on innerHTML if it's an block element within a block element for example a div inside a p - // This seems to fix this problem +tinymce.dom.TreeWalker = function(start_node, root_node) { + var node = start_node; - // Create new div with HTML contents and a BR infront to keep comments - element = self.create('div'); - element.innerHTML = '<br />' + html; + function findSibling(node, start_name, sibling_name, shallow) { + var sibling, parent; - // Add all children from div to target - each (element.childNodes, function(node, i) { - // Skip br element - if (i) - element.appendChild(node); - }); - } - } else - element.innerHTML = html; + if (node) { + // Walk into nodes if it has a start + if (!shallow && node[start_name]) + return node[start_name]; - return html; - }); - }, + // Return the sibling if it has one + if (node != root_node) { + sibling = node[sibling_name]; + if (sibling) + return sibling; - getOuterHTML : function(elm) { - var doc, self = this; + // 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; + } + } + } + }; - elm = self.get(elm); + this.current = function() { + return node; + }; - if (!elm) - return null; + this.next = function(shallow) { + return (node = findSibling(node, 'firstChild', 'nextSibling', shallow)); + }; - if (elm.nodeType === 1 && self.hasOuterHTML) - return elm.outerHTML; + this.prev = function(shallow) { + return (node = findSibling(node, 'lastChild', 'previousSibling', shallow)); + }; +}; - doc = (elm.ownerDocument || self.doc).createElement("body"); - doc.appendChild(elm.cloneNode(true)); +(function(tinymce) { + // Shorten names + var each = tinymce.each, + is = tinymce.is, + isWebKit = tinymce.isWebKit, + isIE = tinymce.isIE, + Entities = tinymce.html.Entities, + simpleSelectorRe = /^([a-z0-9],?)+$/i, + whiteSpaceRegExp = /^[ \t\r\n]*$/; - return doc.innerHTML; + tinymce.create('tinymce.dom.DOMUtils', { + doc : null, + root : null, + files : null, + pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/, + props : { + "for" : "htmlFor", + "class" : "className", + className : "className", + checked : "checked", + disabled : "disabled", + maxlength : "maxLength", + readonly : "readOnly", + selected : "selected", + value : "value", + id : "id", + name : "name", + type : "type" }, - setOuterHTML : function(e, h, d) { - var t = this; + DOMUtils : function(d, s) { + var t = this, globalStyle, name, blockElementsMap; - function setHTML(e, h, d) { - var n, tp; + t.doc = d; + t.win = window; + t.files = {}; + t.cssFlicker = false; + t.counter = 0; + t.stdMode = !tinymce.isIE || d.documentMode >= 8; + t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat" || t.stdMode; + t.hasOuterHTML = "outerHTML" in d.createElement("a"); - tp = d.createElement("body"); - tp.innerHTML = h; + t.settings = s = tinymce.extend({ + keep_values : false, + hex_colors : 1 + }, s); + + t.schema = s.schema; + t.styles = new tinymce.html.Styles({ + url_converter : s.url_converter, + url_converter_scope : s.url_converter_scope + }, s.schema); - n = tp.lastChild; - while (n) { - t.insertAfter(n.cloneNode(true), e); - n = n.previousSibling; + // Fix IE6SP2 flicker and check it failed for pre SP2 + if (tinymce.isIE6) { + try { + d.execCommand('BackgroundImageCache', false, true); + } catch (e) { + t.cssFlicker = true; } + } - t.remove(e); - }; + t.fixDoc(d); + t.events = s.ownEvents ? new tinymce.dom.EventUtils(s.proxy) : tinymce.dom.Event; + tinymce.addUnload(t.destroy, t); + blockElementsMap = s.schema ? s.schema.getBlockElements() : {}; - return this.run(e, function(e) { - e = t.get(e); + t.isBlock = function(node) { + // Fix for #5446 + if (!node) { + return false; + } - // Only set HTML on elements - if (e.nodeType == 1) { - d = d || e.ownerDocument || t.doc; + // This function is called in module pattern style since it might be executed with the wrong this scope + var type = node.nodeType; + + // If it's a node then check the type and use the nodeName + if (type) + return !!(type === 1 && blockElementsMap[node.nodeName]); + + return !!blockElementsMap[node]; + }; + }, - if (isIE) { - try { - // Try outerHTML for IE it sometimes produces an unknown runtime error - if (isIE && e.nodeType == 1) - e.outerHTML = h; - else - setHTML(e, h, d); - } catch (ex) { - // Fix for unknown runtime error - setHTML(e, h, d); - } - } else - setHTML(e, h, d); + fixDoc: function(doc) { + var settings = this.settings, name; + + if (isIE && settings.schema) { + // Add missing HTML 4/5 elements to IE + ('abbr article aside audio canvas ' + + 'details figcaption figure footer ' + + 'header hgroup mark menu meter nav ' + + 'output progress section summary ' + + 'time video').replace(/\w+/g, function(name) { + doc.createElement(name); + }); + + // Create all custom elements + for (name in settings.schema.getCustomElements()) { + doc.createElement(name); } - }); + } }, - decode : Entities.decode, + clone: function(node, deep) { + var self = this, clone, doc; - encode : Entities.encodeAllRaw, + // TODO: Add feature detection here in the future + if (!isIE || node.nodeType !== 1 || deep) { + return node.cloneNode(deep); + } - insertAfter : function(node, reference_node) { - reference_node = this.get(reference_node); + doc = self.doc; - return this.run(node, function(node) { - var parent, nextSibling; + // Make a HTML5 safe shallow copy + if (!deep) { + clone = doc.createElement(node.nodeName); - parent = reference_node.parentNode; - nextSibling = reference_node.nextSibling; + // Copy attribs + each(self.getAttribs(node), function(attr) { + self.setAttrib(clone, attr.nodeName, self.getAttrib(node, attr.nodeName)); + }); - if (nextSibling) - parent.insertBefore(node, nextSibling); - else - parent.appendChild(node); + return clone; + } +/* + // Setup HTML5 patched document fragment + if (!self.frag) { + self.frag = doc.createDocumentFragment(); + self.fixDoc(self.frag); + } - return node; - }); + // Make a deep copy by adding it to the document fragment then removing it this removed the :section + clone = doc.createElement('div'); + self.frag.appendChild(clone); + clone.innerHTML = node.outerHTML; + self.frag.removeChild(clone); +*/ + return clone.firstChild; }, - isBlock : function(node) { - var type = node.nodeType; - - // If it's a node then check the type and use the nodeName - if (type) - return !!(type === 1 && blockElementsMap[node.nodeName]); + getRoot : function() { + var t = this, s = t.settings; - return !!blockElementsMap[node]; + return (s && t.get(s.root_element)) || t.doc.body; }, - replace : function(n, o, k) { - var t = this; + getViewPort : function(w) { + var d, b; - if (is(o, 'array')) - n = n.cloneNode(true); + w = !w ? this.win : w; + d = w.document; + b = this.boxModel ? d.documentElement : d.body; - return t.run(o, function(o) { - if (k) { - each(tinymce.grep(o.childNodes), function(c) { - n.appendChild(c); - }); - } + // Returns viewport size excluding scrollbars + return { + x : w.pageXOffset || b.scrollLeft, + y : w.pageYOffset || b.scrollTop, + w : w.innerWidth || b.clientWidth, + h : w.innerHeight || b.clientHeight + }; + }, - return o.parentNode.replaceChild(n, o); - }); + getRect : function(e) { + var p, t = this, sr; + + e = t.get(e); + p = t.getPos(e); + sr = t.getSize(e); + + return { + x : p.x, + y : p.y, + w : sr.w, + h : sr.h + }; }, - rename : function(elm, name) { - var t = this, newElm; + getSize : function(e) { + var t = this, w, h; - if (elm.nodeName != name.toUpperCase()) { - // Rename block element - newElm = t.create(name); + e = t.get(e); + w = t.getStyle(e, 'width'); + h = t.getStyle(e, 'height'); - // Copy attribs to new block - each(t.getAttribs(elm), function(attr_node) { - t.setAttrib(newElm, attr_node.nodeName, t.getAttrib(elm, attr_node.nodeName)); - }); + // Non pixel value, then force offset/clientWidth + if (w.indexOf('px') === -1) + w = 0; - // Replace block - t.replace(newElm, elm, 1); - } + // Non pixel value, then force offset/clientWidth + if (h.indexOf('px') === -1) + h = 0; - return newElm || elm; + return { + w : parseInt(w, 10) || e.offsetWidth || e.clientWidth, + h : parseInt(h, 10) || e.offsetHeight || e.clientHeight + }; }, - findCommonAncestor : function(a, b) { - var ps = a, pe; + getParent : function(n, f, r) { + return this.getParents(n, f, r, false); + }, - while (ps) { - pe = b; + getParents : function(n, f, r, c) { + var t = this, na, se = t.settings, o = []; - while (pe && ps != pe) - pe = pe.parentNode; + n = t.get(n); + c = c === undefined; - if (ps == pe) - break; + if (se.strict_root) + r = r || t.getRoot(); - ps = ps.parentNode; + // Wrap node name as func + if (is(f, 'string')) { + na = f; + + if (f === '*') { + f = function(n) {return n.nodeType == 1;}; + } else { + f = function(n) { + return t.is(n, na); + }; + } } - if (!ps && a.ownerDocument) - return a.ownerDocument.documentElement; + while (n) { + if (n == r || !n.nodeType || n.nodeType === 9) + break; - return ps; - }, + if (!f || f(n)) { + if (c) + o.push(n); + else + return n; + } - toHex : function(s) { - var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s); + n = n.parentNode; + } - function hex(s) { - s = parseInt(s).toString(16); + return c ? o : null; + }, - return s.length > 1 ? s : '0' + s; // 0 -> 00 - }; + get : function(e) { + var n; - if (c) { - s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]); + if (e && this.doc && typeof(e) == 'string') { + n = e; + e = this.doc.getElementById(e); - return s; + // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick + if (e && e.id !== n) + return this.doc.getElementsByName(n)[1]; } - return s; + return e; }, - getClasses : function() { - var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov; + getNext : function(node, selector) { + return this._findSib(node, selector, 'nextSibling'); + }, - if (t.classes) - return t.classes; + getPrev : function(node, selector) { + return this._findSib(node, selector, 'previousSibling'); + }, - function addClasses(s) { - // IE style imports - each(s.imports, function(r) { - addClasses(r); - }); - each(s.cssRules || s.rules, function(r) { - // Real type or fake it on IE - switch (r.type || 1) { - // Rule - case 1: - if (r.selectorText) { - each(r.selectorText.split(','), function(v) { - v = v.replace(/^\s*|\s*$|^\s\./g, ""); + add : function(p, n, a, h, c) { + var t = this; - // Is internal or it doesn't contain a class - if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v)) - return; + return this.run(p, function(p) { + var e, k; - // Remove everything but class name - ov = v; - v = tinymce._replace(/.*\.([a-z0-9_\-]+).*/i, '$1', v); + e = is(n, 'string') ? t.doc.createElement(n) : n; + t.setAttribs(e, a); - // Filter classes - if (f && !(v = f(v, ov))) - return; + if (h) { + if (h.nodeType) + e.appendChild(h); + else + t.setHTML(e, h); + } - if (!lo[v]) { - cl.push({'class' : v}); - lo[v] = 1; - } - }); - } - break; + return !c ? p.appendChild(e) : e; + }); + }, - // Import - case 3: - addClasses(r.styleSheet); - break; - } - }); - }; + create : function(n, a, h) { + return this.add(this.doc.createElement(n), n, a, h, 1); + }, - try { - each(t.doc.styleSheets, addClasses); - } catch (ex) { - // Ignore + createHTML : function(n, a, h) { + var o = '', t = this, k; + + o += '<' + n; + + for (k in a) { + if (a.hasOwnProperty(k)) + o += ' ' + k + '="' + t.encode(a[k]) + '"'; } - if (cl.length > 0) - t.classes = cl; + // A call to tinymce.is doesn't work for some odd reason on IE9 possible bug inside their JS runtime + if (typeof(h) != "undefined") + return o + '>' + h + '</' + n + '>'; - return cl; + return o + ' />'; }, - run : function(e, f, s) { - var t = this, o; + remove : function(node, keep_children) { + return this.run(node, function(node) { + var child, parent = node.parentNode; - if (t.doc && typeof(e) === 'string') - e = t.get(e); + if (!parent) + return null; - if (!e) - return false; + if (keep_children) { + while (child = node.firstChild) { + // IE 8 will crash if you don't remove completely empty text nodes + if (!tinymce.isIE || child.nodeType !== 3 || child.nodeValue) + parent.insertBefore(child, node); + else + node.removeChild(child); + } + } - s = s || this; - if (!e.nodeType && (e.length || e.length === 0)) { - o = []; + return parent.removeChild(node); + }); + }, - each(e, function(e, i) { - if (e) { - if (typeof(e) == 'string') - e = t.doc.getElementById(e); + setStyle : function(n, na, v) { + var t = this; - o.push(f.call(s, e, i)); - } + return t.run(n, function(e) { + var s, i; + + s = e.style; + + // Camelcase it, if needed + na = na.replace(/-(\D)/g, function(a, b){ + return b.toUpperCase(); }); - return o; - } + // Default px suffix on these + if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v))) + v += 'px'; - return f.call(s, e); - }, + switch (na) { + case 'opacity': + // IE specific opacity + if (isIE) { + s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")"; - getAttribs : function(n) { - var o; + if (!n.currentStyle || !n.currentStyle.hasLayout) + s.display = 'inline-block'; + } - n = this.get(n); + // Fix for older browsers + s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || ''; + break; - if (!n) - return []; + case 'float': + isIE ? s.styleFloat = v : s.cssFloat = v; + break; + + default: + s[na] = v || ''; + } - if (isIE) { - o = []; + // Force update of the style data + if (t.settings.update_styles) + t.setAttrib(e, 'data-mce-style'); + }); + }, - // Object will throw exception in IE - if (n.nodeName == 'OBJECT') - return n.attributes; + getStyle : function(n, na, c) { + n = this.get(n); - // IE doesn't keep the selected attribute if you clone option elements - if (n.nodeName === 'OPTION' && this.getAttrib(n, 'selected')) - o.push({specified : 1, nodeName : 'selected'}); + if (!n) + return; - // It's crazy that this is faster in IE but it's because it returns all attributes all the time - n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) { - o.push({specified : 1, nodeName : a}); + // Gecko + if (this.doc.defaultView && c) { + // Remove camelcase + na = na.replace(/[A-Z]/g, function(a){ + return '-' + a; }); - return o; + try { + return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na); + } catch (ex) { + // Old safari might fail + return null; + } } - return n.attributes; - }, - - isEmpty : function(node, elements) { - var self = this, i, attributes, type, walker, name, parentNode; - - node = node.firstChild; - if (node) { - walker = new tinymce.dom.TreeWalker(node); - elements = elements || self.schema ? self.schema.getNonEmptyElements() : null; + // Camelcase it, if needed + na = na.replace(/-(\D)/g, function(a, b){ + return b.toUpperCase(); + }); - do { - type = node.nodeType; + if (na == 'float') + na = isIE ? 'styleFloat' : 'cssFloat'; - if (type === 1) { - // Ignore bogus elements - if (node.getAttribute('data-mce-bogus')) - continue; + // IE & Opera + if (n.currentStyle && c) + return n.currentStyle[na]; - // Keep empty elements like <img /> - name = node.nodeName.toLowerCase(); - if (elements && elements[name]) { - // Ignore single BR elements in blocks like <p><br /></p> - parentNode = node.parentNode; - if (name === 'br' && self.isBlock(parentNode) && parentNode.firstChild === node && parentNode.lastChild === node) { - continue; - } + return n.style ? n.style[na] : undefined; + }, - return false; - } + setStyles : function(e, o) { + var t = this, s = t.settings, ol; - // Keep elements with data-bookmark attributes or name attribute like <a name="1"></a> - attributes = self.getAttribs(node); - i = node.attributes.length; - while (i--) { - name = node.attributes[i].nodeName; - if (name === "name" || name === 'data-mce-bookmark') - return false; - } - } + ol = s.update_styles; + s.update_styles = 0; - // Keep comment nodes - if (type == 8) - return false; + each(o, function(v, n) { + t.setStyle(e, n, v); + }); - // Keep non whitespace text nodes - if ((type === 3 && !whiteSpaceRegExp.test(node.nodeValue))) - return false; - } while (node = walker.next()); - } + // Update style info + s.update_styles = ol; + if (s.update_styles) + t.setAttrib(e, s.cssText); + }, - return true; + removeAllAttribs: function(e) { + return this.run(e, function(e) { + var i, attrs = e.attributes; + for (i = attrs.length - 1; i >= 0; i--) { + e.removeAttributeNode(attrs.item(i)); + } + }); }, - destroy : function(s) { + setAttrib : function(e, n, v) { var t = this; - if (t.events) - t.events.destroy(); + // Whats the point + if (!e || !n) + return; - t.win = t.doc = t.root = t.events = null; + // Strict XML mode + if (t.settings.strict) + n = n.toLowerCase(); - // Manual destroy then remove unload handler - if (!s) - tinymce.removeUnload(t.destroy); - }, + return this.run(e, function(e) { + var s = t.settings; + var originalValue = e.getAttribute(n); + if (v !== null) { + switch (n) { + case "style": + if (!is(v, 'string')) { + each(v, function(v, n) { + t.setStyle(e, n, v); + }); - createRng : function() { - var d = this.doc; + return; + } - return d.createRange ? d.createRange() : new tinymce.dom.Range(this); - }, + // No mce_style for elements with these since they might get resized by the user + if (s.keep_values) { + if (v && !t._isRes(v)) + e.setAttribute('data-mce-style', v, 2); + else + e.removeAttribute('data-mce-style', 2); + } - nodeIndex : function(node, normalized) { - var idx = 0, lastNodeType, lastNode, nodeType; + e.style.cssText = v; + break; - if (node) { - for (lastNodeType = node.nodeType, node = node.previousSibling, lastNode = node; node; node = node.previousSibling) { - nodeType = node.nodeType; + case "class": + e.className = v || ''; // Fix IE null bug + break; - // Normalize text nodes - if (normalized && nodeType == 3) { - if (nodeType == lastNodeType || !node.nodeValue.length) - continue; - } - idx++; - lastNodeType = nodeType; - } - } + case "src": + case "href": + if (s.keep_values) { + if (s.url_converter) + v = s.url_converter.call(s.url_converter_scope || t, v, n, e); - return idx; - }, + t.setAttrib(e, 'data-mce-' + n, v, 2); + } - split : function(pe, e, re) { - var t = this, r = t.createRng(), bef, aft, pa; + break; - // W3C valid browsers tend to leave empty nodes to the left/right side of the contents, this makes sense - // but we don't want that in our code since it serves no purpose for the end user - // For example if this is chopped: - // <p>text 1<span><b>CHOP</b></span>text 2</p> - // would produce: - // <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p> - // this function will then trim of empty edges and produce: - // <p>text 1</p><b>CHOP</b><p>text 2</p> - function trim(node) { - var i, children = node.childNodes, type = node.nodeType; + case "shape": + e.setAttribute('data-mce-style', v); + break; + } + } + if (is(v) && v !== null && v.length !== 0) + e.setAttribute(n, '' + v, 2); + else + e.removeAttribute(n, 2); - function surroundedBySpans(node) { - var previousIsSpan = node.previousSibling && node.previousSibling.nodeName == 'SPAN'; - var nextIsSpan = node.nextSibling && node.nextSibling.nodeName == 'SPAN'; - return previousIsSpan && nextIsSpan; + // fire onChangeAttrib event for attributes that have changed + if (tinyMCE.activeEditor && originalValue != v) { + var ed = tinyMCE.activeEditor; + ed.onSetAttrib.dispatch(ed, e, n, v); } + }); + }, - if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark') - return; + setAttribs : function(e, o) { + var t = this; - for (i = children.length - 1; i >= 0; i--) - trim(children[i]); + return this.run(e, function(e) { + each(o, function(v, n) { + t.setAttrib(e, n, v); + }); + }); + }, - if (type != 9) { - // Keep non whitespace text nodes - if (type == 3 && node.nodeValue.length > 0) { - // If parent element isn't a block or there isn't any useful contents for example "<p> </p>" - // 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)) - return; - } else if (type == 1) { - // If the only child is a bookmark then move it up - children = node.childNodes; - if (children.length == 1 && children[0] && children[0].nodeType == 1 && children[0].getAttribute('data-mce-type') == 'bookmark') - node.parentNode.insertBefore(children[0], node); + getAttrib : function(e, n, dv) { + var v, t = this, undef; - // Keep non empty elements or img, hr etc - if (children.length || /^(br|hr|input|img)$/i.test(node.nodeName)) - return; - } + e = t.get(e); - t.remove(node); - } + if (!e || e.nodeType !== 1) + return dv === undef ? false : dv; - return node; - }; + if (!is(dv)) + dv = ''; - if (pe && e) { - // Get before chunk - r.setStart(pe.parentNode, t.nodeIndex(pe)); - r.setEnd(e.parentNode, t.nodeIndex(e)); - bef = r.extractContents(); + // Try the mce variant for these + if (/^(src|href|style|coords|shape)$/.test(n)) { + v = e.getAttribute("data-mce-" + n); - // Get after chunk - r = t.createRng(); - r.setStart(e.parentNode, t.nodeIndex(e) + 1); - r.setEnd(pe.parentNode, t.nodeIndex(pe) + 1); - aft = r.extractContents(); + if (v) + return v; + } - // Insert before chunk - pa = pe.parentNode; - pa.insertBefore(trim(bef), pe); + if (isIE && t.props[n]) { + v = e[t.props[n]]; + v = v && v.nodeValue ? v.nodeValue : v; + } - // Insert middle chunk - if (re) - pa.replaceChild(re, e); - else - pa.insertBefore(e, pe); + if (!v) + v = e.getAttribute(n, 2); - // Insert after chunk - pa.insertBefore(trim(aft), pe); - t.remove(pe); + // Check boolean attribs + if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) { + if (e[t.props[n]] === true && v === '') + return n; - return re || e; + return v ? n : ''; } - }, - bind : function(target, name, func, scope) { - var t = this; + // Inner input elements will override attributes on form elements + if (e.nodeName === "FORM" && e.getAttributeNode(n)) + return e.getAttributeNode(n).nodeValue; - if (!t.events) - t.events = new tinymce.dom.EventUtils(); + if (n === 'style') { + v = v || e.style.cssText; - return t.events.add(target, name, func, scope || this); - }, + if (v) { + v = t.serializeStyle(t.parseStyle(v), e.nodeName); - unbind : function(target, name, func) { - var t = this; + if (t.settings.keep_values && !t._isRes(v)) + e.setAttribute('data-mce-style', v); + } + } - if (!t.events) - t.events = new tinymce.dom.EventUtils(); + // Remove Apple and WebKit stuff + if (isWebKit && n === "class" && v) + v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, ''); - return t.events.remove(target, name, func); - }, + // Handle IE issues + if (isIE) { + switch (n) { + case 'rowspan': + case 'colspan': + // IE returns 1 as default value + if (v === 1) + v = ''; + break; - _findSib : function(node, selector, name) { - var t = this, f = selector; + case 'size': + // IE returns +0 as default value for size + if (v === '+0' || v === 20 || v === 0) + v = ''; - if (node) { - // If expression make a function of it using is - if (is(f, 'string')) { - f = function(node) { - return t.is(node, selector); - }; - } + break; - // Loop all siblings - for (node = node[name]; node; node = node[name]) { - if (f(node)) - return node; - } - } + case 'width': + case 'height': + case 'vspace': + case 'checked': + case 'disabled': + case 'readonly': + if (v === 0) + v = ''; - return null; - }, + break; - _isRes : function(c) { - // Is live resizble element - return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c); - } + case 'hspace': + // IE returns -1 as default value + if (v === -1) + v = ''; - /* - walk : function(n, f, s) { - var d = this.doc, w; + break; - if (d.createTreeWalker) { - w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); + case 'maxlength': + case 'tabindex': + // IE returns default value + if (v === 32768 || v === 2147483647 || v === '32768') + v = ''; - while ((n = w.nextNode()) != null) - f.call(s || this, n); - } else - tinymce.walk(n, f, 'childNodes', s); - } - */ + break; - /* - toRGB : function(s) { - var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s); + case 'multiple': + case 'compact': + case 'noshade': + case 'nowrap': + if (v === 65535) + return n; - if (c) { - // #FFF -> #FFFFFF - if (!is(c[3])) - c[3] = c[2] = c[1]; + return dv; - return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")"; + case 'shape': + v = v.toLowerCase(); + break; + + default: + // IE has odd anonymous function for event attributes + if (n.indexOf('on') === 0 && v) + v = tinymce._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1', '' + v); + } } - return s; - } - */ - }); + return (v !== undef && v !== null && v !== '') ? '' + v : dv; + }, - tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0}); -})(tinymce); + getPos : function(n, ro) { + var t = this, x = 0, y = 0, e, d = t.doc, r; -(function(ns) { - // Range constructor - function Range(dom) { - var t = this, - doc = dom.doc, - EXTRACT = 0, - CLONE = 1, - DELETE = 2, - TRUE = true, - FALSE = false, - START_OFFSET = 'startOffset', - START_CONTAINER = 'startContainer', - END_CONTAINER = 'endContainer', - END_OFFSET = 'endOffset', - extend = tinymce.extend, - nodeIndex = dom.nodeIndex; + n = t.get(n); + ro = ro || d.body; - extend(t, { - // Inital states - startContainer : doc, - startOffset : 0, - endContainer : doc, - endOffset : 0, - collapsed : TRUE, - commonAncestorContainer : doc, + if (n) { + // Use getBoundingClientRect if it exists since it's faster than looping offset nodes + if (n.getBoundingClientRect) { + n = n.getBoundingClientRect(); + e = t.boxModel ? d.documentElement : d.body; - // Range constants - START_TO_START : 0, - START_TO_END : 1, - END_TO_END : 2, - END_TO_START : 3, + // Add scroll offsets from documentElement or body since IE with the wrong box model will use d.body and so do WebKit + // Also remove the body/documentelement clientTop/clientLeft on IE 6, 7 since they offset the position + x = n.left + (d.documentElement.scrollLeft || d.body.scrollLeft) - e.clientTop; + y = n.top + (d.documentElement.scrollTop || d.body.scrollTop) - e.clientLeft; - // Public methods - setStart : setStart, - setEnd : setEnd, - setStartBefore : setStartBefore, - setStartAfter : setStartAfter, - setEndBefore : setEndBefore, - setEndAfter : setEndAfter, - collapse : collapse, - selectNode : selectNode, - selectNodeContents : selectNodeContents, - compareBoundaryPoints : compareBoundaryPoints, - deleteContents : deleteContents, - extractContents : extractContents, - cloneContents : cloneContents, - insertNode : insertNode, - surroundContents : surroundContents, - cloneRange : cloneRange - }); + return {x : x, y : y}; + } - function setStart(n, o) { - _setEndPoint(TRUE, n, o); - }; + r = n; + while (r && r != ro && r.nodeType) { + x += r.offsetLeft || 0; + y += r.offsetTop || 0; + r = r.offsetParent; + } - function setEnd(n, o) { - _setEndPoint(FALSE, n, o); - }; + r = n.parentNode; + while (r && r != ro && r.nodeType) { + x -= r.scrollLeft || 0; + y -= r.scrollTop || 0; + r = r.parentNode; + } + } - function setStartBefore(n) { - setStart(n.parentNode, nodeIndex(n)); - }; + return {x : x, y : y}; + }, - function setStartAfter(n) { - setStart(n.parentNode, nodeIndex(n) + 1); - }; + parseStyle : function(st) { + return this.styles.parse(st); + }, - function setEndBefore(n) { - setEnd(n.parentNode, nodeIndex(n)); - }; + serializeStyle : function(o, name) { + return this.styles.serialize(o, name); + }, - function setEndAfter(n) { - setEnd(n.parentNode, nodeIndex(n) + 1); - }; + addStyle: function(cssText) { + var doc = this.doc, head; - function collapse(ts) { - if (ts) { - t[END_CONTAINER] = t[START_CONTAINER]; - t[END_OFFSET] = t[START_OFFSET]; + // Create style element if needed + styleElm = doc.getElementById('mceDefaultStyles'); + if (!styleElm) { + styleElm = doc.createElement('style'), + styleElm.id = 'mceDefaultStyles'; + styleElm.type = 'text/css'; + + head = doc.getElementsByTagName('head')[0]; + if (head.firstChild) { + head.insertBefore(styleElm, head.firstChild); + } else { + head.appendChild(styleElm); + } + } + + // Append style data to old or new style element + if (styleElm.styleSheet) { + styleElm.styleSheet.cssText += cssText; } else { - t[START_CONTAINER] = t[END_CONTAINER]; - t[START_OFFSET] = t[END_OFFSET]; + styleElm.appendChild(doc.createTextNode(cssText)); } + }, - t.collapsed = TRUE; - }; + loadCSS : function(u) { + var t = this, d = t.doc, head; - function selectNode(n) { - setStartBefore(n); - setEndAfter(n); - }; + if (!u) + u = ''; - function selectNodeContents(n) { - setStart(n, 0); - setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length); - }; + head = d.getElementsByTagName('head')[0]; - function compareBoundaryPoints(h, r) { - var sc = t[START_CONTAINER], so = t[START_OFFSET], ec = t[END_CONTAINER], eo = t[END_OFFSET], - rsc = r.startContainer, rso = r.startOffset, rec = r.endContainer, reo = r.endOffset; + each(u.split(','), function(u) { + var link; - // Check START_TO_START - if (h === 0) - return _compareBoundaryPoints(sc, so, rsc, rso); - - // Check START_TO_END - if (h === 1) - return _compareBoundaryPoints(ec, eo, rsc, rso); - - // Check END_TO_END - if (h === 2) - return _compareBoundaryPoints(ec, eo, rec, reo); - - // Check END_TO_START - if (h === 3) - return _compareBoundaryPoints(sc, so, rec, reo); - }; + if (t.files[u]) + return; - function deleteContents() { - _traverse(DELETE); - }; + t.files[u] = true; + link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)}); - function extractContents() { - return _traverse(EXTRACT); - }; + // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug + // This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading + // It's ugly but it seems to work fine. + if (isIE && d.documentMode && d.recalc) { + link.onload = function() { + if (d.recalc) + d.recalc(); - function cloneContents() { - return _traverse(CLONE); - }; + link.onload = null; + }; + } - function insertNode(n) { - var startContainer = this[START_CONTAINER], - startOffset = this[START_OFFSET], nn, o; + head.appendChild(link); + }); + }, - // Node is TEXT_NODE or CDATA - if ((startContainer.nodeType === 3 || startContainer.nodeType === 4) && startContainer.nodeValue) { - if (!startOffset) { - // At the start of text - startContainer.parentNode.insertBefore(n, startContainer); - } else if (startOffset >= startContainer.nodeValue.length) { - // At the end of text - dom.insertAfter(n, startContainer); - } else { - // Middle, need to split - nn = startContainer.splitText(startOffset); - startContainer.parentNode.insertBefore(n, nn); - } - } else { - // Insert element node - if (startContainer.childNodes.length > 0) - o = startContainer.childNodes[startOffset]; + addClass : function(e, c) { + return this.run(e, function(e) { + var o; - if (o) - startContainer.insertBefore(n, o); - else - startContainer.appendChild(n); - } - }; + if (!c) + return 0; - function surroundContents(n) { - var f = t.extractContents(); + if (this.hasClass(e, c)) + return e.className; - t.insertNode(n); - n.appendChild(f); - t.selectNode(n); - }; + o = this.removeClass(e, c); - function cloneRange() { - return extend(new Range(dom), { - startContainer : t[START_CONTAINER], - startOffset : t[START_OFFSET], - endContainer : t[END_CONTAINER], - endOffset : t[END_OFFSET], - collapsed : t.collapsed, - commonAncestorContainer : t.commonAncestorContainer + return e.className = (o != '' ? (o + ' ') : '') + c; }); - }; + }, - // Private methods + removeClass : function(e, c) { + var t = this, re; - function _getSelectedNode(container, offset) { - var child; + return t.run(e, function(e) { + var v; - if (container.nodeType == 3 /* TEXT_NODE */) - return container; + if (t.hasClass(e, c)) { + if (!re) + re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g"); - if (offset < 0) - return container; + v = e.className.replace(re, ' '); + v = tinymce.trim(v != ' ' ? v : ''); - child = container.firstChild; - while (child && offset > 0) { - --offset; - child = child.nextSibling; - } + e.className = v; - if (child) - return child; + // Empty class attr + if (!v) { + e.removeAttribute('class'); + e.removeAttribute('className'); + } - return container; - }; + return v; + } - function _isCollapsed() { - return (t[START_CONTAINER] == t[END_CONTAINER] && t[START_OFFSET] == t[END_OFFSET]); - }; + return e.className; + }); + }, - function _compareBoundaryPoints(containerA, offsetA, containerB, offsetB) { - var c, offsetC, n, cmnRoot, childA, childB; - - // In the first case the boundary-points have the same container. A is before B - // if its offset is less than the offset of B, A is equal to B if its offset is - // equal to the offset of B, and A is after B if its offset is greater than the - // offset of B. - if (containerA == containerB) { - if (offsetA == offsetB) - return 0; // equal + hasClass : function(n, c) { + n = this.get(n); - if (offsetA < offsetB) - return -1; // before + if (!n || !c) + return false; - return 1; // after - } + return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1; + }, - // In the second case a child node C of the container of A is an ancestor - // container of B. In this case, A is before B if the offset of A is less than or - // equal to the index of the child node C and A is after B otherwise. - c = containerB; - while (c && c.parentNode != containerA) - c = c.parentNode; + show : function(e) { + return this.setStyle(e, 'display', 'block'); + }, + + hide : function(e) { + return this.setStyle(e, 'display', 'none'); + }, + + isHidden : function(e) { + e = this.get(e); - if (c) { - offsetC = 0; - n = containerA.firstChild; + return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none'; + }, - while (n != c && offsetC < offsetA) { - offsetC++; - n = n.nextSibling; - } + uniqueId : function(p) { + return (!p ? 'mce_' : p) + (this.counter++); + }, - if (offsetA <= offsetC) - return -1; // before + setHTML : function(element, html) { + var self = this; - return 1; // after - } + return self.run(element, function(element) { + if (isIE) { + // Remove all child nodes, IE keeps empty text nodes in DOM + while (element.firstChild) + element.removeChild(element.firstChild); - // In the third case a child node C of the container of B is an ancestor container - // of A. In this case, A is before B if the index of the child node C is less than - // the offset of B and A is after B otherwise. - c = containerA; - while (c && c.parentNode != containerB) { - c = c.parentNode; - } + try { + // IE will remove comments from the beginning + // unless you padd the contents with something + element.innerHTML = '<br />' + html; + element.removeChild(element.firstChild); + } catch (ex) { + // IE sometimes produces an unknown runtime error on innerHTML if it's an block element within a block element for example a div inside a p + // This seems to fix this problem - if (c) { - offsetC = 0; - n = containerB.firstChild; + // Create new div with HTML contents and a BR infront to keep comments + var newElement = self.create('div'); + newElement.innerHTML = '<br />' + html; - while (n != c && offsetC < offsetB) { - offsetC++; - n = n.nextSibling; - } + // Add all children from div to target + each (tinymce.grep(newElement.childNodes), function(node, i) { + // Skip br element + if (i && element.canHaveHTML) + element.appendChild(node); + }); + } + } else + element.innerHTML = html; - if (offsetC < offsetB) - return -1; // before + return html; + }); + }, - return 1; // after - } + getOuterHTML : function(elm) { + var doc, self = this; - // In the fourth case, none of three other cases hold: the containers of A and B - // are siblings or descendants of sibling nodes. In this case, A is before B if - // the container of A is before the container of B in a pre-order traversal of the - // Ranges' context tree and A is after B otherwise. - cmnRoot = dom.findCommonAncestor(containerA, containerB); - childA = containerA; + elm = self.get(elm); - while (childA && childA.parentNode != cmnRoot) - childA = childA.parentNode; + if (!elm) + return null; - if (!childA) - childA = cmnRoot; + if (elm.nodeType === 1 && self.hasOuterHTML) + return elm.outerHTML; - childB = containerB; - while (childB && childB.parentNode != cmnRoot) - childB = childB.parentNode; + doc = (elm.ownerDocument || self.doc).createElement("body"); + doc.appendChild(elm.cloneNode(true)); - if (!childB) - childB = cmnRoot; + return doc.innerHTML; + }, - if (childA == childB) - return 0; // equal + setOuterHTML : function(e, h, d) { + var t = this; - n = cmnRoot.firstChild; - while (n) { - if (n == childA) - return -1; // before + function setHTML(e, h, d) { + var n, tp; - if (n == childB) - return 1; // after + tp = d.createElement("body"); + tp.innerHTML = h; - n = n.nextSibling; - } - }; + n = tp.lastChild; + while (n) { + t.insertAfter(n.cloneNode(true), e); + n = n.previousSibling; + } - function _setEndPoint(st, n, o) { - var ec, sc; + t.remove(e); + }; - if (st) { - t[START_CONTAINER] = n; - t[START_OFFSET] = o; - } else { - t[END_CONTAINER] = n; - t[END_OFFSET] = o; - } + return this.run(e, function(e) { + e = t.get(e); - // If one boundary-point of a Range is set to have a root container - // other than the current one for the Range, the Range is collapsed to - // the new position. This enforces the restriction that both boundary- - // points of a Range must have the same root container. - ec = t[END_CONTAINER]; - while (ec.parentNode) - ec = ec.parentNode; + // Only set HTML on elements + if (e.nodeType == 1) { + d = d || e.ownerDocument || t.doc; - sc = t[START_CONTAINER]; - while (sc.parentNode) - sc = sc.parentNode; + if (isIE) { + try { + // Try outerHTML for IE it sometimes produces an unknown runtime error + if (isIE && e.nodeType == 1) + e.outerHTML = h; + else + setHTML(e, h, d); + } catch (ex) { + // Fix for unknown runtime error + setHTML(e, h, d); + } + } else + setHTML(e, h, d); + } + }); + }, - if (sc == ec) { - // The start position of a Range is guaranteed to never be after the - // end position. To enforce this restriction, if the start is set to - // be at a position after the end, the Range is collapsed to that - // position. - if (_compareBoundaryPoints(t[START_CONTAINER], t[START_OFFSET], t[END_CONTAINER], t[END_OFFSET]) > 0) - t.collapse(st); - } else - t.collapse(st); + decode : Entities.decode, - t.collapsed = _isCollapsed(); - t.commonAncestorContainer = dom.findCommonAncestor(t[START_CONTAINER], t[END_CONTAINER]); - }; + encode : Entities.encodeAllRaw, - function _traverse(how) { - var c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep; + insertAfter : function(node, reference_node) { + reference_node = this.get(reference_node); - if (t[START_CONTAINER] == t[END_CONTAINER]) - return _traverseSameContainer(how); + return this.run(node, function(node) { + var parent, nextSibling; - for (c = t[END_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) { - if (p == t[START_CONTAINER]) - return _traverseCommonStartContainer(c, how); + parent = reference_node.parentNode; + nextSibling = reference_node.nextSibling; - ++endContainerDepth; - } + if (nextSibling) + parent.insertBefore(node, nextSibling); + else + parent.appendChild(node); - for (c = t[START_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) { - if (p == t[END_CONTAINER]) - return _traverseCommonEndContainer(c, how); + return node; + }); + }, - ++startContainerDepth; - } + replace : function(n, o, k) { + var t = this; - depthDiff = startContainerDepth - endContainerDepth; + if (is(o, 'array')) + n = n.cloneNode(true); - startNode = t[START_CONTAINER]; - while (depthDiff > 0) { - startNode = startNode.parentNode; - depthDiff--; - } + return t.run(o, function(o) { + if (k) { + each(tinymce.grep(o.childNodes), function(c) { + n.appendChild(c); + }); + } - endNode = t[END_CONTAINER]; - while (depthDiff < 0) { - endNode = endNode.parentNode; - depthDiff++; - } + return o.parentNode.replaceChild(n, o); + }); + }, - // ascend the ancestor hierarchy until we have a common parent. - for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) { - startNode = sp; - endNode = ep; - } + rename : function(elm, name) { + var t = this, newElm; - return _traverseCommonAncestors(startNode, endNode, how); - }; + if (elm.nodeName != name.toUpperCase()) { + // Rename block element + newElm = t.create(name); - function _traverseSameContainer(how) { - var frag, s, sub, n, cnt, sibling, xferNode; + // Copy attribs to new block + each(t.getAttribs(elm), function(attr_node) { + t.setAttrib(newElm, attr_node.nodeName, t.getAttrib(elm, attr_node.nodeName)); + }); - if (how != DELETE) - frag = doc.createDocumentFragment(); + // Replace block + t.replace(newElm, elm, 1); + } - // If selection is empty, just return the fragment - if (t[START_OFFSET] == t[END_OFFSET]) - return frag; + return newElm || elm; + }, - // Text node needs special case handling - if (t[START_CONTAINER].nodeType == 3 /* TEXT_NODE */) { - // get the substring - s = t[START_CONTAINER].nodeValue; - sub = s.substring(t[START_OFFSET], t[END_OFFSET]); + findCommonAncestor : function(a, b) { + var ps = a, pe; - // set the original text node to its new value - if (how != CLONE) { - t[START_CONTAINER].deleteData(t[START_OFFSET], t[END_OFFSET] - t[START_OFFSET]); + while (ps) { + pe = b; - // Nothing is partially selected, so collapse to start point - t.collapse(TRUE); - } + while (pe && ps != pe) + pe = pe.parentNode; - if (how == DELETE) - return; + if (ps == pe) + break; - frag.appendChild(doc.createTextNode(sub)); - return frag; + ps = ps.parentNode; } - // Copy nodes between the start/end offsets. - n = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]); - cnt = t[END_OFFSET] - t[START_OFFSET]; + if (!ps && a.ownerDocument) + return a.ownerDocument.documentElement; - while (cnt > 0) { - sibling = n.nextSibling; - xferNode = _traverseFullySelected(n, how); + return ps; + }, - if (frag) - frag.appendChild( xferNode ); + toHex : function(s) { + var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s); - --cnt; - n = sibling; - } + function hex(s) { + s = parseInt(s, 10).toString(16); - // Nothing is partially selected, so collapse to start point - if (how != CLONE) - t.collapse(TRUE); + return s.length > 1 ? s : '0' + s; // 0 -> 00 + }; - return frag; - }; + if (c) { + s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]); - function _traverseCommonStartContainer(endAncestor, how) { - var frag, n, endIdx, cnt, sibling, xferNode; + return s; + } - if (how != DELETE) - frag = doc.createDocumentFragment(); + return s; + }, - n = _traverseRightBoundary(endAncestor, how); + getClasses : function() { + var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov; - if (frag) - frag.appendChild(n); + if (t.classes) + return t.classes; - endIdx = nodeIndex(endAncestor); - cnt = endIdx - t[START_OFFSET]; + function addClasses(s) { + // IE style imports + each(s.imports, function(r) { + addClasses(r); + }); - if (cnt <= 0) { - // Collapse to just before the endAncestor, which - // is partially selected. - if (how != CLONE) { - t.setEndBefore(endAncestor); - t.collapse(FALSE); - } + each(s.cssRules || s.rules, function(r) { + // Real type or fake it on IE + switch (r.type || 1) { + // Rule + case 1: + if (r.selectorText) { + each(r.selectorText.split(','), function(v) { + v = v.replace(/^\s*|\s*$|^\s\./g, ""); - return frag; - } + // Is internal or it doesn't contain a class + if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v)) + return; - n = endAncestor.previousSibling; - while (cnt > 0) { - sibling = n.previousSibling; - xferNode = _traverseFullySelected(n, how); + // Remove everything but class name + ov = v; + v = tinymce._replace(/.*\.([a-z0-9_\-]+).*/i, '$1', v); - if (frag) - frag.insertBefore(xferNode, frag.firstChild); + // Filter classes + if (f && !(v = f(v, ov))) + return; - --cnt; - n = sibling; - } + if (!lo[v]) { + cl.push({'class' : v}); + lo[v] = 1; + } + }); + } + break; - // Collapse to just before the endAncestor, which - // is partially selected. - if (how != CLONE) { - t.setEndBefore(endAncestor); - t.collapse(FALSE); + // Import + case 3: + addClasses(r.styleSheet); + break; + } + }); + }; + + try { + each(t.doc.styleSheets, addClasses); + } catch (ex) { + // Ignore } - return frag; - }; + if (cl.length > 0) + t.classes = cl; - function _traverseCommonEndContainer(startAncestor, how) { - var frag, startIdx, n, cnt, sibling, xferNode; + return cl; + }, - if (how != DELETE) - frag = doc.createDocumentFragment(); + run : function(e, f, s) { + var t = this, o; - n = _traverseLeftBoundary(startAncestor, how); - if (frag) - frag.appendChild(n); + if (t.doc && typeof(e) === 'string') + e = t.get(e); - startIdx = nodeIndex(startAncestor); - ++startIdx; // Because we already traversed it + if (!e) + return false; - cnt = t[END_OFFSET] - startIdx; - n = startAncestor.nextSibling; - while (cnt > 0) { - sibling = n.nextSibling; - xferNode = _traverseFullySelected(n, how); + s = s || this; + if (!e.nodeType && (e.length || e.length === 0)) { + o = []; - if (frag) - frag.appendChild(xferNode); + each(e, function(e, i) { + if (e) { + if (typeof(e) == 'string') + e = t.doc.getElementById(e); - --cnt; - n = sibling; - } + o.push(f.call(s, e, i)); + } + }); - if (how != CLONE) { - t.setStartAfter(startAncestor); - t.collapse(TRUE); + return o; } - return frag; - }; + return f.call(s, e); + }, - function _traverseCommonAncestors(startAncestor, endAncestor, how) { - var n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling; + getAttribs : function(n) { + var o; - if (how != DELETE) - frag = doc.createDocumentFragment(); + n = this.get(n); - n = _traverseLeftBoundary(startAncestor, how); - if (frag) - frag.appendChild(n); + if (!n) + return []; - commonParent = startAncestor.parentNode; - startOffset = nodeIndex(startAncestor); - endOffset = nodeIndex(endAncestor); - ++startOffset; + if (isIE) { + o = []; - cnt = endOffset - startOffset; - sibling = startAncestor.nextSibling; + // Object will throw exception in IE + if (n.nodeName == 'OBJECT') + return n.attributes; - while (cnt > 0) { - nextSibling = sibling.nextSibling; - n = _traverseFullySelected(sibling, how); + // IE doesn't keep the selected attribute if you clone option elements + if (n.nodeName === 'OPTION' && this.getAttrib(n, 'selected')) + o.push({specified : 1, nodeName : 'selected'}); - if (frag) - frag.appendChild(n); + // It's crazy that this is faster in IE but it's because it returns all attributes all the time + n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) { + o.push({specified : 1, nodeName : a}); + }); - sibling = nextSibling; - --cnt; + return o; } - n = _traverseRightBoundary(endAncestor, how); - - if (frag) - frag.appendChild(n); - - if (how != CLONE) { - t.setStartAfter(startAncestor); - t.collapse(TRUE); - } + return n.attributes; + }, - return frag; - }; + isEmpty : function(node, elements) { + var self = this, i, attributes, type, walker, name, brCount = 0; - function _traverseRightBoundary(root, how) { - var next = _getSelectedNode(t[END_CONTAINER], t[END_OFFSET] - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent, isFullySelected = next != t[END_CONTAINER]; + node = node.firstChild; + if (node) { + walker = new tinymce.dom.TreeWalker(node, node.parentNode); + elements = elements || self.schema ? self.schema.getNonEmptyElements() : null; - if (next == root) - return _traverseNode(next, isFullySelected, FALSE, how); + do { + type = node.nodeType; - parent = next.parentNode; - clonedParent = _traverseNode(parent, FALSE, FALSE, how); + if (type === 1) { + // Ignore bogus elements + if (node.getAttribute('data-mce-bogus')) + continue; - while (parent) { - while (next) { - prevSibling = next.previousSibling; - clonedChild = _traverseNode(next, isFullySelected, FALSE, how); + // Keep empty elements like <img /> + name = node.nodeName.toLowerCase(); + if (elements && elements[name]) { + // Ignore single BR elements in blocks like <p><br /></p> or <p><span><br /></span></p> + if (name === 'br') { + brCount++; + continue; + } - if (how != DELETE) - clonedParent.insertBefore(clonedChild, clonedParent.firstChild); + return false; + } - isFullySelected = TRUE; - next = prevSibling; - } + // Keep elements with data-bookmark attributes or name attribute like <a name="1"></a> + attributes = self.getAttribs(node); + i = node.attributes.length; + while (i--) { + name = node.attributes[i].nodeName; + if (name === "name" || name === 'data-mce-bookmark') + return false; + } + } - if (parent == root) - return clonedParent; + // Keep comment nodes + if (type == 8) + return false; - next = parent.previousSibling; - parent = parent.parentNode; + // Keep non whitespace text nodes + if ((type === 3 && !whiteSpaceRegExp.test(node.nodeValue))) + return false; + } while (node = walker.next()); + } - clonedGrandParent = _traverseNode(parent, FALSE, FALSE, how); + return brCount <= 1; + }, - if (how != DELETE) - clonedGrandParent.appendChild(clonedParent); + destroy : function(s) { + var t = this; - clonedParent = clonedGrandParent; - } - }; + t.win = t.doc = t.root = t.events = t.frag = null; - function _traverseLeftBoundary(root, how) { - var next = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]), isFullySelected = next != t[START_CONTAINER], parent, clonedParent, nextSibling, clonedChild, clonedGrandParent; + // Manual destroy then remove unload handler + if (!s) + tinymce.removeUnload(t.destroy); + }, - if (next == root) - return _traverseNode(next, isFullySelected, TRUE, how); + createRng : function() { + var d = this.doc; - parent = next.parentNode; - clonedParent = _traverseNode(parent, FALSE, TRUE, how); + return d.createRange ? d.createRange() : new tinymce.dom.Range(this); + }, - while (parent) { - while (next) { - nextSibling = next.nextSibling; - clonedChild = _traverseNode(next, isFullySelected, TRUE, how); + nodeIndex : function(node, normalized) { + var idx = 0, lastNodeType, lastNode, nodeType; - if (how != DELETE) - clonedParent.appendChild(clonedChild); + if (node) { + for (lastNodeType = node.nodeType, node = node.previousSibling, lastNode = node; node; node = node.previousSibling) { + nodeType = node.nodeType; - isFullySelected = TRUE; - next = nextSibling; + // Normalize text nodes + if (normalized && nodeType == 3) { + if (nodeType == lastNodeType || !node.nodeValue.length) + continue; + } + idx++; + lastNodeType = nodeType; } + } - if (parent == root) - return clonedParent; + return idx; + }, - next = parent.nextSibling; - parent = parent.parentNode; + split : function(pe, e, re) { + var t = this, r = t.createRng(), bef, aft, pa; - clonedGrandParent = _traverseNode(parent, FALSE, TRUE, how); + // W3C valid browsers tend to leave empty nodes to the left/right side of the contents, this makes sense + // but we don't want that in our code since it serves no purpose for the end user + // For example if this is chopped: + // <p>text 1<span><b>CHOP</b></span>text 2</p> + // would produce: + // <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p> + // this function will then trim of empty edges and produce: + // <p>text 1</p><b>CHOP</b><p>text 2</p> + function trim(node) { + var i, children = node.childNodes, type = node.nodeType; - if (how != DELETE) - clonedGrandParent.appendChild(clonedParent); + function surroundedBySpans(node) { + var previousIsSpan = node.previousSibling && node.previousSibling.nodeName == 'SPAN'; + var nextIsSpan = node.nextSibling && node.nextSibling.nodeName == 'SPAN'; + return previousIsSpan && nextIsSpan; + } - clonedParent = clonedGrandParent; - } - }; + if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark') + return; - function _traverseNode(n, isFullySelected, isLeft, how) { - var txtValue, newNodeValue, oldNodeValue, offset, newNode; + for (i = children.length - 1; i >= 0; i--) + trim(children[i]); - if (isFullySelected) - return _traverseFullySelected(n, how); + if (type != 9) { + // Keep non whitespace text nodes + if (type == 3 && node.nodeValue.length > 0) { + // If parent element isn't a block or there isn't any useful contents for example "<p> </p>" + // 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)) + return; + } else if (type == 1) { + // If the only child is a bookmark then move it up + children = node.childNodes; + if (children.length == 1 && children[0] && children[0].nodeType == 1 && children[0].getAttribute('data-mce-type') == 'bookmark') + node.parentNode.insertBefore(children[0], node); - if (n.nodeType == 3 /* TEXT_NODE */) { - txtValue = n.nodeValue; + // Keep non empty elements or img, hr etc + if (children.length || /^(br|hr|input|img)$/i.test(node.nodeName)) + return; + } - if (isLeft) { - offset = t[START_OFFSET]; - newNodeValue = txtValue.substring(offset); - oldNodeValue = txtValue.substring(0, offset); - } else { - offset = t[END_OFFSET]; - newNodeValue = txtValue.substring(0, offset); - oldNodeValue = txtValue.substring(offset); + t.remove(node); } - if (how != CLONE) - n.nodeValue = oldNodeValue; - - if (how == DELETE) - return; - - newNode = n.cloneNode(FALSE); - newNode.nodeValue = newNodeValue; + return node; + }; - return newNode; - } + if (pe && e) { + // Get before chunk + r.setStart(pe.parentNode, t.nodeIndex(pe)); + r.setEnd(e.parentNode, t.nodeIndex(e)); + bef = r.extractContents(); - if (how == DELETE) - return; + // Get after chunk + r = t.createRng(); + r.setStart(e.parentNode, t.nodeIndex(e) + 1); + r.setEnd(pe.parentNode, t.nodeIndex(pe) + 1); + aft = r.extractContents(); - return n.cloneNode(FALSE); - }; + // Insert before chunk + pa = pe.parentNode; + pa.insertBefore(trim(bef), pe); - function _traverseFullySelected(n, how) { - if (how != DELETE) - return how == CLONE ? n.cloneNode(TRUE) : n; + // Insert middle chunk + if (re) + pa.replaceChild(re, e); + else + pa.insertBefore(e, pe); - n.parentNode.removeChild(n); - }; - }; + // Insert after chunk + pa.insertBefore(trim(aft), pe); + t.remove(pe); - ns.Range = Range; -})(tinymce.dom); + return re || e; + } + }, -(function() { - function Selection(selection) { - var self = this, dom = selection.dom, TRUE = true, FALSE = false; + bind : function(target, name, func, scope) { + return this.events.add(target, name, func, scope || this); + }, - function getPosition(rng, start) { - var checkRng, startIndex = 0, endIndex, inside, - children, child, offset, index, position = -1, parent; + unbind : function(target, name, func) { + return this.events.remove(target, name, func); + }, - // Setup test range, collapse it and get the parent - checkRng = rng.duplicate(); - checkRng.collapse(start); - parent = checkRng.parentElement(); + fire : function(target, name, evt) { + return this.events.fire(target, name, evt); + }, - // Check if the selection is within the right document - if (parent.ownerDocument !== selection.dom.doc) - return; + // Returns the content editable state of a node + getContentEditable: function(node) { + var contentEditable; - // IE will report non editable elements as it's parent so look for an editable one - while (parent.contentEditable === "false") { - parent = parent.parentNode; + // Check type + if (node.nodeType != 1) { + return null; } - // If parent doesn't have any children then return that we are inside the element - if (!parent.hasChildNodes()) { - return {node : parent, inside : 1}; + // Check for fake content editable + contentEditable = node.getAttribute("data-mce-contenteditable"); + if (contentEditable && contentEditable !== "inherit") { + return contentEditable; } - // Setup node list and endIndex - children = parent.children; - endIndex = children.length - 1; + // Check for real content editable + return node.contentEditable !== "inherit" ? node.contentEditable : null; + }, - // Perform a binary search for the position - while (startIndex <= endIndex) { - index = Math.floor((startIndex + endIndex) / 2); - // Move selection to node and compare the ranges - child = children[index]; - checkRng.moveToElementText(child); - position = checkRng.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', rng); + _findSib : function(node, selector, name) { + var t = this, f = selector; - // Before/after or an exact match - if (position > 0) { - endIndex = index - 1; - } else if (position < 0) { - startIndex = index + 1; - } else { - return {node : child}; + if (node) { + // If expression make a function of it using is + if (is(f, 'string')) { + f = function(node) { + return t.is(node, selector); + }; + } + + // Loop all siblings + for (node = node[name]; node; node = node[name]) { + if (f(node)) + return node; } } - // Check if child position is before or we didn't find a position - if (position < 0) { - // No element child was found use the parent element and the offset inside that - if (!child) { - checkRng.moveToElementText(parent); - checkRng.collapse(true); - child = parent; - inside = true; - } else - checkRng.collapse(false); + return null; + }, - checkRng.setEndPoint(start ? 'EndToStart' : 'EndToEnd', rng); + _isRes : function(c) { + // Is live resizble element + return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c); + } - // Fix for edge case: <div style="width: 100px; height:100px;"><table>..</table>ab|c</div> - if (checkRng.compareEndPoints(start ? 'StartToStart' : 'StartToEnd', rng) > 0) { - checkRng = rng.duplicate(); - checkRng.collapse(start); + /* + walk : function(n, f, s) { + var d = this.doc, w; - offset = -1; - while (parent == checkRng.parentElement()) { - if (checkRng.move('character', -1) == 0) - break; + if (d.createTreeWalker) { + w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false); - offset++; - } - } + while ((n = w.nextNode()) != null) + f.call(s || this, n); + } else + tinymce.walk(n, f, 'childNodes', s); + } + */ - offset = offset || checkRng.text.replace('\r\n', ' ').length; - } else { - // Child position is after the selection endpoint - checkRng.collapse(true); - checkRng.setEndPoint(start ? 'StartToStart' : 'StartToEnd', rng); + /* + toRGB : function(s) { + var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s); + + if (c) { + // #FFF -> #FFFFFF + if (!is(c[3])) + c[3] = c[2] = c[1]; - // Get the length of the text to find where the endpoint is relative to it's container - offset = checkRng.text.replace('\r\n', ' ').length; + return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")"; } - return {node : child, position : position, offset : offset, inside : inside}; - }; + return s; + } + */ + }); - // Returns a W3C DOM compatible range object by using the IE Range API - function getRange() { - var ieRange = selection.getRng(), domRange = dom.createRng(), element, collapsed, tmpRange, element2, bookmark, fail; + tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0}); +})(tinymce); - // If selection is outside the current document just return an empty range - element = ieRange.item ? ieRange.item(0) : ieRange.parentElement(); - if (element.ownerDocument != dom.doc) - return domRange; +(function(ns) { + // Range constructor + function Range(dom) { + var t = this, + doc = dom.doc, + EXTRACT = 0, + CLONE = 1, + DELETE = 2, + TRUE = true, + FALSE = false, + START_OFFSET = 'startOffset', + START_CONTAINER = 'startContainer', + END_CONTAINER = 'endContainer', + END_OFFSET = 'endOffset', + extend = tinymce.extend, + nodeIndex = dom.nodeIndex; - collapsed = selection.isCollapsed(); + extend(t, { + // Inital states + startContainer : doc, + startOffset : 0, + endContainer : doc, + endOffset : 0, + collapsed : TRUE, + commonAncestorContainer : doc, - // Handle control selection - if (ieRange.item) { - domRange.setStart(element.parentNode, dom.nodeIndex(element)); - domRange.setEnd(domRange.startContainer, domRange.startOffset + 1); + // Range constants + START_TO_START : 0, + START_TO_END : 1, + END_TO_END : 2, + END_TO_START : 3, - return domRange; - } + // Public methods + setStart : setStart, + setEnd : setEnd, + setStartBefore : setStartBefore, + setStartAfter : setStartAfter, + setEndBefore : setEndBefore, + setEndAfter : setEndAfter, + collapse : collapse, + selectNode : selectNode, + selectNodeContents : selectNodeContents, + compareBoundaryPoints : compareBoundaryPoints, + deleteContents : deleteContents, + extractContents : extractContents, + cloneContents : cloneContents, + insertNode : insertNode, + surroundContents : surroundContents, + cloneRange : cloneRange, + toStringIE : toStringIE + }); - function findEndPoint(start) { - var endPoint = getPosition(ieRange, start), container, offset, textNodeOffset = 0, sibling, undef, nodeValue; + function createDocumentFragment() { + return doc.createDocumentFragment(); + }; - container = endPoint.node; - offset = endPoint.offset; + function setStart(n, o) { + _setEndPoint(TRUE, n, o); + }; - if (endPoint.inside && !container.hasChildNodes()) { - domRange[start ? 'setStart' : 'setEnd'](container, 0); - return; - } + function setEnd(n, o) { + _setEndPoint(FALSE, n, o); + }; - if (offset === undef) { - domRange[start ? 'setStartBefore' : 'setEndAfter'](container); - return; - } + function setStartBefore(n) { + setStart(n.parentNode, nodeIndex(n)); + }; - if (endPoint.position < 0) { - sibling = endPoint.inside ? container.firstChild : container.nextSibling; + function setStartAfter(n) { + setStart(n.parentNode, nodeIndex(n) + 1); + }; - if (!sibling) { - domRange[start ? 'setStartAfter' : 'setEndAfter'](container); - return; - } + function setEndBefore(n) { + setEnd(n.parentNode, nodeIndex(n)); + }; - if (!offset) { - if (sibling.nodeType == 3) - domRange[start ? 'setStart' : 'setEnd'](sibling, 0); - else - domRange[start ? 'setStartBefore' : 'setEndBefore'](sibling); + function setEndAfter(n) { + setEnd(n.parentNode, nodeIndex(n) + 1); + }; - return; - } + function collapse(ts) { + if (ts) { + t[END_CONTAINER] = t[START_CONTAINER]; + t[END_OFFSET] = t[START_OFFSET]; + } else { + t[START_CONTAINER] = t[END_CONTAINER]; + t[START_OFFSET] = t[END_OFFSET]; + } - // Find the text node and offset - while (sibling) { - nodeValue = sibling.nodeValue; - textNodeOffset += nodeValue.length; + t.collapsed = TRUE; + }; - // We are at or passed the position we where looking for - if (textNodeOffset >= offset) { - container = sibling; - textNodeOffset -= offset; - textNodeOffset = nodeValue.length - textNodeOffset; - break; - } + function selectNode(n) { + setStartBefore(n); + setEndAfter(n); + }; - sibling = sibling.nextSibling; - } - } else { - // Find the text node and offset - sibling = container.previousSibling; + function selectNodeContents(n) { + setStart(n, 0); + setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length); + }; - if (!sibling) - return domRange[start ? 'setStartBefore' : 'setEndBefore'](container); + function compareBoundaryPoints(h, r) { + var sc = t[START_CONTAINER], so = t[START_OFFSET], ec = t[END_CONTAINER], eo = t[END_OFFSET], + rsc = r.startContainer, rso = r.startOffset, rec = r.endContainer, reo = r.endOffset; - // If there isn't any text to loop then use the first position - if (!offset) { - if (container.nodeType == 3) - domRange[start ? 'setStart' : 'setEnd'](sibling, container.nodeValue.length); - else - domRange[start ? 'setStartAfter' : 'setEndAfter'](sibling); + // Check START_TO_START + if (h === 0) + return _compareBoundaryPoints(sc, so, rsc, rso); + + // Check START_TO_END + if (h === 1) + return _compareBoundaryPoints(ec, eo, rsc, rso); + + // Check END_TO_END + if (h === 2) + return _compareBoundaryPoints(ec, eo, rec, reo); + + // Check END_TO_START + if (h === 3) + return _compareBoundaryPoints(sc, so, rec, reo); + }; - return; - } + function deleteContents() { + _traverse(DELETE); + }; - while (sibling) { - textNodeOffset += sibling.nodeValue.length; + function extractContents() { + return _traverse(EXTRACT); + }; - // We are at or passed the position we where looking for - if (textNodeOffset >= offset) { - container = sibling; - textNodeOffset -= offset; - break; - } + function cloneContents() { + return _traverse(CLONE); + }; - sibling = sibling.previousSibling; - } + function insertNode(n) { + var startContainer = this[START_CONTAINER], + startOffset = this[START_OFFSET], nn, o; + + // Node is TEXT_NODE or CDATA + if ((startContainer.nodeType === 3 || startContainer.nodeType === 4) && startContainer.nodeValue) { + if (!startOffset) { + // At the start of text + startContainer.parentNode.insertBefore(n, startContainer); + } else if (startOffset >= startContainer.nodeValue.length) { + // At the end of text + dom.insertAfter(n, startContainer); + } else { + // Middle, need to split + nn = startContainer.splitText(startOffset); + startContainer.parentNode.insertBefore(n, nn); } + } else { + // Insert element node + if (startContainer.childNodes.length > 0) + o = startContainer.childNodes[startOffset]; - domRange[start ? 'setStart' : 'setEnd'](container, textNodeOffset); - }; + if (o) + startContainer.insertBefore(n, o); + else + startContainer.appendChild(n); + } + }; - try { - // Find start point - findEndPoint(true); + function surroundContents(n) { + var f = t.extractContents(); - // Find end point if needed - if (!collapsed) - findEndPoint(); - } catch (ex) { - // IE has a nasty bug where text nodes might throw "invalid argument" when you - // access the nodeValue or other properties of text nodes. This seems to happend when - // text nodes are split into two nodes by a delete/backspace call. So lets detect it and try to fix it. - if (ex.number == -2147024809) { - // Get the current selection - bookmark = self.getBookmark(2); + t.insertNode(n); + n.appendChild(f); + t.selectNode(n); + }; + + function cloneRange() { + return extend(new Range(dom), { + startContainer : t[START_CONTAINER], + startOffset : t[START_OFFSET], + endContainer : t[END_CONTAINER], + endOffset : t[END_OFFSET], + collapsed : t.collapsed, + commonAncestorContainer : t.commonAncestorContainer + }); + }; - // Get start element - tmpRange = ieRange.duplicate(); - tmpRange.collapse(true); - element = tmpRange.parentElement(); + // Private methods - // Get end element - if (!collapsed) { - tmpRange = ieRange.duplicate(); - tmpRange.collapse(false); - element2 = tmpRange.parentElement(); - element2.innerHTML = element2.innerHTML; - } + function _getSelectedNode(container, offset) { + var child; - // Remove the broken elements - element.innerHTML = element.innerHTML; + if (container.nodeType == 3 /* TEXT_NODE */) + return container; - // Restore the selection - self.moveToBookmark(bookmark); + if (offset < 0) + return container; - // Since the range has moved we need to re-get it - ieRange = selection.getRng(); + child = container.firstChild; + while (child && offset > 0) { + --offset; + child = child.nextSibling; + } - // Find start point - findEndPoint(true); + if (child) + return child; - // Find end point if needed - if (!collapsed) - findEndPoint(); - } else - throw ex; // Throw other errors - } + return container; + }; - return domRange; + function _isCollapsed() { + return (t[START_CONTAINER] == t[END_CONTAINER] && t[START_OFFSET] == t[END_OFFSET]); }; - this.getBookmark = function(type) { - var rng = selection.getRng(), start, end, bookmark = {}; + function _compareBoundaryPoints(containerA, offsetA, containerB, offsetB) { + var c, offsetC, n, cmnRoot, childA, childB; + + // In the first case the boundary-points have the same container. A is before B + // if its offset is less than the offset of B, A is equal to B if its offset is + // equal to the offset of B, and A is after B if its offset is greater than the + // offset of B. + if (containerA == containerB) { + if (offsetA == offsetB) + return 0; // equal - function getIndexes(node) { - var node, parent, root, children, i, indexes = []; + if (offsetA < offsetB) + return -1; // before - parent = node.parentNode; - root = dom.getRoot().parentNode; + return 1; // after + } - while (parent != root && parent.nodeType !== 9) { - children = parent.children; + // In the second case a child node C of the container of A is an ancestor + // container of B. In this case, A is before B if the offset of A is less than or + // equal to the index of the child node C and A is after B otherwise. + c = containerB; + while (c && c.parentNode != containerA) + c = c.parentNode; - i = children.length; - while (i--) { - if (node === children[i]) { - indexes.push(i); - break; - } - } + if (c) { + offsetC = 0; + n = containerA.firstChild; - node = parent; - parent = parent.parentNode; + while (n != c && offsetC < offsetA) { + offsetC++; + n = n.nextSibling; } - return indexes; - }; - - function getBookmarkEndPoint(start) { - var position; - - position = getPosition(rng, start); - if (position) { - return { - position : position.position, - offset : position.offset, - indexes : getIndexes(position.node), - inside : position.inside - }; - } - }; + if (offsetA <= offsetC) + return -1; // before - // Non ubstructive bookmark - if (type === 2) { - // Handle text selection - if (!rng.item) { - bookmark.start = getBookmarkEndPoint(true); + return 1; // after + } - if (!selection.isCollapsed()) - bookmark.end = getBookmarkEndPoint(); - } else - bookmark.start = {ctrl : true, indexes : getIndexes(rng.item(0))}; + // In the third case a child node C of the container of B is an ancestor container + // of A. In this case, A is before B if the index of the child node C is less than + // the offset of B and A is after B otherwise. + c = containerA; + while (c && c.parentNode != containerB) { + c = c.parentNode; } - return bookmark; - }; + if (c) { + offsetC = 0; + n = containerB.firstChild; - this.moveToBookmark = function(bookmark) { - var rng, body = dom.doc.body; + while (n != c && offsetC < offsetB) { + offsetC++; + n = n.nextSibling; + } - function resolveIndexes(indexes) { - var node, i, idx, children; + if (offsetC < offsetB) + return -1; // before - node = dom.getRoot(); - for (i = indexes.length - 1; i >= 0; i--) { - children = node.children; - idx = indexes[i]; + return 1; // after + } - if (idx <= children.length - 1) { - node = children[idx]; - } - } + // In the fourth case, none of three other cases hold: the containers of A and B + // are siblings or descendants of sibling nodes. In this case, A is before B if + // the container of A is before the container of B in a pre-order traversal of the + // Ranges' context tree and A is after B otherwise. + cmnRoot = dom.findCommonAncestor(containerA, containerB); + childA = containerA; - return node; - }; - - function setBookmarkEndPoint(start) { - var endPoint = bookmark[start ? 'start' : 'end'], moveLeft, moveRng, undef; + while (childA && childA.parentNode != cmnRoot) + childA = childA.parentNode; - if (endPoint) { - moveLeft = endPoint.position > 0; + if (!childA) + childA = cmnRoot; - moveRng = body.createTextRange(); - moveRng.moveToElementText(resolveIndexes(endPoint.indexes)); + childB = containerB; + while (childB && childB.parentNode != cmnRoot) + childB = childB.parentNode; - offset = endPoint.offset; - if (offset !== undef) { - moveRng.collapse(endPoint.inside || moveLeft); - moveRng.moveStart('character', moveLeft ? -offset : offset); - } else - moveRng.collapse(start); + if (!childB) + childB = cmnRoot; - rng.setEndPoint(start ? 'StartToStart' : 'EndToStart', moveRng); + if (childA == childB) + return 0; // equal - if (start) - rng.collapse(true); - } - }; + n = cmnRoot.firstChild; + while (n) { + if (n == childA) + return -1; // before - if (bookmark.start) { - if (bookmark.start.ctrl) { - rng = body.createControlRange(); - rng.addElement(resolveIndexes(bookmark.start.indexes)); - rng.select(); - } else { - rng = body.createTextRange(); - setBookmarkEndPoint(true); - setBookmarkEndPoint(); - rng.select(); - } + if (n == childB) + return 1; // after + + n = n.nextSibling; } }; - this.addRange = function(rng) { - var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, doc = selection.dom.doc, body = doc.body; + function _setEndPoint(st, n, o) { + var ec, sc; - function setEndPoint(start) { - var container, offset, marker, tmpRng, nodes; + if (st) { + t[START_CONTAINER] = n; + t[START_OFFSET] = o; + } else { + t[END_CONTAINER] = n; + t[END_OFFSET] = o; + } - marker = dom.create('a'); - container = start ? startContainer : endContainer; - offset = start ? startOffset : endOffset; - tmpRng = ieRng.duplicate(); + // If one boundary-point of a Range is set to have a root container + // other than the current one for the Range, the Range is collapsed to + // the new position. This enforces the restriction that both boundary- + // points of a Range must have the same root container. + ec = t[END_CONTAINER]; + while (ec.parentNode) + ec = ec.parentNode; - if (container == doc || container == doc.documentElement) { - container = body; - offset = 0; - } + sc = t[START_CONTAINER]; + while (sc.parentNode) + sc = sc.parentNode; - if (container.nodeType == 3) { - container.parentNode.insertBefore(marker, container); - tmpRng.moveToElementText(marker); - tmpRng.moveStart('character', offset); - dom.remove(marker); - ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng); - } else { - nodes = container.childNodes; + if (sc == ec) { + // The start position of a Range is guaranteed to never be after the + // end position. To enforce this restriction, if the start is set to + // be at a position after the end, the Range is collapsed to that + // position. + if (_compareBoundaryPoints(t[START_CONTAINER], t[START_OFFSET], t[END_CONTAINER], t[END_OFFSET]) > 0) + t.collapse(st); + } else + t.collapse(st); + + t.collapsed = _isCollapsed(); + t.commonAncestorContainer = dom.findCommonAncestor(t[START_CONTAINER], t[END_CONTAINER]); + }; - if (nodes.length) { - if (offset >= nodes.length) { - dom.insertAfter(marker, nodes[nodes.length - 1]); - } else { - container.insertBefore(marker, nodes[offset]); - } + function _traverse(how) { + var c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep; - tmpRng.moveToElementText(marker); - } else { - // Empty node selection for example <div>|</div> - marker = doc.createTextNode('\uFEFF'); - container.appendChild(marker); - tmpRng.moveToElementText(marker.parentNode); - tmpRng.collapse(TRUE); - } + if (t[START_CONTAINER] == t[END_CONTAINER]) + return _traverseSameContainer(how); - ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng); - dom.remove(marker); - } + for (c = t[END_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) { + if (p == t[START_CONTAINER]) + return _traverseCommonStartContainer(c, how); + + ++endContainerDepth; } - // Setup some shorter versions - startContainer = rng.startContainer; - startOffset = rng.startOffset; - endContainer = rng.endContainer; - endOffset = rng.endOffset; - ieRng = body.createTextRange(); + for (c = t[START_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) { + if (p == t[END_CONTAINER]) + return _traverseCommonEndContainer(c, how); - // If single element selection then try making a control selection out of it - if (startContainer == endContainer && startContainer.nodeType == 1 && startOffset == endOffset - 1) { - if (startOffset == endOffset - 1) { - try { - ctrlRng = body.createControlRange(); - ctrlRng.addElement(startContainer.childNodes[startOffset]); - ctrlRng.select(); - return; - } catch (ex) { - // Ignore - } - } + ++startContainerDepth; } - // Set start/end point of selection - setEndPoint(true); - setEndPoint(); + depthDiff = startContainerDepth - endContainerDepth; - // Select the new range and scroll it into view - ieRng.select(); - }; + startNode = t[START_CONTAINER]; + while (depthDiff > 0) { + startNode = startNode.parentNode; + depthDiff--; + } - // Expose range method - this.getRangeAt = getRange; - }; + endNode = t[END_CONTAINER]; + while (depthDiff < 0) { + endNode = endNode.parentNode; + depthDiff++; + } - // Expose the selection object - tinymce.dom.TridentSelection = Selection; -})(); + // ascend the ancestor hierarchy until we have a common parent. + for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) { + startNode = sp; + endNode = ep; + } + return _traverseCommonAncestors(startNode, endNode, how); + }; -/* - * Sizzle CSS Selector Engine - v1.0 - * Copyright 2009, The Dojo Foundation - * Released under the MIT, BSD, and GPL Licenses. - * More information: http://sizzlejs.com/ - */ -(function(){ - -var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, - done = 0, - toString = Object.prototype.toString, - hasDuplicate = false, - baseHasDuplicate = true; - -// 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(){ - baseHasDuplicate = false; - return 0; -}); + function _traverseSameContainer(how) { + var frag, s, sub, n, cnt, sibling, xferNode, start, len; -var Sizzle = function(selector, context, results, seed) { - results = results || []; - context = context || document; + if (how != DELETE) + frag = createDocumentFragment(); - var origContext = context; + // If selection is empty, just return the fragment + if (t[START_OFFSET] == t[END_OFFSET]) + return frag; - if ( context.nodeType !== 1 && context.nodeType !== 9 ) { - return []; - } - - if ( !selector || typeof selector !== "string" ) { - return results; - } + // Text node needs special case handling + if (t[START_CONTAINER].nodeType == 3 /* TEXT_NODE */) { + // get the substring + s = t[START_CONTAINER].nodeValue; + sub = s.substring(t[START_OFFSET], t[END_OFFSET]); - var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context), - soFar = selector, ret, cur, pop, i; - - // Reset the position of the chunker regexp (start from head) - do { - chunker.exec(""); - m = chunker.exec(soFar); + // set the original text node to its new value + if (how != CLONE) { + n = t[START_CONTAINER]; + start = t[START_OFFSET]; + len = t[END_OFFSET] - t[START_OFFSET]; - if ( m ) { - soFar = m[3]; - - parts.push( m[1] ); - - if ( m[2] ) { - extra = m[3]; - break; - } - } - } while ( m ); + if (start === 0 && len >= n.nodeValue.length - 1) { + n.parentNode.removeChild(n); + } else { + n.deleteData(start, len); + } - if ( parts.length > 1 && origPOS.exec( selector ) ) { - if ( parts.length === 2 && Expr.relative[ parts[0] ] ) { - set = posProcess( parts[0] + parts[1], context ); - } else { - set = Expr.relative[ parts[0] ] ? - [ context ] : - Sizzle( parts.shift(), context ); + // Nothing is partially selected, so collapse to start point + t.collapse(TRUE); + } - while ( parts.length ) { - selector = parts.shift(); + if (how == DELETE) + return; - if ( Expr.relative[ selector ] ) { - selector += parts.shift(); + if (sub.length > 0) { + frag.appendChild(doc.createTextNode(sub)); } - - set = posProcess( selector, set ); + + return frag; } - } - } 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]; - } - 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; + // Copy nodes between the start/end offsets. + n = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]); + cnt = t[END_OFFSET] - t[START_OFFSET]; - if ( parts.length > 0 ) { - checkSet = makeArray(set); - } else { - prune = false; + while (n && cnt > 0) { + sibling = n.nextSibling; + xferNode = _traverseFullySelected(n, how); + + if (frag) + frag.appendChild( xferNode ); + + --cnt; + n = sibling; } - while ( parts.length ) { - cur = parts.pop(); - pop = cur; + // Nothing is partially selected, so collapse to start point + if (how != CLONE) + t.collapse(TRUE); - if ( !Expr.relative[ cur ] ) { - cur = ""; - } else { - pop = parts.pop(); - } + return frag; + }; - if ( pop == null ) { - pop = context; - } + function _traverseCommonStartContainer(endAncestor, how) { + var frag, n, endIdx, cnt, sibling, xferNode; - Expr.relative[ cur ]( checkSet, pop, contextXML ); - } - } else { - checkSet = parts = []; - } - } + if (how != DELETE) + frag = createDocumentFragment(); - if ( !checkSet ) { - checkSet = set; - } + n = _traverseRightBoundary(endAncestor, how); - if ( !checkSet ) { - Sizzle.error( cur || selector ); - } + if (frag) + frag.appendChild(n); - 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 ) { - results.push( set[i] ); + endIdx = nodeIndex(endAncestor); + cnt = endIdx - t[START_OFFSET]; + + if (cnt <= 0) { + // Collapse to just before the endAncestor, which + // is partially selected. + if (how != CLONE) { + t.setEndBefore(endAncestor); + t.collapse(FALSE); } + + return frag; } - } - } else { - makeArray( checkSet, results ); - } - if ( extra ) { - Sizzle( extra, origContext, results, seed ); - Sizzle.uniqueSort( results ); - } + n = endAncestor.previousSibling; + while (cnt > 0) { + sibling = n.previousSibling; + xferNode = _traverseFullySelected(n, how); - return results; -}; + if (frag) + frag.insertBefore(xferNode, frag.firstChild); -Sizzle.uniqueSort = function(results){ - if ( sortOrder ) { - hasDuplicate = baseHasDuplicate; - results.sort(sortOrder); + --cnt; + n = sibling; + } - if ( hasDuplicate ) { - for ( var i = 1; i < results.length; i++ ) { - if ( results[i] === results[i-1] ) { - results.splice(i--, 1); - } + // Collapse to just before the endAncestor, which + // is partially selected. + if (how != CLONE) { + t.setEndBefore(endAncestor); + t.collapse(FALSE); } - } - } - return results; -}; + return frag; + }; -Sizzle.matches = function(expr, set){ - return Sizzle(expr, null, null, set); -}; + function _traverseCommonEndContainer(startAncestor, how) { + var frag, startIdx, n, cnt, sibling, xferNode; -Sizzle.find = function(expr, context, isXML){ - var set; + if (how != DELETE) + frag = createDocumentFragment(); - if ( !expr ) { - return []; - } + n = _traverseLeftBoundary(startAncestor, how); + if (frag) + frag.appendChild(n); - for ( var i = 0, l = Expr.order.length; i < l; i++ ) { - var type = Expr.order[i], match; - - if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { - var left = match[1]; - match.splice(1,1); - - if ( left.substr( left.length - 1 ) !== "\\" ) { - match[1] = (match[1] || "").replace(/\\/g, ""); - set = Expr.find[ type ]( match, context, isXML ); - if ( set != null ) { - expr = expr.replace( Expr.match[ type ], "" ); - break; - } - } - } - } + startIdx = nodeIndex(startAncestor); + ++startIdx; // Because we already traversed it - if ( !set ) { - set = context.getElementsByTagName("*"); - } + cnt = t[END_OFFSET] - startIdx; + n = startAncestor.nextSibling; + while (n && cnt > 0) { + sibling = n.nextSibling; + xferNode = _traverseFullySelected(n, how); - return {set: set, expr: expr}; -}; + if (frag) + frag.appendChild(xferNode); -Sizzle.filter = function(expr, set, inplace, not){ - var old = expr, result = [], curLoop = set, match, anyFound, - isXMLFilter = set && set[0] && Sizzle.isXML(set[0]); + --cnt; + n = sibling; + } - while ( expr && set.length ) { - for ( var type in Expr.filter ) { - if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) { - var filter = Expr.filter[ type ], found, item, left = match[1]; - anyFound = false; + if (how != CLONE) { + t.setStartAfter(startAncestor); + t.collapse(TRUE); + } - match.splice(1,1); + return frag; + }; - if ( left.substr( left.length - 1 ) === "\\" ) { - continue; - } + function _traverseCommonAncestors(startAncestor, endAncestor, how) { + var n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling; - if ( curLoop === result ) { - result = []; - } + if (how != DELETE) + frag = createDocumentFragment(); - if ( Expr.preFilter[ type ] ) { - match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter ); + n = _traverseLeftBoundary(startAncestor, how); + if (frag) + frag.appendChild(n); - if ( !match ) { - anyFound = found = true; - } else if ( match === true ) { - continue; - } - } + commonParent = startAncestor.parentNode; + startOffset = nodeIndex(startAncestor); + endOffset = nodeIndex(endAncestor); + ++startOffset; - if ( match ) { - for ( var i = 0; (item = curLoop[i]) != null; i++ ) { - if ( item ) { - found = filter( item, match, i, curLoop ); - var pass = not ^ !!found; + cnt = endOffset - startOffset; + sibling = startAncestor.nextSibling; - if ( inplace && found != null ) { - if ( pass ) { - anyFound = true; - } else { - curLoop[i] = false; - } - } else if ( pass ) { - result.push( item ); - anyFound = true; - } - } - } - } + while (cnt > 0) { + nextSibling = sibling.nextSibling; + n = _traverseFullySelected(sibling, how); - if ( found !== undefined ) { - if ( !inplace ) { - curLoop = result; - } + if (frag) + frag.appendChild(n); - expr = expr.replace( Expr.match[ type ], "" ); + sibling = nextSibling; + --cnt; + } - if ( !anyFound ) { - return []; - } + n = _traverseRightBoundary(endAncestor, how); - break; - } - } - } + if (frag) + frag.appendChild(n); - // Improper expression - if ( expr === old ) { - if ( anyFound == null ) { - Sizzle.error( expr ); - } else { - break; + if (how != CLONE) { + t.setStartAfter(startAncestor); + t.collapse(TRUE); } - } - old = expr; - } + return frag; + }; - return curLoop; -}; + function _traverseRightBoundary(root, how) { + var next = _getSelectedNode(t[END_CONTAINER], t[END_OFFSET] - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent, isFullySelected = next != t[END_CONTAINER]; -Sizzle.error = function( msg ) { - throw "Syntax error, unrecognized expression: " + msg; -}; + if (next == root) + return _traverseNode(next, isFullySelected, FALSE, how); -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*\]/, - TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/, - CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/, - 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"); - } - }, - relative: { - "+": function(checkSet, part){ - var isPartStr = typeof part === "string", - isTag = isPartStr && !/\W/.test(part), - isPartStrNotTag = isPartStr && !isTag; + parent = next.parentNode; + clonedParent = _traverseNode(parent, FALSE, FALSE, how); - if ( isTag ) { - part = part.toLowerCase(); - } + while (parent) { + while (next) { + prevSibling = next.previousSibling; + clonedChild = _traverseNode(next, isFullySelected, FALSE, how); - for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) { - if ( (elem = checkSet[i]) ) { - while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {} + if (how != DELETE) + clonedParent.insertBefore(clonedChild, clonedParent.firstChild); - checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ? - elem || false : - elem === part; + isFullySelected = TRUE; + next = prevSibling; } - } - if ( isPartStrNotTag ) { - Sizzle.filter( part, checkSet, true ); - } - }, - ">": function(checkSet, part){ - var isPartStr = typeof part === "string", - elem, i = 0, l = checkSet.length; + if (parent == root) + return clonedParent; + + next = parent.previousSibling; + parent = parent.parentNode; - if ( isPartStr && !/\W/.test(part) ) { - part = part.toLowerCase(); + clonedGrandParent = _traverseNode(parent, FALSE, FALSE, how); - 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 : - elem.parentNode === part; - } - } + if (how != DELETE) + clonedGrandParent.appendChild(clonedParent); - if ( isPartStr ) { - Sizzle.filter( part, checkSet, true ); - } + clonedParent = clonedGrandParent; } - }, - "": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck, nodeCheck; + }; - if ( typeof part === "string" && !/\W/.test(part) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } + function _traverseLeftBoundary(root, how) { + var next = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]), isFullySelected = next != t[START_CONTAINER], parent, clonedParent, nextSibling, clonedChild, clonedGrandParent; - checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML); - }, - "~": function(checkSet, part, isXML){ - var doneName = done++, checkFn = dirCheck, nodeCheck; + if (next == root) + return _traverseNode(next, isFullySelected, TRUE, how); - if ( typeof part === "string" && !/\W/.test(part) ) { - part = part.toLowerCase(); - nodeCheck = part; - checkFn = dirNodeCheck; - } + parent = next.parentNode; + clonedParent = _traverseNode(parent, FALSE, TRUE, how); - checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML); - } - }, - find: { - ID: function(match, context, isXML){ - if ( typeof context.getElementById !== "undefined" && !isXML ) { - var m = context.getElementById(match[1]); - return m ? [m] : []; - } - }, - NAME: function(match, context){ - if ( typeof context.getElementsByName !== "undefined" ) { - var ret = [], results = context.getElementsByName(match[1]); + while (parent) { + while (next) { + nextSibling = next.nextSibling; + clonedChild = _traverseNode(next, isFullySelected, TRUE, how); - for ( var i = 0, l = results.length; i < l; i++ ) { - if ( results[i].getAttribute("name") === match[1] ) { - ret.push( results[i] ); - } + if (how != DELETE) + clonedParent.appendChild(clonedChild); + + isFullySelected = TRUE; + next = nextSibling; } - return ret.length === 0 ? null : ret; - } - }, - TAG: function(match, context){ - return context.getElementsByTagName(match[1]); - } - }, - preFilter: { - CLASS: function(match, curLoop, inplace, result, not, isXML){ - match = " " + match[1].replace(/\\/g, "") + " "; + if (parent == root) + return clonedParent; - if ( isXML ) { - return match; - } + next = parent.nextSibling; + parent = parent.parentNode; - 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 ( !inplace ) { - result.push( elem ); - } - } else if ( inplace ) { - curLoop[i] = false; - } - } - } + clonedGrandParent = _traverseNode(parent, FALSE, TRUE, how); - return false; - }, - ID: function(match){ - return match[1].replace(/\\/g, ""); - }, - TAG: function(match, curLoop){ - return match[1].toLowerCase(); - }, - CHILD: function(match){ - if ( match[1] === "nth" ) { - // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6' - var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec( - match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" || - !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]); + if (how != DELETE) + clonedGrandParent.appendChild(clonedParent); - // calculate the numbers (first)n+(last) including if they are negative - match[2] = (test[1] + (test[2] || 1)) - 0; - match[3] = test[3] - 0; + clonedParent = clonedGrandParent; } + }; - // TODO: Move to normal caching system - match[0] = done++; + function _traverseNode(n, isFullySelected, isLeft, how) { + var txtValue, newNodeValue, oldNodeValue, offset, newNode; - return match; - }, - ATTR: function(match, curLoop, inplace, result, not, isXML){ - var name = match[1].replace(/\\/g, ""); - - if ( !isXML && Expr.attrMap[name] ) { - match[1] = Expr.attrMap[name]; - } + if (isFullySelected) + return _traverseFullySelected(n, how); - if ( match[2] === "~=" ) { - match[4] = " " + match[4] + " "; - } + if (n.nodeType == 3 /* TEXT_NODE */) { + txtValue = n.nodeValue; - return match; - }, - 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); + if (isLeft) { + offset = t[START_OFFSET]; + newNodeValue = txtValue.substring(offset); + oldNodeValue = txtValue.substring(0, offset); } 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){ - match.unshift( true ); - return match; - } - }, - filters: { - enabled: function(elem){ - return elem.disabled === false && elem.type !== "hidden"; - }, - disabled: function(elem){ - return elem.disabled === true; - }, - checked: function(elem){ - return elem.checked === true; - }, - selected: function(elem){ - // Accessing this property makes selected-by-default - // options in Safari work properly - elem.parentNode.selectedIndex; - return elem.selected === true; - }, - parent: function(elem){ - return !!elem.firstChild; - }, - empty: function(elem){ - return !elem.firstChild; - }, - has: function(elem, i, match){ - return !!Sizzle( match[3], elem ).length; - }, - header: function(elem){ - return (/h\d/i).test( elem.nodeName ); - }, - text: function(elem){ - return "text" === elem.type; - }, - radio: function(elem){ - return "radio" === elem.type; - }, - checkbox: function(elem){ - return "checkbox" === elem.type; - }, - file: function(elem){ - return "file" === elem.type; - }, - password: function(elem){ - return "password" === elem.type; - }, - submit: function(elem){ - return "submit" === elem.type; - }, - image: function(elem){ - return "image" === elem.type; - }, - reset: function(elem){ - return "reset" === elem.type; - }, - button: function(elem){ - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; - }, - input: function(elem){ - return (/input|select|textarea|button/i).test(elem.nodeName); - } - }, - setFilters: { - first: function(elem, i){ - return i === 0; - }, - last: function(elem, i, match, array){ - return i === array.length - 1; - }, - even: function(elem, i){ - return i % 2 === 0; - }, - odd: function(elem, i){ - return i % 2 === 1; - }, - lt: function(elem, i, match){ - return i < match[3] - 0; - }, - gt: function(elem, i, match){ - return i > match[3] - 0; - }, - nth: function(elem, i, match){ - return match[3] - 0 === i; - }, - 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 ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } else if ( name === "contains" ) { - return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0; - } else if ( name === "not" ) { - var not = match[3]; - - for ( var j = 0, l = not.length; j < l; j++ ) { - if ( not[j] === elem ) { - return false; - } + offset = t[END_OFFSET]; + newNodeValue = txtValue.substring(0, offset); + oldNodeValue = txtValue.substring(offset); } - return true; - } else { - Sizzle.error( "Syntax error, unrecognized expression: " + 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; - } - } - if ( type === "first" ) { - return true; - } - node = elem; - case 'last': - while ( (node = node.nextSibling) ) { - if ( node.nodeType === 1 ) { - return false; - } - } - return true; - case 'nth': - var first = match[2], last = match[3]; + if (how != CLONE) + n.nodeValue = oldNodeValue; - if ( first === 1 && last === 0 ) { - return true; - } - - var doneName = match[0], - parent = elem.parentNode; - - if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) { - var count = 0; - for ( node = parent.firstChild; node; node = node.nextSibling ) { - if ( node.nodeType === 1 ) { - node.nodeIndex = ++count; - } - } - parent.sizcache = doneName; - } - - var diff = elem.nodeIndex - last; - if ( first === 0 ) { - return diff === 0; - } else { - return ( diff % first === 0 && diff / first >= 0 ); - } - } - }, - 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; - }, - CLASS: function(elem, match){ - return (" " + (elem.className || elem.getAttribute("class")) + " ") - .indexOf( match ) > -1; - }, - ATTR: function(elem, match){ - var name = match[1], - result = Expr.attrHandle[ name ] ? - Expr.attrHandle[ name ]( elem ) : - elem[ name ] != null ? - elem[ name ] : - elem.getAttribute( name ), - value = result + "", - type = match[2], - check = match[4]; - - return result == null ? - type === "!=" : - type === "=" ? - value === check : - type === "*=" ? - value.indexOf(check) >= 0 : - type === "~=" ? - (" " + value + " ").indexOf(check) >= 0 : - !check ? - value && result !== false : - type === "!=" ? - value !== check : - type === "^=" ? - value.indexOf(check) === 0 : - type === "$=" ? - value.substr(value.length - check.length) === check : - type === "|=" ? - value === check || value.substr(0, check.length + 1) === check + "-" : - false; - }, - POS: function(elem, match, i, array){ - var name = match[2], filter = Expr.setFilters[ name ]; - - if ( filter ) { - return filter( elem, i, match, array ); - } - } - } -}; + if (how == DELETE) + return; -var origPOS = Expr.match.POS, - fescape = function(all, num){ - return "\\" + (num - 0 + 1); - }; + newNode = dom.clone(n, FALSE); + newNode.nodeValue = newNodeValue; -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) ); -} + return newNode; + } -var makeArray = function(array, results) { - array = Array.prototype.slice.call( array, 0 ); + if (how == DELETE) + return; - if ( results ) { - results.push.apply( results, array ); - return results; - } - - return array; -}; + return dom.clone(n, FALSE); + }; -// Perform a simple check to determine if the browser is capable of -// converting a NodeList to an array using builtin methods. -// Also verifies that the returned array holds DOM nodes -// (which is not the case in the Blackberry browser) -try { - Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType; + function _traverseFullySelected(n, how) { + if (how != DELETE) + return how == CLONE ? dom.clone(n, TRUE) : n; -// Provide a fallback method if it does not work -} catch(e){ - makeArray = function(array, results) { - var ret = results || [], i = 0; + n.parentNode.removeChild(n); + }; - 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] ); - } - } + function toStringIE() { + return dom.create('body', null, cloneContents()).outerText; } - - return ret; + + return t; }; -} - -var sortOrder; -if ( document.documentElement.compareDocumentPosition ) { - sortOrder = function( a, b ) { - if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.compareDocumentPosition ? -1 : 1; - } + ns.Range = Range; - var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; - if ( ret === 0 ) { - hasDuplicate = true; - } - return ret; + // Older IE versions doesn't let you override toString by it's constructor so we have to stick it in the prototype + Range.prototype.toString = function() { + return this.toStringIE(); }; -} else if ( "sourceIndex" in document.documentElement ) { - sortOrder = function( a, b ) { - if ( !a.sourceIndex || !b.sourceIndex ) { - if ( a == b ) { - hasDuplicate = true; - } - return a.sourceIndex ? -1 : 1; - } +})(tinymce.dom); - 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; - } +(function() { + function Selection(selection) { + var self = this, dom = selection.dom, TRUE = true, FALSE = false; - 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; - } - return ret; - }; -} + function getPosition(rng, start) { + var checkRng, startIndex = 0, endIndex, inside, + children, child, offset, index, position = -1, parent; + + // Setup test range, collapse it and get the parent + checkRng = rng.duplicate(); + checkRng.collapse(start); + parent = checkRng.parentElement(); -// Utility function for retreiving the text value of an array of DOM nodes -Sizzle.getText = function( elems ) { - var ret = "", elem; + // Check if the selection is within the right document + if (parent.ownerDocument !== selection.dom.doc) + return; - for ( var i = 0; elems[i]; i++ ) { - elem = elems[i]; + // IE will report non editable elements as it's parent so look for an editable one + while (parent.contentEditable === "false") { + parent = parent.parentNode; + } - // Get the text from text nodes and CDATA nodes - if ( elem.nodeType === 3 || elem.nodeType === 4 ) { - ret += elem.nodeValue; + // If parent doesn't have any children then return that we are inside the element + if (!parent.hasChildNodes()) { + return {node : parent, inside : 1}; + } - // Traverse everything else, except comment nodes - } else if ( elem.nodeType !== 8 ) { - ret += Sizzle.getText( elem.childNodes ); - } - } + // Setup node list and endIndex + children = parent.children; + endIndex = children.length - 1; - return ret; -}; + // Perform a binary search for the position + while (startIndex <= endIndex) { + index = Math.floor((startIndex + endIndex) / 2); + + // Move selection to node and compare the ranges + child = children[index]; + checkRng.moveToElementText(child); + position = checkRng.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', rng); -// 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(); - 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){ - 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 : []; + // Before/after or an exact match + if (position > 0) { + endIndex = index - 1; + } else if (position < 0) { + startIndex = index + 1; + } else { + return {node : child}; + } } - }; - - 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 -})(); - -(function(){ - // Check to see if the browser returns only elements - // when doing getElementsByTagName("*") - // Create a fake element - var div = document.createElement("div"); - div.appendChild( document.createComment("") ); + // Check if child position is before or we didn't find a position + if (position < 0) { + // No element child was found use the parent element and the offset inside that + if (!child) { + checkRng.moveToElementText(parent); + checkRng.collapse(true); + child = parent; + inside = true; + } else + checkRng.collapse(false); - // Make sure no comments are found - if ( div.getElementsByTagName("*").length > 0 ) { - Expr.find.TAG = function(match, context){ - var results = context.getElementsByTagName(match[1]); + // 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 + // 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()) { + break; + } - // Filter out possible comments - if ( match[1] === "*" ) { - var tmp = []; + offset++; + } + } else { + // Child position is after the selection endpoint + checkRng.collapse(true); - for ( var i = 0; results[i]; i++ ) { - if ( results[i].nodeType === 1 ) { - tmp.push( results[i] ); + // 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()) { + break; } - } - results = tmp; + offset++; + } } - return results; + return {node : child, position : position, offset : offset, inside : inside}; }; - } - // 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); - }; - } + // Returns a W3C DOM compatible range object by using the IE Range API + function getRange() { + var ieRange = selection.getRng(), domRange = dom.createRng(), element, collapsed, tmpRange, element2, bookmark, fail; - div = null; // release memory in IE -})(); + // If selection is outside the current document just return an empty range + element = ieRange.item ? ieRange.item(0) : ieRange.parentElement(); + if (element.ownerDocument != dom.doc) + return domRange; -if ( document.querySelectorAll ) { - (function(){ - var oldSizzle = Sizzle, div = document.createElement("div"); - div.innerHTML = "<p class='TEST'></p>"; + collapsed = selection.isCollapsed(); - // Safari can't handle uppercase or unicode characters when - // in quirks mode. - if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { - return; - } - - Sizzle = function(query, context, extra, seed){ - context = context || document; + // Handle control selection + if (ieRange.item) { + domRange.setStart(element.parentNode, dom.nodeIndex(element)); + domRange.setEnd(domRange.startContainer, domRange.startOffset + 1); - // 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){} + return domRange; } - - return oldSizzle(query, context, extra, seed); - }; - - for ( var prop in oldSizzle ) { - Sizzle[ prop ] = oldSizzle[ prop ]; - } - - div = null; // release memory in IE - })(); -} - -(function(){ - var div = document.createElement("div"); - - div.innerHTML = "<div class='test e'></div><div class='test'></div>"; - - // Opera can't find a second classname (in 9.6) - // Also, make sure that getElementsByClassName actually exists - if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) { - return; - } - - // Safari caches class attributes, doesn't catch changes (in 3.2) - div.lastChild.className = "e"; - - if ( div.getElementsByClassName("e").length === 1 ) { - return; - } - - Expr.order.splice(1, 0, "CLASS"); - Expr.find.CLASS = function(match, context, isXML) { - if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) { - return context.getElementsByClassName(match[1]); - } - }; - div = null; // release memory in IE -})(); + function findEndPoint(start) { + var endPoint = getPosition(ieRange, start), container, offset, textNodeOffset = 0, sibling, undef, nodeValue; -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; + container = endPoint.node; + offset = endPoint.offset; - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; + if (endPoint.inside && !container.hasChildNodes()) { + domRange[start ? 'setStart' : 'setEnd'](container, 0); + return; } - if ( elem.nodeType === 1 && !isXML ){ - elem.sizcache = doneName; - elem.sizset = i; + if (offset === undef) { + domRange[start ? 'setStartBefore' : 'setEndAfter'](container); + return; } - if ( elem.nodeName.toLowerCase() === cur ) { - match = elem; - break; - } + if (endPoint.position < 0) { + sibling = endPoint.inside ? container.firstChild : container.nextSibling; - elem = elem[dir]; - } + if (!sibling) { + domRange[start ? 'setStartAfter' : 'setEndAfter'](container); + return; + } - checkSet[i] = match; - } - } -} - -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; - - while ( elem ) { - if ( elem.sizcache === doneName ) { - match = checkSet[elem.sizset]; - break; - } + if (!offset) { + if (sibling.nodeType == 3) + domRange[start ? 'setStart' : 'setEnd'](sibling, 0); + else + domRange[start ? 'setStartBefore' : 'setEndBefore'](sibling); - if ( elem.nodeType === 1 ) { - if ( !isXML ) { - elem.sizcache = doneName; - elem.sizset = i; + return; } - if ( typeof cur !== "string" ) { - if ( elem === cur ) { - match = true; + + // Find the text node and offset + while (sibling) { + nodeValue = sibling.nodeValue; + textNodeOffset += nodeValue.length; + + // We are at or passed the position we where looking for + if (textNodeOffset >= offset) { + container = sibling; + textNodeOffset -= offset; + textNodeOffset = nodeValue.length - textNodeOffset; break; } - } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) { - match = elem; - break; + sibling = sibling.nextSibling; } - } - - elem = elem[dir]; - } - - checkSet[i] = match; - } - } -} - -Sizzle.contains = document.compareDocumentPosition ? function(a, b){ - return !!(a.compareDocumentPosition(b) & 16); -} : function(a, b){ - return a !== b && (a.contains ? a.contains(b) : true); -}; + } else { + // Find the text node and offset + sibling = container.previousSibling; -Sizzle.isXML = function(elem){ - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; + if (!sibling) + return domRange[start ? 'setStartBefore' : 'setEndBefore'](container); -var posProcess = function(selector, context){ - var tmpSet = [], later = "", match, - root = context.nodeType ? [context] : context; + // If there isn't any text to loop then use the first position + if (!offset) { + if (container.nodeType == 3) + domRange[start ? 'setStart' : 'setEnd'](sibling, container.nodeValue.length); + else + domRange[start ? 'setStartAfter' : 'setEndAfter'](sibling); - // Position selectors must be done after the filter - // And so must :not(positional) so we move all PSEUDOs to the end - while ( (match = Expr.match.PSEUDO.exec( selector )) ) { - later += match[0]; - selector = selector.replace( Expr.match.PSEUDO, "" ); - } + return; + } - selector = Expr.relative[selector] ? selector + "*" : selector; + while (sibling) { + textNodeOffset += sibling.nodeValue.length; - for ( var i = 0, l = root.length; i < l; i++ ) { - Sizzle( selector, root[i], tmpSet ); - } + // We are at or passed the position we where looking for + if (textNodeOffset >= offset) { + container = sibling; + textNodeOffset -= offset; + break; + } - return Sizzle.filter( later, tmpSet ); -}; + sibling = sibling.previousSibling; + } + } -// EXPOSE + domRange[start ? 'setStart' : 'setEnd'](container, textNodeOffset); + }; -window.tinymce.dom.Sizzle = Sizzle; + try { + // Find start point + findEndPoint(true); -})(); + // Find end point if needed + if (!collapsed) + findEndPoint(); + } catch (ex) { + // IE has a nasty bug where text nodes might throw "invalid argument" when you + // access the nodeValue or other properties of text nodes. This seems to happend when + // text nodes are split into two nodes by a delete/backspace call. So lets detect it and try to fix it. + if (ex.number == -2147024809) { + // Get the current selection + bookmark = self.getBookmark(2); + // Get start element + tmpRange = ieRange.duplicate(); + tmpRange.collapse(true); + element = tmpRange.parentElement(); -(function(tinymce) { - // Shorten names - var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event; + // Get end element + if (!collapsed) { + tmpRange = ieRange.duplicate(); + tmpRange.collapse(false); + element2 = tmpRange.parentElement(); + element2.innerHTML = element2.innerHTML; + } - tinymce.create('tinymce.dom.EventUtils', { - EventUtils : function() { - this.inits = []; - this.events = []; - }, + // Remove the broken elements + element.innerHTML = element.innerHTML; - add : function(o, n, f, s) { - var cb, t = this, el = t.events, r; + // Restore the selection + self.moveToBookmark(bookmark); - if (n instanceof Array) { - r = []; + // Since the range has moved we need to re-get it + ieRange = selection.getRng(); - each(n, function(n) { - r.push(t.add(o, n, f, s)); - }); + // Find start point + findEndPoint(true); - return r; + // Find end point if needed + if (!collapsed) + findEndPoint(); + } else + throw ex; // Throw other errors } - // Handle array - if (o && o.hasOwnProperty && o instanceof Array) { - r = []; - - each(o, function(o) { - o = DOM.get(o); - r.push(t.add(o, n, f, s)); - }); - - return r; - } + return domRange; + }; - o = DOM.get(o); + this.getBookmark = function(type) { + var rng = selection.getRng(), start, end, bookmark = {}; - if (!o) - return; + function getIndexes(node) { + var parent, root, children, i, indexes = []; - // Setup event callback - cb = function(e) { - // Is all events disabled - if (t.disabled) - return; + parent = node.parentNode; + root = dom.getRoot().parentNode; - e = e || window.event; + while (parent != root && parent.nodeType !== 9) { + children = parent.children; - // Patch in target, preventDefault and stopPropagation in IE it's W3C valid - if (e && isIE) { - if (!e.target) - e.target = e.srcElement; + i = children.length; + while (i--) { + if (node === children[i]) { + indexes.push(i); + break; + } + } - // Patch in preventDefault, stopPropagation methods for W3C compatibility - tinymce.extend(e, t._stoppers); + node = parent; + parent = parent.parentNode; } - if (!s) - return f(e); - - return f.call(s, e); + return indexes; }; - if (n == 'unload') { - tinymce.unloads.unshift({func : cb}); - return cb; - } - - if (n == 'init') { - if (t.domLoaded) - cb(); - else - t.inits.push(cb); - - return cb; - } - - // Store away listener reference - el.push({ - obj : o, - name : n, - func : f, - cfunc : cb, - scope : s - }); - - t._add(o, n, cb); - - return f; - }, - - remove : function(o, n, f) { - var t = this, a = t.events, s = false, r; + function getBookmarkEndPoint(start) { + var position; - // Handle array - if (o && o.hasOwnProperty && o instanceof Array) { - r = []; + position = getPosition(rng, start); + if (position) { + return { + position : position.position, + offset : position.offset, + indexes : getIndexes(position.node), + inside : position.inside + }; + } + }; - each(o, function(o) { - o = DOM.get(o); - r.push(t.remove(o, n, f)); - }); + // Non ubstructive bookmark + if (type === 2) { + // Handle text selection + if (!rng.item) { + bookmark.start = getBookmarkEndPoint(true); - return r; + if (!selection.isCollapsed()) + bookmark.end = getBookmarkEndPoint(); + } else + bookmark.start = {ctrl : true, indexes : getIndexes(rng.item(0))}; } - o = DOM.get(o); - - each(a, function(e, i) { - if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) { - a.splice(i, 1); - t._remove(o, n, e.cfunc); - s = true; - return false; - } - }); - - return s; - }, + return bookmark; + }; - clear : function(o) { - var t = this, a = t.events, i, e; + this.moveToBookmark = function(bookmark) { + var rng, body = dom.doc.body; - if (o) { - o = DOM.get(o); + function resolveIndexes(indexes) { + var node, i, idx, children; - for (i = a.length - 1; i >= 0; i--) { - e = a[i]; + node = dom.getRoot(); + for (i = indexes.length - 1; i >= 0; i--) { + children = node.children; + idx = indexes[i]; - if (e.obj === o) { - t._remove(e.obj, e.name, e.cfunc); - e.obj = e.cfunc = null; - a.splice(i, 1); + if (idx <= children.length - 1) { + node = children[idx]; } } - } - }, - - cancel : function(e) { - if (!e) - return false; - this.stop(e); + return node; + }; + + function setBookmarkEndPoint(start) { + var endPoint = bookmark[start ? 'start' : 'end'], moveLeft, moveRng, undef; - return this.prevent(e); - }, + if (endPoint) { + moveLeft = endPoint.position > 0; - stop : function(e) { - if (e.stopPropagation) - e.stopPropagation(); - else - e.cancelBubble = true; + moveRng = body.createTextRange(); + moveRng.moveToElementText(resolveIndexes(endPoint.indexes)); - return false; - }, + offset = endPoint.offset; + if (offset !== undef) { + moveRng.collapse(endPoint.inside || moveLeft); + moveRng.moveStart('character', moveLeft ? -offset : offset); + } else + moveRng.collapse(start); - prevent : function(e) { - if (e.preventDefault) - e.preventDefault(); - else - e.returnValue = false; + rng.setEndPoint(start ? 'StartToStart' : 'EndToStart', moveRng); - return false; - }, + if (start) + rng.collapse(true); + } + }; - destroy : function() { - var t = this; + if (bookmark.start) { + if (bookmark.start.ctrl) { + rng = body.createControlRange(); + rng.addElement(resolveIndexes(bookmark.start.indexes)); + rng.select(); + } else { + rng = body.createTextRange(); + setBookmarkEndPoint(true); + setBookmarkEndPoint(); + rng.select(); + } + } + }; - each(t.events, function(e, i) { - t._remove(e.obj, e.name, e.cfunc); - e.obj = e.cfunc = null; - }); + this.addRange = function(rng) { + var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, sibling, + doc = selection.dom.doc, body = doc.body, nativeRng, ctrlElm; - t.events = []; - t = null; - }, + function setEndPoint(start) { + var container, offset, marker, tmpRng, nodes; - _add : function(o, n, f) { - if (o.attachEvent) - o.attachEvent('on' + n, f); - else if (o.addEventListener) - o.addEventListener(n, f, false); - else - o['on' + n] = f; - }, + marker = dom.create('a'); + container = start ? startContainer : endContainer; + offset = start ? startOffset : endOffset; + tmpRng = ieRng.duplicate(); - _remove : function(o, n, f) { - if (o) { - try { - if (o.detachEvent) - o.detachEvent('on' + n, f); - else if (o.removeEventListener) - o.removeEventListener(n, f, false); - else - o['on' + n] = null; - } catch (ex) { - // Might fail with permission denined on IE so we just ignore that + if (container == doc || container == doc.documentElement) { + container = body; + offset = 0; } - } - }, - - _pageInit : function(win) { - var t = this; - // Keep it from running more than once - if (t.domLoaded) - return; + if (container.nodeType == 3) { + container.parentNode.insertBefore(marker, container); + tmpRng.moveToElementText(marker); + tmpRng.moveStart('character', offset); + dom.remove(marker); + ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng); + } else { + nodes = container.childNodes; - t.domLoaded = true; + if (nodes.length) { + if (offset >= nodes.length) { + dom.insertAfter(marker, nodes[nodes.length - 1]); + } else { + container.insertBefore(marker, nodes[offset]); + } - each(t.inits, function(c) { - c(); - }); + tmpRng.moveToElementText(marker); + } else if (container.canHaveHTML) { + // Empty node selection for example <div>|</div> + // Setting innerHTML with a span marker then remove that marker seems to keep empty block elements open + container.innerHTML = '<span>\uFEFF</span>'; + marker = container.firstChild; + tmpRng.moveToElementText(marker); + tmpRng.collapse(FALSE); // Collapse false works better than true for some odd reason + } - t.inits = []; - }, + ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng); + dom.remove(marker); + } + } - _wait : function(win) { - var t = this, doc = win.document; + // Setup some shorter versions + startContainer = rng.startContainer; + startOffset = rng.startOffset; + endContainer = rng.endContainer; + endOffset = rng.endOffset; + ieRng = body.createTextRange(); - // No need since the document is already loaded - if (win.tinyMCE_GZ && tinyMCE_GZ.loaded) { - t.domLoaded = 1; - return; - } + // 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 (startOffset == endOffset && !startContainer.hasChildNodes()) { + if (startContainer.canHaveHTML) { + // Check if previous sibling is an empty block if it is then we need to render it + // IE would otherwise move the caret into the sibling instead of the empty startContainer see: #5236 + // Example this: <p></p><p>|</p> would become this: <p>|</p><p></p> + sibling = startContainer.previousSibling; + if (sibling && !sibling.hasChildNodes() && dom.isBlock(sibling)) { + sibling.innerHTML = '\uFEFF'; + } else { + sibling = null; + } - // When loaded asynchronously, the DOM Content may already be loaded - if (doc.readyState === 'complete') { - t._pageInit(win); - return; - } + startContainer.innerHTML = '<span>\uFEFF</span><span>\uFEFF</span>'; + ieRng.moveToElementText(startContainer.lastChild); + ieRng.select(); + dom.doc.selection.clear(); + startContainer.innerHTML = ''; - // Use IE method - if (doc.attachEvent) { - doc.attachEvent("onreadystatechange", function() { - if (doc.readyState === "complete") { - doc.detachEvent("onreadystatechange", arguments.callee); - t._pageInit(win); + if (sibling) { + sibling.innerHTML = ''; + } + return; + } else { + startOffset = dom.nodeIndex(startContainer); + startContainer = startContainer.parentNode; } - }); + } - if (doc.documentElement.doScroll && win == win.top) { - (function() { - if (t.domLoaded) - return; + if (startOffset == endOffset - 1) { + try { + ctrlElm = startContainer.childNodes[startOffset]; + ctrlRng = body.createControlRange(); + ctrlRng.addElement(ctrlElm); + ctrlRng.select(); - try { - // If IE is used, use the trick by Diego Perini licensed under MIT by request to the author. - // http://javascript.nwbox.com/IEContentLoaded/ - doc.documentElement.doScroll("left"); - } catch (ex) { - setTimeout(arguments.callee, 0); + // Check if the range produced is on the correct element and is a control range + // On IE 8 it will select the parent contentEditable container if you select an inner element see: #5398 + nativeRng = selection.getRng(); + if (nativeRng.item && ctrlElm === nativeRng.item(0)) { return; } - - t._pageInit(win); - })(); + } catch (ex) { + // Ignore + } } - } else if (doc.addEventListener) { - t._add(win, 'DOMContentLoaded', function() { - t._pageInit(win); - }); } - t._add(win, 'load', function() { - t._pageInit(win); - }); - }, - - _stoppers : { - preventDefault : function() { - this.returnValue = false; - }, + // Set start/end point of selection + setEndPoint(true); + setEndPoint(); - stopPropagation : function() { - this.cancelBubble = true; - } - } - }); + // Select the new range and scroll it into view + ieRng.select(); + }; - Event = tinymce.dom.Event = new tinymce.dom.EventUtils(); + // Expose range method + this.getRangeAt = getRange; + }; - // Dispatch DOM content loaded event for IE and Safari - Event._wait(window); + // Expose the selection object + tinymce.dom.TridentSelection = Selection; +})(); - tinymce.addUnload(function() { - Event.destroy(); - }); -})(tinymce); (function(tinymce) { tinymce.dom.Element = function(id, settings) { @@ -7376,20 +7978,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) { @@ -7475,15 +8077,16 @@ 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) { + Selection : function(dom, win, serializer, editor) { var t = this; t.dom = dom; t.win = win; t.serializer = serializer; + t.editor = editor; // Add events each([ @@ -7582,7 +8185,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 @@ -7639,7 +8242,7 @@ window.tinymce.dom.Sizzle = Sizzle; }, getStart : function() { - var rng = this.getRng(), startElement, parentElement, checkRng, node; + var self = this, rng = self.getRng(), startElement, parentElement, checkRng, node; if (rng.duplicate || rng.item) { // Control selection, return first item @@ -7650,6 +8253,9 @@ window.tinymce.dom.Sizzle = Sizzle; checkRng = rng.duplicate(); checkRng.collapse(1); startElement = checkRng.parentElement(); + if (startElement.ownerDocument !== self.dom.doc) { + startElement = self.dom.getRoot(); + } // Check if range parent is inside the start element, then return the inner parent element // This will fix issues when a single element is selected, IE would otherwise return the wrong start element @@ -7676,31 +8282,34 @@ window.tinymce.dom.Sizzle = Sizzle; }, getEnd : function() { - var t = this, r = t.getRng(), e, eo; + var self = this, rng = self.getRng(), endElement, endOffset; - if (r.duplicate || r.item) { - if (r.item) - return r.item(0); + if (rng.duplicate || rng.item) { + if (rng.item) + return rng.item(0); - r = r.duplicate(); - r.collapse(0); - e = r.parentElement(); + rng = rng.duplicate(); + rng.collapse(0); + endElement = rng.parentElement(); + if (endElement.ownerDocument !== self.dom.doc) { + endElement = self.dom.getRoot(); + } - if (e && e.nodeName == 'BODY') - return e.lastChild || e; + if (endElement && endElement.nodeName == 'BODY') + return endElement.lastChild || endElement; - return e; + return endElement; } else { - e = r.endContainer; - eo = r.endOffset; + endElement = rng.endContainer; + endOffset = rng.endOffset; - if (e.nodeType == 1 && e.hasChildNodes()) - e = e.childNodes[eo > 0 ? eo - 1 : eo]; + if (endElement.nodeType == 1 && endElement.hasChildNodes()) + endElement = endElement.childNodes[endOffset > 0 ? endOffset - 1 : endOffset]; - if (e && e.nodeType == 3) - return e.parentNode; + if (endElement && endElement.nodeType == 3) + return endElement.parentNode; - return e; + return endElement; } }, @@ -7718,46 +8327,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; - } + 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); + } + } + }; - point.push(offset); - } else { - childNodes = container.childNodes; + moveEndPoint(true); + moveEndPoint(); - if (offset >= childNodes.length && childNodes.length) { - after = 1; - offset = Math.max(0, childNodes.length - 1); - } + 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; - point.push(t.dom.nodeIndex(childNodes[offset], normalized) + after); + if (container.nodeType == 3) { + if (normalized) { + for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling) + offset += node.nodeValue.length; } - for (; container && container != root; container = container.parentNode) - point.push(t.dom.nodeIndex(container, normalized)); + point.push(offset); + } else { + childNodes = container.childNodes; - return point; - }; + if (offset >= childNodes.length && childNodes.length) { + after = 1; + offset = Math.max(0, childNodes.length - 1); + } - bookmark.start = getPoint(rng, true); + point.push(t.dom.nodeIndex(childNodes[offset], normalized) + after); + } - if (!t.isCollapsed()) - bookmark.end = getPoint(rng); + for (; container && container != root; container = container.parentNode) + point.push(t.dom.nodeIndex(container, normalized)); - return bookmark; + 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); @@ -7790,7 +8422,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>'); @@ -7813,7 +8445,7 @@ window.tinymce.dom.Sizzle = Sizzle; return {name : name, index : findIndex(name, element)}; // W3C method - rng2 = rng.cloneRange(); + rng2 = normalizeTableCellSelection(rng.cloneRange()); // Insert end marker if (!collapsed) { @@ -7821,6 +8453,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)); } @@ -7833,122 +8466,122 @@ window.tinymce.dom.Sizzle = Sizzle; moveToBookmark : function(bookmark) { var t = this, dom = t.dom, marker1, marker2, rng, root, startContainer, endContainer, startOffset, endOffset; - if (bookmark) { - if (bookmark.start) { - rng = dom.createRng(); - root = dom.getRoot(); + function setEndPoint(start) { + var point = bookmark[start ? 'start' : 'end'], i, node, offset, children; - function setEndPoint(start) { - var point = bookmark[start ? 'start' : 'end'], i, node, offset, children; + if (point) { + offset = point[0]; - if (point) { - offset = point[0]; + // Find container node + for (node = root, i = point.length - 1; i >= 1; i--) { + children = node.childNodes; - // Find container node - for (node = root, i = point.length - 1; i >= 1; i--) { - children = node.childNodes; + if (point[i] > children.length - 1) + return; - if (point[i] > children.length - 1) - return; + node = children[point[i]]; + } - node = children[point[i]]; - } + // Move text offset to best suitable location + if (node.nodeType === 3) + offset = Math.min(point[0], node.nodeValue.length); - // 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); - // 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); + } - // Set offset within container node - if (start) - rng.setStart(node, offset); - else - rng.setEnd(node, offset); - } + return true; + }; - return true; - }; + function restoreEndPoint(suffix) { + var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep; - if (t.tridentSel) - return t.tridentSel.moveToBookmark(bookmark); + if (marker) { + node = marker.parentNode; - if (setEndPoint(true) && setEndPoint()) { - t.setRng(rng); + 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; } - } 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 (!keep) { + prev = marker.previousSibling; + next = marker.nextSibling; - if (suffix == 'start') { - if (!keep) { - idx = dom.nodeIndex(marker); - } else { - node = marker.firstChild; - idx = 1; - } + // Remove all marker text nodes + each(tinymce.grep(marker.childNodes), function(node) { + if (node.nodeType == 3) + node.nodeValue = node.nodeValue.replace(/\uFEFF/g, ''); + }); - startContainer = endContainer = node; + // 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 { - if (!keep) { - idx = dom.nodeIndex(marker); - } else { - node = marker.firstChild; - idx = 1; - } - - endContainer = node; + endContainer = prev; 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, ''); - }); + 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" />'; - // 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; - } - } - } - } - }; + return node; + }; - 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" />' : ' '; + if (bookmark) { + if (bookmark.start) { + rng = dom.createRng(); + root = dom.getRoot(); - return node; - }; + if (t.tridentSel) + return t.tridentSel.moveToBookmark(bookmark); + if (setEndPoint(true) && setEndPoint()) { + t.setRng(rng); + } + } else if (bookmark.id) { // Restore start/end points restoreEndPoint('start'); restoreEndPoint('end'); @@ -7969,6 +8602,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); @@ -7976,32 +8635,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); } @@ -8045,50 +8678,60 @@ 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) { s = t.getSel(); @@ -8102,14 +8745,25 @@ 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; } } else { // Is W3C Range if (r.cloneRange) { - t.tridentSel.addRange(r); - return; + try { + t.tridentSel.addRange(r); + return; + } catch (ex) { + //IE9 throws an error here if called before selection is placed in the editor + } } // Is IE specific range @@ -8132,6 +8786,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(); @@ -8149,19 +8811,12 @@ window.tinymce.dom.Sizzle = Sizzle; } // If the anchor node is a element instead of a text node then return this element - //if (tinymce.isWebKit && sel.anchorNode && sel.anchorNode.nodeType == 1) + //if (tinymce.isWebKit && sel.anchorNode && sel.anchorNode.nodeType == 1) // return sel.anchorNode.childNodes[sel.anchorOffset]; // 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 { @@ -8199,7 +8854,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); @@ -8212,54 +8867,120 @@ window.tinymce.dom.Sizzle = Sizzle; return bl; }, - normalize : function() { - var self = this, rng, normalized; + isForward: function(){ + var dom = this.dom, sel = this.getSel(), anchorRange, focusRange; - // 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; + // 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, 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; @@ -8276,43 +8997,140 @@ 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()); } }, - destroy : function(s) { - var t = this; + selectorChanged: function(selector, callback) { + var self = this, currentSelectors; + + if (!self.selectorChangedData) { + self.selectorChangedData = {}; + currentSelectors = {}; + + self.editor.onNodeChange.addToTop(function(ed, cm, node) { + var dom = self.dom, parents = dom.getParents(node, null, dom.getRoot()), matchedSelectors = {}; + + // Check for new matching selectors + each(self.selectorChangedData, function(callbacks, selector) { + each(parents, function(node) { + if (dom.is(node, selector)) { + if (!currentSelectors[selector]) { + // Execute callbacks + each(callbacks, function(callback) { + callback(true, {node: node, selector: selector, parents: parents}); + }); + + currentSelectors[selector] = callbacks; + } + + matchedSelectors[selector] = callbacks; + return false; + } + }); + }); + + // Check if current selectors still match + each(currentSelectors, function(callbacks, selector) { + if (!matchedSelectors[selector]) { + delete currentSelectors[selector]; + + each(callbacks, function(callback) { + callback(false, {node: node, selector: selector, parents: parents}); + }); + } + }); + }); + } + + // Add selector listeners + if (!self.selectorChangedData[selector]) { + self.selectorChangedData[selector] = []; + } + + self.selectorChangedData[selector].push(callback); + + return self; + }, - t.win = null; + scrollIntoView: function(elm) { + var y, viewPort, self = this, dom = self.dom; + + viewPort = dom.getViewPort(self.editor.getWin()); + y = dom.getPos(elm).y; + if (y < viewPort.y || y + 25 > viewPort.y + viewPort.h) { + self.editor.getWin().scrollTo(0, y < viewPort.y ? y : y - viewPort.h + 25); + } + }, + + destroy : function(manual) { + var self = this; + + self.win = null; // Manual destroy then remove unload handler - if (!s) - tinymce.removeUnload(t.destroy); + if (!manual) + tinymce.removeUnload(self.destroy); }, // IE has an issue where you can't select/move the caret by clicking outside the body if the document is in standards mode _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(); @@ -8362,6 +9180,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') { @@ -8436,13 +9257,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); } }); @@ -8459,6 +9280,27 @@ window.tinymce.dom.Sizzle = Sizzle; } }); + // Remove expando attributes + htmlParser.addAttributeFilter('data-mce-expando', function(nodes, name, args) { + var i = nodes.length; + + while (i--) { + nodes[i].attr(name, null); + } + }); + + htmlParser.addNodeFilter('noscript', function(nodes) { + var i = nodes.length, node; + + while (i--) { + node = nodes[i].firstChild; + + if (node) { + node.value = tinymce.html.Entities.decode(node.value); + } + } + }); + // Force script into CDATA sections and remove the mce- prefix also add comments around styles htmlParser.addNodeFilter('script,style', function(nodes, name) { var i = nodes.length, node, value; @@ -8611,12 +9453,12 @@ 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 if (!args.cleanup) - args.content = args.content.replace(/\uFEFF|\u200B/g, ''); + args.content = args.content.replace(/\uFEFF/g, ''); // Post process if (!args.no_events) @@ -8651,7 +9493,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; @@ -8710,11 +9552,10 @@ window.tinymce.dom.Sizzle = Sizzle; } // Create new script element - elm = dom.create('script', { - id : id, - type : 'text/javascript', - src : tinymce._addVer(url) - }); + elm = document.createElement('script'); + elm.id = id; + elm.type = 'text/javascript'; + elm.src = tinymce._addVer(url); // Add onload listener for non IE browsers since IE9 // fires onload event before the script is parsed and executed @@ -8760,7 +9601,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; } @@ -8790,7 +9631,7 @@ window.tinymce.dom.Sizzle = Sizzle; callback.func.call(callback.scope); }); - scriptLoadedCallbacks[url] = undefined; + scriptLoadedCallbacks[url] = undef; }; queueLoadedCallbacks.push({ @@ -8847,46 +9688,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'; @@ -9118,12 +9919,15 @@ tinymce.dom.TreeWalker = function(start_node, root_node) { t.destroy = function() { each(items, function(item) { - dom.unbind(dom.get(item.id), 'focus', itemFocussed); - dom.unbind(dom.get(item.id), 'blur', itemBlurred); + var elm = dom.get(item.id); + + dom.unbind(elm, 'focus', itemFocussed); + dom.unbind(elm, 'blur', itemBlurred); }); - dom.unbind(dom.get(root), 'focus', rootFocussed); - dom.unbind(dom.get(root), 'keydown', rootKeydown); + var rootElm = dom.get(root); + dom.unbind(rootElm, 'focus', rootFocussed); + dom.unbind(rootElm, 'keydown', rootKeydown); items = dom = root = t.focus = itemFocussed = itemBlurred = rootKeydown = rootFocussed = null; t.destroy = function() {}; @@ -9202,21 +10006,23 @@ tinymce.dom.TreeWalker = function(start_node, root_node) { // Set up state and listeners for each item. each(items, function(item, idx) { - var tabindex; + var tabindex, elm; if (!item.id) { item.id = dom.uniqueId('_mce_item_'); } + elm = dom.get(item.id); + if (excludeFromTabOrder) { - dom.bind(item.id, 'blur', itemBlurred); + dom.bind(elm, 'blur', itemBlurred); tabindex = '-1'; } else { tabindex = (idx === 0 ? '0' : '-1'); } - dom.setAttrib(item.id, 'tabindex', tabindex); - dom.bind(dom.get(item.id), 'focus', itemFocussed); + elm.setAttribute('tabindex', tabindex); + dom.bind(elm, 'focus', itemFocussed); }); // Setup initial state for root element. @@ -9225,10 +10031,11 @@ tinymce.dom.TreeWalker = function(start_node, root_node) { } dom.setAttrib(root, 'tabindex', '-1'); - + // Setup listeners for root element. - dom.bind(dom.get(root), 'focus', rootFocussed); - dom.bind(dom.get(root), 'keydown', rootKeydown); + var rootElm = dom.get(root); + dom.bind(rootElm, 'focus', rootFocussed); + dom.bind(rootElm, 'keydown', rootKeydown); } }); })(tinymce); @@ -9547,8 +10354,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}); @@ -9638,7 +10445,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { if (m.settings.onclick) m.settings.onclick(e); - return Event.cancel(e); // Cancel to fix onbeforeunload problem + return false; // Cancel to fix onbeforeunload problem } }); @@ -9831,8 +10638,12 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { n = DOM.add(n, s.element || 'span', {'class' : 'mceText', title : o.settings.title}, o.settings.title); - if (o.settings.style) + if (o.settings.style) { + if (typeof o.settings.style == "function") + o.settings.style = o.settings.style(); + DOM.setAttrib(n, 'style', o.settings.style); + } if (tb.childNodes.length == 1) DOM.addClass(ro, 'mceFirst'); @@ -9865,7 +10676,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { l = DOM.encode(s.label || ''); h = '<a role="button" id="' + this.id + '" href="javascript:;" class="' + cp + ' ' + cp + 'Enabled ' + s['class'] + (l ? ' ' + cp + 'Labeled' : '') +'" onmousedown="return false;" onclick="return false;" aria-labelledby="' + this.id + '_voice" title="' + DOM.encode(s.title) + '">'; if (s.image && !(this.editor &&this.editor.forcedHighContrastMode) ) - h += '<img class="mceIcon" src="' + s.image + '" alt="' + DOM.encode(s.title) + '" />' + l; + h += '<span class="mceIcon ' + s['class'] + '"><img class="mceIcon" src="' + s.image + '" alt="' + DOM.encode(s.title) + '" /></span>' + (l ? '<span class="' + cp + 'Label">' + l + '</span>' : ''); else h += '<span class="mceIcon ' + s['class'] + '"></span>' + (l ? '<span class="' + cp + 'Label">' + l + '</span>' : ''); @@ -9903,7 +10714,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) { @@ -9922,12 +10733,15 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { t.onRenderMenu = new tinymce.util.Dispatcher(this); t.classPrefix = 'mceListBox'; + t.marked = {}; }, select : function(va) { var t = this, fv, f; - if (va == undefined) + t.marked = {}; + + if (va == undef) return t.selectByIndex(-1); // Is string or number make function selector @@ -9958,6 +10772,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { selectByIndex : function(idx) { var t = this, e, o, label; + t.marked = {}; + if (idx != t.selectedIndex) { e = DOM.get(t.id + '_text'); label = DOM.get(t.id + '_voiceDesc'); @@ -9981,6 +10797,10 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } }, + mark : function(value) { + this.marked[value] = true; + }, + add : function(n, v, o) { var t = this; @@ -10013,7 +10833,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) @@ -10032,13 +10852,19 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { m.settings.keyboard_focus = !tinymce.isOpera; // Opera is buggy when it comes to auto focus // Select in menu - if (t.oldID) - m.items[t.oldID].setSelected(0); + each(t.items, function(o) { + if (m.items[o.id]) { + m.items[o.id].setSelected(0); + } + }); each(t.items, function(o) { + if (m.items[o.id] && t.marked[o.value]) { + m.items[o.id].setSelected(1); + } + if (o.value === t.selectedValue) { m.items[o.id].setSelected(1); - t.oldID = o.id; } }); @@ -10074,7 +10900,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 }); @@ -10094,7 +10920,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", @@ -10184,7 +11010,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) { @@ -10204,7 +11030,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 @@ -10357,7 +11183,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); @@ -10541,7 +11367,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; @@ -10558,6 +11384,16 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { DOM.select('a', t.id + '_menu')[0].focus(); // Select first link } + t.keyboardNav = new tinymce.ui.KeyboardNavigation({ + root: t.id + '_menu', + items: DOM.select('a', t.id + '_menu'), + onCancel: function() { + t.hideMenu(); + t.focus(); + } + }); + + t.keyboardNav.focus(); t.isMenuVisible = 1; }, @@ -10578,13 +11414,14 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { t.isMenuVisible = 0; t.onHideMenu.dispatch(); + t.keyboardNav.destroy(); } }, 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'}); @@ -10613,7 +11450,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); @@ -10642,15 +11479,6 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { } DOM.addClass(m, 'mceColorSplitMenu'); - - new tinymce.ui.KeyboardNavigation({ - root: t.id + '_menu', - items: DOM.select('a', t.id + '_menu'), - onCancel: function() { - t.hideMenu(); - t.focus(); - } - }); // Prevent IE from scrolling and hindering click to occur #4019 Event.add(t.id + '_menu', 'mousedown', function(e) {return Event.cancel(e);}); @@ -10663,7 +11491,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { if (e && e.nodeName.toLowerCase() == 'a' && (c = e.getAttribute('data-mce-color'))) t.setColor(c); - return Event.cancel(e); // Prevent IE auto save warning + return false; // Prevent IE auto save warning }); return w; @@ -10692,11 +11520,17 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', { }, destroy : function() { - this.parent(); + var self = this; + + self.parent(); - Event.clear(this.id + '_menu'); - Event.clear(this.id + '_more'); - DOM.remove(this.id + '_menu'); + Event.clear(self.id + '_menu'); + Event.clear(self.id + '_more'); + DOM.remove(self.id + '_menu'); + + if (self.keyboardNav) { + self.keyboardNav.destroy(); + } } }); })(tinymce); @@ -10909,7 +11743,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('/')); @@ -10933,7 +11767,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(/[\/\\][^\/]+$/, ''); @@ -10968,6 +11802,26 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { init : function(s) { var t = this, pl, sl = tinymce.ScriptLoader, e, el = [], ed; + function createId(elm) { + var id = elm.id; + + // Use element id, or unique name or generate a unique id + if (!id) { + id = elm.name; + + if (id && !DOM.get(id)) { + id = elm.name; + } else { + // Generate unique name + id = DOM.uniqueId(); + } + + elm.setAttribute('id', id); + } + + return id; + }; + function execCallback(se, n, s) { var f = se[n]; @@ -10983,15 +11837,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return f.apply(s || this, Array.prototype.slice.call(arguments, 2)); }; - s = extend({ - theme : "simple", - language : "en" - }, s); + function hasClass(n, c) { + return c.constructor === RegExp ? c.test(n.className) : DOM.hasClass(n, c); + }; t.settings = s; // Legacy call - Event.add(document, 'init', function() { + Event.bind(window, 'ready', function() { var l, co; execCallback(s, 'onpageload'); @@ -11026,30 +11879,36 @@ 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(v) { - if (s.editor_deselector && hasClass(v, s.editor_deselector)) + each(DOM.select('textarea'), function(elm) { + if (s.editor_deselector && hasClass(elm, s.editor_deselector)) return; - if (!s.editor_selector || hasClass(v, s.editor_selector)) { - // Can we use the name - e = DOM.get(v.name); - if (!v.id && !e) - v.id = v.name; - - // Generate unique name if missing or already exists - if (!v.id || t.get(v.id)) - v.id = DOM.uniqueId(); - - ed = new tinymce.Editor(v.id, s); + if (!s.editor_selector || hasClass(elm, s.editor_selector)) { + ed = new tinymce.Editor(createId(elm), s); el.push(ed); ed.render(1); } }); break; + + default: + if (s.types) { + // Process type specific selector + each(s.types, function(type) { + each(DOM.select(type.selector), function(elm) { + var editor = new tinymce.Editor(createId(elm), tinymce.extend({}, s, type)); + el.push(editor); + editor.render(1); + }); + }); + } else if (s.selector) { + // Process global selector + each(DOM.select(s.selector), function(elm) { + var editor = new tinymce.Editor(createId(elm), s); + el.push(editor); + editor.render(1); + }); + } } // Call onInit when all editors are initialized @@ -11080,9 +11939,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }, get : function(id) { - if (id === undefined) + if (id === undef) return this.editors; + if (!this.editors.hasOwnProperty(id)) + return undef; + return this.editors[id]; }, @@ -11101,6 +11963,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { self.onAddEditor.dispatch(self, editor); + // Patch the tinymce.Editor instance with jQuery adapter logic + if (tinymce.adapter) + tinymce.adapter.patchEditor(editor); + + return editor; }, @@ -11133,6 +12000,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": @@ -11161,12 +12034,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); } @@ -11249,167 +12116,84 @@ 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; - - 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', + Editor : function(id, settings) { + var self = this, TRUE = true; - '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', + theme : 'advanced', skin : 'default', delta_width : 0, delta_height : 0, 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', - indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr', - 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,option,optgroup,datalist', + 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,option,optgroup,datalist', + 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); + + self.id = self.editorId = id; + + self.isNotDirty = false; - t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, { + 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 = []; + + self.contentStyles = []; + + // 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) { @@ -11417,7 +12201,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Page is not loaded yet, wait for it if (!Event.domLoaded) { - Event.add(document, 'init', function() { + Event.add(window, 'ready', function() { t.render(); }); return; @@ -11430,8 +12214,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; @@ -11439,6 +12222,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form')) DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id); + // Hide target element early to prevent content flashing + if (!s.content_editable) { + t.orgVisibility = t.getElement().style.visibility; + t.getElement().style.visibility = 'hidden'; + } + if (tinymce.WindowManager) t.windowManager = new tinymce.WindowManager(t); @@ -11500,7 +12289,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { if (s.language && s.language_load !== false) sl.add(tinymce.baseURL + '/langs/' + s.language + '.js'); - if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme]) + if (s.theme && typeof s.theme != "function" && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme]) ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js'); each(explode(s.plugins), function(p) { @@ -11510,9 +12299,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 @@ -11535,20 +12323,25 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }, init : function() { - var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re, i, initializedPlugins = []; + var n, t = this, s = t.settings, w, h, mh, e = t.getElement(), o, ti, u, bi, bc, re, i, initializedPlugins = []; tinymce.add(t); s.aria_label = s.aria_label || DOM.getAttrib(e, 'aria-label', t.getLang('aria.rich_text_area')); if (s.theme) { - s.theme = s.theme.replace(/-/, ''); - o = ThemeManager.get(s.theme); - t.theme = new o(); + if (typeof s.theme != "function") { + s.theme = s.theme.replace(/-/, ''); + o = ThemeManager.get(s.theme); + t.theme = new o(); - if (t.theme.init && s.init_theme) - t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, '')); + if (t.theme.init) + t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/$/, '')); + } else { + t.theme = s.theme; + } } + function initPlugin(p) { var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/$/, ''), po; if (c && tinymce.inArray(initializedPlugins,p) === -1) { @@ -11582,85 +12375,93 @@ 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) { - w = s.width || e.style.width || e.offsetWidth; - h = s.height || e.style.height || e.offsetHeight; + if (s.render_ui && t.theme) { t.orgDisplay = e.style.display; - re = /^[0-9\.]+(|px)$/i; - if (re.test('' + w)) - w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100); + if (typeof s.theme != "function") { + w = s.width || e.style.width || e.offsetWidth; + h = s.height || e.style.height || e.offsetHeight; + mh = s.min_height || 100; + re = /^[0-9\.]+(|px)$/i; + + if (re.test('' + w)) + w = Math.max(parseInt(w, 10) + (o.deltaWidth || 0), 100); + + if (re.test('' + h)) + h = Math.max(parseInt(h, 10) + (o.deltaHeight || 0), mh); + + // Render UI + o = t.theme.renderUI({ + targetNode : e, + width : w, + height : h, + deltaWidth : s.delta_width, + deltaHeight : s.delta_height + }); + + // Resize editor + DOM.setStyles(o.sizeContainer || o.editorContainer, { + width : w, + height : h + }); - if (re.test('' + h)) - h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100); + h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : ''); + if (h < mh) + h = mh; + } else { + o = s.theme(t, e); - // Render UI - o = t.theme.renderUI({ - targetNode : e, - width : w, - height : h, - deltaWidth : s.delta_width, - deltaHeight : s.delta_height - }); + // Convert element type to id:s + if (o.editorContainer.nodeType) { + o.editorContainer = o.editorContainer.id = o.editorContainer.id || t.id + "_parent"; + } - t.editorContainer = o.editorContainer; - } + // Convert element type to id:s + if (o.iframeContainer.nodeType) { + o.iframeContainer = o.iframeContainer.id = o.iframeContainer.id || t.id + "_iframecontainer"; + } + // Use specified iframe height or the targets offsetHeight + h = o.iframeHeight || e.offsetHeight; - // User specified a document.domain value - if (document.domain && location.hostname != document.domain) - tinymce.relaxedDomain = document.domain; + // Store away the selection when it's changed to it can be restored later with a editor.focus() call + if (isIE) { + t.onInit.add(function(ed) { + ed.dom.bind(ed.getBody(), 'beforedeactivate keydown', function() { + ed.lastIERng = ed.selection.getRng(); + }); + }); + } + } - // Resize editor - DOM.setStyles(o.sizeContainer || o.editorContainer, { - width : w, - height : h - }); + t.editorContainer = o.editorContainer; + } // Load specified content CSS last if (s.content_css) { - tinymce.each(explode(s.content_css), function(u) { + 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; + // Load specified content CSS last + if (s.content_style) { + t.contentStyles.push(s.content_style); + } + + // 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) + tinymce.relaxedDomain = document.domain; t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml">'; @@ -11670,10 +12471,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />'; // IE8 doesn't support carets behind images setting ie7_compat would force IE8+ to run in IE7 compat mode. - if (s.ie7_compat) - t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />'; - else - t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />'; + if (tinymce.isIE8) { + if (s.ie7_compat) + t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />'; + else + t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />'; + } t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />'; @@ -11701,7 +12504,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 @@ -11720,78 +12523,73 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }); t.contentAreaContainer = o.iframeContainer; - DOM.get(o.editorContainer).style.display = t.orgDisplay; + + if (o.editorContainer) { + DOM.get(o.editorContainer).style.display = t.orgDisplay; + } + + // Restore visibility on target element + e.style.visibility = t.orgVisibility; + DOM.get(t.id).style.display = 'none'; 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, contentCssText; // 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]; @@ -11803,13 +12601,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--) { @@ -11818,7 +12616,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--) { @@ -11829,318 +12627,117 @@ 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(); - - while (i--) { - node = nodes[i]; - - if (node.isEmpty(nonEmptyElements)) - node.empty().append(new tinymce.html.Node('br', 1)).shortEnded = true; - } - }); - - t.serializer = new tinymce.dom.Serializer(s, t.dom, t.schema); - - t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer); - - t.formatter = new tinymce.Formatter(this); - - // Register default formats - t.formatter.register({ - alignleft : [ - {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}}, - {selector : 'img,table', collapsed : false, styles : {'float' : 'left'}} - ], - - aligncenter : [ - {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}}, - {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'}}, - {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'}} - ], - - 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); - - // Pass through - t.undoManager.onAdd.add(function(um, l) { - if (um.hasUndo()) - return t.onChange.dispatch(t, l, um); - }); - - t.undoManager.onUndo.add(function(um, l) { - return t.onUndo.dispatch(t, l, um); - }); - - t.undoManager.onRedo.add(function(um, l) { - return t.onRedo.dispatch(t, l, um); - }); - - t.forceBlocks = new tinymce.ForceBlocks(t, { - forced_root_block : s.forced_root_block - }); - - 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 (s.save_callback) { - t.onSaveContent.add(function(ed, o) { - var h = t.execCallback('save_callback', t.id, o.content, t.getBody()); - - if (h) - o.content = h; - }); - } - - if (s.onchange_callback) { - t.onChange.add(function(ed, l) { - t.execCallback('onchange_callback', t, l); - }); - } + self.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) { + var i = nodes.length, node, nonEmptyElements = self.schema.getNonEmptyElements(); - 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) + '-->'; - }); - }); - } - }); - } + while (i--) { + node = nodes[i]; - 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 (node.isEmpty(nonEmptyElements)) + node.empty().append(new tinymce.html.Node('br', 1)).shortEnded = true; + } + }); - if (s.preformatted) { - t.onPostProcess.add(function(ed, o) { - o.content = o.content.replace(/^\s*<pre.*?>/, ''); - o.content = o.content.replace(/<\/pre>\s*$/, ''); + self.serializer = new tinymce.dom.Serializer(settings, self.dom, self.schema); - if (o.set) - o.content = '<pre class="mceItemHidden">' + o.content + '</pre>'; - }); - } + self.selection = new tinymce.dom.Selection(self.dom, self.getWin(), self.serializer, self); - if (s.verify_css_classes) { - t.serializer.attribValueFilter = function(n, v) { - var s, cl; + self.formatter = new tinymce.Formatter(self); - if (n == 'class') { - // Build regexp for classes - if (!t.classesRE) { - cl = t.dom.getClasses(); + self.undoManager = new tinymce.UndoManager(self); - if (cl.length > 0) { - s = ''; + self.forceBlocks = new tinymce.ForceBlocks(self); + self.enterKey = new tinymce.EnterKey(self); + self.editorCommands = new tinymce.EditorCommands(self); - each (cl, function(o) { - s += (s ? '|' : '') + o['class']; - }); + self.onExecCommand.add(function(editor, command) { + // Don't refresh the select lists until caret move + if (!/^(FontName|FontSize)$/.test(command)) + self.nodeChanged(); + }); - t.classesRE = new RegExp('(' + s + ')', 'gi'); - } - } + // Pass through + self.serializer.onPreProcess.add(function(se, o) { + return self.onPreProcess.dispatch(self, o, se); + }); - return !t.classesRE || /(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(v) || t.classesRE.test(v) ? v : ''; - } + self.serializer.onPostProcess.add(function(se, o) { + return self.onPostProcess.dispatch(self, o, se); + }); - return v; - }; - } + self.onPreInit.dispatch(self); - if (s.cleanup_callback) { - t.onBeforeSetContent.add(function(ed, o) { - o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o); - }); + if (!settings.browser_spellcheck && !settings.gecko_spellcheck) + doc.body.spellcheck = false; - t.onPreProcess.add(function(ed, o) { - if (o.set) - t.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o); + if (!settings.readonly) { + self.bindNativeEvents(); + } - if (o.get) - t.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o); - }); + self.controlManager.onPostRender.dispatch(self, self.controlManager); + self.onPostRender.dispatch(self); - t.onPostProcess.add(function(ed, o) { - if (o.set) - o.content = t.execCallback('cleanup_callback', 'insert_to_editor', o.content, o); + self.quirks = tinymce.util.Quirks(self); - if (o.get) - o.content = t.execCallback('cleanup_callback', 'get_from_editor', o.content, o); - }); - } + if (settings.directionality) + body.dir = settings.directionality; - 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 (settings.nowrap) + body.style.whiteSpace = "nowrap"; - 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); + 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) + '-->'; + }); + }); }); } // 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; - - if (ed.dom.isBlock(pn) && pn.lastChild === n) - ed.dom.add(pn, 'br', {'data-mce-bogus' : 1}); - }); - }; + self.load({initial : true, format : 'html'}); + self.startContent = self.getContent({format : 'raw'}); - t.onExecCommand.add(function(ed, cmd) { - if (cmd === 'CreateLink') - fixLinks(ed); - }); + self.initialized = true; - t.onSetContent.add(t.selection.onSetContent.add(fixLinks)); - } + 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}); + + // Add editor specific CSS styles + if (self.contentStyles.length > 0) { + contentCssText = ''; - t.load({initial : true, format : 'html'}); - t.startContent = t.getContent({format : 'raw'}); - t.undoManager.add(); - t.initialized = true; + each(self.contentStyles, function(style) { + contentCssText += style + "\r\n"; + }); - 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.dom.addStyle(contentCssText); + } // 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); @@ -12149,29 +12746,45 @@ 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 (!skip_focus) { + if (self.lastIERng) { + selection.setRng(self.lastIERng); + } - if (!sf) { // 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 @@ -12182,17 +12795,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) { @@ -12224,7 +12836,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 + '}'; }); }, @@ -12258,37 +12870,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) { @@ -12306,7 +12921,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 || {}; @@ -12331,7 +12946,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 @@ -12473,24 +13088,26 @@ 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(); + + // defer the call to hide to prevent an IE9 crash #4921 + DOM.hide(self.getContainer()); + DOM.setStyle(self.id, 'display', self.orgDisplay); }, isHidden : function() { @@ -12532,12 +13149,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); @@ -12611,18 +13222,22 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { if (!args.no_events) self.onSetContent.dispatch(self, args); - self.selection.normalize(); + // Don't normalize selection if the focused element isn't the body in content editable mode since it will steal focus otherwise + if (!self.settings.content_editable || document.activeElement === self.getBody()) { + self.selection.normalize(); + } return args.content; }, getContent : function(args) { - var self = this, content; + var self = this, content, body = self.getBody(); // Setup args object args = args || {}; args.format = args.format || 'html'; args.get = true; + args.getInner = true; // Do preprocessing if (!args.no_events) @@ -12630,11 +13245,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Get raw contents or by default the cleaned contents if (args.format == 'raw') - content = self.getBody().innerHTML; + content = body.innerHTML; + else if (args.format == 'text') + content = body.innerText || body.textContent; else - content = self.serializer.serialize(self.getBody(), args); + content = self.serializer.serialize(body, args); - args.content = tinymce.trim(content); + // Trim whitespace in beginning/end of HTML + if (args.format != 'text') { + args.content = tinymce.trim(content); + } else { + args.content = content; + } // Do post processing if (!args.no_events) @@ -12650,12 +13272,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() { @@ -12667,111 +13289,135 @@ 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'); + if (!dom.getAttrib(elm, 'href', false)) { + value = dom.getAttrib(elm, 'name') || elm.id; + cls = 'mceItemAnchor'; - if (v) { - if (t.hasVisual) - t.dom.addClass(e, 'mceItemAnchor'); - else - t.dom.removeClass(e, 'mceItemAnchor'); + if (value) { + if (self.hasVisual) + dom.addClass(elm, cls); + else + 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(), doc = self.getDoc(); + + if (!self.removed) { + self.removed = 1; // Cancels post remove event execution + + // Fixed bug where IE has a blinking cursor left from the editor + if (isIE && doc) + doc.execCommand('SelectAll'); + + // We must save before we hide so Safari doesn't crash + self.save(); + + DOM.setStyle(self.id, 'display', self.orgDisplay); + + // Don't clear the window or document if content editable + // is enabled since other instances might still be present + if (!self.settings.content_editable) { + Event.unbind(self.getWin()); + Event.unbind(self.getDoc()); + } - t.removed = 1; // Cancels post remove event execution - t.hide(); + Event.unbind(self.getBody()); + Event.clear(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 = []; + // Clear all execCommand listeners this is required to avoid errors if the editor was removed inside another command + self.onExecCommand.listeners = []; - tinymce.remove(t); - DOM.remove(e); + tinymce.remove(self); + DOM.remove(elm); + } }, destroy : function(s) { @@ -12781,6 +13427,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { if (t.destroyed) return; + // We must unbind on Gecko since it would otherwise produce the pesky "attempt to run compile-and-go script on a cleared scope" message + if (isGecko) { + Event.unbind(t.getDoc()); + Event.unbind(t.getWin()); + Event.unbind(t.getBody()); + } + if (!s) { tinymce.removeUnload(t.destroy); tinyMCE.onBeforeUnload.remove(t._beforeUnload); @@ -12793,18 +13446,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { t.controlManager.destroy(); t.selection.destroy(); t.dom.destroy(); - - // Remove all events - - // 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()); - } - - Event.clear(t.getBody()); - Event.clear(t.formElement); } if (t.formElement) { @@ -12822,425 +13463,322 @@ 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); - }); - + _refreshContentEditable : function() { + var self = this, body, parent; - // 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; + // Check if the editor was hidden and the re-initalize contentEditable mode by removing and adding the body again + if (self._isHidden()) { + body = self.getBody(); + parent = body.parentNode; - e = e.target; + parent.removeChild(body); + parent.appendChild(body); - if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('data-mce-src'))) - e.src = t.documentBaseURI.toAbsolute(v); - }); + body.focus(); } + }, - // 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(); + _isHidden : function() { + var s; - 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 (!isGecko) + return 0; - if (!s.table_inline_editing) - try {d.execCommand('enableInlineTableEditing', false, false);} catch (ex) {} + // Weird, wheres that cursor selection? + s = this.selection.getSel(); + return (!s || !s.rangeCount || s.rangeCount === 0); + } + }); +})(tinymce); +(function(tinymce) { + var each = tinymce.each; - if (!s.object_resizing) - try {d.execCommand('enableObjectResizing', false, false);} catch (ex) {} - } - }; + tinymce.Editor.prototype.setupEvents = function() { + var self = this, settings = self.settings; - t.onBeforeExecCommand.add(setOpts); - t.onMouseDown.add(setOpts); - } + // Add events to the editor + each([ + 'onPreInit', - // Add node change handlers - t.onMouseUp.add(t.nodeChanged); - //t.onClick.add(t.nodeChanged); - t.onKeyUp.add(function(ed, e) { - var c = e.keyCode; + 'onBeforeRenderUI', - 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(); - }); + 'onPostRender', + 'onLoad', - // Add block quote deletion handler - t.onKeyDown.add(function(ed, e) { - if (e.keyCode != VK.BACKSPACE) - return; + 'onInit', - var rng = ed.selection.getRng(); - if (!rng.collapsed) - return; + 'onRemove', - var n = rng.startContainer; - var offset = rng.startOffset; + 'onActivate', - while (n && n.nodeType && n.nodeType != 1 && n.parentNode) - n = n.parentNode; + 'onDeactivate', - // 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); + 'onClick', - // Move the caret to the beginning of n - rng.setStart(n, 0); - rng.setEnd(n, 0); - ed.selection.setRng(rng); - ed.selection.collapse(false); - } - }); + 'onEvent', + 'onMouseUp', + 'onMouseDown', - // Add reset handler - t.onReset.add(function() { - t.setContent(t.startContent, {format : 'raw'}); - }); + 'onDblClick', - // 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'); - } + 'onKeyDown', - // 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'); + 'onKeyUp', - // BlockFormat shortcuts keys - for (i=1; i<=6; i++) - t.addShortcut('ctrl+' + i, '', ['FormatBlock', false, 'h' + i]); + 'onKeyPress', - t.addShortcut('ctrl+7', '', ['FormatBlock', false, 'p']); - t.addShortcut('ctrl+8', '', ['FormatBlock', false, 'div']); - t.addShortcut('ctrl+9', '', ['FormatBlock', false, 'address']); + 'onContextMenu', - function find(e) { - var v = null; + 'onSubmit', - if (!e.altKey && !e.ctrlKey && !e.metaKey) - return v; + 'onReset', - each(t.shortcuts, function(o) { - if (tinymce.isMac && o.ctrl != e.metaKey) - return; - else if (!tinymce.isMac && o.ctrl != e.ctrlKey) - return; + 'onPaste', - if (o.alt != e.altKey) - return; + 'onPreProcess', - if (o.shift != e.shiftKey) - return; + 'onPostProcess', - if (e.keyCode == o.keyCode || (e.charCode && e.charCode == o.charCode)) { - v = o; - return false; - } - }); + 'onBeforeSetContent', - return v; - }; + 'onBeforeGetContent', - t.onKeyUp.add(function(ed, e) { - var o = find(e); + 'onSetContent', - if (o) - return Event.cancel(e); - }); + 'onGetContent', - t.onKeyPress.add(function(ed, e) { - var o = find(e); + 'onLoadContent', - if (o) - return Event.cancel(e); - }); + 'onSaveContent', - t.onKeyDown.add(function(ed, e) { - var o = find(e); + 'onNodeChange', - if (o) { - o.func.call(o.scope); - return Event.cancel(e); - } - }); - } + 'onChange', - 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; + 'onBeforeExecCommand', - e = e.target; + 'onExecCommand', - // Don't do this action for non image elements - if (e.nodeName !== 'IMG') - return; + 'onUndo', - if (re) - dom.unbind(re.node, re.ev, re.cb); + 'onRedo', - if (!dom.hasClass(e, 'mceItemNoResize')) { - ev = 'resizeend'; - cb = dom.bind(e, ev, function(e) { - var v; + 'onVisualAid', - e = e.target; + 'onSetProgressState', - if (v = dom.getStyle(e, 'width')) { - dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, '')); - dom.setStyle(e, 'width', ''); - } + 'onSetAttrib' + ], function(name) { + self[name] = new tinymce.util.Dispatcher(self); + }); - 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); - } + // 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); + }); - re = t.resizeInfo = { - node : e, - ev : ev, - cb : cb - }; - }); - } + self.onPreProcess.add(function(ed, o) { + if (o.set) + ed.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o); - if (tinymce.isOpera) { - t.onClick.add(function(ed, e) { - Event.prevent(e); - }); - } + if (o.get) + ed.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o); + }); - // Add custom undo/redo handlers - if (s.custom_undo_redo) { - function addUndo() { - t.undoManager.typing = false; - t.undoManager.add(); - }; + self.onPostProcess.add(function(ed, o) { + if (o.set) + o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o); - var focusLostFunc = tinymce.isGecko ? 'blur' : 'focusout'; - dom.bind(t.getDoc(), focusLostFunc, function(e){ - if (!t.removed && t.undoManager.typing) - addUndo(); - }); + if (o.get) + o.content = ed.execCallback('cleanup_callback', 'get_from_editor', o.content, o); + }); + } - // Add undo level when contents is drag/dropped within the editor - t.dom.bind(t.dom.getRoot(), 'dragend', function(e) { - addUndo(); - }); + // 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()); + }); + } - t.onKeyUp.add(function(ed, e) { - var keyCode = e.keyCode; + // 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) { + e.preventDefault(); + e.stopPropagation(); + } + }); + } - if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || e.ctrlKey) - addUndo(); - }); + // 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()); + }); + } - t.onKeyDown.add(function(ed, e) { - var keyCode = e.keyCode, sel; + // 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 (keyCode == 8) { - sel = t.getDoc().selection; + if (h) + o.content = h; + }); + } - // Fix IE control + backspace browser bug - if (sel && sel.createRange && sel.createRange().item) { - t.undoManager.beforeChange(); - ed.dom.remove(sel.createRange().item(0)); - addUndo(); + // Handle legacy onchange_callback option + if (settings.onchange_callback) { + self.onChange.add(function(ed, l) { + ed.execCallback('onchange_callback', ed, l); + }); + } + }; - return Event.cancel(e); - } - } + 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 + }; - // 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(); + // Handler that takes a native event and sends it out to a dispatcher like onKeyDown + function eventHandler(evt, args) { + var type = evt.type; - if (t.undoManager.typing) - addUndo(); + // Don't fire events when it's removed + if (self.removed) + return; - 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); + } + }; - // 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(); - } - }); + // Opera doesn't support focus event for contentEditable elements so we need to fake it + function doOperaFocus(e) { + self.focus(true); + }; - t.onMouseDown.add(function() { - if (t.undoManager.typing) - addUndo(); - }); + function nodeChanged(ed, e) { + // Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything + if (e.keyCode != 65 || !tinymce.VK.metaKeyPressed(e)) { + self.selection.normalize(); } - // Bug fix for FireFox keeping styles from end of selection instead of start. - if (tinymce.isGecko) { - function getAttributeApplyFunction() { - var template = t.dom.getAttribs(t.selection.getStart().cloneNode(false)); + self.nodeChanged(); + } + + // Add DOM events + each(nativeToDispatcherMap, function(dispatcherName, nativeName) { + var root = settings.content_editable ? self.getBody() : self.getDoc(); - return function() { - var target = t.selection.getStart(); + switch (nativeName) { + case 'contextmenu': + dom.bind(root, nativeName, eventHandler); + break; - if (target !== t.getBody()) { - t.dom.setAttrib(target, "style", null); + case 'paste': + dom.bind(self.getBody(), nativeName, eventHandler); + break; - each(template, function(attr) { - target.setAttributeNode(attr.cloneNode(true)); - }); - } - }; - } + case 'submit': + case 'reset': + dom.bind(self.getElement().form || tinymce.DOM.getParent(self.id, 'form'), nativeName, eventHandler); + break; - function isSelectionAcrossElements() { - var s = t.selection; + default: + dom.bind(root, nativeName, eventHandler); + } + }); - return !s.isCollapsed() && s.getStart() != s.getEnd(); - } + // 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); + }); - t.onKeyPress.add(function(ed, e) { - var applyAttributes; + if (settings.content_editable && tinymce.isOpera) { + dom.bind(self.getBody(), 'click', doOperaFocus); + dom.bind(self.getBody(), 'keydown', doOperaFocus); + } - if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) { - applyAttributes = getAttributeApplyFunction(); - t.getDoc().execCommand('delete', false, null); - applyAttributes(); + // Add node change handler + self.onMouseUp.add(nodeChanged); - return Event.cancel(e); - } - }); + self.onKeyUp.add(function(ed, e) { + var keyCode = e.keyCode; - t.dom.bind(t.getDoc(), 'cut', function(e) { - var applyAttributes; + 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(ed, e); + }); - if (isSelectionAcrossElements()) { - applyAttributes = getAttributeApplyFunction(); - t.onKeyUp.addToTop(Event.cancel, Event); + // Add reset handler + self.onReset.add(function() { + self.setContent(self.startContent, {format : 'raw'}); + }); - setTimeout(function() { - applyAttributes(); - t.onKeyUp.remove(Event.cancel, Event); - }, 0); - } - }); - } - }, + // 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; - _refreshContentEditable : function() { - var self = this, body, parent; + if (shortcut.ctrl != ctrlState || shortcut.alt != e.altKey || shortcut.shift != e.shiftKey) + return; - // Check if the editor was hidden and the re-initalize contentEditable mode by removing and adding the body again - if (self._isHidden()) { - body = self.getBody(); - parent = body.parentNode; + if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) { + e.preventDefault(); - parent.removeChild(body); - parent.appendChild(body); + if (execute) { + shortcut.func.call(shortcut.scope); + } - body.focus(); + return true; + } + }); } - }, + }; - _isHidden : function() { - var s; + self.onKeyUp.add(function(ed, e) { + handleShortcut(e); + }); - if (!isGecko) - return 0; + self.onKeyPress.add(function(ed, e) { + handleShortcut(e); + }); - // Weird, wheres that cursor selection? - s = this.selection.getSel(); - return (!s || !s.rangeCount || s.rangeCount == 0); + 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, @@ -13303,10 +13841,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); @@ -13317,7 +13855,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) { @@ -13542,7 +14080,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Insert bookmark node and get the parent selection.setContent(bookmarkHtml); - parentNode = editor.selection.getNode(); + parentNode = selection.getNode(); rootNode = editor.getBody(); // Opera will return the document node when selection is in root @@ -13616,6 +14154,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { editor.setContent(editor.getContent().replace(/tiny_mce_marker/g, function() { return value })); }, + mceToggleFormat : function(command, ui, value) { + toggleFormat(value); + }, + mceSetContent : function(command, ui, value) { editor.setContent(value); }, @@ -13629,6 +14171,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { intentValue = parseInt(intentValue); if (!queryCommandState('InsertUnorderedList') && !queryCommandState('InsertOrderedList')) { + // If forced_root_blocks is set to false we don't have a block to indent so lets create a div + if (!settings.forced_root_block && !dom.getParent(selection.getNode(), dom.isBlock)) { + formatter.apply('div'); + } + each(selection.getSelectedBlocks(), function(element) { if (command == 'outdent') { value = Math.max(0, parseInt(element.style.paddingLeft || 0) - intentValue); @@ -13700,10 +14247,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { selectAll : function() { var root = dom.getRoot(), rng = dom.createRng(); - rng.setStart(root, 0); - rng.setEnd(root, root.childNodes.length); + // Old IE does a better job with selectall than new versions + if (selection.getRng().setStart) { + rng.setStart(root, 0); + rng.setEnd(root, root.childNodes.length); - editor.selection.setRng(rng); + selection.setRng(rng); + } else { + execNativeCommand('SelectAll'); + } } }); @@ -13712,9 +14264,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); }); @@ -13744,7 +14294,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }, 'InsertUnorderedList,InsertOrderedList' : function(command) { - return dom.getParent(selection.getNode(), command == 'insertunorderedlist' ? 'UL' : 'OL'); + var list = dom.getParent(selection.getNode(), 'ul,ol'); + return list && + (command === 'insertunorderedlist' && list.tagName === 'UL' + || command === 'insertorderedlist' && list.tagName === 'OL'); } }, 'state'); @@ -13765,17 +14318,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); @@ -13783,741 +14334,327 @@ 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() { - return tinymce.trim(editor.getContent({format : 'raw', no_events : 1})); - }; - - return self = { - typing : false, - - onAdd : new Dispatcher(self), - - onUndo : new Dispatcher(self), - - onRedo : new Dispatcher(self), - - beforeChange : function() { - beforeBookmark = editor.selection.getBookmark(2, true); - }, - - add : function(level) { - var i, settings = editor.settings, lastLevel; - - level = level || {}; - level.content = getContent(); - - // Add undo level if needed - lastLevel = data[index]; - if (lastLevel && lastLevel.content == level.content) - return null; - - // Set before bookmark on previous level - if (data[index]) - data[index].beforeBookmark = beforeBookmark; - - // Time to compress - if (settings.custom_undo_redo_levels) { - if (data.length > settings.custom_undo_redo_levels) { - for (i = 0; i < data.length - 1; i++) - data[i] = data[i + 1]; - - data.length--; - index = data.length; - } - } - - // Get a non intrusive normalized bookmark - level.bookmark = editor.selection.getBookmark(2, true); - - // Crop array if needed - if (index < data.length - 1) - data.length = index + 1; - - data.push(level); - index = data.length - 1; - - self.onAdd.dispatch(self, level); - editor.isNotDirty = 0; - - return level; - }, - - undo : function() { - var level, i; - - if (self.typing) { - self.add(); - self.typing = false; - } - - if (index > 0) { - level = data[--index]; - - editor.setContent(level.content, {format : 'raw'}); - editor.selection.moveToBookmark(level.beforeBookmark); - - self.onUndo.dispatch(self, level); - } - - return level; - }, - - redo : function() { - var level; - - if (index < data.length - 1) { - level = data[++index]; - - editor.setContent(level.content, {format : 'raw'}); - editor.selection.moveToBookmark(level.bookmark); - - self.onRedo.dispatch(self, level); - } - - return level; - }, - - clear : function() { - data = []; - index = 0; - self.typing = false; - }, - - hasUndo : function() { - return index > 0 || this.typing; - }, - - hasRedo : function() { - return index < data.length - 1 && !this.typing; - } + // 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, '')); }; - }; -})(tinymce); - -(function(tinymce) { - // Shorten names - var Event = tinymce.dom.Event, - isIE = tinymce.isIE, - isGecko = tinymce.isGecko, - isOpera = tinymce.isOpera, - each = tinymce.each, - extend = tinymce.extend, - TRUE = true, - FALSE = false; - - function cloneFormats(node) { - var clone, temp, inner; - - do { - if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) { - if (clone) { - temp = node.cloneNode(false); - temp.appendChild(clone); - clone = temp; - } else { - clone = inner = node.cloneNode(false); - } - - clone.removeAttribute('id'); - } - } while (node = node.parentNode); - - if (clone) - return {wrapper : clone, inner : inner}; - }; - - // Checks if the selection/caret is at the end of the specified block element - function isAtEnd(rng, par) { - var rng2 = par.ownerDocument.createRange(); - - rng2.setStart(rng.endContainer, rng.endOffset); - rng2.setEndAfter(par); - - // Get number of characters to the right of the cursor if it's zero then we are at the end and need to merge the next block element - return rng2.cloneContents().textContent.length == 0; - }; - - function splitList(selection, dom, li) { - var listBlock, block; - - if (dom.isEmpty(li)) { - listBlock = dom.getParent(li, 'ul,ol'); - - if (!dom.getParent(listBlock.parentNode, 'ul,ol')) { - dom.split(listBlock, li); - block = dom.create('p', 0, '<br data-mce-bogus="1" />'); - dom.replace(block, li); - selection.select(block, 1); - } - - return FALSE; - } - - return TRUE; - }; - - tinymce.create('tinymce.ForceBlocks', { - ForceBlocks : function(ed) { - var t = this, s = ed.settings, elm; - - t.editor = ed; - t.dom = ed.dom; - elm = (s.forced_root_block || 'p').toLowerCase(); - s.element = elm.toUpperCase(); - - ed.onPreInit.add(t.setup, t); - }, - - setup : function() { - var t = this, ed = t.editor, s = ed.settings, dom = ed.dom, selection = ed.selection, blockElements = ed.schema.getBlockElements(); - - // Force root blocks - if (s.forced_root_block) { - function addRootBlocks() { - var node = selection.getStart(), rootNode = ed.getBody(), rng, startContainer, startOffset, endContainer, endOffset, rootBlockNode, tempNode, offset = -0xFFFFFF; - - if (!node || node.nodeType !== 1) - return; - - // Check if node is wrapped in block - while (node != rootNode) { - if (blockElements[node.nodeName]) - return; - - 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) { - rng = ed.getDoc().body.createTextRange(); - rng.moveToElementText(rng.item(0)); - } - - 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; - } - } - - // 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(s.forced_root_block); - node.parentNode.insertBefore(rootBlockNode, node); - } - - tempNode = node; - node = node.nextSibling; - rootBlockNode.appendChild(tempNode); - } else { - rootBlockNode = null; - node = node.nextSibling; - } - } - - if (rng.setStart) { - rng.setStart(startContainer, startOffset); - rng.setEnd(endContainer, endOffset); - selection.setRng(rng); - } else { - try { - rng = ed.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 - } - } - - ed.nodeChanged(); - }; - - ed.onKeyUp.add(addRootBlocks); - ed.onClick.add(addRootBlocks); - } - - if (s.force_br_newlines) { - // Force IE to produce BRs on enter - if (isIE) { - ed.onKeyPress.add(function(ed, e) { - var n; - - if (e.keyCode == 13 && selection.getNode().nodeName != 'LI') { - selection.setContent('<br id="__" /> ', {format : 'raw'}); - n = dom.get('__'); - n.removeAttribute('id'); - selection.select(n); - selection.collapse(); - return Event.cancel(e); - } - }); - } - } - - if (s.force_p_newlines) { - if (!isIE) { - ed.onKeyPress.add(function(ed, e) { - if (e.keyCode == 13 && !e.shiftKey && !t.insertPara(e)) - Event.cancel(e); - }); - } else { - // Ungly hack to for IE to preserve the formatting when you press - // enter at the end of a block element with formatted contents - // This logic overrides the browsers default logic with - // custom logic that enables us to control the output - tinymce.addUnload(function() { - t._previousFormats = 0; // Fix IE leak - }); - - ed.onKeyPress.add(function(ed, e) { - t._previousFormats = 0; - - // Clone the current formats, this will later be applied to the new block contents - if (e.keyCode == 13 && !e.shiftKey && ed.selection.isCollapsed() && s.keep_styles) - t._previousFormats = cloneFormats(ed.selection.getStart()); - }); - - ed.onKeyUp.add(function(ed, e) { - // Let IE break the element and the wrap the new caret location in the previous formats - if (e.keyCode == 13 && !e.shiftKey) { - var parent = ed.selection.getStart(), fmt = t._previousFormats; - - // Parent is an empty block - if (!parent.hasChildNodes() && fmt) { - parent = dom.getParent(parent, dom.isBlock); - - if (parent && parent.nodeName != 'LI') { - parent.innerHTML = ''; - - if (t._previousFormats) { - parent.appendChild(fmt.wrapper); - fmt.inner.innerHTML = '\uFEFF'; - } else - parent.innerHTML = '\uFEFF'; - - selection.select(parent, 1); - selection.collapse(true); - ed.getDoc().execCommand('Delete', false, null); - t._previousFormats = 0; - } - } - } - }); - } - - if (isGecko) { - ed.onKeyDown.add(function(ed, e) { - if ((e.keyCode == 8 || e.keyCode == 46) && !e.shiftKey) - t.backspaceDelete(e, e.keyCode == 8); - }); - } - } - - // Workaround for missing shift+enter support, http://bugs.webkit.org/show_bug.cgi?id=16973 - if (tinymce.isWebKit) { - function insertBr(ed) { - var rng = selection.getRng(), br, div = dom.create('div', null, ' '), divYPos, vpHeight = dom.getViewPort(ed.getWin()).h; - - // Insert BR element - rng.insertNode(br = dom.create('br')); - - // Place caret after BR - rng.setStartAfter(br); - rng.setEndAfter(br); - selection.setRng(rng); - - // Could not place caret after BR then insert an nbsp entity and move the caret - if (selection.getSel().focusNode == br.previousSibling) { - selection.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br)); - selection.collapse(TRUE); - } - - // Create a temporary DIV after the BR and get the position as it - // seems like getPos() returns 0 for text nodes and BR elements. - dom.insertAfter(div, br); - divYPos = dom.getPos(div).y; - dom.remove(div); - - // Scroll to new position, scrollIntoView can't be used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117 - if (divYPos > vpHeight) // It is not necessary to scroll if the DIV is inside the view port. - ed.getWin().scrollTo(0, divYPos); - }; - - ed.onKeyPress.add(function(ed, e) { - if (e.keyCode == 13 && (e.shiftKey || (s.force_br_newlines && !dom.getParent(selection.getNode(), 'h1,h2,h3,h4,h5,h6,ol,ul')))) { - insertBr(ed); - Event.cancel(e); - } - }); - } - - // IE specific fixes - if (isIE) { - // Replaces IE:s auto generated paragraphs with the specified element name - if (s.element != 'P') { - ed.onKeyPress.add(function(ed, e) { - t.lastElm = selection.getNode().nodeName; - }); - ed.onKeyUp.add(function(ed, e) { - var bl, n = selection.getNode(), b = ed.getBody(); - - if (b.childNodes.length === 1 && n.nodeName == 'P') { - n = dom.rename(n, s.element); - selection.select(n); - selection.collapse(); - ed.nodeChanged(); - } else if (e.keyCode == 13 && !e.shiftKey && t.lastElm != 'P') { - bl = dom.getParent(n, 'p'); - - if (bl) { - dom.rename(bl, s.element); - ed.nodeChanged(); - } - } - }); - } - } - }, + function addNonTypingUndoLevel() { + self.typing = false; + self.add(); + }; - getParentBlock : function(n) { - var d = this.dom; + // Create event instances + onBeforeAdd = new Dispatcher(self); + onAdd = new Dispatcher(self); + onUndo = new Dispatcher(self); + onRedo = new Dispatcher(self); - return d.getParent(n, d.isBlock); - }, + // 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); + }); - insertPara : function(e) { - var t = this, ed = t.editor, dom = ed.dom, d = ed.getDoc(), se = ed.settings, s = ed.selection.getSel(), r = s.getRangeAt(0), b = d.body; - var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car; + // Pass though onUndo event from UndoManager to Editor + onUndo.add(function(undoman, level) { + return editor.onUndo.dispatch(editor, level, undoman); + }); - ed.undoManager.beforeChange(); + // Pass though onRedo event from UndoManager to Editor + onRedo.add(function(undoman, level) { + return editor.onRedo.dispatch(editor, level, undoman); + }); - // If root blocks are forced then use Operas default behavior since it's really good -// Removed due to bug: #1853816 -// if (se.forced_root_block && isOpera) -// return TRUE; + // Add initial undo level when the editor is initialized + editor.onInit.add(function() { + self.add(); + }); - // Setup before range - rb = d.createRange(); + // 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(); + } + }); - // If is before the first block element and in body, then move it into first block element - rb.setStart(s.anchorNode, s.anchorOffset); - rb.collapse(TRUE); + // 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(); + } + }); - // Setup after range - ra = d.createRange(); + // 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.getBody(), 'focusout', function(e) { + if (!editor.removed && self.typing) { + addNonTypingUndoLevel(); + } + }); - // If is before the first block element and in body, then move it into first block element - ra.setStart(s.focusNode, s.focusOffset); - ra.collapse(TRUE); + editor.onKeyUp.add(function(editor, e) { + var keyCode = e.keyCode; - // Setup start/end points - dir = rb.compareBoundaryPoints(rb.START_TO_END, ra) < 0; - sn = dir ? s.anchorNode : s.focusNode; - so = dir ? s.anchorOffset : s.focusOffset; - en = dir ? s.focusNode : s.anchorNode; - eo = dir ? s.focusOffset : s.anchorOffset; + if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 45 || keyCode == 13 || e.ctrlKey) { + addNonTypingUndoLevel(); + } + }); - // If selection is in empty table cell - if (sn === en && /^(TD|TH)$/.test(sn.nodeName)) { - if (sn.firstChild.nodeName == 'BR') - dom.remove(sn.firstChild); // Remove BR + editor.onKeyDown.add(function(editor, e) { + var keyCode = e.keyCode; - // Create two new block elements - if (sn.childNodes.length == 0) { - ed.dom.add(sn, se.element, null, '<br />'); - aft = ed.dom.add(sn, se.element, null, '<br />'); - } else { - n = sn.innerHTML; - sn.innerHTML = ''; - ed.dom.add(sn, se.element, null, n); - aft = ed.dom.add(sn, se.element, null, '<br />'); + // 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(); } - // Move caret into the last one - r = d.createRange(); - r.selectNodeContents(aft); - r.collapse(1); - ed.selection.setRng(r); - - return FALSE; + return; } - // If the caret is in an invalid location in FF we need to move it into the first block - if (sn == b && en == b && b.firstChild && ed.dom.isBlock(b.firstChild)) { - sn = en = sn.firstChild; - so = eo = 0; - rb = d.createRange(); - rb.setStart(sn, 0); - ra = d.createRange(); - ra.setStart(en, 0); + // 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(); } + }); - // If the body is totally empty add a BR element this might happen on webkit - if (!d.body.hasChildNodes()) { - d.body.appendChild(dom.create('br')); + editor.onMouseDown.add(function(editor, e) { + if (self.typing) { + addNonTypingUndoLevel(); } + }); - // Never use body as start or end node - sn = sn.nodeName == "HTML" ? d.body : sn; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes - sn = sn.nodeName == "BODY" ? sn.firstChild : sn; - en = en.nodeName == "HTML" ? d.body : en; // Fix for Opera bug: https://bugs.opera.com/show_bug.cgi?id=273224&comments=yes - en = en.nodeName == "BODY" ? en.firstChild : en; + // Add keyboard shortcuts for undo/redo keys + editor.addShortcut('ctrl+z', 'undo_desc', 'Undo'); + editor.addShortcut('ctrl+y', 'redo_desc', 'Redo'); - // Get start and end blocks - sb = t.getParentBlock(sn); - eb = t.getParentBlock(en); - bn = sb ? sb.nodeName : se.element; // Get block name to create + self = { + // Explose for debugging reasons + data : data, - // Return inside list use default browser behavior - if (n = t.dom.getParent(sb, 'li,pre')) { - if (n.nodeName == 'LI') - return splitList(ed.selection, t.dom, n); + typing : false, + + onBeforeAdd: onBeforeAdd, - return TRUE; - } + onAdd : onAdd, - // If caption or absolute layers then always generate new blocks within - if (sb && (sb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { - bn = se.element; - sb = null; - } + onUndo : onUndo, - // If caption or absolute layers then always generate new blocks within - if (eb && (eb.nodeName == 'CAPTION' || /absolute|relative|fixed/gi.test(dom.getStyle(sb, 'position', 1)))) { - bn = se.element; - eb = null; - } + onRedo : onRedo, - // Use P instead - if (/(TD|TABLE|TH|CAPTION)/.test(bn) || (sb && bn == "DIV" && /left|right/gi.test(dom.getStyle(sb, 'float', 1)))) { - bn = se.element; - sb = eb = null; - } + beforeChange : function() { + beforeBookmark = editor.selection.getBookmark(2, true); + }, - // Setup new before and after blocks - bef = (sb && sb.nodeName == bn) ? sb.cloneNode(0) : ed.dom.create(bn); - aft = (eb && eb.nodeName == bn) ? eb.cloneNode(0) : ed.dom.create(bn); + add : function(level) { + var i, settings = editor.settings, lastLevel; - // Remove id from after clone - aft.removeAttribute('id'); + level = level || {}; + level.content = getContent(); + + self.onBeforeAdd.dispatch(self, level); - // Is header and cursor is at the end, then force paragraph under - if (/^(H[1-6])$/.test(bn) && isAtEnd(r, sb)) - aft = ed.dom.create(se.element); + // Add undo level if needed + lastLevel = data[index]; + if (lastLevel && lastLevel.content == level.content) + return null; - // Find start chop node - n = sc = sn; - do { - if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) - break; + // Set before bookmark on previous level + if (data[index]) + data[index].beforeBookmark = beforeBookmark; - sc = n; - } while ((n = n.previousSibling ? n.previousSibling : n.parentNode)); + // Time to compress + if (settings.custom_undo_redo_levels) { + if (data.length > settings.custom_undo_redo_levels) { + for (i = 0; i < data.length - 1; i++) + data[i] = data[i + 1]; - // Find end chop node - n = ec = en; - do { - if (n == b || n.nodeType == 9 || t.dom.isBlock(n) || /(TD|TABLE|TH|CAPTION)/.test(n.nodeName)) - break; + data.length--; + index = data.length; + } + } - ec = n; - } while ((n = n.nextSibling ? n.nextSibling : n.parentNode)); + // Get a non intrusive normalized bookmark + level.bookmark = editor.selection.getBookmark(2, true); - // Place first chop part into before block element - if (sc.nodeName == bn) - rb.setStart(sc, 0); - else - rb.setStartBefore(sc); + // Crop array if needed + if (index < data.length - 1) + data.length = index + 1; - rb.setEnd(sn, so); - bef.appendChild(rb.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari + data.push(level); + index = data.length - 1; - // Place secnd chop part within new block element - try { - ra.setEndAfter(ec); - } catch(ex) { - //console.debug(s.focusNode, s.focusOffset); - } + self.onAdd.dispatch(self, level); + editor.isNotDirty = 0; - ra.setStart(en, eo); - aft.appendChild(ra.cloneContents() || d.createTextNode('')); // Empty text node needed for Safari + return level; + }, - // Create range around everything - r = d.createRange(); - if (!sc.previousSibling && sc.parentNode.nodeName == bn) { - r.setStartBefore(sc.parentNode); - } else { - if (rb.startContainer.nodeName == bn && rb.startOffset == 0) - r.setStartBefore(rb.startContainer); - else - r.setStart(rb.startContainer, rb.startOffset); - } + undo : function() { + var level, i; - if (!ec.nextSibling && ec.parentNode.nodeName == bn) - r.setEndAfter(ec.parentNode); - else - r.setEnd(ra.endContainer, ra.endOffset); + if (self.typing) { + self.add(); + self.typing = false; + } - // Delete and replace it with new block elements - r.deleteContents(); + if (index > 0) { + level = data[--index]; - if (isOpera) - ed.getWin().scrollTo(0, vp.y); + editor.setContent(level.content, {format : 'raw'}); + editor.selection.moveToBookmark(level.beforeBookmark); - // Never wrap blocks in blocks - if (bef.firstChild && bef.firstChild.nodeName == bn) - bef.innerHTML = bef.firstChild.innerHTML; + self.onUndo.dispatch(self, level); + } - if (aft.firstChild && aft.firstChild.nodeName == bn) - aft.innerHTML = aft.firstChild.innerHTML; + return level; + }, - function appendStyles(e, en) { - var nl = [], nn, n, i; + redo : function() { + var level; - e.innerHTML = ''; + if (index < data.length - 1) { + level = data[++index]; - // Make clones of style elements - if (se.keep_styles) { - n = en; - do { - // We only want style specific elements - if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(n.nodeName)) { - nn = n.cloneNode(FALSE); - dom.setAttrib(nn, 'id', ''); // Remove ID since it needs to be unique - nl.push(nn); - } - } while (n = n.parentNode); + editor.setContent(level.content, {format : 'raw'}); + editor.selection.moveToBookmark(level.bookmark); + + self.onRedo.dispatch(self, level); } - // Append style elements to aft - if (nl.length > 0) { - for (i = nl.length - 1, nn = e; i >= 0; i--) - nn = nn.appendChild(nl[i]); + return level; + }, - // Padd most inner style element - nl[0].innerHTML = isOpera ? '\u00a0' : '<br />'; // Extra space for Opera so that the caret can move there - return nl[0]; // Move caret to most inner element - } else - e.innerHTML = isOpera ? '\u00a0' : '<br />'; // Extra space for Opera so that the caret can move there - }; - - // Padd empty blocks - if (dom.isEmpty(bef)) - appendStyles(bef, sn); - - // Fill empty afterblook with current style - if (dom.isEmpty(aft)) - car = appendStyles(aft, en); - - // Opera needs this one backwards for older versions - if (isOpera && parseFloat(opera.version()) < 9.5) { - r.insertNode(bef); - r.insertNode(aft); - } else { - r.insertNode(aft); - r.insertNode(bef); + clear : function() { + data = []; + index = 0; + self.typing = false; + }, + + hasUndo : function() { + return index > 0 || this.typing; + }, + + hasRedo : function() { + return index < data.length - 1 && !this.typing; } + }; - // Normalize - aft.normalize(); - bef.normalize(); + return self; + }; +})(tinymce); - // Move cursor and scroll into view - ed.selection.select(aft, true); - ed.selection.collapse(true); +tinymce.ForceBlocks = function(editor) { + var settings = editor.settings, dom = editor.dom, selection = editor.selection, blockElements = editor.schema.getBlockElements(); - // 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 - y = ed.dom.getPos(aft).y; - //ch = aft.clientHeight; + function addRootBlocks() { + var node = selection.getStart(), rootNode = editor.getBody(), rng, startContainer, startOffset, endContainer, endOffset, rootBlockNode, tempNode, offset = -0xFFFFFF, wrapped, isInEditorDocument; - // Is element within viewport - if (y < vp.y || y + 25 > vp.y + vp.h) { - ed.getWin().scrollTo(0, y < vp.y ? y : y - vp.h + 25); // Needs to be hardcoded to roughly one line of text if a huge text block is broken into two blocks + if (!node || node.nodeType !== 1 || !settings.forced_root_block) + return; - /*console.debug( - 'Element: y=' + y + ', h=' + ch + ', ' + - 'Viewport: y=' + vp.y + ", h=" + vp.h + ', bottom=' + (vp.y + vp.h) - );*/ - } + // Check if node is wrapped in block + while (node && node != rootNode) { + if (blockElements[node.nodeName]) + return; - ed.undoManager.add(); + node = node.parentNode; + } - return FALSE; - }, + // 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); + } - backspaceDelete : function(e, bs) { - var t = this, ed = t.editor, b = ed.getBody(), dom = ed.dom, n, se = ed.selection, r = se.getRng(), sc = r.startContainer, n, w, tn, walker; + isInEditorDocument = rng.parentElement().ownerDocument === editor.getDoc(); + tmpRng = rng.duplicate(); + tmpRng.collapse(true); + startOffset = tmpRng.move('character', offset) * -1; - // Delete when caret is behind a element doesn't work correctly on Gecko see #3011651 - if (!bs && r.collapsed && sc.nodeType == 1 && r.startOffset == sc.childNodes.length) { - walker = new tinymce.dom.TreeWalker(sc.lastChild, sc); + if (!tmpRng.collapsed) { + tmpRng = rng.duplicate(); + tmpRng.collapse(false); + endOffset = (tmpRng.move('character', offset) * -1) - startOffset; + } + } - // Walk the dom backwards until we find a text node - for (n = sc.lastChild; n; n = walker.prev()) { - if (n.nodeType == 3) { - r.setStart(n, n.nodeValue.length); - r.collapse(true); - se.setRng(r); - return; - } + // Wrap non block elements and text nodes + node = rootNode.firstChild; + while (node) { + if (node.nodeType === 3 || (node.nodeType == 1 && !blockElements[node.nodeName])) { + // Remove empty text nodes + if (node.nodeType === 3 && node.nodeValue.length == 0) { + tempNode = node; + node = node.nextSibling; + dom.remove(tempNode); + continue; } - } - // The caret sometimes gets stuck in Gecko if you delete empty paragraphs - // This workaround removes the element by hand and moves the caret to the previous element - if (sc && ed.dom.isBlock(sc) && !/^(TD|TH)$/.test(sc.nodeName) && bs) { - if (sc.childNodes.length == 0 || (sc.childNodes.length == 1 && sc.firstChild.nodeName == 'BR')) { - // Find previous block element - n = sc; - while ((n = n.previousSibling) && !ed.dom.isBlock(n)) ; + if (!rootBlockNode) { + rootBlockNode = dom.create(settings.forced_root_block); + node.parentNode.insertBefore(rootBlockNode, node); + wrapped = true; + } - if (n) { - if (sc != b.firstChild) { - // Find last text node - w = ed.dom.doc.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, FALSE); - while (tn = w.nextNode()) - n = tn; + tempNode = node; + node = node.nextSibling; + rootBlockNode.appendChild(tempNode); + } else { + rootBlockNode = null; + node = node.nextSibling; + } + } - // Place caret at the end of last text node - r = ed.getDoc().createRange(); - r.setStart(n, n.nodeValue ? n.nodeValue.length : 0); - r.setEnd(n, n.nodeValue ? n.nodeValue.length : 0); - se.setRng(r); + if (wrapped) { + if (rng.setStart) { + rng.setStart(startContainer, startOffset); + rng.setEnd(endContainer, endOffset); + selection.setRng(rng); + } else { + // Only select if the previous selection was inside the document to prevent auto focus in quirks mode + if (isInEditorDocument) { + try { + rng = editor.getDoc().body.createTextRange(); + rng.moveToElementText(rootNode); + rng.collapse(true); + rng.moveStart('character', startOffset); - // Remove the target container - ed.dom.remove(sc); - } + if (endOffset > 0) + rng.moveEnd('character', endOffset); - return Event.cancel(e); + rng.select(); + } catch (ex) { + // Ignore } } } + + editor.nodeChanged(); } - }); -})(tinymce); + }; + + // Force root blocks + if (settings.forced_root_block) { + editor.onKeyUp.add(addRootBlocks); + editor.onNodeChange.add(addRootBlocks); + } +}; (function(tinymce) { // Shorten names @@ -14575,28 +14712,40 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return c; }, - createControl : function(n) { - var c, t = this, ed = t.editor; + createControl : function(name) { + var ctrl, i, l, self = this, editor = self.editor, factories, ctrlName; + + // Build control factory cache + if (!self.controlFactories) { + self.controlFactories = []; + each(editor.plugins, function(plugin) { + if (plugin.createControl) { + self.controlFactories.push(plugin); + } + }); + } - each(ed.plugins, function(p) { - if (p.createControl) { - c = p.createControl(n, t); + // Create controls by asking cached factories + factories = self.controlFactories; + for (i = 0, l = factories.length; i < l; i++) { + ctrl = factories[i].createControl(name, self); - if (c) - return false; + if (ctrl) { + return self.add(ctrl); } - }); + } - switch (n) { - case "|": - case "separator": - return t.createSeparator(); + // Create sepearator + if (name === "|" || name === "separator") { + return self.createSeparator(); } - if (!c && ed.buttons && (c = ed.buttons[n])) - return t.createButton(n, c); + // Create control from button collection + if (editor.buttons && (ctrl = editor.buttons[name])) { + return self.createButton(name, ctrl); + } - return t.add(c); + return self.add(ctrl); }, createDropMenu : function(id, s, cc) { @@ -14611,6 +14760,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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); @@ -14995,52 +15146,152 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { alert : function(tx, cb, s, w) { var t = this; - w = w || window; - w.alert(t._decode(t.editor.getLang(tx, tx))); + w = w || window; + w.alert(t._decode(t.editor.getLang(tx, tx))); + + if (cb) + cb.call(s || t); + }, + + resizeBy : function(dw, dh, win) { + win.resizeBy(dw, dh); + }, + + // Internal functions + + _decode : function(s) { + return tinymce.DOM.decode(s).replace(/\\n/g, '\n'); + } + }); +}(tinymce)); +(function(tinymce) { + tinymce.Formatter = function(ed) { + var formats = {}, + each = tinymce.each, + dom = ed.dom, + selection = ed.selection, + TreeWalker = tinymce.dom.TreeWalker, + rangeUtils = new tinymce.dom.RangeUtils(dom), + isValid = ed.schema.isValidChild, + isArray = tinymce.isArray, + isBlock = dom.isBlock, + forcedRootBlock = ed.settings.forced_root_block, + nodeIndex = dom.nodeIndex, + INVISIBLE_CHAR = '\uFEFF', + MCE_ATTR_RE = /^(src|href|style)$/, + FALSE = false, + TRUE = true, + formatChangeData, + undef, + getContentEditable = dom.getContentEditable; + + function isTextBlock(name) { + return !!ed.schema.getTextBlocks()[name.toLowerCase()]; + } + + function getParents(node, selector) { + return dom.getParents(node, selector, dom.getRoot()); + }; + + function isCaretNode(node) { + 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'}, - if (cb) - cb.call(s || t); - }, + link : {inline : 'a', selector : 'a', remove : 'all', split : true, deep : true, + onmatch : function(node) { + return true; + }, - resizeBy : function(dw, dh, win) { - win.resizeBy(dw, dh); - }, + onformat : function(elm, fmt, vars) { + each(vars, function(value, key) { + dom.setAttrib(elm, key, value); + }); + } + }, - // Internal functions + 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} + ] + }); - _decode : function(s) { - return tinymce.DOM.decode(s).replace(/\\n/g, '\n'); - } - }); -}(tinymce)); -(function(tinymce) { - tinymce.Formatter = function(ed) { - var formats = {}, - each = tinymce.each, - dom = ed.dom, - selection = ed.selection, - TreeWalker = tinymce.dom.TreeWalker, - rangeUtils = new tinymce.dom.RangeUtils(dom), - isValid = ed.schema.isValidChild, - isBlock = dom.isBlock, - forcedRootBlock = ed.settings.forced_root_block, - nodeIndex = dom.nodeIndex, - INVISIBLE_CHAR = '\uFEFF', - MCE_ATTR_RE = /^(src|href|style)$/, - FALSE = false, - TRUE = true, - undefined; + // 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'}); + }); - function isArray(obj) { - return obj instanceof Array; + // Register user defined formats + register(ed.settings.formats); }; - function getParents(node, selector) { - return dom.getParents(node, selector, dom.getRoot()); - }; + 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'); - function isCaretNode(node) { - return node.nodeType === 1 && node.id === '_mce_caret'; + // 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 @@ -15062,15 +15313,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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 @@ -15143,7 +15394,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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; } } @@ -15155,7 +15406,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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; @@ -15193,8 +15444,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { each(tinymce.grep(node.childNodes), process); return 0; } else { - currentWrapElm = wrapElm.cloneNode(FALSE); - + currentWrapElm = dom.clone(wrapElm, FALSE); + // create a list of the nodes on the same side of the list as the selection each(tinymce.grep(node.childNodes), function(n, index) { if ((startIndex < listIndex && index < listIndex) || (startIndex > listIndex && index > listIndex)) { @@ -15202,7 +15453,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { n.parentNode.removeChild(n); } }); - + // insert the wrapping element either before or after the list. if (startIndex < listIndex) { node.insertBefore(currentWrapElm, list); @@ -15220,9 +15471,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return currentWrapElm; } }; - + function applyRngStyle(rng, bookmark, node_specific) { - var newWrappers = [], wrapName, wrapElm; + var newWrappers = [], wrapName, wrapElm, contentEditable = true; // Setup wrapper element wrapName = format.inline || format.block; @@ -15233,7 +15484,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { var currentWrapElm; function process(node) { - var nodeName = node.nodeName.toLowerCase(), parentName = node.parentNode.nodeName.toLowerCase(), found; + var nodeName, parentName, found, hasContentEditableState, lastContentEditable; + + lastContentEditable = contentEditable; + nodeName = node.nodeName.toLowerCase(); + parentName = node.parentNode.nodeName.toLowerCase(); + + // Node has a contentEditable value + if (node.nodeType === 1 && getContentEditable(node)) { + lastContentEditable = contentEditable; + contentEditable = getContentEditable(node) === "true"; + hasContentEditableState = true; // We don't want to wrap the container only it's children + } // Stop wrapping on br elements if (isEq(nodeName, 'br')) { @@ -15253,7 +15515,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } // Can we rename the block - if (format.block && !format.wrapper && isTextBlock(nodeName)) { + if (contentEditable && !hasContentEditableState && format.block && !format.wrapper && isTextBlock(nodeName)) { node = dom.rename(node, wrapName); setElementFormat(node); newWrappers.push(node); @@ -15284,12 +15546,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } // Is it valid to wrap this item - if (isValid(wrapName, nodeName) && isValid(parentName, wrapName) && + if (contentEditable && !hasContentEditableState && isValid(wrapName, nodeName) && isValid(parentName, wrapName) && !(!node_specific && node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279) && !isCaretNode(node)) { // Start wrapping if (!currentWrapElm) { // Wrap the node - currentWrapElm = wrapElm.cloneNode(FALSE); + currentWrapElm = dom.clone(wrapElm, FALSE); node.parentNode.insertBefore(currentWrapElm, node); newWrappers.push(currentWrapElm); } @@ -15301,9 +15563,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } else { // Start a new wrapper for possible children currentWrapElm = 0; - + each(tinymce.grep(node.childNodes), process); + if (hasContentEditableState) { + contentEditable = lastContentEditable; // Restore last contentEditable state from stack + } + // End the last wrapper currentWrapElm = 0; } @@ -15320,7 +15586,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { var i, currentWrapElm, children; if (node.nodeName === 'A') { - currentWrapElm = wrapElm.cloneNode(FALSE); + currentWrapElm = dom.clone(wrapElm, FALSE); newWrappers.push(currentWrapElm); children = tinymce.grep(node.childNodes); @@ -15338,6 +15604,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } // Cleanup + each(newWrappers, function(node) { var childCount; @@ -15364,7 +15631,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // If child was found and of the same type as the current node if (child && matchName(child, format)) { - clone = child.cloneNode(FALSE); + clone = dom.clone(child, FALSE); setElementFormat(clone); dom.replace(clone, node, TRUE); @@ -15453,6 +15720,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Obtain selection node before selection is unselected by applyRngStyle() var curSelNode = ed.selection.getNode(); + // If the formats have a default block and we can't find a parent block then start wrapping it with a DIV this is for forced_root_blocks: false + // It's kind of a hack but people should be using the default block type P since all desktop editors work that way + if (!forcedRootBlock && formatList[0].defaultBlock && !dom.getParent(curSelNode, dom.isBlock)) { + apply(formatList[0].defaultBlock); + } + // Apply formatting to selection ed.selection.setRng(adjustSelectionToVisibleSelection()); bookmark = selection.getBookmark(); @@ -15474,25 +15747,45 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }; function remove(name, vars, node) { - var formatList = get(name), format = formatList[0], bookmark, i, rng; + var formatList = get(name), format = formatList[0], bookmark, i, rng, contentEditable = true; // Merges the styles for each node function process(node) { - var children, i, l; + var children, i, l, localContentEditable, lastContentEditable, hasContentEditableState; + + // Skip on text nodes as they have neither format to remove nor children + if (node.nodeType === 3) { + return; + } + + // Node has a contentEditable value + if (node.nodeType === 1 && getContentEditable(node)) { + lastContentEditable = contentEditable; + contentEditable = getContentEditable(node) === "true"; + hasContentEditableState = true; // We don't want to wrap the container only it's children + } // Grab the children first since the nodelist might be changed children = tinymce.grep(node.childNodes); // Process current node - for (i = 0, l = formatList.length; i < l; i++) { - if (removeFormat(formatList[i], vars, node, node)) - break; + if (contentEditable && !hasContentEditableState) { + for (i = 0, l = formatList.length; i < l; i++) { + if (removeFormat(formatList[i], vars, node, node)) + break; + } } // Process the children if (format.deep) { - for (i = 0, l = children.length; i < l; i++) - process(children[i]); + if (children.length) { + for (i = 0, l = children.length; i < l; i++) + process(children[i]); + + if (hasContentEditableState) { + contentEditable = lastContentEditable; // Restore last contentEditable state from stack + } + } } }; @@ -15523,7 +15816,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { formatRootParent = format_root.parentNode; for (parent = container.parentNode; parent && parent != formatRootParent; parent = parent.parentNode) { - clone = parent.cloneNode(FALSE); + clone = dom.clone(parent, FALSE); for (i = 0; i < formatList.length; i++) { if (removeFormat(formatList[i], vars, clone, clone)) { @@ -15578,7 +15871,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }; function removeRngStyle(rng) { - var startContainer, endContainer; + var startContainer, endContainer, node; rng = expandRng(rng, formatList, TRUE); @@ -15587,6 +15880,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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'}); @@ -15648,17 +15947,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { ed.nodeChanged(); } else performCaretAction('remove', name, vars); - - // 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); @@ -15678,7 +15972,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // 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') @@ -15774,7 +16068,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { matchedFormatNames.push(name); } } - }); + }, dom.getRoot()); return matchedFormatNames; }; @@ -15803,6 +16097,62 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return FALSE; }; + function formatChanged(formats, callback, similar) { + var currentFormats; + + // Setup format node change logic + if (!formatChangeData) { + formatChangeData = {}; + currentFormats = {}; + + ed.onNodeChange.addToTop(function(ed, cm, node) { + var parents = getParents(node), matchedFormats = {}; + + // Check for new formats + each(formatChangeData, function(callbacks, format) { + each(parents, function(node) { + if (matchNode(node, format, {}, callbacks.similar)) { + if (!currentFormats[format]) { + // Execute callbacks + each(callbacks, function(callback) { + callback(true, {node: node, format: format, parents: parents}); + }); + + currentFormats[format] = callbacks; + } + + matchedFormats[format] = callbacks; + return false; + } + }); + }); + + // Check if current formats still match + each(currentFormats, function(callbacks, format) { + if (!matchedFormats[format]) { + delete currentFormats[format]; + + each(callbacks, function(callback) { + callback(false, {node: node, format: format, parents: parents}); + }); + } + }); + }); + } + + // Add format listeners + each(formats.split(','), function(format) { + if (!formatChangeData[format]) { + formatChangeData[format] = []; + formatChangeData[format].similar = similar; + } + + formatChangeData[format].push(callback); + }); + + return this; + }; + // Expose to public tinymce.extend(this, { get : get, @@ -15813,9 +16163,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { match : match, matchAll : matchAll, matchNode : matchNode, - canApply : canApply + canApply : canApply, + formatChanged: formatChanged }); + // Initialize + defaultFormats(); + addKeyboardShortcuts(); + // Private functions function matchName(node, format) { @@ -15882,19 +16237,24 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }; function expandRng(rng, format, remove) { - var startContainer = rng.startContainer, + 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'; root = dom.getRoot(); + function isBogusBr(node) { + return node.nodeName == "BR" && node.getAttribute('data-mce-bogus') && !node.nextSibling; + }; + // If it's a text node and the offset is inside the text if (container.nodeType == 3 && !isWhiteSpaceNode(container)) { if (start ? startOffset > 0 : endOffset < container.nodeValue.length) { @@ -15909,7 +16269,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Walk left/right for (sibling = parent[siblingName]; sibling; sibling = sibling[siblingName]) { - if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling)) { + if (!isBookmarkNode(sibling) && !isWhiteSpaceNode(sibling) && !isBogusBr(sibling)) { return parent; } } @@ -15929,7 +16289,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // 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]; @@ -15957,89 +16317,163 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { endOffset = endContainer.nodeValue.length; } - // Exclude bookmark nodes if possible - if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) { - startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode; - startContainer = startContainer.nextSibling || startContainer; + // Expands the node to the closes contentEditable false element if it exists + function findParentContentEditable(node) { + var parent = node; - if (startContainer.nodeType == 3) - startOffset = 0; - } + while (parent) { + if (parent.nodeType === 1 && getContentEditable(parent)) { + return getContentEditable(parent) === "false" ? parent : node; + } - if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) { - endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode; - endContainer = endContainer.previousSibling || endContainer; + parent = parent.parentNode; + } - if (endContainer.nodeType == 3) - endOffset = endContainer.length; - } + return node; + }; - if (format[0].inline) { - if (rng.collapsed) { - function findWordEndPoint(container, offset, start) { - var walker, node, pos, lastTextNode; + function findWordEndPoint(container, offset, start) { + var walker, node, pos, lastTextNode; - function findSpace(node, offset) { - var pos, pos2, str = node.nodeValue; + function findSpace(node, offset) { + var pos, pos2, str = node.nodeValue; - if (typeof(offset) == "undefined") { - offset = start ? str.length : 0; - } + 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; + 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; - } + // 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; - }; + return pos; + }; - if (container.nodeType === 3) { - pos = findSpace(container, offset); + if (container.nodeType === 3) { + pos = findSpace(container, offset); - if (pos !== -1) { - return {container : container, offset : pos}; - } + if (pos !== -1) { + return {container : container, offset : pos}; + } - lastTextNode = container; - } + 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); + // 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 (pos !== -1) { + return {container : node, offset : pos}; } + } else if (isBlock(node)) { + break; + } + } - if (lastTextNode) { - if (start) { - offset = 0; - } else { - offset = lastTextNode.length; - } + if (lastTextNode) { + if (start) { + offset = 0; + } else { + offset = lastTextNode.length; + } - return {container: lastTextNode, offset: offset}; - } + 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, isTextBlock); + + // 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); + + // Exclude bookmark nodes if possible + if (isBookmarkNode(startContainer.parentNode) || isBookmarkNode(startContainer)) { + startContainer = isBookmarkNode(startContainer) ? startContainer : startContainer.parentNode; + startContainer = startContainer.nextSibling || startContainer; + + if (startContainer.nodeType == 3) + startOffset = 0; + } + + if (isBookmarkNode(endContainer.parentNode) || isBookmarkNode(endContainer)) { + endContainer = isBookmarkNode(endContainer) ? endContainer : endContainer.parentNode; + endContainer = endContainer.previousSibling || endContainer; + + if (endContainer.nodeType == 3) + endOffset = endContainer.length; + } + if (format[0].inline) { + if (rng.collapsed) { // Expand left to closest word boundery endPoint = findWordEndPoint(startContainer, startOffset, true); if (endPoint) { @@ -16067,9 +16501,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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; } } } @@ -16091,29 +16522,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // 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'); @@ -16121,38 +16529,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // 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'); @@ -16289,14 +16665,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { function removeNode(node, format) { var parentNode = node.parentNode, rootBlockElm; - if (format.block) { - if (!forcedRootBlock) { - function find(node, next, inc) { - node = getNonWhiteSpaceSibling(node, next, inc); + function find(node, next, inc) { + node = getNonWhiteSpaceSibling(node, next, inc); - return !node || (node.nodeName == 'BR' || isBlock(node)); - }; + return !node || (node.nodeName == 'BR' || isBlock(node)); + }; + if (format.block) { + if (!forcedRootBlock) { // Append BR elements if needed before we remove the block if (isBlock(node) && !isBlock(parentNode)) { if (!find(node, FALSE) && !find(node.firstChild, TRUE, 1)) @@ -16376,7 +16752,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { value = obj2[name]; // Obj2 doesn't have obj1 item - if (value === undefined) + if (value === undef) return FALSE; // Obj2 item has a different value @@ -16409,20 +16785,20 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { return TRUE; }; - // 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; + 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; - } + if (sibling.nodeType == 1 && !isBookmarkNode(sibling)) + return sibling; + } - return node; - }; + return node; + }; + // Check if next/prev exists and that they are elements + if (prev && next) { // If previous sibling is empty then jump over it prev = findElementSibling(prev, 'previousSibling'); next = findElementSibling(next, 'nextSibling'); @@ -16476,7 +16852,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } // 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; } @@ -16484,17 +16860,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { }; function performCaretAction(type, name, vars) { - var invisibleChar, caretContainerId = '_mce_caret', debug = ed.settings.caret_debug; - - // Setup invisible character use zero width space on Gecko since it doesn't change the heigt of the container - invisibleChar = tinymce.isGecko ? '\u200B' : INVISIBLE_CHAR; + var caretContainerId = '_mce_caret', debug = ed.settings.caret_debug; // Creates a caret container bogus element function createCaretContainer(fill) { var caretContainer = dom.create('span', {id: caretContainerId, 'data-mce-bogus': true, style: debug ? 'color:red' : ''}); if (fill) { - caretContainer.appendChild(ed.getDoc().createTextNode(invisibleChar)); + caretContainer.appendChild(ed.getDoc().createTextNode(INVISIBLE_CHAR)); } return caretContainer; @@ -16502,7 +16875,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { function isCaretContainerEmpty(node, nodes) { while (node) { - if ((node.nodeType === 3 && node.nodeValue !== invisibleChar) || node.childNodes.length > 1) { + if ((node.nodeType === 3 && node.nodeValue !== INVISIBLE_CHAR) || node.childNodes.length > 1) { return false; } @@ -16611,7 +16984,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { // Move selection back to caret position selection.moveToBookmark(bookmark); } else { - if (!caretContainer || textNode.nodeValue !== invisibleChar) { + if (!caretContainer || textNode.nodeValue !== INVISIBLE_CHAR) { caretContainer = createCaretContainer(true); textNode = caretContainer.firstChild; @@ -16637,7 +17010,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { node = container; if (container.nodeType == 3) { - if (offset != container.nodeValue.length || container.nodeValue === invisibleChar) { + if (offset != container.nodeValue.length || container.nodeValue === INVISIBLE_CHAR) { hasContentAfter = true; } @@ -16685,12 +17058,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { node = caretContainer; for (i = parents.length - 1; i >= 0; i--) { - node.appendChild(parents[i].cloneNode(false)); + node.appendChild(dom.clone(parents[i], false)); node = node.firstChild; } // Insert invisible character into inner most format element - node.appendChild(dom.doc.createTextNode(invisibleChar)); + node.appendChild(dom.doc.createTextNode(INVISIBLE_CHAR)); node = node.firstChild; // Insert caret container after the formated node @@ -16701,6 +17074,21 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } }; + // Checks if the parent caret container node isn't empty if that is the case it + // will remove the bogus state on all children that isn't empty + function unmarkBogusCaretParents() { + var i, caretContainer, node; + + caretContainer = getParentCaretContainer(selection.getStart()); + if (caretContainer && !dom.isEmpty(caretContainer)) { + tinymce.walk(caretContainer, function(node) { + if (node.nodeType == 1 && node.id !== caretContainerId && !dom.isEmpty(node)) { + dom.setAttrib(node, 'data-mce-bogus', null); + } + }, 'childNodes'); + } + }; + // Only bind the caret events once if (!self._hasCaretEvents) { // Mark current caret container elements as bogus when getting the contents so we don't end up with empty elements @@ -16720,6 +17108,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { tinymce.each('onMouseUp onKeyUp'.split(' '), function(name) { ed[name].addToTop(function() { removeCaretContainer(); + unmarkBogusCaretParents(); }); }); @@ -16730,8 +17119,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { if (keyCode == 8 || keyCode == 37 || keyCode == 39) { removeCaretContainer(getParentCaretContainer(selection.getStart())); } + + unmarkBogusCaretParents(); }); + // Remove bogus state if they got filled by contents using editor.selection.setContent + selection.onSetContent.add(unmarkBogusCaretParents); + self._hasCaretEvents = true; } @@ -16745,23 +17139,25 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { 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 - 1) { + 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 if (container.nodeType == 1) { nodes = container.childNodes; container = nodes[Math.min(offset, nodes.length - 1)]; - walker = new TreeWalker(container); + 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()) { @@ -16781,24 +17177,33 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', { } } }; - }; })(tinymce); tinymce.onAddEditor.add(function(tinymce, ed) { var filters, fontSizes, dom, settings = ed.settings; - 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); + }); - 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); }); + } + }; - dom.rename(node, 'span'); - }; + if (settings.inline_styles) { + fontSizes = tinymce.explode(settings.font_size_legacy_values); filters = { font : function(dom, node) { @@ -16806,7 +17211,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) { backgroundColor : node.style.backgroundColor, color : node.color, fontFamily : node.face, - fontSize : fontSizes[parseInt(node.size) - 1] + fontSize : fontSizes[parseInt(node.size, 10) - 1] }); }, @@ -16823,16 +17228,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); @@ -16842,3 +17237,575 @@ tinymce.onAddEditor.add(function(tinymce, ed) { } }); +(function(tinymce) { + var TreeWalker = tinymce.dom.TreeWalker; + + tinymce.EnterKey = function(editor) { + var dom = editor.dom, selection = editor.selection, settings = editor.settings, undoManager = editor.undoManager, nonEmptyElementsMap = editor.schema.getNonEmptyElements(); + + function handleEnterKey(evt) { + var rng = selection.getRng(true), tmpRng, editableRoot, container, offset, parentBlock, documentMode, shiftKey, + 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|FORM)$/.test(node.nodeName) && + !/^(fixed|absolute)/i.test(node.style.position) && + dom.getContentEditable(node) !== "true"; + }; + + // Renders empty block on IE + function renderBlockOnIE(block) { + var oldRng; + + if (tinymce.isIE && dom.isBlock(block)) { + oldRng = selection.getRng(); + block.appendChild(dom.create('span', null, '\u00a0')); + selection.select(block); + block.lastChild.outerHTML = ''; + selection.setRng(oldRng); + } + }; + + // Remove the first empty inline element of the block so this: <p><b><em></em></b>x</p> becomes this: <p>x</p> + function trimInlineElementsOnLeftSideOfBlock(block) { + var node = block, firstChilds = [], i; + + // Find inner most first child ex: <p><i><b>*</b></i></p> + while (node = node.firstChild) { + if (dom.isBlock(node)) { + return; + } + + if (node.nodeType == 1 && !nonEmptyElementsMap[node.nodeName.toLowerCase()]) { + firstChilds.push(node); + } + } + + i = firstChilds.length; + while (i--) { + node = firstChilds[i]; + if (!node.hasChildNodes() || (node.firstChild == node.lastChild && node.firstChild.nodeValue === '')) { + dom.remove(node); + } else { + // Remove <a> </a> see #5381 + if (node.nodeName == "A" && (node.innerText || node.textContent) === ' ') { + dom.remove(node); + } + } + } + }; + + // 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, tempElm; + + rng = dom.createRng(); + + if (root.hasChildNodes()) { + walker = new TreeWalker(root, root); + + while (node = walker.current()) { + if (node.nodeType == 3) { + rng.setStart(node, 0); + rng.setEnd(node, 0); + break; + } + + if (nonEmptyElementsMap[node.nodeName.toLowerCase()]) { + rng.setStartBefore(node); + rng.setEndBefore(node); + break; + } + + lastNode = node; + node = walker.next(); + } + + if (!node) { + rng.setStart(lastNode, 0); + rng.setEnd(lastNode, 0); + } + } else { + if (root.nodeName == 'BR') { + 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); + } + } + + 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 + y = dom.getPos(root).y; + if (y < viewPort.y || y + 25 > viewPort.y + viewPort.h) { + editor.getWin().scrollTo(0, y < viewPort.y ? y : y - viewPort.h + 25); // Needs to be hardcoded to roughly one line of text if a huge text block is broken into two blocks + } + }; + + // Creates a new block element by cloning the current one or creating a new one if the name is specified + // This function will also copy any text formatting from the parent block and add it to the new one + function createNewBlock(name) { + var node = container, block, clonedNode, caretNode; + + block = name || parentBlockName == "TABLE" ? dom.create(name || newBlockName) : parentBlock.cloneNode(false); + caretNode = block; + + // Clone any parent styles + if (settings.keep_styles !== false) { + do { + if (/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(node.nodeName)) { + // Never clone a caret containers + if (node.id == '_mce_caret') { + continue; + } + + 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); + } + } + } while (node = node.parentNode); + } + + // BR is needed in empty blocks on non IE browsers + if (!tinymce.isIE) { + caretNode.innerHTML = '<br data-mce-bogus="1">'; + } + + return block; + }; + + // Returns true/false if the caret is at the start/end of the parent block element + function isCaretAtStartOrEndOfBlock(start) { + 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; + } + + // If the caret if before the first element in parentBlock + if (start && container.nodeType == 1 && container == parentBlock.firstChild) { + 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); + + // If caret is in beginning or end of a text block then jump to the next/previous node + if (container.nodeType == 3) { + if (start && offset == 0) { + walker.prev(); + } else if (!start && offset == container.nodeValue.length) { + walker.next(); + } + } + + while (node = walker.current()) { + if (node.nodeType === 1) { + // Ignore bogus elements + if (!node.getAttribute('data-mce-bogus')) { + // Keep empty elements like <img /> <input /> but not trailing br:s like <p>text|<br></p> + name = node.nodeName.toLowerCase(); + if (nonEmptyElementsMap[name] && name !== 'br') { + return false; + } + } + } else if (node.nodeType === 3 && !/^[ \t\r\n]*$/.test(node.nodeValue)) { + return false; + } + + if (start) { + walker.prev(); + } else { + walker.next(); + } + } + + return true; + }; + + // Wraps any text nodes or inline elements in the specified forced root block name + function wrapSelfAndSiblingsInDefaultBlock(container, offset) { + 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 (!parentBlock || !canSplitBlock(parentBlock)) { + parentBlock = parentBlock || editableRoot; + + if (!parentBlock.hasChildNodes()) { + newBlock = dom.create(blockName); + parentBlock.appendChild(newBlock); + rng.setStart(newBlock, 0); + rng.setEnd(newBlock, 0); + return newBlock; + } + + // Find parent that is the first child of parentBlock + node = container; + while (node.parentNode != parentBlock) { + node = node.parentNode; + } + + // Loop left to find start node start wrapping at + while (node && !dom.isBlock(node)) { + startNode = node; + node = node.previousSibling; + } + + if (startNode) { + newBlock = dom.create(blockName); + startNode.parentNode.insertBefore(newBlock, startNode); + + // Start wrapping until we hit a block + node = startNode; + while (node && !dom.isBlock(node)) { + next = node.nextSibling; + newBlock.appendChild(node); + node = next; + } + + // Restore range to it's past location + rng.setStart(container, offset); + rng.setEnd(container, offset); + } + } + + return container; + }; + + // Inserts a block or br before/after or in the middle of a split list of the LI is empty + function handleEmptyListItem() { + function isFirstOrLastLi(first) { + var node = containerBlock[first ? 'firstChild' : 'lastChild']; + + // Find first/last element since there might be whitespace there + while (node) { + if (node.nodeType == 1) { + break; + } + + node = node[first ? 'nextSibling' : 'previousSibling']; + } + + return node === parentBlock; + }; + + newBlock = newBlockName ? createNewBlock(newBlockName) : dom.create('BR'); + + if (isFirstOrLastLi(true) && isFirstOrLastLi()) { + // Is first and last list item then replace the OL/UL with a text block + dom.replace(newBlock, containerBlock); + } else if (isFirstOrLastLi(true)) { + // First LI in list then remove LI and add text block before list + containerBlock.parentNode.insertBefore(newBlock, containerBlock); + } else if (isFirstOrLastLi()) { + // Last LI in list then temove LI and add text block after list + dom.insertAfter(newBlock, containerBlock); + renderBlockOnIE(newBlock); + } else { + // Middle LI in list the split the list and insert a text block in the middle + // Extract after fragment and insert it after the current block + tmpRng = rng.cloneRange(); + tmpRng.setStartAfter(parentBlock); + tmpRng.setEndAfter(containerBlock); + fragment = tmpRng.extractContents(); + dom.insertAfter(fragment, containerBlock); + dom.insertAfter(newBlock, containerBlock); + } + + dom.remove(parentBlock); + moveToCaretPosition(newBlock); + undoManager.add(); + }; + + // Walks the parent block to the right and look for BR elements + function hasRightSideBr() { + var walker = new TreeWalker(container, parentBlock), node; + + while (node = walker.current()) { + if (node.nodeName == 'BR') { + return true; + } + + node = walker.next(); + } + } + + // Inserts a BR element if the forced_root_block option is set to false or empty string + function insertBr() { + var brElm, extraBr, marker; + + if (container && container.nodeType == 3 && offset >= container.nodeValue.length) { + // Insert extra BR element at the end block elements + if (!tinymce.isIE && !hasRightSideBr()) { + brElm = dom.create('br'); + rng.insertNode(brElm); + rng.setStartAfter(brElm); + rng.setEndAfter(brElm); + extraBr = true; + } + } + + brElm = dom.create('br'); + rng.insertNode(brElm); + + // Rendering modes below IE8 doesn't display BR elements in PRE unless we have a \n before it + if (tinymce.isIE && parentBlockName == 'PRE' && (!documentMode || documentMode < 8)) { + brElm.parentNode.insertBefore(dom.doc.createTextNode('\r'), brElm); + } + + // Insert temp marker and scroll to that + marker = dom.create('span', {}, ' '); + brElm.parentNode.insertBefore(marker, brElm); + selection.scrollIntoView(marker); + dom.remove(marker); + + if (!extraBr) { + rng.setStartAfter(brElm); + rng.setEndAfter(brElm); + } else { + rng.setStartBefore(brElm); + rng.setEndBefore(brElm); + } + + selection.setRng(rng); + undoManager.add(); + }; + + // Trims any linebreaks at the beginning of node user for example when pressing enter in a PRE element + function trimLeadingLineBreaks(node) { + do { + if (node.nodeType === 3) { + node.nodeValue = node.nodeValue.replace(/^[\r\n]+/, ''); + } + + 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; + }; + + // Adds a BR at the end of blocks that only contains an IMG or INPUT since these might be floated and then they won't expand the block + function addBrToBlockIfNeeded(block) { + var lastChild; + + // IE will render the blocks correctly other browsers needs a BR + if (!tinymce.isIE) { + block.normalize(); // Remove empty text nodes that got left behind by the extract + + // Check if the block is empty or contains a floated last child + lastChild = block.lastChild; + if (!lastChild || (/^(left|right)$/gi.test(dom.getStyle(lastChild, 'float', true)))) { + dom.add(block, 'br'); + } + } + }; + + // Delete any selected contents + if (!rng.collapsed) { + editor.execCommand('Delete'); + return; + } + + // Event is blocked by some other handler for example the lists plugin + if (evt.isDefaultPrevented()) { + return; + } + + // Setup range items and newBlockName + container = rng.startContainer; + offset = rng.startOffset; + newBlockName = (settings.force_p_newlines ? 'p' : '') || settings.forced_root_block; + newBlockName = newBlockName ? newBlockName.toUpperCase() : ''; + documentMode = dom.doc.documentMode; + shiftKey = evt.shiftKey; + + // 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; + if (isAfterLastNodeInContainer && container.nodeType == 3) { + offset = container.nodeValue.length; + } else { + 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 || 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> + // This won't happen if root blocks are disabled or the shiftKey is pressed + if ((newBlockName && !shiftKey) || (!newBlockName && shiftKey)) { + container = wrapSelfAndSiblingsInDefaultBlock(container, offset); + } + + // Find parent block and setup empty block paddings + parentBlock = dom.getParent(container, dom.isBlock); + containerBlock = parentBlock ? dom.getParent(parentBlock.parentNode, dom.isBlock) : null; + + // Setup block names + parentBlockName = parentBlock ? parentBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 + containerBlockName = containerBlock ? containerBlock.nodeName.toUpperCase() : ''; // IE < 9 & HTML5 + + // Enter inside block contained within a LI then split or insert before/after LI + if (containerBlockName == 'LI' && !evt.ctrlKey) { + parentBlock = containerBlock; + parentBlockName = containerBlockName; + } + + // Handle enter in LI + if (parentBlockName == 'LI') { + if (!newBlockName && shiftKey) { + insertBr(); + return; + } + + // Handle enter inside an empty list item + if (dom.isEmpty(parentBlock)) { + // Let the list plugin or browser handle nested lists for now + if (/^(UL|OL|LI)$/.test(containerBlock.parentNode.nodeName)) { + return false; + } + + handleEmptyListItem(); + return; + } + } + + // Don't split PRE tags but insert a BR instead easier when writing code samples etc + if (parentBlockName == 'PRE' && settings.br_in_pre !== false) { + if (!shiftKey) { + insertBr(); + return; + } + } else { + // If no root block is configured then insert a BR by default or if the shiftKey is pressed + if ((!newBlockName && !shiftKey && parentBlockName != 'LI') || (newBlockName && shiftKey)) { + insertBr(); + return; + } + } + + // Default block name if it's not configured + newBlockName = newBlockName || 'P'; + + // Insert new block before/after the parent block depending on caret location + if (isCaretAtStartOrEndOfBlock()) { + // If the caret is at the end of a header we produce a P tag after it similar to Word unless we are in a hgroup + if (/^(H[1-6]|PRE)$/.test(parentBlockName) && containerBlockName != 'HGROUP') { + newBlock = createNewBlock(newBlockName); + } else { + newBlock = createNewBlock(); + } + + // Split the current container block element if enter is pressed inside an empty inner block element + if (settings.end_container_on_empty_block && canSplitBlock(containerBlock) && dom.isEmpty(parentBlock)) { + // Split container block for example a BLOCKQUOTE at the current blockParent location for example a P + newBlock = dom.split(containerBlock, parentBlock); + } else { + dom.insertAfter(newBlock, parentBlock); + } + + moveToCaretPosition(newBlock); + } else if (isCaretAtStartOrEndOfBlock(true)) { + // Insert new block before + newBlock = parentBlock.parentNode.insertBefore(createNewBlock(), parentBlock); + renderBlockOnIE(newBlock); + } else { + // Extract after fragment and insert it after the current block + tmpRng = rng.cloneRange(); + tmpRng.setEndAfter(parentBlock); + fragment = tmpRng.extractContents(); + trimLeadingLineBreaks(fragment); + newBlock = fragment.firstChild; + dom.insertAfter(fragment, parentBlock); + trimInlineElementsOnLeftSideOfBlock(newBlock); + addBrToBlockIfNeeded(parentBlock); + moveToCaretPosition(newBlock); + } + + dom.setAttrib(newBlock, 'id', ''); // Remove ID since it needs to be document unique + undoManager.add(); + } + + editor.onKeyDown.add(function(ed, evt) { + if (evt.keyCode == 13) { + if (handleEnterKey(evt) !== false) { + evt.preventDefault(); + } + } + }); + }; +})(tinymce); +