]> git.donarmstrong.com Git - roundcube.git/commitdiff
Imported Debian patch 0.5.2+dfsg-1
authorVincent Bernat <bernat@debian.org>
Sat, 23 Apr 2011 22:35:34 +0000 (00:35 +0200)
committerJérémy Bobbio <lunar@debian.org>
Sat, 18 Jun 2011 19:40:14 +0000 (21:40 +0200)
176 files changed:
CHANGELOG
INSTALL
SQL/postgres.initial.sql
SQL/postgres.update.sql
config/main.inc.php.dist
debian/changelog
debian/control
debian/roundcube-core.logrotate
debian/roundcube-core.postinst
index.php
plugins/archive/archive.php
plugins/archive/localization/cs_CZ.inc
plugins/autologon/autologon.php
plugins/help/localization/cs_CZ.inc
plugins/help/localization/ru_RU.inc
plugins/http_authentication/http_authentication.php
plugins/managesieve/Changelog
plugins/managesieve/lib/Net/Sieve.php
plugins/managesieve/lib/rcube_sieve.php
plugins/managesieve/localization/es_ES.inc
plugins/managesieve/localization/fr_FR.inc
plugins/managesieve/localization/pl_PL.inc
plugins/managesieve/localization/ru_RU.inc
plugins/managesieve/managesieve.js
plugins/managesieve/managesieve.php
plugins/managesieve/tests/Makefile [new file with mode: 0644]
plugins/managesieve/tests/parser.phpt [new file with mode: 0644]
plugins/managesieve/tests/tokenize.phpt [new file with mode: 0644]
plugins/markasjunk/localization/cs_CZ.inc
plugins/markasjunk/markasjunk.php
plugins/markasjunk/package.xml
plugins/new_user_identity/new_user_identity.php
plugins/password/README
plugins/password/config.inc.php.dist
plugins/password/drivers/directadmin.php
plugins/password/drivers/ldap.php
plugins/password/drivers/ldap_simple.php
plugins/password/drivers/virtualmin.php
plugins/password/drivers/xmail.php
plugins/password/localization/es_ES.inc
plugins/password/localization/ru_RU.inc
plugins/password/package.xml
plugins/password/password.js
plugins/password/password.php
plugins/show_additional_headers/show_additional_headers.php
plugins/squirrelmail_usercopy/squirrelmail_usercopy.php
plugins/subscriptions_option/localization/cs_CZ.inc
plugins/userinfo/localization/cs_CZ.inc
plugins/vcard_attachments/localization/cs_CZ.inc
plugins/vcard_attachments/localization/es_ES.inc
plugins/vcard_attachments/package.xml
plugins/virtuser_file/virtuser_file.php
plugins/virtuser_query/virtuser_query.php
program/include/iniset.php
program/include/main.inc
program/include/rcmail.php
program/include/rcmail.php.orig [new file with mode: 0644]
program/include/rcube_browser.php
program/include/rcube_imap.php
program/include/rcube_imap_generic.php
program/include/rcube_mdb2.php
program/include/rcube_message.php
program/include/rcube_session.php
program/include/rcube_smtp.php
program/include/rcube_template.php
program/include/rcube_user.php
program/js/app.js
program/js/app.js.src
program/js/common.js
program/js/googiespell.js
program/js/list.js
program/js/list.js.src
program/js/tiny_mce/langs/en.js
program/js/tiny_mce/plugins/contextmenu/editor_plugin.js
program/js/tiny_mce/plugins/contextmenu/editor_plugin_src.js
program/js/tiny_mce/plugins/emotions/emotions.htm
program/js/tiny_mce/plugins/media/css/media.css
program/js/tiny_mce/plugins/media/editor_plugin.js
program/js/tiny_mce/plugins/media/editor_plugin_src.js
program/js/tiny_mce/plugins/media/js/media.js
program/js/tiny_mce/plugins/media/langs/en_dlg.js
program/js/tiny_mce/plugins/media/media.htm
program/js/tiny_mce/plugins/nonbreaking/editor_plugin.js
program/js/tiny_mce/plugins/nonbreaking/editor_plugin_src.js
program/js/tiny_mce/plugins/paste/editor_plugin.js
program/js/tiny_mce/plugins/paste/editor_plugin_src.js
program/js/tiny_mce/plugins/searchreplace/editor_plugin.js
program/js/tiny_mce/plugins/searchreplace/editor_plugin_src.js
program/js/tiny_mce/plugins/searchreplace/js/searchreplace.js
program/js/tiny_mce/plugins/searchreplace/searchreplace.htm
program/js/tiny_mce/plugins/spellchecker/editor_plugin.js
program/js/tiny_mce/plugins/spellchecker/editor_plugin_src.js
program/js/tiny_mce/plugins/tabfocus/editor_plugin.js
program/js/tiny_mce/plugins/tabfocus/editor_plugin_src.js
program/js/tiny_mce/plugins/table/cell.htm
program/js/tiny_mce/plugins/table/editor_plugin.js
program/js/tiny_mce/plugins/table/editor_plugin_src.js
program/js/tiny_mce/plugins/table/js/cell.js
program/js/tiny_mce/plugins/table/js/row.js
program/js/tiny_mce/plugins/table/js/table.js
program/js/tiny_mce/plugins/table/langs/en_dlg.js
program/js/tiny_mce/plugins/table/merge_cells.htm
program/js/tiny_mce/plugins/table/row.htm
program/js/tiny_mce/plugins/table/table.htm
program/js/tiny_mce/plugins/visualchars/editor_plugin.js
program/js/tiny_mce/plugins/visualchars/editor_plugin_src.js
program/js/tiny_mce/themes/advanced/about.htm
program/js/tiny_mce/themes/advanced/anchor.htm
program/js/tiny_mce/themes/advanced/charmap.htm
program/js/tiny_mce/themes/advanced/color_picker.htm
program/js/tiny_mce/themes/advanced/editor_template.js
program/js/tiny_mce/themes/advanced/editor_template_src.js
program/js/tiny_mce/themes/advanced/image.htm
program/js/tiny_mce/themes/advanced/js/about.js
program/js/tiny_mce/themes/advanced/js/anchor.js
program/js/tiny_mce/themes/advanced/js/charmap.js
program/js/tiny_mce/themes/advanced/js/color_picker.js
program/js/tiny_mce/themes/advanced/js/image.js
program/js/tiny_mce/themes/advanced/js/link.js
program/js/tiny_mce/themes/advanced/js/source_editor.js
program/js/tiny_mce/themes/advanced/langs/en.js
program/js/tiny_mce/themes/advanced/langs/en_dlg.js
program/js/tiny_mce/themes/advanced/link.htm
program/js/tiny_mce/themes/advanced/skins/default/content.css
program/js/tiny_mce/themes/advanced/skins/default/ui.css
program/js/tiny_mce/themes/advanced/skins/o2k7/content.css
program/js/tiny_mce/themes/advanced/skins/o2k7/dialog.css
program/js/tiny_mce/themes/advanced/skins/o2k7/ui.css
program/js/tiny_mce/themes/advanced/skins/o2k7/ui_black.css
program/js/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css
program/js/tiny_mce/themes/advanced/source_editor.htm
program/js/tiny_mce/themes/simple/editor_template.js
program/js/tiny_mce/themes/simple/editor_template_src.js
program/js/tiny_mce/tiny_mce.js
program/js/tiny_mce/tiny_mce_popup.js
program/js/tiny_mce/tiny_mce_src.js
program/js/tiny_mce/utils/form_utils.js
program/js/tiny_mce/utils/mctabs.js
program/js/tiny_mce/utils/validate.js
program/lib/html2text.php
program/lib/washtml.php
program/localization/de_CH/labels.inc
program/localization/de_CH/messages.inc
program/localization/de_DE/messages.inc
program/localization/fr_FR/labels.inc
program/localization/index.inc
program/steps/mail/func.inc
program/steps/settings/save_prefs.inc
program/steps/utils/spell_googie.inc
program/steps/utils/spell_html_googie.inc
skins/default/iehacks.css
skins/default/images/abook_toolbar.png
skins/default/images/buttons/bg.gif
skins/default/images/dbutton.png
skins/default/images/dimple.png
skins/default/images/display/icons.png
skins/default/images/icons/expanded.png
skins/default/images/icons/glass.png
skins/default/images/icons/glass_roll.png
skins/default/images/icons/groupactions.png
skins/default/images/listheader.gif
skins/default/images/mail_footer.png
skins/default/images/mail_toolbar.png
skins/default/images/messageicons.png
skins/default/images/pagenav.gif
skins/default/images/searchfield.gif
skins/default/images/tabs-left.gif
skins/default/images/tabs-right.gif
skins/default/images/taskicons.gif
skins/default/images/taskicons.png
skins/default/images/watermark.gif
skins/default/templates/addressbook.html
skins/default/templates/contact.html
skins/default/templates/contactadd.html
skins/default/templates/contactedit.html
skins/default/templates/messageprint.html

index 867472610ce8792d0197905db9f1e54ebd33d6e4..a4cd90bf83636c325d80b5d0586766406667d4b8 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,32 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- TinyMCE 3.4.2 now compatible with IE9
+- PEAR::Net_SMTP 1.5.2, fixed timeout issue (#1487843)
+- Fix bug where template name without plugin prefix was used in render_page hook
+- Support 'abort' and 'result' response in 'preferences_save' hook, add error handling
+- Fix bug where some content would cause hang on html2text conversion (#1487863)
+- Improve space-stuffing handling in format=flowed messages (#1487861)
+- Fix bug where some dates would produce SQL error in MySQL (#1487856)
+- Added workaround for some IMAP server with broken STATUS response (#1487859)
+- Fix bug where default_charset was not used for text messages (#1487836)
+- Stateless request tokens. No keep-alive necessary on login page (#1487829)
+- Force names of unique constraints in PostgreSQL DDL
+- Add code for prevention from IMAP connection hangs when server closes socket unexpectedly
+- Remove redundant DELETE query (for old session deletion) on login
+- Get around unreliable rand() and mt_rand() in session ID generation (#1486281)
+- Fix some emails are not shown using Cyrus IMAP (#1487820)
+- Fix handling of mime-encoded words with non-integral number of octets in a word (#1487801)
+- Fix parsing links with non-printable characters inside (#1487805)
+- Fixed de_CH/de_DE localization bugs (#1487773)
+- Add variable for 'Today' label in date_today option (#1486120)
+- Applied plugin changes since 0.5-stable release
+- Fix SQL query in rcube_user::query() so it uses index on MySQL again
+- Use only one from IMAP authentication methods to prevent login delays (1487784)
+- Fix strftime format support in date_today option
+- Removed redundant </form> tags from contact add/edit pages
+- Fix CSS error in contact details screen on IE7 (#1487775)
+
 RELEASE 0.5.1
 -------------
 - Fix handling of attachments with invalid content type (#1487767)
diff --git a/INSTALL b/INSTALL
index 956fb24cd8ab6de7606b4911e629192e6917f16d..ed51b13614fe8d865846176634c3cc3d2d5ad43f 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -22,7 +22,6 @@ REQUIREMENTS
    - MDB2 2.5.0 or newer
    - Mail_Mime 1.8.1 or newer
    - Net_SMTP 1.4.2 or newer
-   - Net_IDNA2 0.1.1 or newer
    - Auth_SASL 1.0.3 or newer
 * php.ini options (see .htaccess file):
    - error_reporting E_ALL & ~E_NOTICE (or lower)
index 089cae036c584eee08caaaab8e21144e5838800b..d6f4db71f08cf59bc23f194f148d0d13fe3c256c 100644 (file)
@@ -25,7 +25,7 @@ CREATE TABLE users (
     last_login timestamp with time zone DEFAULT NULL,
     "language" varchar(5),
     preferences text DEFAULT ''::text NOT NULL,
-    UNIQUE (username, mail_host)
+    CONSTRAINT users_username_key UNIQUE (username, mail_host)
 );
 
 CREATE INDEX users_alias_id_idx ON users (alias);
@@ -217,7 +217,7 @@ CREATE TABLE messages (
     size integer DEFAULT 0 NOT NULL,
     headers text NOT NULL,
     structure text,
-    UNIQUE (user_id, cache_key, uid)
+    CONSTRAINT messages_user_id_key UNIQUE (user_id, cache_key, uid)
 );
 
 CREATE INDEX messages_index_idx ON messages (user_id, cache_key, idx);
index 2f4498d36897050fa600a100b5955db25e34804e..0ae8d3f7fda5cab464a9ac98e8e443546fd336e9 100644 (file)
@@ -85,7 +85,7 @@ ALTER TABLE users ALTER last_login SET DEFAULT NULL;
 -- Updates from version 0.4.2
 
 DROP INDEX users_username_id_idx;
-ALTER TABLE users ADD UNIQUE (username, mail_host);
+ALTER TABLE users ADD CONSTRAINT users_username_key UNIQUE (username, mail_host);
 ALTER TABLE contacts ALTER email TYPE varchar(255);
 
 TRUNCATE messages;
index ea0092b0d7e25f9f63d5b92be4fd9aefd911f8a1..f00bfa8afe856d9702fc6cfeeb9505a76e85dbf9 100644 (file)
@@ -347,6 +347,7 @@ $rcmail_config['date_short'] = 'D H:i';
 $rcmail_config['date_long'] = 'd.m.Y H:i';
 
 // use this format for today's date display (date or strftime format)
+// Note: $ character will be replaced with 'Today' label
 $rcmail_config['date_today'] = 'H:i';
 
 // store draft message is this mailbox
index 04aa1251f9bd388b3c6a6e1fcf5d71360c9fcbb3..509a625af242332bae25237aaded10958718d5df 100644 (file)
@@ -1,3 +1,12 @@
+roundcube (0.5.2+dfsg-1) unstable; urgency=low
+
+  * New upstream release
+  * Update logrotate configuration. Closes: #619410.
+  * Make debian-db.php owned by root. This really closes: #608976.
+  * Bump Standards-Version. No changes required.
+
+ -- Vincent Bernat <bernat@debian.org>  Sun, 24 Apr 2011 00:35:34 +0200
+
 roundcube (0.5.1+dfsg-7) unstable; urgency=low
 
   * Make dbconfig-common use sqlite by default to ensure that the package
index d4b6c2f1dbdbd204f3301bc4412c5038dfd39058..0f91fb5ddf982ceae4ef6d752ee5f022f78883a3 100644 (file)
@@ -5,7 +5,7 @@ Maintainer: Debian Roundcube Maintainers <pkg-roundcube-maintainers@lists.alioth
 Uploaders: Vincent Bernat <bernat@debian.org>, Romain Beauxis <toots@rastageeks.org>
 Build-Depends: cdbs, debhelper (>= 5), dh-buildinfo, po-debconf, yui-compressor
 Homepage: http://www.roundcube.net/
-Standards-Version: 3.9.1
+Standards-Version: 3.9.2
 Vcs-Svn: svn://svn.debian.org/svn/pkg-roundcube/trunk
 Vcs-Browser: http://svn.debian.org/wsvn/pkg-roundcube/trunk/
 
index 9b6c0a9b57399eeed8e3786e7fe5f974ee486b3a..3d95dadf5d0cbe69c850fbc73e9d3a5007244c53 100644 (file)
@@ -1,6 +1,8 @@
-/var/log/roundcube/sendmail /var/log/roundcube/errors {
-   weekly
-   rotate 4
-   compress
-   missingok
+/var/log/roundcube/errors /var/log/roundcube/sendmail /var/log/roundcube/userlogins {
+  create 0640 www-data adm
+  compress
+  missingok
+  notifempty
+  rotate 52
+  weekly
 }
index f033b52b7a2f89d41ef8fbfd0f37d2c986fdfe66..f07f3d3cefee43000c2687fd9e913563ddbe4718 100644 (file)
@@ -8,7 +8,7 @@ set -e
 . /usr/share/debconf/confmodule
 . /usr/share/dbconfig-common/dpkg/postinst 
 dbc_generate_include=php:/etc/roundcube/debian-db.php
-dbc_generate_include_owner="www-data:www-data"
+dbc_generate_include_owner="root:www-data"
 dbc_generate_include_perms="640"
 dbc_dbfile_owner="www-data:www-data"
 dbc_dbfile_perms="0660"
index 883faa6d659cf321c490d5b3e18d0f2f50d79b25..ff9bc8ec0c1aa254ca567eac31ed954ba7f45acf 100644 (file)
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
 /*
  +-------------------------------------------------------------------------+
  | Roundcube Webmail IMAP Client                                           |
- | Version 0.5.1                                                           |
+ | Version 0.5.2                                                           |
  |                                                                         |
  | Copyright (C) 2005-2011, Roundcube Dev. - Switzerland                   |
  |                                                                         |
@@ -23,7 +23,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                          |
  +-------------------------------------------------------------------------+
 
- $Id: index.php 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: index.php 4674 2011-04-20 09:03:08Z thomasb $
 
 */
 
@@ -95,10 +95,12 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
   }
   else if ($auth['valid'] && !$auth['abort'] &&
         !empty($auth['host']) && !empty($auth['user']) &&
-        $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'])) {
-    // create new session ID
+        $RCMAIL->login($auth['user'], $auth['pass'], $auth['host'])
+  ) {
+    // create new session ID, don't destroy the current session
+    // it was destroyed already by $RCMAIL->kill_session() above
     $RCMAIL->session->remove('temp');
-    $RCMAIL->session->regenerate_id();
+    $RCMAIL->session->regenerate_id(false);
 
     // send auth cookie if necessary
     $RCMAIL->authenticate_session();
@@ -110,7 +112,7 @@ if ($RCMAIL->task == 'login' && $RCMAIL->action == 'login') {
     $query = array();
     if ($url = get_input_value('_url', RCUBE_INPUT_POST)) {
       parse_str($url, $query);
-      
+
       // prevent endless looping on login page
       if ($query['_task'] == 'login')
         unset($query['_task']);
@@ -180,7 +182,7 @@ else {
 
   // check client X-header to verify request origin
   if ($OUTPUT->ajax_call) {
-    if (rc_request_header('X-Roundcube-Request') != $RCMAIL->get_request_token()) {
+    if (rc_request_header('X-Roundcube-Request') != $RCMAIL->get_request_token() && !$RCMAIL->config->get('devel_mode')) {
       header('HTTP/1.1 404 Not Found');
       die("Invalid Request");
     }
index fbb01296d7f10fb08ca58a1ead069f28f44b81a7..843b61217612e611a96a4e410b7fd0fe30d28a38 100644 (file)
@@ -30,6 +30,8 @@ class archive extends rcube_plugin
             'command' => 'plugin.archive',
             'imagepas' => $skin_path.'/archive_pas.png',
             'imageact' => $skin_path.'/archive_act.png',
+            'width' => 32,
+            'height' => 32,
             'title' => 'buttontitle',
             'domain' => $this->ID,
         ),
index 1396fb8e88a77a2eb6086d917a15c065f2741008..bb257bca06332f79a611729e75d4e71039e9fbf5 100644 (file)
@@ -6,7 +6,7 @@
 | language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the Roundcube archive plugin                         |
-| Copyright (C) 2005-2009, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2009, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index bc3d2ee7649d8298be3bc5c80f71191454e35ea3..9601d61a6e4f7b629dce6c54f21dd8c2f0bde13e 100644 (file)
@@ -31,6 +31,8 @@ class autologon extends rcube_plugin
       $args['user'] = 'me';
       $args['pass'] = '******';
       $args['host'] = 'localhost';
+      $args['cookiecheck'] = false;
+      $args['valid'] = true;
     }
   
     return $args;
index 472c753c560faa52ccdefab2dc959a9b1d6f9567..ae8b39a06b271412d5c717e6c2fb58a188d04215 100644 (file)
@@ -6,7 +6,7 @@
 | language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the Roundcube help plugin                            |
-| Copyright (C) 2005-2009, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2009, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index aad0a616ed0ddd7743056492a70dbed56564d600..9f1de410c9b47c8b557205a834a1ec51c71d651a 100644 (file)
@@ -6,7 +6,7 @@
 | plugins/help/localization/ru_RU.inc                                   |
 |                                                                       |
 | Language file of the Roundcube help plugin                            |
-| Copyright (C) 2005-2010, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2010, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index a8003cf463f9a5be6a3d770327efa2fe2fa76a93..6da6488a003ac364de4ad30ed9726d5ce07c2d30 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Make use of an existing HTTP authentication and perform login with the existing user credentials
  *
- * @version 1.1
+ * @version 1.2
  * @author Thomas Bruederli
  */
 class http_authentication extends rcube_plugin
@@ -36,6 +36,7 @@ class http_authentication extends rcube_plugin
     }
     
     $args['cookiecheck'] = false;
+    $args['valid'] = true;
   
     return $args;
   }
index 61d198ce626075822f0896953939ef7ddeac7e86..20e3bb8c654a9aced0e9cd88c10930e7357c97bf 100644 (file)
@@ -1,6 +1,18 @@
+- Fix escaping of backslash character in quoted strings (#1487780)
+- Fix STARTTLS for timsieved < 2.3.10
+- Fix handling of non-safe characters (double-quote, backslash)
+  or UTF-8 characters (dovecot's implementation bug workaround)
+  in script names
+
+* version 3.0 [2011-02-01]
+-----------------------------------------------------------
 - Added support for SASL proxy authentication (#1486691)
 - Fixed parsing of scripts with \r\n line separator
 - Apply forgotten changes for form errors handling
+- Fix multi-line strings parsing (#1487685)
+- Added tests for script parser
+- Rewritten script parser
+- Fix double request when clicking on Filters tab using Firefox
 
 * version 2.10 [2010-10-10]
 -----------------------------------------------------------
index ecc907194136f711adfbc58b017e0ac9e9bf855a..0f6a5f67ad65bc18bceff1a2e6a0fccf71989cc6 100644 (file)
@@ -475,7 +475,9 @@ class Net_Sieve
         if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
             return PEAR::raiseError('Not currently in TRANSACTION state', 1);
         }
-        if (PEAR::isError($res = $this->_doCmd(sprintf('HAVESPACE "%s" %d', $scriptname, $size)))) {
+
+        $command = sprintf('HAVESPACE %s %d', $this->_escape($scriptname), $size);
+        if (PEAR::isError($res = $this->_doCmd($command))) {
             return $res;
         }
         return true;
@@ -740,7 +742,9 @@ class Net_Sieve
         if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
             return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
         }
-        if (PEAR::isError($res = $this->_doCmd(sprintf('DELETESCRIPT "%s"', $scriptname)))) {
+
+        $command = sprintf('DELETESCRIPT %s', $this->_escape($scriptname));
+        if (PEAR::isError($res = $this->_doCmd($command))) {
             return $res;
         }
         return true;
@@ -759,11 +763,12 @@ class Net_Sieve
             return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
         }
 
-        if (PEAR::isError($res = $this->_doCmd(sprintf('GETSCRIPT "%s"', $scriptname)))) {
+        $command = sprintf('GETSCRIPT %s', $this->_escape($scriptname));
+        if (PEAR::isError($res = $this->_doCmd($command))) {
             return $res;
         }
 
-        return preg_replace('/{[0-9]+}\r\n/', '', $res);
+        return preg_replace('/^{[0-9]+}\r\n/', '', $res);
     }
 
     /**
@@ -779,9 +784,12 @@ class Net_Sieve
         if (NET_SIEVE_STATE_TRANSACTION != $this->_state) {
             return PEAR::raiseError('Not currently in AUTHORISATION state', 1);
         }
-        if (PEAR::isError($res = $this->_doCmd(sprintf('SETACTIVE "%s"', $scriptname)))) {
+
+        $command = sprintf('SETACTIVE %s', $this->_escape($scriptname));
+        if (PEAR::isError($res = $this->_doCmd($command))) {
             return $res;
         }
+
         $this->_activeScript = $scriptname;
         return true;
     }
@@ -808,9 +816,10 @@ class Net_Sieve
         $res = explode("\r\n", $res);
         foreach ($res as $value) {
             if (preg_match('/^"(.*)"( ACTIVE)?$/i', $value, $matches)) {
-                $scripts[] = $matches[1];
+                $script_name = stripslashes($matches[1]);
+                $scripts[] = $script_name;
                 if (!empty($matches[2])) {
-                    $activescript = $matches[1];
+                    $activescript = $script_name;
                 }
             }
         }
@@ -833,8 +842,10 @@ class Net_Sieve
         }
 
         $stringLength = $this->_getLineLength($scriptdata);
+        $command      = sprintf("PUTSCRIPT %s {%d+}\r\n%s",
+            $this->_escape($scriptname), $stringLength, $scriptdata);
 
-        if (PEAR::isError($res = $this->_doCmd(sprintf("PUTSCRIPT \"%s\" {%d+}\r\n%s", $scriptname, $stringLength, $scriptdata)))) {
+        if (PEAR::isError($res = $this->_doCmd($command))) {
             return $res;
         }
 
@@ -980,6 +991,28 @@ class Net_Sieve
         return $lastline;
     }
 
+    /**
+     * Receives x bytes from the server.
+     *
+     * @param int $length  Number of bytes to read
+     *
+     * @return string  The server response.
+     */
+    function _recvBytes($length)
+    {
+        $response = '';
+        $response_length = 0;
+
+        while ($response_length < $length) {
+            $response .= $this->_sock->read($length - $response_length);
+            $response_length = $this->_getLineLength($response);
+        }
+
+        $this->_debug("S: " . rtrim($response));
+
+        return $response;
+    }
+
     /**
      * Send a command and retrieves a response from the server.
      *
@@ -1013,11 +1046,11 @@ class Net_Sieve
 
                 if ('NO' == substr($uc_line, 0, 2)) {
                     // Check for string literal error message.
-                    if (preg_match('/^no {([0-9]+)\+?}/i', $line, $matches)) {
-                        $line .= str_replace(
-                            "\r\n", ' ', $this->_sock->read($matches[1] + 2)
-                        );
-                        $this->_debug("S: $line");
+                    if (preg_match('/{([0-9]+)}$/i', $line, $matches)) {
+                        $line = substr($line, 0, -(strlen($matches[1])+2))
+                            . str_replace(
+                                "\r\n", ' ', $this->_recvBytes($matches[1] + 2)
+                            );
                     }
                     return PEAR::raiseError(trim($response . substr($line, 2)), 3);
                 }
@@ -1052,16 +1085,9 @@ class Net_Sieve
                     return PEAR::raiseError(trim($response . $line), 6);
                 }
 
-                if (preg_match('/^{([0-9]+)\+?}/i', $line, $matches)) {
-                    // Matches String Responses.
-                    $str_size = $matches[1] + 2;
-                    $line = '';
-                    $line_length = 0;
-                    while ($line_length < $str_size) {
-                        $line .= $this->_sock->read($str_size - $line_length);
-                        $line_length = $this->_getLineLength($line);
-                    }
-                    $this->_debug("S: $line");
+                if (preg_match('/^{([0-9]+)}/i', $line, $matches)) {
+                    // Matches literal string responses.
+                    $line = $this->_recvBytes($matches[1] + 2);
 
                     if (!$auth) {
                         // Receive the pending OK only if we aren't
@@ -1146,7 +1172,13 @@ class Net_Sieve
 
         // The server should be sending a CAPABILITY response after
         // negotiating TLS. Read it, and ignore if it doesn't.
-        $this->_doCmd();
+        // Doesn't work with older timsieved versions
+        $regexp = '/^CYRUS TIMSIEVED V([0-9.]+)/';
+        if (!preg_match($regexp, $this->_capability['implementation'], $matches)
+            || version_compare($matches[1], '2.3.10', '>=')
+        ) {
+            $this->_doCmd();
+        }
 
         // RFC says we need to query the server capabilities again now that we
         // are under encryption.
@@ -1191,6 +1223,24 @@ class Net_Sieve
         return $string;
     }
 
+    /**
+     * Convert string into RFC's quoted-string or literal-c2s form
+     *
+     * @param string $string The string to convert.
+     *
+     * @return string Result string
+     */
+    function _escape($string)
+    {
+        // Some implementations doesn't allow UTF-8 characters in quoted-string
+        // It's safe to use literal-c2s
+        if (preg_match('/[^\x01-\x09\x0B-\x0C\x0E-\x7F]/', $string)) {
+            return sprintf("{%d+}\r\n%s", $this->_getLineLength($string), $string);
+        }
+
+        return '"' . addcslashes($string, '\\"') . '"';
+    }
+
     /**
      * Write debug text to the current debug output handler.
      *
index 89ae7d496e9ea2d4378383218a74cbeb06b2dd80..64bdb20f02384028655dd7c3bc0ff10f913ba751 100644 (file)
@@ -1,11 +1,11 @@
 <?php
 
-/*
+/**
   Classes for managesieve operations (using PEAR::Net_Sieve)
 
   Author: Aleksander Machniak <alec@alec.pl>
 
-  $Id: rcube_sieve.php 4241 2010-11-20 17:59:50Z alec $
+  $Id: rcube_sieve.php 4555 2011-02-16 10:48:11Z alec $
 
 */
 
@@ -57,7 +57,7 @@ class rcube_sieve
             $this->sieve->setDebug(true, array($this, 'debug_handler'));
         }
 
-        if (PEAR::isError($this->sieve->connect($host, $port, NULL, $usetls))) {
+        if (PEAR::isError($this->sieve->connect($host, $port, null, $usetls))) {
             return $this->_set_error(SIEVE_ERROR_CONNECTION);
         }
 
@@ -414,12 +414,17 @@ class rcube_sieve_script
      * @param  string  Script's text content
      * @param  array   Disabled extensions
      */
-    public function __construct($script, $disabled=NULL)
+    public function __construct($script, $disabled=null)
     {
-        if (!empty($disabled))
-            foreach ($disabled as $ext)
-                if (($idx = array_search($ext, $this->supported)) !== false)
+        if (!empty($disabled)) {
+            // we're working on lower-cased names
+            $disabled = array_map('strtolower', (array) $disabled);
+            foreach ($disabled as $ext) {
+                if (($idx = array_search($ext, $this->supported)) !== false) {
                     unset($this->supported[$idx]);
+                }
+            }
+        }
 
         $this->content = $this->_parse_text($script);
     }
@@ -513,14 +518,11 @@ class rcube_sieve_script
                     $tests[$i] .= 'size :' . ($test['type']=='under' ? 'under ' : 'over ') . $test['arg'];
                     break;
                 case 'true':
-                    $tests[$i] .= ($test['not'] ? 'not true' : 'true');
+                    $tests[$i] .= ($test['not'] ? 'false' : 'true');
                     break;
                 case 'exists':
                     $tests[$i] .= ($test['not'] ? 'not ' : '');
-                    if (is_array($test['arg']))
-                        $tests[$i] .= 'exists ["' . implode('", "', $this->_escape_string($test['arg'])) . '"]';
-                    else
-                        $tests[$i] .= 'exists "' . $this->_escape_string($test['arg']) . '"';
+                    $tests[$i] .= 'exists ' . self::escape_string($test['arg']);
                     break;
                 case 'header':
                     $tests[$i] .= ($test['not'] ? 'not ' : '');
@@ -533,33 +535,34 @@ class rcube_sieve_script
                     }
                     else
                         $tests[$i] .= 'header :' . $test['type'];
-                    
-                    if (is_array($test['arg1']))
-                        $tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['arg1'])) . '"]';
-                    else
-                        $tests[$i] .= ' "' . $this->_escape_string($test['arg1']) . '"';
-
-                    if (is_array($test['arg2']))
-                        $tests[$i] .= ' ["' . implode('", "', $this->_escape_string($test['arg2'])) . '"]';
-                    else
-                        $tests[$i] .= ' "' . $this->_escape_string($test['arg2']) . '"';
 
+                    $tests[$i] .= ' ' . self::escape_string($test['arg1']);
+                    $tests[$i] .= ' ' . self::escape_string($test['arg2']);
                     break;
                 }
                 $i++;
             }
 
-//          $script .= ($idx>0 ? 'els' : '').($rule['join'] ? 'if allof (' : 'if anyof (');
             // disabled rule: if false #....
-            $script .= 'if' . ($rule['disabled'] ? ' false #' : '');
-            $script .= $rule['join'] ? ' allof (' : ' anyof (';
-            if (sizeof($tests) > 1)
-                $script .= implode(", ", $tests);
-            else if (sizeof($tests))
-                $script .= $tests[0];
-            else
-                $script .= 'true';
-            $script .= ")\n{\n";
+            $script .= 'if ' . ($rule['disabled'] ? 'false # ' : '');
+
+            if (empty($tests)) {
+                $tests_str = 'true';
+            }
+            else if (count($tests) > 1) {
+                $tests_str = implode(', ', $tests);
+            }
+            else {
+                $tests_str = $tests[0];
+            }
+
+            if ($rule['join'] || count($tests) > 1) {
+                $script .= sprintf('%s (%s)', $rule['join'] ? 'allof' : 'anyof', $tests_str);
+            }
+            else {
+                $script .= $tests_str;
+            }
+            $script .= "\n{\n";
 
             // action(s)
             foreach ($rule['actions'] as $action) {
@@ -571,7 +574,7 @@ class rcube_sieve_script
                         $script .= ':copy ';
                         array_push($exts, 'copy');
                     }
-                    $script .= "\"" . $this->_escape_string($action['target']) . "\";\n";
+                    $script .= self::escape_string($action['target']) . ";\n";
                     break;
                 case 'redirect':
                     $script .= "\tredirect ";
@@ -579,15 +582,13 @@ class rcube_sieve_script
                         $script .= ':copy ';
                         array_push($exts, 'copy');
                     }
-                    $script .= "\"" . $this->_escape_string($action['target']) . "\";\n";
+                    $script .= self::escape_string($action['target']) . ";\n";
                     break;
                 case 'reject':
                 case 'ereject':
                     array_push($exts, $action['type']);
-                    if (strpos($action['target'], "\n")!==false)
-                        $script .= "\t".$action['type']." text:\n" . $action['target'] . "\n.\n;\n";
-                    else
-                        $script .= "\t".$action['type']." \"" . $this->_escape_string($action['target']) . "\";\n";
+                    $script .= "\t".$action['type']." "
+                        . self::escape_string($action['target']) . ";\n";
                     break;
                 case 'keep':
                 case 'discard':
@@ -597,22 +598,19 @@ class rcube_sieve_script
                 case 'vacation':
                     array_push($exts, 'vacation');
                     $script .= "\tvacation";
-                    if ($action['days'])
+                    if (!empty($action['days']))
                         $script .= " :days " . $action['days'];
-                    if ($action['addresses'])
-                        $script .= " :addresses " . $this->_print_list($action['addresses']);
-                    if ($action['subject'])
-                        $script .= " :subject \"" . $this->_escape_string($action['subject']) . "\"";
-                    if ($action['handle'])
-                        $script .= " :handle \"" . $this->_escape_string($action['handle']) . "\"";
-                    if ($action['from'])
-                        $script .= " :from \"" . $this->_escape_string($action['from']) . "\"";
-                    if ($action['mime'])
+                    if (!empty($action['addresses']))
+                        $script .= " :addresses " . self::escape_string($action['addresses']);
+                    if (!empty($action['subject']))
+                        $script .= " :subject " . self::escape_string($action['subject']);
+                    if (!empty($action['handle']))
+                        $script .= " :handle " . self::escape_string($action['handle']);
+                    if (!empty($action['from']))
+                        $script .= " :from " . self::escape_string($action['from']);
+                    if (!empty($action['mime']))
                         $script .= " :mime";
-                    if (strpos($action['reason'], "\n")!==false)
-                        $script .= " text:\n" . $action['reason'] . "\n.\n;\n";
-                    else
-                        $script .= " \"" . $this->_escape_string($action['reason']) . "\";\n";
+                    $script .= " " . self::escape_string($action['reason']) . ";\n";
                     break;
                 }
             }
@@ -656,9 +654,6 @@ class rcube_sieve_script
         $i = 0;
         $content = array();
 
-        // remove C comments
-        $script = preg_replace('|/\*.*?\*/|sm', '', $script);
-
         // tokenize rules
         if ($tokens = preg_split('/(# rule:\[.*\])\r?\n/', $script, -1, PREG_SPLIT_DELIM_CAPTURE)) {
             foreach($tokens as $token) {
@@ -686,31 +681,118 @@ class rcube_sieve_script
      */
     private function _tokenize_rule($content)
     {
-        $result = NULL;
+        $cond = strtolower(self::tokenize($content, 1));
+
+        if ($cond != 'if' && $cond != 'elsif' && $cond != 'else') {
+            return null;
+        }
+
+        $disabled = false;
+        $join     = false;
+
+        // disabled rule (false + comment): if false # .....
+        if (preg_match('/^\s*false\s+#/i', $content)) {
+            $content = preg_replace('/^\s*false\s+#\s*/i', '', $content);
+            $disabled = true;
+        }
+
+        while (strlen($content)) {
+            $tokens = self::tokenize($content, true);
+            $separator = array_pop($tokens);
+
+            if (!empty($tokens)) {
+                $token = array_shift($tokens);
+            }
+            else {
+                $token = $separator;
+            }
+
+            $token = strtolower($token);
+
+            if ($token == 'not') {
+                $not = true;
+                $token = strtolower(array_shift($tokens));
+            }
+            else {
+                $not = false;
+            }
+
+            switch ($token) {
+            case 'allof':
+                $join = true;
+                break;
+            case 'anyof':
+                break;
+
+            case 'size':
+                $size = array('test' => 'size', 'not'  => $not);
+                for ($i=0, $len=count($tokens); $i<$len; $i++) {
+                    if (!is_array($tokens[$i])
+                        && preg_match('/^:(under|over)$/i', $tokens[$i])
+                    ) {
+                        $size['type'] = strtolower(substr($tokens[$i], 1));
+                    }
+                    else {
+                        $size['arg'] = $tokens[$i];
+                    }
+                }
+
+                $tests[] = $size;
+                break;
+
+            case 'header':
+                $header = array('test' => 'header', 'not' => $not, 'arg1' => '', 'arg2' => '');
+                for ($i=0, $len=count($tokens); $i<$len; $i++) {
+                    if (!is_array($tokens[$i]) && preg_match('/^:comparator$/i', $tokens[$i])) {
+                        $i++;
+                    }
+                    else if (!is_array($tokens[$i]) && preg_match('/^:(count|value)$/i', $tokens[$i])) {
+                        $header['type'] = strtolower(substr($tokens[$i], 1)) . '-' . $tokens[++$i];
+                    }
+                    else if (!is_array($tokens[$i]) && preg_match('/^:(is|contains|matches)$/i', $tokens[$i])) {
+                        $header['type'] = strtolower(substr($tokens[$i], 1));
+                    }
+                    else {
+                        $header['arg1'] = $header['arg2'];
+                        $header['arg2'] = $tokens[$i];
+                    }
+                }
 
-        if (preg_match('/^(if|elsif|else)\s+((true|false|not\s+true|allof|anyof|exists|header|not|size)(.*))\s+\{(.*)\}$/sm',
-            trim($content), $matches)) {
+                $tests[] = $header;
+                break;
 
-            $tests = trim($matches[2]);
+            case 'exists':
+                $tests[] = array('test' => 'exists', 'not'  => $not,
+                    'arg'  => array_pop($tokens));
+                break;
+
+            case 'true':
+                $tests[] = array('test' => 'true', 'not'  => $not);
+                break;
 
-            // disabled rule (false + comment): if false #.....
-            if ($matches[3] == 'false') {
-                $tests = preg_replace('/^false\s+#\s+/', '', $tests);
-                $disabled = true;
+            case 'false':
+                $tests[] = array('test' => 'true', 'not'  => !$not);
+                break;
+            }
+
+            // goto actions...
+            if ($separator == '{') {
+                break;
             }
-            else
-                $disabled = false;
-
-            list($tests, $join) = $this->_parse_tests($tests);
-            $actions = $this->_parse_actions(trim($matches[5]));
-
-            if ($tests && $actions)
-                $result = array(
-                    'type'     => $matches[1],
-                    'tests'    => $tests,
-                    'actions'  => $actions,
-                    'join'     => $join,
-                    'disabled' => $disabled,
+        }
+
+        // ...and actions block
+        if ($tests) {
+            $actions = $this->_parse_actions($content);
+        }
+
+        if ($tests && $actions) {
+            $result = array(
+                'type'     => $cond,
+                'tests'    => $tests,
+                'actions'  => $actions,
+                'join'     => $join,
+                'disabled' => $disabled,
             );
         }
 
@@ -725,94 +807,76 @@ class rcube_sieve_script
      */
     private function _parse_actions($content)
     {
-        $result = NULL;
-
-        // supported actions
-        $patterns[] = '^\s*discard;';
-        $patterns[] = '^\s*keep;';
-        $patterns[] = '^\s*stop;';
-        $patterns[] = '^\s*redirect\s+(.*?[^\\\]);';
-        if (in_array('fileinto', $this->supported))
-            $patterns[] = '^\s*fileinto\s+(.*?[^\\\]);';
-        if (in_array('reject', $this->supported)) {
-            $patterns[] = '^\s*reject\s+text:(.*)\n\.\n;';
-            $patterns[] = '^\s*reject\s+(.*?[^\\\]);';
-            $patterns[] = '^\s*ereject\s+text:(.*)\n\.\n;';
-            $patterns[] = '^\s*ereject\s+(.*?[^\\\]);';
-        }
-        if (in_array('vacation', $this->supported))
-            $patterns[] = '^\s*vacation\s+(.*?[^\\\]);';
+        $result = null;
 
-        $pattern = '/(' . implode('\s*$)|(', $patterns) . '$\s*)/ms';
+        while (strlen($content)) {
+            $tokens = self::tokenize($content, true);
+            $separator = array_pop($tokens);
 
-        // parse actions body
-        if (preg_match_all($pattern, $content, $mm, PREG_SET_ORDER)) {
-            foreach ($mm as $m) {
-                $content = trim($m[0]);
+            if (!empty($tokens)) {
+                $token = array_shift($tokens);
+            }
+            else {
+                $token = $separator;
+            }
 
-                if(preg_match('/^(discard|keep|stop)/', $content, $matches)) {
-                    $result[] = array('type' => $matches[1]);
-                }
-                else if(preg_match('/^fileinto/', $content)) {
-                    $target = $m[sizeof($m)-1];
-                    $copy = false;
-                    if (preg_match('/^:copy\s+/', $target)) {
-                        $target = preg_replace('/^:copy\s+/', '', $target);
+            switch ($token) {
+            case 'discard':
+            case 'keep':
+            case 'stop':
+                $result[] = array('type' => $token);
+                break;
+
+            case 'fileinto':
+            case 'redirect':
+                $copy   = false;
+                $target = '';
+
+                for ($i=0, $len=count($tokens); $i<$len; $i++) {
+                    if (strtolower($tokens[$i]) == ':copy') {
                         $copy = true;
                     }
-                    $result[] = array('type' => 'fileinto', 'copy' => $copy,
-                        'target' => $this->_parse_string($target));
-                }
-                else if(preg_match('/^redirect/', $content)) {
-                    $target = $m[sizeof($m)-1];
-                    $copy = false;
-                    if (preg_match('/^:copy\s+/', $target)) {
-                        $target = preg_replace('/^:copy\s+/', '', $target);
-                        $copy = true;
+                    else {
+                        $target = $tokens[$i];
                     }
-                    $result[] = array('type' => 'redirect', 'copy' => $copy,
-                        'target' => $this->_parse_string($target));
-                }
-                else if(preg_match('/^(reject|ereject)\s+(.*);$/sm', $content, $matches)) {
-                    $result[] = array('type' => $matches[1], 'target' => $this->_parse_string($matches[2]));
                 }
-                else if(preg_match('/^vacation\s+(.*);$/sm', $content, $matches)) {
-                    $vacation = array('type' => 'vacation');
 
-                    if (preg_match('/:days\s+([0-9]+)/', $content, $vm)) {
-                        $vacation['days'] = $vm[1];
-                        $content = preg_replace('/:days\s+([0-9]+)/', '', $content);
+                $result[] = array('type' => $token, 'copy' => $copy,
+                    'target' => $target);
+                break;
+
+            case 'reject':
+            case 'ereject':
+                $result[] = array('type' => $token, 'target' => array_pop($tokens));
+                break;
+
+            case 'vacation':
+                $vacation = array('type' => 'vacation', 'reason' => array_pop($tokens));
+
+                for ($i=0, $len=count($tokens); $i<$len; $i++) {
+                    $tok = strtolower($tokens[$i]);
+                    if ($tok == ':days') {
+                        $vacation['days'] = $tokens[++$i];
                     }
-                    if (preg_match('/:subject\s+"(.*?[^\\\])"/', $content, $vm)) {
-                        $vacation['subject'] = $vm[1];
-                        $content = preg_replace('/:subject\s+"(.*?[^\\\])"/', '', $content);
+                    else if ($tok == ':subject') {
+                        $vacation['subject'] = $tokens[++$i];
                     }
-                    if (preg_match('/:addresses\s+\[(.*?[^\\\])\]/', $content, $vm)) {
-                        $vacation['addresses'] = $this->_parse_list($vm[1]);
-                        $content = preg_replace('/:addresses\s+\[(.*?[^\\\])\]/', '', $content);
+                    else if ($tok == ':addresses') {
+                        $vacation['addresses'] = $tokens[++$i];
                     }
-                    if (preg_match('/:handle\s+"(.*?[^\\\])"/', $content, $vm)) {
-                        $vacation['handle'] = $vm[1];
-                        $content = preg_replace('/:handle\s+"(.*?[^\\\])"/', '', $content);
+                    else if ($tok == ':handle') {
+                        $vacation['handle'] = $tokens[++$i];
                     }
-                    if (preg_match('/:from\s+"(.*?[^\\\])"/', $content, $vm)) {
-                        $vacation['from'] = $vm[1];
-                        $content = preg_replace('/:from\s+"(.*?[^\\\])"/', '', $content);
+                    else if ($tok == ':from') {
+                        $vacation['from'] = $tokens[++$i];
                     }
-
-                    $content = preg_replace('/^vacation/', '', $content);
-                    $content = preg_replace('/;$/', '', $content);
-                    $content = trim($content);
-
-                    if (preg_match('/^:mime/', $content, $vm)) {
+                    else if ($tok == ':mime') {
                         $vacation['mime'] = true;
-                        $content = preg_replace('/^:mime/', '', $content);
                     }
-
-                    $vacation['reason'] = $this->_parse_string($content);
-
-                    $result[] = $vacation;
                 }
+
+                $result[] = $vacation;
+                break;
             }
         }
 
@@ -820,171 +884,196 @@ class rcube_sieve_script
     }
 
     /**
-     * Parse test/conditions section
+     * Escape special chars into quoted string value or multi-line string
+     * or list of strings
      *
-     * @param string Text
+     * @param string $str Text or array (list) of strings
+     *
+     * @return string Result text
      */
-    private function _parse_tests($content)
+    static function escape_string($str)
     {
-        $result = NULL;
+        if (is_array($str) && count($str) > 1) {
+            foreach($str as $idx => $val)
+                $str[$idx] = self::escape_string($val);
 
-        // lists
-        if (preg_match('/^(allof|anyof)\s+\((.*)\)$/sm', $content, $matches)) {
-            $content = $matches[2];
-            $join = $matches[1]=='allof' ? true : false;
+            return '[' . implode(',', $str) . ']';
         }
-        else
-            $join = false;
-
-        // supported tests regular expressions
-        // TODO: comparators, envelope
-        $patterns[] = '(not\s+)?(exists)\s+\[(.*?[^\\\])\]';
-        $patterns[] = '(not\s+)?(exists)\s+(".*?[^\\\]")';
-        $patterns[] = '(not\s+)?(true)';
-        $patterns[] = '(not\s+)?(size)\s+:(under|over)\s+([0-9]+[KGM]{0,1})';
-        $patterns[] = '(not\s+)?(header)\s+:(contains|is|matches)((\s+))\[(.*?[^\\\]")\]\s+\[(.*?[^\\\]")\]';
-        $patterns[] = '(not\s+)?(header)\s+:(contains|is|matches)((\s+))(".*?[^\\\]")\s+(".*?[^\\\]")';
-        $patterns[] = '(not\s+)?(header)\s+:(contains|is|matches)((\s+))\[(.*?[^\\\]")\]\s+(".*?[^\\\]")';
-        $patterns[] = '(not\s+)?(header)\s+:(contains|is|matches)((\s+))(".*?[^\\\]")\s+\[(.*?[^\\\]")\]';
-               $patterns[] = '(not\s+)?(header)\s+:(count\s+"[gtleqn]{2}"|value\s+"[gtleqn]{2}")(\s+:comparator\s+"(.*?[^\\\])")?\s+\[(.*?[^\\\]")\]\s+\[(.*?[^\\\]")\]';
-               $patterns[] = '(not\s+)?(header)\s+:(count\s+"[gtleqn]{2}"|value\s+"[gtleqn]{2}")(\s+:comparator\s+"(.*?[^\\\])")?\s+(".*?[^\\\]")\s+(".*?[^\\\]")';
-               $patterns[] = '(not\s+)?(header)\s+:(count\s+"[gtleqn]{2}"|value\s+"[gtleqn]{2}")(\s+:comparator\s+"(.*?[^\\\])")?\s+\[(.*?[^\\\]")\]\s+(".*?[^\\\]")';
-               $patterns[] = '(not\s+)?(header)\s+:(count\s+"[gtleqn]{2}"|value\s+"[gtleqn]{2}")(\s+:comparator\s+"(.*?[^\\\])")?\s+(".*?[^\\\]")\s+\[(.*?[^\\\]")\]';
-
-        // join patterns...
-        $pattern = '/(' . implode(')|(', $patterns) . ')/';
-
-        // ...and parse tests list
-        if (preg_match_all($pattern, $content, $matches, PREG_SET_ORDER)) {
-            foreach ($matches as $match) {
-                $size = sizeof($match);
-
-                if (preg_match('/^(not\s+)?size/', $match[0])) {
-                    $result[] = array(
-                        'test' => 'size',
-                        'not'  => $match[$size-4] ? true : false,
-                        'type' => $match[$size-2], // under/over
-                        'arg'  => $match[$size-1], // value
-                    );
-                }
-                else if (preg_match('/^(not\s+)?header/', $match[0])) {
-                    $type = $match[$size-5];
-                    if (preg_match('/^(count|value)\s+"([gtleqn]{2})"/', $type, $m))
-                        $type = $m[1] . '-' . $m[2];
-                    
-                    $result[] = array(
-                        'test' => 'header',
-                        'type' => $type, // is/contains/matches
-                                               'not'  => $match[$size-7] ? true : false,
-                        'arg1' => $this->_parse_list($match[$size-2]), // header(s)
-                        'arg2' => $this->_parse_list($match[$size-1]), // string(s)
-                    );
-                }
-                else if (preg_match('/^(not\s+)?exists/', $match[0])) {
-                    $result[] = array(
-                        'test' => 'exists',
-                        'not'  => $match[$size-3] ? true : false,
-                        'arg'  => $this->_parse_list($match[$size-1]), // header(s)
-                    );
-                }
-                else if (preg_match('/^(not\s+)?true/', $match[0])) {
-                    $result[] = array(
-                        'test' => 'true',
-                        'not'  => $match[$size-2] ? true : false,
-                    );
-                }
-            }
+        else if (is_array($str)) {
+            $str = array_pop($str);
         }
 
-        return array($result, $join);
+        // multi-line string
+        if (preg_match('/[\r\n\0]/', $str) || strlen($str) > 1024) {
+            return sprintf("text:\n%s\n.\n", self::escape_multiline_string($str));
+        }
+        // quoted-string
+        else {
+            $replace = array('\\' => '\\\\', '"' => '\\"');
+            $str = str_replace(array_keys($replace), array_values($replace), $str);
+            return '"' . $str . '"';
+        }
     }
 
     /**
-     * Parse string value
+     * Escape special chars in multi-line string value
+     *
+     * @param string $str Text
      *
-     * @param string Text
+     * @return string Text
      */
-    private function _parse_string($content)
+    static function escape_multiline_string($str)
     {
-        $text = '';
-        $content = trim($content);
+        $str = preg_split('/(\r?\n)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE);
 
-        if (preg_match('/^text:(.*)\.$/sm', $content, $matches))
-            $text = trim($matches[1]);
-        else if (preg_match('/^"(.*)"$/', $content, $matches))
-            $text = str_replace('\"', '"', $matches[1]);
+        foreach ($str as $idx => $line) {
+            // dot-stuffing
+            if (isset($line[0]) && $line[0] == '.') {
+                $str[$idx] = '.' . $line;
+            }
+        }
 
-        return $text;
+        return implode($str);
     }
 
     /**
-     * Escape special chars in string value
+     * Splits script into string tokens
+     *
+     * @param string &$str    The script
+     * @param mixed  $num     Number of tokens to return, 0 for all
+     *                        or True for all tokens until separator is found.
+     *                        Separator will be returned as last token.
+     * @param int    $in_list Enable to called recursively inside a list
      *
-     * @param string Text
+     * @return mixed Tokens array or string if $num=1
      */
-    private function _escape_string($content)
+    static function tokenize(&$str, $num=0, $in_list=false)
     {
-        $replace['/"/'] = '\\"';
+        $result = array();
 
-        if (is_array($content)) {
-            for ($x=0, $y=sizeof($content); $x<$y; $x++)
-                $content[$x] = preg_replace(array_keys($replace),
-                    array_values($replace), $content[$x]);
+        // remove spaces from the beginning of the string
+        while (($str = ltrim($str)) !== ''
+            && (!$num || $num === true || count($result) < $num)
+        ) {
+            switch ($str[0]) {
 
-            return $content;
-        }
-        else
-            return preg_replace(array_keys($replace), array_values($replace), $content);
-    }
+            // Quoted string
+            case '"':
+                $len = strlen($str);
 
-    /**
-     * Parse string or list of strings to string or array of strings
-     *
-     * @param string Text
-     */
-    private function _parse_list($content)
-    {
-        $result = array();
+                for ($pos=1; $pos<$len; $pos++) {
+                    if ($str[$pos] == '"') {
+                        break;
+                    }
+                    if ($str[$pos] == "\\") {
+                        if ($str[$pos + 1] == '"' || $str[$pos + 1] == "\\") {
+                            $pos++;
+                        }
+                    }
+                }
+                if ($str[$pos] != '"') {
+                    // error
+                }
+                // we need to strip slashes for a quoted string
+                $result[] = stripslashes(substr($str, 1, $pos - 1));
+                $str      = substr($str, $pos + 1);
+                break;
 
-        for ($x=0, $len=strlen($content); $x<$len; $x++) {
-            switch ($content[$x]) {
-            case '\\':
-                $str .= $content[++$x];
+            // Parenthesized list
+            case '[':
+                $str = substr($str, 1);
+                $result[] = self::tokenize($str, 0, true);
                 break;
-            case '"':
-                if (isset($str)) {
-                    $result[] = $str;
-                    unset($str);
+            case ']':
+                $str = substr($str, 1);
+                return $result;
+                break;
+
+            // list/test separator
+            case ',':
+            // command separator
+            case ';':
+            // block/tests-list
+            case '(':
+            case ')':
+            case '{':
+            case '}':
+                $sep = $str[0];
+                $str = substr($str, 1);
+                if ($num === true) {
+                    $result[] = $sep;
+                    break 2; 
+                }
+                break;
+
+            // bracket-comment
+            case '/':
+                if ($str[1] == '*') {
+                    if ($end_pos = strpos($str, '*/')) {
+                        $str = substr($str, $end_pos + 2);
+                    }
+                    else {
+                        // error
+                        $str = '';
+                    }
                 }
-                else
-                    $str = '';
                 break;
+
+            // hash-comment
+            case '#':
+                if ($lf_pos = strpos($str, "\n")) {
+                    $str = substr($str, $lf_pos);
+                    break;
+                }
+                else {
+                    $str = '';
+                }
+
+            // String atom
             default:
-                if(isset($str))
-                    $str .= $content[$x];
-            break;
+                // empty or one character
+                if ($str === '') {
+                    break 2;
+                }
+                if (strlen($str) < 2) {
+                    $result[] = $str;
+                    $str = '';
+                    break;
+                }
+
+                // tag/identifier/number
+                if (preg_match('/^([a-z0-9:_]+)/i', $str, $m)) {
+                    $str = substr($str, strlen($m[1]));
+
+                    if ($m[1] != 'text:') {
+                        $result[] = $m[1];
+                    }
+                    // multiline string
+                    else {
+                        // possible hash-comment after "text:"
+                        if (preg_match('/^( |\t)*(#[^\n]+)?\n/', $str, $m)) {
+                            $str = substr($str, strlen($m[0]));
+                        }
+                        // get text until alone dot in a line
+                        if (preg_match('/^(.*)\r?\n\.\r?\n/sU', $str, $m)) {
+                            $text = $m[1];
+                            // remove dot-stuffing
+                            $text = str_replace("\n..", "\n.", $text);
+                            $str = substr($str, strlen($m[0]));
+                        }
+                        else {
+                            $text = '';
+                        }
+
+                        $result[] = $text;
+                    }
+                }
+
+                break;
             }
         }
 
-        if (sizeof($result)>1)
-            return $result;
-        else if (sizeof($result) == 1)
-            return $result[0];
-        else
-            return NULL;
+        return $num === 1 ? (isset($result[0]) ? $result[0] : null) : $result;
     }
 
-    /**
-     * Convert array of elements to list of strings
-     *
-     * @param string Text
-     */
-    private function _print_list($list)
-    {
-        $list = (array) $list;
-        foreach($list as $idx => $val)
-            $list[$idx] = $this->_escape_string($val);
-
-        return '["' . implode('","', $list) . '"]';
-    }
 }
index 6130d70188b0c355e076cf3abbffd96bbd0e7c4f..1dad18d991f7e58eb5072e575b60713bbd9c48d7 100644 (file)
@@ -9,7 +9,7 @@ $labels['filteradd'] = 'Agregar filtro';
 $labels['filterdel'] = 'Eliminar filtro';
 $labels['moveup'] = 'Mover arriba';
 $labels['movedown'] = 'Mover abajo';
-$labels['filterallof'] = 'coinidir con todas las reglas siguientes';
+$labels['filterallof'] = 'coincidir con todas las reglas siguientes';
 $labels['filteranyof'] = 'coincidir con alguna de las reglas siguientes';
 $labels['filterany'] = 'todos los mensajes';
 $labels['filtercontains'] = 'contiene';
index 0b494f04117cae3a8d3f3a716d626e94f835d16e..49bd3c676a6c777767dc7c2abfd39c7d1b587742 100644 (file)
@@ -27,6 +27,8 @@ $labels['messagereply'] = 'Répondre avec le message';
 $labels['messagedelete'] = 'Supprimer le message';
 $labels['messagediscard'] = 'Rejeter avec le message';
 $labels['messagecopyto'] = 'Copier le message vers';
+$labels['messagesendcopy'] = 'Envoyer une copie du message Ã ';
+$labels['messagecopyto'] = 'Copier le message vers';
 $labels['messagesendcopy'] = 'Envoyer une copie du message à';
 $labels['messagesrules'] = 'Pour les mails entrants:';
 $labels['messagesactions'] = '...exécuter les actions suivantes:';
index e530619a45f8b5aa80904c34074e3ab5b9f484dd..1fbe65d5b09e6e209e9a7e1c8c7174979ad2352e 100644 (file)
@@ -41,10 +41,10 @@ $labels['vacationaddresses'] = 'Lista dodatkowych adresów odbiorców (oddzielon
 $labels['vacationreason'] = 'Treść (przyczyna nieobecności):';
 $labels['filterset'] = 'Zbiór filtrów';
 $labels['filtersetadd'] = 'Dodaj zbiór filtrów';
-$labels['filtersetdel'] = 'Usuń bierzący zbiór filtrów';
-$labels['filtersetact'] = 'Aktywuj bierzący zbiór filtrów';
-$labels['filtersetdeact'] = 'Deaktywuj bierzący zbiór filtrów';
-$labels['filtersetget'] = 'Pobierz bierzący zbiór filtrów w formacie tekstowym';
+$labels['filtersetdel'] = 'Usuń bieżący zbiór filtrów';
+$labels['filtersetact'] = 'Aktywuj bieżący zbiór filtrów';
+$labels['filtersetdeact'] = 'Deaktywuj bieżący zbiór filtrów';
+$labels['filtersetget'] = 'Pobierz bieżący zbiór filtrów w formacie tekstowym';
 $labels['filterdef'] = 'Definicja filtra';
 $labels['filtersetname'] = 'Nazwa zbioru';
 $labels['newfilterset'] = 'Nowy zbiór filtrów';
index c7c8bb07442e9d8780b95171c7d062cb1bb9580a..c9cd336085d2e87c9fb666eb0d7be02c97ecd08b 100644 (file)
@@ -76,6 +76,18 @@ $labels['countislessthanequal'] = 'количество меньше или ра
 $labels['countequals'] = 'количество равно';
 $labels['countnotequals'] = 'количество не равно';
 $labels['valueisgreaterthan'] = 'значение больше, чем';
+$labels['countisgreaterthan'] = 'кПлОÑ\87еÑ\81Ñ\82вП Ð±ÐŸÐ»Ñ\8cÑ\88е, Ñ\87еЌ';
+$labels['countisgreaterthanequal'] = 'кПлОÑ\87еÑ\81Ñ\82вП Ð±ÐŸÐ»Ñ\8cÑ\88е ÐžÐ»Ðž Ñ\80авМП';
+$labels['countislessthan'] = 'кПлОÑ\87еÑ\81Ñ\82вП ÐŒÐµÐœÑ\8cÑ\88е, Ñ\87еЌ';
+$labels['countislessthanequal'] = 'кПлОÑ\87еÑ\81Ñ\82вП ÐŒÐµÐœÑ\8cÑ\88е ÐžÐ»Ðž Ñ\80авМП';
+$labels['countequals'] = 'кПлОÑ\87еÑ\81Ñ\82вП Ñ\80авМП';
+$labels['countnotequals'] = 'кПлОÑ\87еÑ\81Ñ\82вП ÐœÐµ Ñ\80авМП';
+$labels['valueisgreaterthan'] = 'зМаÑ\87еМОе Ð±ÐŸÐ»Ñ\8cÑ\88е, Ñ\87еЌ';
+$labels['valueisgreaterthanequal'] = 'зМаÑ\87еМОе Ð±ÐŸÐ»Ñ\8cÑ\88е ÐžÐ»Ðž Ñ\80авМП';
+$labels['valueislessthan'] = 'зМаÑ\87еМОе ÐŒÐµÐœÑ\8cÑ\88е, Ñ\87еЌ';
+$labels['valueislessthanequal'] = 'зМаÑ\87еМОе ÐŒÐµÐœÑ\8cÑ\88е ÐžÐ»Ðž Ñ\80авМП';
+$labels['valueequals'] = 'зМаÑ\87еМОе Ñ\80авМП';
+$labels['valuenotequals'] = 'зМаÑ\87еМОе ÐœÐµ Ñ\80авМП';
 $labels['valueisgreaterthanequal'] = 'значение больше или равно';
 $labels['valueislessthan'] = 'значение меньше, чем';
 $labels['valueislessthanequal'] = 'значение меньше или равно';
index 6b96561b495131875ebbf60ce99ef1bf6915d317..04977eb1a9a841d84c038343b817de5b44f80f01 100644 (file)
@@ -7,12 +7,10 @@ if (window.rcmail) {
     var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.managesieve')
       .attr('title', rcmail.gettext('managesieve.managefilters'))
       .html(rcmail.gettext('managesieve.filters'))
-      .bind('click', function(e){ return rcmail.command('plugin.managesieve', this) })
       .appendTo(tab);
 
     // add button and register commands
     rcmail.add_element(tab, 'tabs');
-    rcmail.register_command('plugin.managesieve', function() { rcmail.goto_url('plugin.managesieve') }, true);
     rcmail.register_command('plugin.managesieve-save', function() { rcmail.managesieve_save() }, true);
     rcmail.register_command('plugin.managesieve-add', function() { rcmail.managesieve_add() }, true);
     rcmail.register_command('plugin.managesieve-del', function() { rcmail.managesieve_del() }, true);
index 535f3826502160dd8ae91120fad694ed4068fee4..d8b6084e45bccb517848327e6864fd5bf6f21eb0 100644 (file)
@@ -7,12 +7,12 @@
  * It's clickable interface which operates on text scripts and communicates
  * with server using managesieve protocol. Adds Filters tab in Settings.
  *
- * @version 2.10
+ * @version 3.0
  * @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
  *
  * Configuration (see config.inc.php.dist)
  *
- * $Id: managesieve.php 4241 2010-11-20 17:59:50Z alec $
+ * $Id: managesieve.php 4555 2011-02-16 10:48:11Z alec $
  */
 
 class managesieve extends rcube_plugin
@@ -66,7 +66,7 @@ class managesieve extends rcube_plugin
         $host = rcube_parse_host($this->rc->config->get('managesieve_host', 'localhost'));
         $port = $this->rc->config->get('managesieve_port', 2000);
 
-        $host = idn_to_ascii($host);
+        $host = rcube_idn_to_ascii($host);
 
         // try to connect to managesieve server and to fetch the script
         $this->sieve = new rcube_sieve($_SESSION['username'],
diff --git a/plugins/managesieve/tests/Makefile b/plugins/managesieve/tests/Makefile
new file mode 100644 (file)
index 0000000..072be2f
--- /dev/null
@@ -0,0 +1,7 @@
+
+clean:
+       rm -f *.log *.php *.diff *.exp *.out
+
+
+test:
+       pear run-tests *.phpt
diff --git a/plugins/managesieve/tests/parser.phpt b/plugins/managesieve/tests/parser.phpt
new file mode 100644 (file)
index 0000000..a3b820d
--- /dev/null
@@ -0,0 +1,103 @@
+--TEST--
+Main test of script parser
+--SKIPIF--
+--FILE--
+<?php
+include('../lib/rcube_sieve.php');
+
+$txt = '
+require ["fileinto","vacation","reject","relational","comparator-i;ascii-numeric"];
+# rule:[spam]
+if anyof (header :contains "X-DSPAM-Result" "Spam")
+{
+       fileinto "Spam";
+       stop;
+}
+# rule:[test1]
+if anyof (header :contains ["From","To"] "test@domain.tld")
+{
+       discard;
+       stop;
+}
+# rule:[test2]
+if anyof (not header :contains ["Subject"] "[test]", header :contains "Subject" "[test2]")
+{
+       fileinto "test";
+       stop;
+}
+# rule:[test-vacation]
+if anyof (header :contains "Subject" "vacation")
+{
+       vacation :days 1 text:
+# test
+test test /* test */
+test
+.
+;
+       stop;
+}
+# rule:[comments]
+if anyof (true) /* comment
+ * "comment" #comment */ {
+    /* comment */ stop;
+# comment
+}
+# rule:[reject]
+if size :over 5000K {
+    reject "Message over 5MB size limit. Please contact me before sending this.";
+}
+# rule:[redirect]
+if header :value "ge" :comparator "i;ascii-numeric"
+    ["X-Spam-score"] ["14"] {redirect "test@test.tld";}
+';
+
+$s = new rcube_sieve_script($txt);
+echo $s->as_text();
+
+?>
+--EXPECT--
+require ["fileinto","vacation","reject","relational","comparator-i;ascii-numeric"];
+# rule:[spam]
+if header :contains "X-DSPAM-Result" "Spam"
+{
+       fileinto "Spam";
+       stop;
+}
+# rule:[test1]
+if header :contains ["From","To"] "test@domain.tld"
+{
+       discard;
+       stop;
+}
+# rule:[test2]
+if anyof (not header :contains "Subject" "[test]", header :contains "Subject" "[test2]")
+{
+       fileinto "test";
+       stop;
+}
+# rule:[test-vacation]
+if header :contains "Subject" "vacation"
+{
+       vacation :days 1 text:
+# test
+test test /* test */
+test
+.
+;
+       stop;
+}
+# rule:[comments]
+if true
+{
+       stop;
+}
+# rule:[reject]
+if size :over 5000K
+{
+       reject "Message over 5MB size limit. Please contact me before sending this.";
+}
+# rule:[redirect]
+if header :value "ge" :comparator "i;ascii-numeric" "X-Spam-score" "14"
+{
+       redirect "test@test.tld";
+}
diff --git a/plugins/managesieve/tests/tokenize.phpt b/plugins/managesieve/tests/tokenize.phpt
new file mode 100644 (file)
index 0000000..d1f68ac
--- /dev/null
@@ -0,0 +1,66 @@
+--TEST--
+Script parsing: tokenizer
+--SKIPIF--
+--FILE--
+<?php
+include('../lib/rcube_sieve.php');
+
+$txt[1] = array(1, 'text: #test
+This is test ; message;
+Multi line
+.
+;
+');
+$txt[2] = array(0, '["test1","test2"]');
+$txt[3] = array(1, '["test"]');
+$txt[4] = array(1, '"te\\"st"');
+$txt[5] = array(0, 'test #comment');
+$txt[6] = array(0, 'text:
+test
+.
+text:
+test
+.
+');
+$txt[7] = array(1, '"\\a\\\\\\"a"');
+
+foreach ($txt as $idx => $t) {
+    echo "[$idx]---------------\n"; 
+    var_dump(rcube_sieve_script::tokenize($t[1], $t[0]));
+}
+?>
+--EXPECT--
+[1]---------------
+string(34) "This is test ; message;
+Multi line"
+[2]---------------
+array(1) {
+  [0]=>
+  array(2) {
+    [0]=>
+    string(5) "test1"
+    [1]=>
+    string(5) "test2"
+  }
+}
+[3]---------------
+array(1) {
+  [0]=>
+  string(4) "test"
+}
+[4]---------------
+string(5) "te"st"
+[5]---------------
+array(1) {
+  [0]=>
+  string(4) "test"
+}
+[6]---------------
+array(2) {
+  [0]=>
+  string(4) "test"
+  [1]=>
+  string(4) "test"
+}
+[7]---------------
+string(4) "a\"a"
index c547e5a441213f7bf185f4880e5dfbb2e226dd88..18509cf510bad2c563589cfd5eb97bcfb021c425 100644 (file)
@@ -6,7 +6,7 @@
 | language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the Roundcube markasjunk plugin                      |
-| Copyright (C) 2005-2009, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2009, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index 4c15a270f87a6a97851c5f998d311d89a2820f1e..697d880ca2738e8e75214f60ee00e3a045e8286f 100644 (file)
@@ -27,7 +27,9 @@ class markasjunk extends rcube_plugin
         'command' => 'plugin.markasjunk',
         'imagepas' => $skin_path.'/junk_pas.png',
         'imageact' => $skin_path.'/junk_act.png',
-       'title' => 'markasjunk.buttontitle'), 'toolbar');
+        'width' => 32,
+        'height' => 32,
+        'title' => 'markasjunk.buttontitle'), 'toolbar');
     }
   }
 
index 8ca7b18dedb14603bdfa9eb2f8a10d5e792af8d8..d76bd0c28121e6627bccabfd8239909987a5b30a 100644 (file)
@@ -42,6 +42,7 @@
                        <file name="localization/es_AR.inc" role="data"></file>
                        <file name="localization/es_ES.inc" role="data"></file>
                        <file name="localization/et_EE.inc" role="data"></file>
+                       <file name="localization/gl_ES.inc" role="data"></file>
                        <file name="localization/ja_JP.inc" role="data"></file>
                        <file name="localization/pl_PL.inc" role="data"></file>
                        <file name="localization/ru_RU.inc" role="data"></file>
index ecdf7c137830bbc00289e5510b1cd1c4d7b63b8e..45750facd46d9ddf5d0a14efbc0df700c6cfa323 100644 (file)
@@ -40,7 +40,7 @@ class new_user_identity extends rcube_plugin
             if (count($results->records) == 1) {
                 $args['user_name'] = $results->records[0]['name'];
                 if (!$args['user_email'] && strpos($results->records[0]['email'], '@')) {
-                    $args['user_email'] = idn_to_ascii($results->records[0]['email']);
+                    $args['user_email'] = rcube_idn_to_ascii($results->records[0]['email']);
                 }
             }
         }
index a31a0e07642a9d6f9efa6c722fa491bf925b9427..81e4f1ead9ce52d5dd7edb9c80fe5031a4ba1abc 100644 (file)
 
  As in sasl driver this one allows to change password using shell
  utility called "virtualmin". See drivers/chgvirtualminpasswd.c for
- installation instructions.
+ installation instructions. See also config.inc.php.dist file.
 
 
  2.9. hMailServer (hmail)
index 54e9e51c67795e6bc0b190ca410d4f3e252f2b82..ddf8812170887f4f2ed210f9824b8825c198e6c4 100644 (file)
@@ -18,6 +18,9 @@ $rcmail_config['password_minimum_length'] = 0;
 // Change to false to remove this check.
 $rcmail_config['password_require_nonalpha'] = false;
 
+// Enables logging of password changes into logs/password
+$rcmail_config['password_log'] = false;
+
 
 // SQL Driver options
 // ------------------
@@ -195,8 +198,15 @@ $rcmail_config['password_ldap_force_replace'] = true;
 // Whenever the password is changed, the attribute will be updated if set (e.g. shadowLastChange)
 $rcmail_config['password_ldap_lchattr'] = '';
 
-// Also try to update Samba password attributes: sambaNTPassword and sambaPwdLastSet
-$rcmail_config['password_ldap_samba'] = false;
+// LDAP Samba password attribute, e.g. sambaNTPassword
+// Name of the LDAP's Samba attribute used for storing user password
+$rcmail_config['password_ldap_samba_pwattr'] = '';
+// LDAP Samba Password Last Change Date attribute, e.g. sambaPwdLastSet
+// Some places use an attribute to store the date of the last password change
+// The date is meassured in "seconds since epoch" (an integer value)
+// Whenever the password is changed, the attribute will be updated if set
+$rcmail_config['password_ldap_samba_lchattr'] = '';
 
 
 // DirectAdmin Driver options
@@ -275,3 +285,16 @@ $rcmail_config['hmailserver_server'] = array(
     'Password' => 'password' // windows user password
 );
 
+
+// Virtualmin Driver options
+// -------------------------
+// Username format:
+// 0: username@domain
+// 1: username%domain
+// 2: username.domain
+// 3: domain.username
+// 4: username-domain
+// 5: domain-username
+// 6: username_domain
+// 7: domain_username
+$rcmail_config['password_virtualmin_format'] = 0;
index d11aae70a5c213662e69a40a1a18fb3e2bd837c7..6ca3264c5bf61ed5a9f2d266dc3421ad8758bd3d 100644 (file)
@@ -316,8 +316,8 @@ class HTTPSocket {
             }
 
         }
-        
-        list($this->result_header,$this->result_body) = split("\r\n\r\n",$this->result,2);
+
+        list($this->result_header, $this->result_body) = explode("\r\n\r\n", $this->result, 2);
 
         if ($this->bind_host)
         {
@@ -378,7 +378,7 @@ class HTTPSocket {
         {
             if ($asArray)
             {
-                return split("\n",$this->fetch_body());
+                return explode("\n", $this->fetch_body());
             }
 
             return $this->fetch_body();
@@ -438,14 +438,14 @@ class HTTPSocket {
      */
     function fetch_header( $header = '' )
     {
-        $array_headers = split("\r\n",$this->result_header);
-        
+        $array_headers = explode("\r\n", $this->result_header);
+
         $array_return = array( 0 => $array_headers[0] );
         unset($array_headers[0]);
 
         foreach ( $array_headers as $pair )
         {
-            list($key,$value) = split(": ",$pair,2);
+            list($key,$value) = explode(": ", $pair, 2);
             $array_return[strtolower($key)] = $value;
         }
 
index e4d91fe1b61daaa47173ffea33a9ad20602c5403..a18f349d7b854f55248af5f92229b57e9aa005d2 100644 (file)
@@ -62,43 +62,59 @@ function password_save($curpass, $passwd)
         return PASSWORD_CONNECT_ERROR;
     }
 
-    // Crypting new password
-    $newCryptedPassword = hashPassword($passwd, $rcmail->config->get('password_ldap_encodage'));
-    if (!$newCryptedPassword) {
+    $crypted_pass = hashPassword($passwd, $rcmail->config->get('password_ldap_encodage'));
+    $force        = $rcmail->config->get('password_ldap_force_replace');
+    $pwattr       = $rcmail->config->get('password_ldap_pwattr');
+    $lchattr      = $rcmail->config->get('password_ldap_lchattr');
+    $smbpwattr    = $rcmail->config->get('password_ldap_samba_pwattr');
+    $smblchattr   = $rcmail->config->get('password_ldap_samba_lchattr');
+    $samba        = $rcmail->config->get('password_ldap_samba');
+
+    // Support password_ldap_samba option for backward compat.
+    if ($samba && !$smbpwattr) {
+        $smbpwattr  = 'sambaNTPassword';
+        $smblchattr = 'sambaPwdLastSet';
+    }
+
+    // Crypt new password
+    if (!$crypted_pass) {
         return PASSWORD_CRYPT_ERROR;
     }
 
+    // Crypt new samba password
+    if ($smbpwattr && !($samba_pass = hashPassword($passwd, 'samba'))) {
+           return PASSWORD_CRYPT_ERROR;
+    }
+
     // Writing new crypted password to LDAP
     $userEntry = $ldap->getEntry($userDN);
     if (Net_LDAP2::isError($userEntry)) {
         return PASSWORD_CONNECT_ERROR;
     }
 
-    $pwattr = $rcmail->config->get('password_ldap_pwattr');
-    $force = $rcmail->config->get('password_ldap_force_replace');
-
-    if (!$userEntry->replace(array($pwattr => $newCryptedPassword), $force)) {
+    if (!$userEntry->replace(array($pwattr => $crypted_pass), $force)) {
         return PASSWORD_CONNECT_ERROR;
     }
 
     // Updating PasswordLastChange Attribute if desired
-    if ($lchattr = $rcmail->config->get('password_ldap_lchattr')) {
+    if ($lchattr) {
        $current_day = (int)(time() / 86400);
        if (!$userEntry->replace(array($lchattr => $current_day), $force)) {
            return PASSWORD_CONNECT_ERROR;
        }
     }
 
-    if (Net_LDAP2::isError($userEntry->update())) {
-        return PASSWORD_CONNECT_ERROR;
+    // Update Samba password and last change fields
+    if ($smbpwattr) {
+        $userEntry->replace(array($smbpwattr => $samba_pass), $force);
+    }
+    // Update Samba password last change field
+    if ($smblchattr) {
+        $userEntry->replace(array($smblchattr => time()), $force);
     }
 
-    // Update Samba password fields, ignore errors if attributes are not found
-    if ($rcmail->config->get('password_ldap_samba')) {
-        $sambaNTPassword = hash('md4', rcube_charset_convert($passwd, RCMAIL_CHARSET, 'UTF-16LE'));
-        $userEntry->replace(array('sambaNTPassword' => $sambaNTPassword), $force);
-        $userEntry->replace(array('sambaPwdLastSet' => time()), $force);
-        $userEntry->update();
+    if (Net_LDAP2::isError($userEntry->update())) {
+        return PASSWORD_CONNECT_ERROR;
     }
 
     // All done, no error
@@ -253,6 +269,15 @@ function hashPassword( $passwordClear, $encodageType )
             }
             break;
 
+        case 'samba':
+            if (function_exists('hash')) {
+                $cryptedPassword = hash('md4', rcube_charset_convert($password_clear, RCMAIL_CHARSET, 'UTF-16LE'));
+            } else {
+                               /* Your PHP install does not have the hash() function */
+                               return false;
+            }
+            break;
+
         case 'clear':
         default:
             $cryptedPassword = $passwordClear;
index 67f53d0917f1ebb7c2926d18ff0805f5313b4a2f..482b7e56fc4ea27a5e5582b153c578344d0d1ba6 100644 (file)
@@ -14,19 +14,19 @@ function password_save($curpass, $passwd)
 {
        $rcmail = rcmail::get_instance();
 
-       /* Connect */
+       // Connect
        if (!$ds = ldap_connect($rcmail->config->get('password_ldap_host'), $rcmail->config->get('password_ldap_port'))) {
                ldap_unbind($ds);
                return PASSWORD_CONNECT_ERROR;
        }
 
-       /* Set protocol version */
+       // Set protocol version
        if (!ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $rcmail->config->get('password_ldap_version'))) {
                ldap_unbind($ds);
                return PASSWORD_CONNECT_ERROR;
        }
 
-       /* Start TLS */
+       // Start TLS
        if ($rcmail->config->get('password_ldap_starttls')) {
                if (!ldap_start_tls($ds)) {
                        ldap_unbind($ds);
@@ -34,7 +34,7 @@ function password_save($curpass, $passwd)
                }
        }
 
-       /* Build user DN */
+       // Build user DN
        if ($user_dn = $rcmail->config->get('password_ldap_userDN_mask')) {
                $user_dn = ldap_simple_substitute_vars($user_dn);
        } else {
@@ -46,7 +46,7 @@ function password_save($curpass, $passwd)
                return PASSWORD_CONNECT_ERROR;
        }
 
-       /* Connection method */
+       // Connection method
        switch ($rcmail->config->get('password_ldap_method')) {
                case 'admin':
                        $binddn = $rcmail->config->get('password_ldap_adminDN');
@@ -59,31 +59,51 @@ function password_save($curpass, $passwd)
                        break;
        }
 
-       /* Bind */
-       if (!ldap_bind($ds, $binddn, $bindpw)) {
-               ldap_unbind($ds);
-               return PASSWORD_CONNECT_ERROR;
-       }
 
-       /* Crypting new password */
        $crypted_pass = ldap_simple_hash_password($passwd, $rcmail->config->get('password_ldap_encodage'));
+       $lchattr      = $rcmail->config->get('password_ldap_lchattr');
+       $pwattr       = $rcmail->config->get('password_ldap_pwattr');
+    $smbpwattr    = $rcmail->config->get('password_ldap_samba_pwattr');
+    $smblchattr   = $rcmail->config->get('password_ldap_samba_lchattr');
+    $samba        = $rcmail->config->get('password_ldap_samba');
+
+    // Support password_ldap_samba option for backward compat.
+    if ($samba && !$smbpwattr) {
+        $smbpwattr  = 'sambaNTPassword';
+        $smblchattr = 'sambaPwdLastSet';
+    }
+
+       // Crypt new password
        if (!$crypted_pass) {
-               ldap_unbind($ds);
                return PASSWORD_CRYPT_ERROR;
        }
 
-       $entree[$rcmail->config->get('password_ldap_pwattr')] = $crypted_pass;
+    // Crypt new Samba password
+    if ($smbpwattr && !($samba_pass = ldap_simple_hash_password($passwd, 'samba'))) {
+           return PASSWORD_CRYPT_ERROR;
+    }
 
-       /* Updating PasswordLastChange Attribute if desired */
-       if ($lchattr = $rcmail->config->get('password_ldap_lchattr')) {
+       // Bind
+       if (!ldap_bind($ds, $binddn, $bindpw)) {
+               ldap_unbind($ds);
+               return PASSWORD_CONNECT_ERROR;
+       }
+
+       $entree[$pwattr] = $crypted_pass;
+
+       // Update PasswordLastChange Attribute if desired
+       if ($lchattr) {
                $entree[$lchattr] = (int)(time() / 86400);
        }
 
-    /* Update Samba password fields */
-    if ($smbattr = $rcmail->config->get('password_ldap_samba')) {
-        $sambaNTPassword = hash('md4', rcube_charset_convert($passwd, RCMAIL_CHARSET, 'UTF-16LE'));
-        $entree['sambaNTPassword'] = $sambaNTPassword;
-        $entree['sambaPwdLastSet'] = time();
+    // Update Samba password
+    if ($smbpwattr) {
+        $entree[$smbpwattr] = $samba_pass;
+    }
+
+    // Update Samba password last change
+    if ($smblchattr) {
+        $entree[$smblchattr] = time();
     }
 
        if (!ldap_modify($ds, $user_dn, $entree)) {
@@ -91,7 +111,7 @@ function password_save($curpass, $passwd)
                return PASSWORD_CONNECT_ERROR;
        }
 
-       /* All done, no error */
+       // All done, no error
        ldap_unbind($ds);
        return PASSWORD_SUCCESS;
 }
@@ -215,6 +235,14 @@ function ldap_simple_hash_password($password_clear, $encodage_type)
                                return false;
                        }
                        break;
+        case 'samba':
+            if (function_exists('hash')) {
+                $crypted_password = hash('md4', rcube_charset_convert($password_clear, RCMAIL_CHARSET, 'UTF-16LE'));
+            } else {
+                               /* Your PHP install does not have the hash() function */
+                               return false;
+            }
+            break;
                case 'clear':
                default:
                        $crypted_password = $password_clear;
index 96200d61c1cc7cbcf8193253335ce4f50e40fe23..78ef4e7c3861bc496b907223ce59fd507fd67c96 100644 (file)
  * It only works with virtualmin on the same host where Roundcube runs
  * and requires shell access and gcc in order to compile the binary.
  *
- * @version 1.0
+ * @version 2.0
  * @author Martijn de Munnik
  */
 
 function password_save($currpass, $newpass)
 {
-    $curdir = realpath(dirname(__FILE__));
-    $username = escapeshellcmd($_SESSION['username']);
-    $domain = substr(strrchr($username, "@"), 1);
+    $rcmail = rcmail::get_instance();
+
+    $format   = $rcmail->config->get('password_virtualmin_format', 0);
+    $username = $_SESSION['username'];
+
+    switch ($format) {
+        case 1: // username%domain
+            $domain = substr(strrchr($username, "%"), 1);
+            break;
+        case 2: // username.domain (could be bogus)
+            $pieces = explode(".", $username);
+            $domain = $pieces[count($pieces)-2]. "." . end($pieces);
+            break;
+        case 3: // domain.username (could be bogus)
+            $pieces = explode(".", $username);
+            $domain = $pieces[0]. "." . $pieces[1];
+            break;
+        case 4: // username-domain
+            $domain = substr(strrchr($username, "-"), 1);
+            break;
+        case 5: // domain-username
+            $domain = str_replace(strrchr($username, "-"), "", $username);
+            break;
+        case 6: // username_domain
+            $domain = substr(strrchr($username, "_"), 1);
+            break;
+        case 7: // domain_username
+            $pieces = explode("_", $username);
+            $domain = $pieces[0];
+            break;
+        default: // username@domain
+            $domain = substr(strrchr($username, "@"), 1);
+    }
+                                                                                                                                                                                                                                                                                                            
+    $username = escapeshellcmd($username);
+    $domain   = escapeshellcmd($domain);
+    $newpass  = escapeshellcmd($newpass);
+    $curdir   = realpath(dirname(__FILE__));
 
     exec("$curdir/chgvirtualminpasswd modify-user --domain $domain --user $username --pass $newpass", $output, $returnvalue);
 
index 39d1e71863ac9b0873fbecccb549cadb1793290d..c7f4261587f8e381794c3c28cd7d101865453ba7 100644 (file)
@@ -20,7 +20,7 @@
 function password_save($currpass, $newpass)
 {
     $rcmail = rcmail::get_instance();
-    list($user,$domain) = split('@',$_SESSION['username']);
+    list($user,$domain) = explode('@', $_SESSION['username']);
 
     $xmail = new XMail;
 
index b9a9c1626398428f3d95c6a4fb82e8867fed9d93..32879b4aa254a138e2dcebd6a129cc711ee79fa5 100644 (file)
@@ -1,21 +1,21 @@
 <?php
 
 $labels = array();
-$labels['changepasswd']  = 'Cambiar Contraseña';
-$labels['curpasswd']  = 'Contraseña Actual:';
-$labels['newpasswd']  = 'Contraseña Nueva:';
-$labels['confpasswd']  = 'Confirmar Contraseña:';
+$labels['changepasswd']  = 'Cambiar contraseña';
+$labels['curpasswd']  = 'Contraseña actual:';
+$labels['newpasswd']  = 'Contraseña nueva:';
+$labels['confpasswd']  = 'Confirmar contraseña:';
 
 $messages = array();
-$messages['nopassword'] = 'Por favor introduce una nueva contraseña.';
-$messages['nocurpassword'] = 'Por favor introduce la contraseña actual.';
-$messages['passwordincorrect'] = 'Contraseña actual incorrecta.';
-$messages['passwordinconsistency'] = 'Las contraseñas no coinciden, por favor inténtalo de nuevo.';
+$messages['nopassword'] = 'Por favor introduzca una contraseña nueva.';
+$messages['nocurpassword'] = 'Por favor introduzca la contraseña actual.';
+$messages['passwordincorrect'] = 'La contraseña actual es incorrecta.';
+$messages['passwordinconsistency'] = 'Las contraseñas no coinciden. Por favor, inténtelo de nuevo.';
 $messages['crypterror'] = 'No se pudo guardar la contraseña nueva. Falta la función de cifrado.';
 $messages['connecterror'] = 'No se pudo guardar la contraseña nueva. Error de conexión';
 $messages['internalerror'] = 'No se pudo guardar la contraseña nueva.';
-$messages['passwordshort'] = 'Tu contraseña debe tener una longitud mínima de $length.';
-$messages['passwordweak'] = 'Tu nueva contraseña debe incluir al menos un número y un signo de puntuación.';
-$messages['passwordforbidden'] = 'La contraseña contiene caracteres prohibidos.';
+$messages['passwordshort'] = 'La contraseña debe tener por lo menos $length caracteres.';
+$messages['passwordweak'] = 'La contraseña debe incluir al menos un número y un signo de puntuación.';
+$messages['passwordforbidden'] = 'La contraseña introducida contiene caracteres no permitidos.';
 
 ?>
index 5a108d660a466668fdb8fb1658ca52484ba7232c..3776b45983e29a4a228f7e47d8aafd94b709a977 100644 (file)
@@ -5,7 +5,7 @@
 | plugins/password/localization/ru_RU.inc                               |
 |                                                                       |
 | Language file of the Roundcube help plugin                            |
-| Copyright (C) 2005-2010, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2010, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index 1d63142d9dd2d47f8736457e69062b4ec62837f6..a4827dfd0f40db6f9e68bd2f4c3504b58991ed45 100644 (file)
@@ -15,8 +15,8 @@
                <email>alec@alec.pl</email>
                <active>yes</active>
        </lead>
-       <date></date>
-       <time></time>
+       <date>2011-02-15</date>
+       <time>12:00</time>
        <version>
                <release>2.2</release>
                <api>1.6</api>
 - ldap_simple driver: fix parse error
 - ldap/ldap_simple drivers: support %dc variable in config
 - ldap/ldap_simple drivers: support Samba password change
+- Fix extended error messages handling (#1487676)
+- Fix double request when clicking on Password tab in Firefox
+- Fix deprecated split() usage in xmail and directadmin drivers (#1487769)
+- Added option (password_log) for logging password changes
+- Virtualmin driver: Add option for setting username format (#1487781)
     </notes>
        <contents>
                <dir baseinstalldir="/" name="/">
@@ -61,6 +66,7 @@
                        <file name="localization/et_EE.inc" role="data"></file>
                        <file name="localization/fi_FI.inc" role="data"></file>
                        <file name="localization/fr_FR.inc" role="data"></file>
+                       <file name="localization/gl_ES.inc" role="data"></file>
                        <file name="localization/hu_HU.inc" role="data"></file>
                        <file name="localization/it_IT.inc" role="data"></file>
                        <file name="localization/lt_LT.inc" role="data"></file>
index 17fe3f7bb51bc60ab39f89aea97fec4dba384579..26376b36d071b6e9862fa7acee66f56fa598d1a8 100644 (file)
@@ -7,13 +7,11 @@ if (window.rcmail) {
   rcmail.addEventListener('init', function(evt) {
     // <span id="settingstabdefault" class="tablink"><roundcube:button command="preferences" type="link" label="preferences" title="editpreferences" /></span>
     var tab = $('<span>').attr('id', 'settingstabpluginpassword').addClass('tablink');
-    
-    var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.password').html(rcmail.gettext('password')).appendTo(tab);
-    button.bind('click', function(e){ return rcmail.command('plugin.password', this) });
+    var button = $('<a>').attr('href', rcmail.env.comm_path+'&_action=plugin.password')
+      .html(rcmail.gettext('password')).appendTo(tab);
 
     // add button and register commands
     rcmail.add_element(tab, 'tabs');
-    rcmail.register_command('plugin.password', function() { rcmail.goto_url('plugin.password') }, true);
     rcmail.register_command('plugin.password-save', function() { 
       var input_curpasswd = rcube_find_object('_curpasswd');
       var input_newpasswd = rcube_find_object('_newpasswd');
index 6d3042b5fa52deaf50ed5a9fb67dba675ea1a417..8fc95ea86b7f6b5ea1b10f0db96a0ff3a95e4960 100644 (file)
@@ -128,7 +128,15 @@ class password extends rcube_plugin
             // try to save the password
             else if (!($res = $this->_save($curpwd, $newpwd))) {
                 $rcmail->output->command('display_message', $this->gettext('successfullysaved'), 'confirmation');
+
+                // Reset session password
                 $_SESSION['password'] = $rcmail->encrypt($newpwd);
+
+                // Log password change
+                if ($rcmail->config->get('password_log')) {
+                    write_log('password', sprintf('Password changed for user %s (ID: %d) from %s',
+                        $rcmail->user->get_username(), $rcmail->user->ID, rcmail_remote_ip()));
+                }
             }
             else {
                 $rcmail->output->command('display_message', $res, 'error');
@@ -232,8 +240,8 @@ class password extends rcube_plugin
         $result = password_save($curpass, $passwd);
 
         if (is_array($result)) {
-            $result  = $result['code'];
             $message = $result['message'];
+            $result  = $result['code'];
         }
 
         switch ($result) {
index 1cbe690e9ac9379ebb042c9457f54617dfaf8b27..0007ce3358dceaf37c16a6dfe0f2ff0a8f346ecc 100644 (file)
@@ -44,7 +44,7 @@ class show_additional_headers extends rcube_plugin
     foreach ((array)$rcmail->config->get('show_additional_headers', array()) as $header) {
       $key = strtolower($header);
       if ($value = $p['headers']->others[$key])
-        $p['output'][$key] = array('title' => $header, 'value' => $value);
+        $p['output'][$key] = array('title' => $header, 'value' => Q($value));
     }
 
     return $p;
index 5d7cc012e320ddb16e4410079dfc0bc0260eb155..ee6bcc04b806505a0615a804fafb158ac31459d2 100644 (file)
@@ -73,8 +73,8 @@ class squirrelmail_usercopy extends rcube_plugin
                                foreach ($this->abook as $rec) {
                                    // #1487096 handle multi-address and/or too long items
                                    $rec['email'] = array_shift(explode(';', $rec['email']));
-                    if (check_email(idn_to_ascii($rec['email']))) {
-                        $rec['email'] = idn_to_utf8($rec['email']);
+                    if (check_email(rcube_idn_to_ascii($rec['email']))) {
+                        $rec['email'] = rcube_idn_to_utf8($rec['email']);
                                        $contacts->insert($rec, true);
                                }
                            }
index d625201971e2129e9179243e38114461eca57341..0d9c1fc73533c44ee2544508745b5a0c8ed9ac5e 100644 (file)
@@ -6,7 +6,7 @@
 | language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the Roundcube subscriptions option plugin            |
-| Copyright (C) 2005-2009, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2009, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index 30f8221c99135fe39edeb90b209a051b3d328760..20cd4ae9bfafc1a404194fbbb1c797705f87bf13 100644 (file)
@@ -6,7 +6,7 @@
 | language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the Roundcube userinfo plugin                        |
-| Copyright (C) 2005-2009, Roundcube Dev. - Switzerland                 |
+| Copyright (C) 2005-2009, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index 5d7c9c4c237e86f30a8978bb160c014e04fbd9e8..11ae8c98ff47027977e7d6eb147f4cfee3262e87 100644 (file)
@@ -5,7 +5,7 @@
 | language/cs_CZ/labels.inc                                             |
 |                                                                       |
 | Language file of the Roundcube Webmail client                         |
-| Copyright (C) 2008-2010, RoundQube Dev. - Switzerland                 |
+| Copyright (C) 2008-2010, The Roundcube Dev Team                       |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 +-----------------------------------------------------------------------+
index c00b4990bf435de4ef38f4b042978dd5a6c8bd68..0aba6b391f00b762a060f0cb737a7fc82c49a355 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 
 $labels = array();
-$labels['addvcardmsg'] = 'Añadir tarjeta a la libreta de direcciones';
-$labels['vcardsavefailed'] = 'Imposible guardar la tarjeta';
+$labels['addvcardmsg'] = 'Añadir la tarjeta a la libreta de direcciones';
+$labels['vcardsavefailed'] = 'No ha sido posible guardar la tarjeta';
 
 ?>
\ No newline at end of file
index 714750b141325e588dd590d77fb4ea578eb2b191..e5eaf71879353878c388d9af05f26c111457d772 100644 (file)
@@ -51,6 +51,7 @@
                        <file name="localization/de_DE.inc" role="data"></file>
                        <file name="localization/es_ES.inc" role="data"></file>
                        <file name="localization/et_EE.inc" role="data"></file>
+                       <file name="localization/gl_ES.inc" role="data"></file>
                        <file name="localization/it_IT.inc" role="data"></file>
                        <file name="localization/ja_JP.inc" role="data"></file>
                        <file name="localization/es_ES.inc" role="data"></file>
index d91e532a9c52ef3cebc942b53d2c0dcfc7bf524b..9d4efd12b747e493a4380ffde9a31d6d38ef0d1f 100644 (file)
@@ -40,7 +40,7 @@ class virtuser_file extends rcube_plugin
                $arr = preg_split('/\s+/', $r[$i]);
 
                if (count($arr) > 0 && strpos($arr[0], '@')) {
-                       $result[] = idn_to_ascii(trim(str_replace('\\@', '@', $arr[0])));
+                       $result[] = rcube_idn_to_ascii(trim(str_replace('\\@', '@', $arr[0])));
 
                        if ($p['first']) {
                            $p['email'] = $result[0];
index 8f154c235b614f1d7b77de012e0327d6736961ec..e59095f293d99db5d4cf59eeb02dcfa73e29e7c8 100644 (file)
@@ -58,11 +58,11 @@ class virtuser_query extends rcube_plugin
                if (strpos($sql_arr[0], '@')) {
                        if ($p['extended'] && count($sql_arr) > 1) {
                            $result[] = array(
-                                   'email'         => idn_to_ascii($sql_arr[0]),
+                                   'email'         => rcube_idn_to_ascii($sql_arr[0]),
                                'name'              => $sql_arr[1],
                                    'organization'  => $sql_arr[2],
-                               'reply-to'          => idn_to_ascii($sql_arr[3]),
-                                   'bcc'                   => idn_to_ascii($sql_arr[4]),
+                               'reply-to'          => rcube_idn_to_ascii($sql_arr[3]),
+                                   'bcc'                   => rcube_idn_to_ascii($sql_arr[4]),
                                    'signature'         => $sql_arr[5],
                                'html_signature' => (int)$sql_arr[6],
                        );
index 73a02b08013e1374bbd5c84b6265dad82cbe4ae0..92a2d90c0b848655751868a98b9da553a8a7e5a5 100755 (executable)
@@ -16,7 +16,7 @@
  |         Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: iniset.php 4469 2011-01-29 14:55:12Z thomasb $
+ $Id: iniset.php 4674 2011-04-20 09:03:08Z thomasb $
 
 */
 
@@ -36,7 +36,7 @@ foreach ($crit_opts as $optname => $optval) {
 }
 
 // application constants
-define('RCMAIL_VERSION', '0.5.1');
+define('RCMAIL_VERSION', '0.5.2');
 define('RCMAIL_CHARSET', 'UTF-8');
 define('JS_OBJECT_NAME', 'rcmail');
 define('RCMAIL_START', microtime(true));
index d02dca5e2d67db6d3c26f030c8b9da568fdc2b32..76db5670aa11e786cffe730a6fa08854ad81b421 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: main.inc 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: main.inc 4568 2011-02-24 12:12:09Z alec $
 
 */
 
@@ -972,7 +972,7 @@ function parse_attrib_string($str)
  * @return string Formatted date string
  */
 function format_date($date, $format=NULL)
-  {
+{
   global $CONFIG;
   
   $ts = NULL;
@@ -996,7 +996,7 @@ function format_date($date, $format=NULL)
 
   if (empty($ts))
     return '';
-   
+
   // get user's timezone
   if ($CONFIG['timezone'] === 'auto')
     $tz = isset($_SESSION['timezone']) ? $_SESSION['timezone'] : date('Z')/3600;
@@ -1008,7 +1008,7 @@ function format_date($date, $format=NULL)
 
   // convert time to user's timezone
   $timestamp = $ts - date('Z', $ts) + ($tz * 3600);
-  
+
   // get current timestamp in user's timezone
   $now = time();  // local time
   $now -= (int)date('Z'); // make GMT time
@@ -1016,30 +1016,33 @@ function format_date($date, $format=NULL)
   $now_date = getdate($now);
 
   $today_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday'], $now_date['year']);
-  $week_limit = mktime(0, 0, 0, $now_date['mon'], $now_date['mday']-6, $now_date['year']);
+  $week_limit  = mktime(0, 0, 0, $now_date['mon'], $now_date['mday']-6, $now_date['year']);
 
   // define date format depending on current time
   if (!$format) {
-    if ($CONFIG['prettydate'] && $timestamp > $today_limit && $timestamp < $now)
-      return sprintf('%s %s', rcube_label('today'), date($CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i', $timestamp));
+    if ($CONFIG['prettydate'] && $timestamp > $today_limit && $timestamp < $now) {
+      $format = $CONFIG['date_today'] ? $CONFIG['date_today'] : 'H:i';
+      $today  = true;
+    }
     else if ($CONFIG['prettydate'] && $timestamp > $week_limit && $timestamp < $now)
       $format = $CONFIG['date_short'] ? $CONFIG['date_short'] : 'D H:i';
     else
       $format = $CONFIG['date_long'] ? $CONFIG['date_long'] : 'd.m.Y H:i';
-    }
+  }
 
   // strftime() format
-  if (preg_match('/%[a-z]+/i', $format))
-    return strftime($format, $timestamp);
+  if (preg_match('/%[a-z]+/i', $format)) {
+    $format = strftime($format, $timestamp);
+    return $today ? (rcube_label('today') . ' ' . $format) : $format;
+  }
 
   // parse format string manually in order to provide localized weekday and month names
   // an alternative would be to convert the date() format string to fit with strftime()
   $out = '';
-  for($i=0; $i<strlen($format); $i++)
-    {
+  for($i=0; $i<strlen($format); $i++) {
     if ($format{$i}=='\\')  // skip escape chars
       continue;
-    
+
     // write char "as-is"
     if ($format{$i}==' ' || $format{$i-1}=='\\')
       $out .= $format{$i};
@@ -1059,11 +1062,22 @@ function format_date($date, $format=NULL)
       $out .= strftime('%x %X', $timestamp);
     else
       $out .= date($format{$i}, $timestamp);
+  }
+
+  if ($today) {
+    $label = rcube_label('today');
+    // replcae $ character with "Today" label (#1486120)
+    if (strpos($out, '$') !== false) {
+      $out = preg_replace('/\$/', $label, $out, 1);
+    }
+    else {
+      $out = $label . ' ' . $out;
     }
-  
-  return $out;
   }
 
+  return $out;
+}
+
 
 /**
  * Compose a valid representation of name and e-mail address
@@ -1679,7 +1693,7 @@ function rcube_html_editor($mode='')
 {
   global $RCMAIL, $CONFIG;
 
-  $hook = $RCMAIL->plugins->exec_hook('hmtl_editor', array('mode' => $mode));
+  $hook = $RCMAIL->plugins->exec_hook('html_editor', array('mode' => $mode));
 
   if ($hook['abort'])
     return;  
index d3d2390793909220ec116e881d278167b80cec76..4aa95a0ded775d39a0aae422165e700fbddc8e9d 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcmail.php 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: rcmail.php 4626 2011-03-31 12:32:44Z alec $
 
 */
 
@@ -1071,9 +1071,6 @@ class rcmail
    */
   public function shutdown()
   {
-    if (is_object($this->imap))
-      $this->imap->close();
-
     if (is_object($this->smtp))
       $this->smtp->disconnect();
 
@@ -1108,12 +1105,9 @@ class rcmail
    */
   public function get_request_token()
   {
-    $key = $this->task;
-
-    if (!$_SESSION['request_tokens'][$key])
-      $_SESSION['request_tokens'][$key] = md5(uniqid($key . mt_rand(), true));
-
-    return $_SESSION['request_tokens'][$key];
+    $sess_id = $_COOKIE[ini_get('session.name')];
+    if (!$sess_id) $sess_id = session_id();
+    return md5('RT' . $this->task . $this->config->get('des_key') . $sess_id);
   }
 
 
@@ -1126,7 +1120,8 @@ class rcmail
   public function check_request($mode = RCUBE_INPUT_POST)
   {
     $token = get_input_value('_token', $mode);
-    return !empty($token) && $_SESSION['request_tokens'][$this->task] == $token;
+    $sess_id = $_COOKIE[ini_get('session.name')];
+    return !empty($sess_id) && $token == $this->get_request_token();
   }
 
 
@@ -1198,6 +1193,9 @@ class rcmail
       }
     }
 
+    if (is_object($this->imap))
+      $this->imap->close();
+
     return $base64 ? base64_encode($cipher) : $cipher;
   }
 
diff --git a/program/include/rcmail.php.orig b/program/include/rcmail.php.orig
new file mode 100644 (file)
index 0000000..9613dba
--- /dev/null
@@ -0,0 +1,1325 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcmail.php                                            |
+ |                                                                       |
+ | This file is part of the Roundcube Webmail client                     |
+ | Copyright (C) 2008-2010, Roundcube Dev. - Switzerland                 |
+ | Licensed under the GNU GPL                                            |
+ |                                                                       |
+ | PURPOSE:                                                              |
+ |   Application class providing core functions and holding              |
+ |   instances of all 'global' objects like db- and imap-connections     |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com>                        |
+ +-----------------------------------------------------------------------+
+
+ $Id: rcmail.php 4626 2011-03-31 12:32:44Z alec $
+
+*/
+
+
+/**
+ * Application class of Roundcube Webmail
+ * implemented as singleton
+ *
+ * @package Core
+ */
+class rcmail
+{
+  /**
+   * Main tasks.
+   *
+   * @var array
+   */
+  static public $main_tasks = array('mail','settings','addressbook','login','logout','utils','dummy');
+
+  /**
+   * Singleton instace of rcmail
+   *
+   * @var rcmail
+   */
+  static private $instance;
+
+  /**
+   * Stores instance of rcube_config.
+   *
+   * @var rcube_config
+   */
+  public $config;
+
+  /**
+   * Stores rcube_user instance.
+   *
+   * @var rcube_user
+   */
+  public $user;
+
+  /**
+   * Instace of database class.
+   *
+   * @var rcube_mdb2
+   */
+  public $db;
+
+  /**
+   * Instace of rcube_session class.
+   *
+   * @var rcube_session
+   */
+  public $session;
+
+  /**
+   * Instance of rcube_smtp class.
+   *
+   * @var rcube_smtp
+   */
+  public $smtp;
+
+  /**
+   * Instance of rcube_imap class.
+   *
+   * @var rcube_imap
+   */
+  public $imap;
+
+  /**
+   * Instance of rcube_template class.
+   *
+   * @var rcube_template
+   */
+  public $output;
+
+  /**
+   * Instance of rcube_plugin_api.
+   *
+   * @var rcube_plugin_api
+   */
+  public $plugins;
+
+  /**
+   * Current task.
+   *
+   * @var string
+   */
+  public $task;
+
+  /**
+   * Current action.
+   *
+   * @var string
+   */
+  public $action = '';
+  public $comm_path = './';
+
+  private $texts;
+  private $books = array();
+
+
+  /**
+   * This implements the 'singleton' design pattern
+   *
+   * @return rcmail The one and only instance
+   */
+  static function get_instance()
+  {
+    if (!self::$instance) {
+      self::$instance = new rcmail();
+      self::$instance->startup();  // init AFTER object was linked with self::$instance
+    }
+
+    return self::$instance;
+  }
+
+
+  /**
+   * Private constructor
+   */
+  private function __construct()
+  {
+    // load configuration
+    $this->config = new rcube_config();
+
+    register_shutdown_function(array($this, 'shutdown'));
+  }
+
+
+  /**
+   * Initial startup function
+   * to register session, create database and imap connections
+   *
+   * @todo Remove global vars $DB, $USER
+   */
+  private function startup()
+  {
+    // initialize syslog
+    if ($this->config->get('log_driver') == 'syslog') {
+      $syslog_id = $this->config->get('syslog_id', 'roundcube');
+      $syslog_facility = $this->config->get('syslog_facility', LOG_USER);
+      openlog($syslog_id, LOG_ODELAY, $syslog_facility);
+    }
+
+    // connect to database
+    $GLOBALS['DB'] = $this->get_dbh();
+
+    // start session
+    $this->session_init();
+
+    // create user object
+    $this->set_user(new rcube_user($_SESSION['user_id']));
+
+    // configure session (after user config merge!)
+    $this->session_configure();
+
+    // set task and action properties
+    $this->set_task(get_input_value('_task', RCUBE_INPUT_GPC));
+    $this->action = asciiwords(get_input_value('_action', RCUBE_INPUT_GPC));
+
+    // reset some session parameters when changing task
+    if ($this->task != 'utils') {
+      if ($this->session && $_SESSION['task'] != $this->task)
+        $this->session->remove('page');
+      // set current task to session
+      $_SESSION['task'] = $this->task;
+    }
+
+    // init output class
+    if (!empty($_REQUEST['_remote']))
+      $GLOBALS['OUTPUT'] = $this->json_init();
+    else
+      $GLOBALS['OUTPUT'] = $this->load_gui(!empty($_REQUEST['_framed']));
+
+    // create plugin API and load plugins
+    $this->plugins = rcube_plugin_api::get_instance();
+
+    // init plugins
+    $this->plugins->init();
+  }
+
+
+  /**
+   * Setter for application task
+   *
+   * @param string Task to set
+   */
+  public function set_task($task)
+  {
+    $task = asciiwords($task);
+
+    if ($this->user && $this->user->ID)
+      $task = !$task ? 'mail' : $task;
+    else
+      $task = 'login';
+
+    $this->task = $task;
+    $this->comm_path = $this->url(array('task' => $this->task));
+
+    if ($this->output)
+      $this->output->set_env('task', $this->task);
+  }
+
+
+  /**
+   * Setter for system user object
+   *
+   * @param rcube_user Current user instance
+   */
+  public function set_user($user)
+  {
+    if (is_object($user)) {
+      $this->user = $user;
+      $GLOBALS['USER'] = $this->user;
+
+      // overwrite config with user preferences
+      $this->config->set_user_prefs((array)$this->user->get_prefs());
+    }
+
+    $_SESSION['language'] = $this->user->language = $this->language_prop($this->config->get('language', $_SESSION['language']));
+
+    // set localization
+    setlocale(LC_ALL, $_SESSION['language'] . '.utf8', 'en_US.utf8');
+
+    // workaround for http://bugs.php.net/bug.php?id=18556
+    if (in_array($_SESSION['language'], array('tr_TR', 'ku', 'az_AZ')))
+      setlocale(LC_CTYPE, 'en_US' . '.utf8');
+  }
+
+
+  /**
+   * Check the given string and return a valid language code
+   *
+   * @param string Language code
+   * @return string Valid language code
+   */
+  private function language_prop($lang)
+  {
+    static $rcube_languages, $rcube_language_aliases;
+
+    // user HTTP_ACCEPT_LANGUAGE if no language is specified
+    if (empty($lang) || $lang == 'auto') {
+       $accept_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
+       $lang = str_replace('-', '_', $accept_langs[0]);
+     }
+
+    if (empty($rcube_languages)) {
+      @include(INSTALL_PATH . 'program/localization/index.inc');
+    }
+
+    // check if we have an alias for that language
+    if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang])) {
+      $lang = $rcube_language_aliases[$lang];
+    }
+    // try the first two chars
+    else if (!isset($rcube_languages[$lang])) {
+      $short = substr($lang, 0, 2);
+
+      // check if we have an alias for the short language code
+      if (!isset($rcube_languages[$short]) && isset($rcube_language_aliases[$short])) {
+        $lang = $rcube_language_aliases[$short];
+      }
+      // expand 'nn' to 'nn_NN'
+      else if (!isset($rcube_languages[$short])) {
+        $lang = $short.'_'.strtoupper($short);
+      }
+    }
+
+    if (!isset($rcube_languages[$lang]) || !is_dir(INSTALL_PATH . 'program/localization/' . $lang)) {
+      $lang = 'en_US';
+    }
+
+    return $lang;
+  }
+
+
+  /**
+   * Get the current database connection
+   *
+   * @return rcube_mdb2  Database connection object
+   */
+  public function get_dbh()
+  {
+    if (!$this->db) {
+      $config_all = $this->config->all();
+
+      $this->db = new rcube_mdb2($config_all['db_dsnw'], $config_all['db_dsnr'], $config_all['db_persistent']);
+      $this->db->sqlite_initials = INSTALL_PATH . 'SQL/sqlite.initial.sql';
+      $this->db->set_debug((bool)$config_all['sql_debug']);
+    }
+
+    return $this->db;
+  }
+
+
+  /**
+   * Return instance of the internal address book class
+   *
+   * @param string  Address book identifier
+   * @param boolean True if the address book needs to be writeable
+   * @return rcube_contacts Address book object
+   */
+  public function get_address_book($id, $writeable = false)
+  {
+    $contacts = null;
+    $ldap_config = (array)$this->config->get('ldap_public');
+    $abook_type = strtolower($this->config->get('address_book_type'));
+
+    $plugin = $this->plugins->exec_hook('addressbook_get', array('id' => $id, 'writeable' => $writeable));
+
+    // plugin returned instance of a rcube_addressbook
+    if ($plugin['instance'] instanceof rcube_addressbook) {
+      $contacts = $plugin['instance'];
+    }
+    else if ($id && $ldap_config[$id]) {
+      $contacts = new rcube_ldap($ldap_config[$id], $this->config->get('ldap_debug'), $this->config->mail_domain($_SESSION['imap_host']));
+    }
+    else if ($id === '0') {
+      $contacts = new rcube_contacts($this->db, $this->user->ID);
+    }
+    else if ($abook_type == 'ldap') {
+      // Use the first writable LDAP address book.
+      foreach ($ldap_config as $id => $prop) {
+        if (!$writeable || $prop['writable']) {
+          $contacts = new rcube_ldap($prop, $this->config->get('ldap_debug'), $this->config->mail_domain($_SESSION['imap_host']));
+          break;
+        }
+      }
+    }
+    else { // $id == 'sql'
+      $contacts = new rcube_contacts($this->db, $this->user->ID);
+    }
+
+    // add to the 'books' array for shutdown function
+    if (!in_array($contacts, $this->books))
+      $this->books[] = $contacts;
+
+    return $contacts;
+  }
+
+
+  /**
+   * Return address books list
+   *
+   * @param boolean True if the address book needs to be writeable
+   * @return array  Address books array
+   */
+  public function get_address_sources($writeable = false)
+  {
+    $abook_type = strtolower($this->config->get('address_book_type'));
+    $ldap_config = $this->config->get('ldap_public');
+    $autocomplete = (array) $this->config->get('autocomplete_addressbooks');
+    $list = array();
+
+    // We are using the DB address book
+    if ($abook_type != 'ldap') {
+      $contacts = new rcube_contacts($this->db, null);
+      $list['0'] = array(
+        'id' => 0,
+        'name' => rcube_label('personaladrbook'),
+        'groups' => $contacts->groups,
+        'readonly' => false,
+        'autocomplete' => in_array('sql', $autocomplete)
+      );
+    }
+
+    if ($ldap_config) {
+      $ldap_config = (array) $ldap_config;
+      foreach ($ldap_config as $id => $prop)
+        $list[$id] = array(
+          'id' => $id,
+          'name' => $prop['name'],
+          'groups' => false,
+          'readonly' => !$prop['writable'],
+          'autocomplete' => in_array('sql', $autocomplete)
+        );
+    }
+
+    $plugin = $this->plugins->exec_hook('addressbooks_list', array('sources' => $list));
+    $list = $plugin['sources'];
+
+    if ($writeable && !empty($list)) {
+      foreach ($list as $idx => $item) {
+        if ($item['readonly']) {
+          unset($list[$idx]);
+        }
+      }
+    }
+
+    return $list;
+  }
+
+
+  /**
+   * Init output object for GUI and add common scripts.
+   * This will instantiate a rcmail_template object and set
+   * environment vars according to the current session and configuration
+   *
+   * @param boolean True if this request is loaded in a (i)frame
+   * @return rcube_template Reference to HTML output object
+   */
+  public function load_gui($framed = false)
+  {
+    // init output page
+    if (!($this->output instanceof rcube_template))
+      $this->output = new rcube_template($this->task, $framed);
+
+    // set keep-alive/check-recent interval
+    if ($this->session && ($keep_alive = $this->session->get_keep_alive())) {
+      $this->output->set_env('keep_alive', $keep_alive);
+    }
+
+    if ($framed) {
+      $this->comm_path .= '&_framed=1';
+      $this->output->set_env('framed', true);
+    }
+
+    $this->output->set_env('task', $this->task);
+    $this->output->set_env('action', $this->action);
+    $this->output->set_env('comm_path', $this->comm_path);
+    $this->output->set_charset(RCMAIL_CHARSET);
+
+    // add some basic label to client
+    $this->output->add_label('loading', 'servererror');
+
+    return $this->output;
+  }
+
+
+  /**
+   * Create an output object for JSON responses
+   *
+   * @return rcube_json_output Reference to JSON output object
+   */
+  public function json_init()
+  {
+    if (!($this->output instanceof rcube_json_output))
+      $this->output = new rcube_json_output($this->task);
+
+    return $this->output;
+  }
+
+
+  /**
+   * Create SMTP object and connect to server
+   *
+   * @param boolean True if connection should be established
+   */
+  public function smtp_init($connect = false)
+  {
+    $this->smtp = new rcube_smtp();
+
+    if ($connect)
+      $this->smtp->connect();
+  }
+
+
+  /**
+   * Create global IMAP object and connect to server
+   *
+   * @param boolean True if connection should be established
+   * @todo Remove global $IMAP
+   */
+  public function imap_init($connect = false)
+  {
+    // already initialized
+    if (is_object($this->imap))
+      return;
+
+    $this->imap = new rcube_imap($this->db);
+    $this->imap->debug_level = $this->config->get('debug_level');
+    $this->imap->skip_deleted = $this->config->get('skip_deleted');
+
+    // enable caching of imap data
+    if ($this->config->get('enable_caching')) {
+      $this->imap->set_caching(true);
+    }
+
+    // set pagesize from config
+    $this->imap->set_pagesize($this->config->get('pagesize', 50));
+
+    // Setting root and delimiter before establishing the connection
+    // can save time detecting them using NAMESPACE and LIST
+    $options = array(
+      'auth_method' => $this->config->get('imap_auth_type', 'check'),
+      'auth_cid'    => $this->config->get('imap_auth_cid'),
+      'auth_pw'     => $this->config->get('imap_auth_pw'),
+      'debug'       => (bool) $this->config->get('imap_debug', 0),
+      'force_caps'  => (bool) $this->config->get('imap_force_caps'),
+      'timeout'     => (int) $this->config->get('imap_timeout', 0),
+    );
+
+    $this->imap->set_options($options);
+
+    // set global object for backward compatibility
+    $GLOBALS['IMAP'] = $this->imap;
+
+    $hook = $this->plugins->exec_hook('imap_init', array('fetch_headers' => $this->imap->fetch_add_headers));
+    if ($hook['fetch_headers'])
+      $this->imap->fetch_add_headers = $hook['fetch_headers'];
+
+    // support this parameter for backward compatibility but log warning
+    if ($connect) {
+      $this->imap_connect();
+      raise_error(array(
+        'code' => 800, 'type' => 'imap',
+        'file' => __FILE__, 'line' => __LINE__,
+        'message' => "rcube::imap_init(true) is deprecated, use rcube::imap_connect() instead"),
+        true, false);
+    }
+  }
+
+
+  /**
+   * Connect to IMAP server with stored session data
+   *
+   * @return bool True on success, false on error
+   */
+  public function imap_connect()
+  {
+    if (!$this->imap)
+      $this->imap_init();
+
+    if ($_SESSION['imap_host'] && !$this->imap->conn->connected()) {
+      if (!$this->imap->connect($_SESSION['imap_host'], $_SESSION['username'], $this->decrypt($_SESSION['password']), $_SESSION['imap_port'], $_SESSION['imap_ssl'])) {
+        if ($this->output)
+          $this->output->show_message($this->imap->get_error_code() == -1 ? 'imaperror' : 'sessionerror', 'error');
+      }
+      else {
+        $this->set_imap_prop();
+        return $this->imap->conn;
+      }
+    }
+
+    return false;
+  }
+
+
+  /**
+   * Create session object and start the session.
+   */
+  public function session_init()
+  {
+    // session started (Installer?)
+    if (session_id())
+      return;
+
+    $lifetime = $this->config->get('session_lifetime', 0) * 60;
+
+    // set session domain
+    if ($domain = $this->config->get('session_domain')) {
+      ini_set('session.cookie_domain', $domain);
+    }
+    // set session garbage collecting time according to session_lifetime
+    if ($lifetime) {
+      ini_set('session.gc_maxlifetime', $lifetime * 2);
+    }
+
+    ini_set('session.cookie_secure', rcube_https_check());
+    ini_set('session.name', 'roundcube_sessid');
+    ini_set('session.use_cookies', 1);
+    ini_set('session.use_only_cookies', 1);
+    ini_set('session.serialize_handler', 'php');
+
+    // use database for storing session data
+    $this->session = new rcube_session($this->get_dbh(), $lifetime);
+
+    $this->session->register_gc_handler('rcmail_temp_gc');
+    if ($this->config->get('enable_caching'))
+      $this->session->register_gc_handler('rcmail_cache_gc');
+
+    // start PHP session (if not in CLI mode)
+    if ($_SERVER['REMOTE_ADDR'])
+      session_start();
+
+    // set initial session vars
+    if (!isset($_SESSION['auth_time'])) {
+      $_SESSION['auth_time'] = time();
+      $_SESSION['temp'] = true;
+    }
+  }
+
+
+  /**
+   * Configure session object internals
+   */
+  public function session_configure()
+  {
+    if (!$this->session)
+      return;
+
+    $lifetime = $this->config->get('session_lifetime', 0) * 60;
+
+    // set keep-alive/check-recent interval
+    if ($keep_alive = $this->config->get('keep_alive')) {
+      // be sure that it's less than session lifetime
+      if ($lifetime)
+        $keep_alive = min($keep_alive, $lifetime - 30);
+      $keep_alive = max(60, $keep_alive);
+      $this->session->set_keep_alive($keep_alive);
+    }
+  }
+
+
+  /**
+   * Perfom login to the IMAP server and to the webmail service.
+   * This will also create a new user entry if auto_create_user is configured.
+   *
+   * @param string IMAP user name
+   * @param string IMAP password
+   * @param string IMAP host
+   * @return boolean True on success, False on failure
+   */
+  function login($username, $pass, $host=NULL)
+  {
+    $user = NULL;
+    $config = $this->config->all();
+
+    if (!$host)
+      $host = $config['default_host'];
+
+    // Validate that selected host is in the list of configured hosts
+    if (is_array($config['default_host'])) {
+      $allowed = false;
+      foreach ($config['default_host'] as $key => $host_allowed) {
+        if (!is_numeric($key))
+          $host_allowed = $key;
+        if ($host == $host_allowed) {
+          $allowed = true;
+          break;
+        }
+      }
+      if (!$allowed)
+        return false;
+      }
+    else if (!empty($config['default_host']) && $host != rcube_parse_host($config['default_host']))
+      return false;
+
+    // parse $host URL
+    $a_host = parse_url($host);
+    if ($a_host['host']) {
+      $host = $a_host['host'];
+      $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? $a_host['scheme'] : null;
+      if (!empty($a_host['port']))
+        $imap_port = $a_host['port'];
+      else if ($imap_ssl && $imap_ssl != 'tls' && (!$config['default_port'] || $config['default_port'] == 143))
+        $imap_port = 993;
+    }
+
+    $imap_port = $imap_port ? $imap_port : $config['default_port'];
+
+    /* Modify username with domain if required
+       Inspired by Marco <P0L0_notspam_binware.org>
+    */
+    // Check if we need to add domain
+    if (!empty($config['username_domain']) && strpos($username, '@') === false) {
+      if (is_array($config['username_domain']) && isset($config['username_domain'][$host]))
+        $username .= '@'.rcube_parse_host($config['username_domain'][$host], $host);
+      else if (is_string($config['username_domain']))
+        $username .= '@'.rcube_parse_host($config['username_domain'], $host);
+    }
+
+    // Convert username to lowercase. If IMAP backend
+    // is case-insensitive we need to store always the same username (#1487113)
+    if ($config['login_lc']) {
+      $username = mb_strtolower($username);
+    }
+
+    // try to resolve email address from virtuser table
+    if (strpos($username, '@') && ($virtuser = rcube_user::email2user($username))) {
+      $username = $virtuser;
+    }
+
+    // Here we need IDNA ASCII
+    // Only rcube_contacts class is using domain names in Unicode
+    $host = rcube_idn_to_ascii($host);
+    if (strpos($username, '@')) {
+      // lowercase domain name
+      list($local, $domain) = explode('@', $username);
+      $username = $local . '@' . mb_strtolower($domain);
+      $username = rcube_idn_to_ascii($username);
+    }
+
+    // user already registered -> overwrite username
+    if ($user = rcube_user::query($username, $host))
+      $username = $user->data['username'];
+
+    if (!$this->imap)
+      $this->imap_init();
+
+    // try IMAP login
+    if (!($imap_login = $this->imap->connect($host, $username, $pass, $imap_port, $imap_ssl))) {
+      // try with lowercase
+      $username_lc = mb_strtolower($username);
+      if ($username_lc != $username) {
+        // try to find user record again -> overwrite username
+        if (!$user && ($user = rcube_user::query($username_lc, $host)))
+          $username_lc = $user->data['username'];
+
+        if ($imap_login = $this->imap->connect($host, $username_lc, $pass, $imap_port, $imap_ssl))
+          $username = $username_lc;
+      }
+    }
+
+    // exit if IMAP login failed
+    if (!$imap_login)
+      return false;
+
+    $this->set_imap_prop();
+
+    // user already registered -> update user's record
+    if (is_object($user)) {
+      // create default folders on first login
+      if (!$user->data['last_login'] && $config['create_default_folders'])
+        $this->imap->create_default_folders();
+      $user->touch();
+    }
+    // create new system user
+    else if ($config['auto_create_user']) {
+      if ($created = rcube_user::create($username, $host)) {
+        $user = $created;
+        // create default folders on first login
+        if ($config['create_default_folders'])
+          $this->imap->create_default_folders();
+      }
+      else {
+        raise_error(array(
+          'code' => 600, 'type' => 'php',
+          'file' => __FILE__, 'line' => __LINE__,
+          'message' => "Failed to create a user record. Maybe aborted by a plugin?"
+          ), true, false);
+      }
+    }
+    else {
+      raise_error(array(
+        'code' => 600, 'type' => 'php',
+        'file' => __FILE__, 'line' => __LINE__,
+        'message' => "Acces denied for new user $username. 'auto_create_user' is disabled"
+        ), true, false);
+    }
+
+    // login succeeded
+    if (is_object($user) && $user->ID) {
+      $this->set_user($user);
+
+      // set session vars
+      $_SESSION['user_id']   = $user->ID;
+      $_SESSION['username']  = $user->data['username'];
+      $_SESSION['imap_host'] = $host;
+      $_SESSION['imap_port'] = $imap_port;
+      $_SESSION['imap_ssl']  = $imap_ssl;
+      $_SESSION['password']  = $this->encrypt($pass);
+      $_SESSION['login_time'] = mktime();
+
+      if (isset($_REQUEST['_timezone']) && $_REQUEST['_timezone'] != '_default_')
+        $_SESSION['timezone'] = floatval($_REQUEST['_timezone']);
+
+      // force reloading complete list of subscribed mailboxes
+      $this->imap->clear_cache('mailboxes');
+
+      return true;
+    }
+
+    return false;
+  }
+
+
+  /**
+   * Set root dir and last stored mailbox
+   * This must be done AFTER connecting to the server!
+   */
+  public function set_imap_prop()
+  {
+    $this->imap->set_charset($this->config->get('default_charset', RCMAIL_CHARSET));
+
+    if ($default_folders = $this->config->get('default_imap_folders')) {
+      $this->imap->set_default_mailboxes($default_folders);
+    }
+    if (isset($_SESSION['mbox'])) {
+      $this->imap->set_mailbox($_SESSION['mbox']);
+    }
+    if (isset($_SESSION['page'])) {
+      $this->imap->set_page($_SESSION['page']);
+    }
+  }
+
+
+  /**
+   * Auto-select IMAP host based on the posted login information
+   *
+   * @return string Selected IMAP host
+   */
+  public function autoselect_host()
+  {
+    $default_host = $this->config->get('default_host');
+    $host = null;
+
+    if (is_array($default_host)) {
+      $post_host = get_input_value('_host', RCUBE_INPUT_POST);
+
+      // direct match in default_host array
+      if ($default_host[$post_host] || in_array($post_host, array_values($default_host))) {
+        $host = $post_host;
+      }
+
+      // try to select host by mail domain
+      list($user, $domain) = explode('@', get_input_value('_user', RCUBE_INPUT_POST));
+      if (!empty($domain)) {
+        foreach ($default_host as $imap_host => $mail_domains) {
+          if (is_array($mail_domains) && in_array($domain, $mail_domains)) {
+            $host = $imap_host;
+            break;
+          }
+        }
+      }
+
+      // take the first entry if $host is still an array
+      if (empty($host)) {
+        $host = array_shift($default_host);
+      }
+    }
+    else if (empty($default_host)) {
+      $host = get_input_value('_host', RCUBE_INPUT_POST);
+    }
+    else
+      $host = rcube_parse_host($default_host);
+
+    return $host;
+  }
+
+
+  /**
+   * Get localized text in the desired language
+   *
+   * @param mixed Named parameters array or label name
+   * @return string Localized text
+   */
+  public function gettext($attrib, $domain=null)
+  {
+    // load localization files if not done yet
+    if (empty($this->texts))
+      $this->load_language();
+
+    // extract attributes
+    if (is_string($attrib))
+      $attrib = array('name' => $attrib);
+
+    $nr = is_numeric($attrib['nr']) ? $attrib['nr'] : 1;
+    $name = $attrib['name'] ? $attrib['name'] : '';
+
+    // check for text with domain
+    if ($domain && ($text_item = $this->texts[$domain.'.'.$name]))
+      ;
+    // text does not exist
+    else if (!($text_item = $this->texts[$name])) {
+      return "[$name]";
+    }
+
+    // make text item array
+    $a_text_item = is_array($text_item) ? $text_item : array('single' => $text_item);
+
+    // decide which text to use
+    if ($nr == 1) {
+      $text = $a_text_item['single'];
+    }
+    else if ($nr > 0) {
+      $text = $a_text_item['multiple'];
+    }
+    else if ($nr == 0) {
+      if ($a_text_item['none'])
+        $text = $a_text_item['none'];
+      else if ($a_text_item['single'])
+        $text = $a_text_item['single'];
+      else if ($a_text_item['multiple'])
+        $text = $a_text_item['multiple'];
+    }
+
+    // default text is single
+    if ($text == '') {
+      $text = $a_text_item['single'];
+    }
+
+    // replace vars in text
+    if (is_array($attrib['vars'])) {
+      foreach ($attrib['vars'] as $var_key => $var_value)
+        $text = str_replace($var_key[0]!='$' ? '$'.$var_key : $var_key, $var_value, $text);
+    }
+
+    // format output
+    if (($attrib['uppercase'] && strtolower($attrib['uppercase']=='first')) || $attrib['ucfirst'])
+      return ucfirst($text);
+    else if ($attrib['uppercase'])
+      return mb_strtoupper($text);
+    else if ($attrib['lowercase'])
+      return mb_strtolower($text);
+
+    return $text;
+  }
+
+
+  /**
+   * Load a localization package
+   *
+   * @param string Language ID
+   */
+  public function load_language($lang = null, $add = array())
+  {
+    $lang = $this->language_prop(($lang ? $lang : $_SESSION['language']));
+
+    // load localized texts
+    if (empty($this->texts) || $lang != $_SESSION['language']) {
+      $this->texts = array();
+
+      // handle empty lines after closing PHP tag in localization files
+      ob_start();
+
+      // get english labels (these should be complete)
+      @include(INSTALL_PATH . 'program/localization/en_US/labels.inc');
+      @include(INSTALL_PATH . 'program/localization/en_US/messages.inc');
+
+      if (is_array($labels))
+        $this->texts = $labels;
+      if (is_array($messages))
+        $this->texts = array_merge($this->texts, $messages);
+
+      // include user language files
+      if ($lang != 'en' && is_dir(INSTALL_PATH . 'program/localization/' . $lang)) {
+        include_once(INSTALL_PATH . 'program/localization/' . $lang . '/labels.inc');
+        include_once(INSTALL_PATH . 'program/localization/' . $lang . '/messages.inc');
+
+        if (is_array($labels))
+          $this->texts = array_merge($this->texts, $labels);
+        if (is_array($messages))
+          $this->texts = array_merge($this->texts, $messages);
+      }
+
+      ob_end_clean();
+
+      $_SESSION['language'] = $lang;
+    }
+
+    // append additional texts (from plugin)
+    if (is_array($add) && !empty($add))
+      $this->texts += $add;
+  }
+
+
+  /**
+   * Read directory program/localization and return a list of available languages
+   *
+   * @return array List of available localizations
+   */
+  public function list_languages()
+  {
+    static $sa_languages = array();
+
+    if (!sizeof($sa_languages)) {
+      @include(INSTALL_PATH . 'program/localization/index.inc');
+
+      if ($dh = @opendir(INSTALL_PATH . 'program/localization')) {
+        while (($name = readdir($dh)) !== false) {
+          if ($name[0] == '.' || !is_dir(INSTALL_PATH . 'program/localization/' . $name))
+            continue;
+
+          if ($label = $rcube_languages[$name])
+            $sa_languages[$name] = $label;
+        }
+        closedir($dh);
+      }
+    }
+
+    return $sa_languages;
+  }
+
+
+  /**
+   * Check the auth hash sent by the client against the local session credentials
+   *
+   * @return boolean True if valid, False if not
+   */
+  function authenticate_session()
+  {
+    // advanced session authentication
+    if ($this->config->get('double_auth')) {
+      $now = time();
+      $valid = ($_COOKIE['sessauth'] == $this->get_auth_hash(session_id(), $_SESSION['auth_time']) ||
+                $_COOKIE['sessauth'] == $this->get_auth_hash(session_id(), $_SESSION['last_auth']));
+
+      // renew auth cookie every 5 minutes (only for GET requests)
+      if (!$valid || ($_SERVER['REQUEST_METHOD']!='POST' && $now - $_SESSION['auth_time'] > 300)) {
+        $_SESSION['last_auth'] = $_SESSION['auth_time'];
+        $_SESSION['auth_time'] = $now;
+        rcmail::setcookie('sessauth', $this->get_auth_hash(session_id(), $now), 0);
+      }
+    }
+    else {
+      $valid = $this->config->get('ip_check') ? $_SERVER['REMOTE_ADDR'] == $this->session->get_ip() : true;
+    }
+
+    // check session filetime
+    $lifetime = $this->config->get('session_lifetime');
+    $sess_ts = $this->session->get_ts();
+    if (!empty($lifetime) && !empty($sess_ts) && $sess_ts + $lifetime*60 < time()) {
+      $valid = false;
+    }
+
+    return $valid;
+  }
+
+
+  /**
+   * Destroy session data and remove cookie
+   */
+  public function kill_session()
+  {
+    $this->plugins->exec_hook('session_destroy');
+
+    $this->session->remove();
+    $_SESSION = array('language' => $this->user->language, 'auth_time' => time(), 'temp' => true);
+    rcmail::setcookie('sessauth', '-del-', time() - 60);
+    $this->user->reset();
+  }
+
+
+  /**
+   * Do server side actions on logout
+   */
+  public function logout_actions()
+  {
+    $config = $this->config->all();
+
+    // on logout action we're not connected to imap server
+    if (($config['logout_purge'] && !empty($config['trash_mbox'])) || $config['logout_expunge']) {
+      if (!$this->authenticate_session())
+        return;
+
+      $this->imap_connect();
+    }
+
+    if ($config['logout_purge'] && !empty($config['trash_mbox'])) {
+      $this->imap->clear_mailbox($config['trash_mbox']);
+    }
+
+    if ($config['logout_expunge']) {
+      $this->imap->expunge('INBOX');
+    }
+  }
+
+
+  /**
+   * Function to be executed in script shutdown
+   * Registered with register_shutdown_function()
+   */
+  public function shutdown()
+  {
+    if (is_object($this->smtp))
+      $this->smtp->disconnect();
+
+    foreach ($this->books as $book)
+      if (is_object($book))
+        $book->close();
+
+    // before closing the database connection, write session data
+    if ($_SERVER['REMOTE_ADDR'])
+      session_write_close();
+
+    // write performance stats to logs/console
+    if ($this->config->get('devel_mode')) {
+      if (function_exists('memory_get_usage'))
+        $mem = show_bytes(memory_get_usage());
+      if (function_exists('memory_get_peak_usage'))
+        $mem .= '/'.show_bytes(memory_get_peak_usage());
+
+      $log = $this->task . ($this->action ? '/'.$this->action : '') . ($mem ? " [$mem]" : '');
+      if (defined('RCMAIL_START'))
+        rcube_print_time(RCMAIL_START, $log);
+      else
+        console($log);
+    }
+  }
+
+
+  /**
+   * Generate a unique token to be used in a form request
+   *
+   * @return string The request token
+   */
+  public function get_request_token()
+  {
+    $sess_id = $_COOKIE[ini_get('session.name')];
+    if (!$sess_id) $sess_id = session_id();
+    return md5('RT' . $this->task . $this->config->get('des_key') . $sess_id);
+  }
+
+
+  /**
+   * Check if the current request contains a valid token
+   *
+   * @param int Request method
+   * @return boolean True if request token is valid false if not
+   */
+  public function check_request($mode = RCUBE_INPUT_POST)
+  {
+    $token = get_input_value('_token', $mode);
+    $sess_id = $_COOKIE[ini_get('session.name')];
+    return !empty($sess_id) && $token == $this->get_request_token();
+  }
+
+
+  /**
+   * Create unique authorization hash
+   *
+   * @param string Session ID
+   * @param int Timestamp
+   * @return string The generated auth hash
+   */
+  private function get_auth_hash($sess_id, $ts)
+  {
+    $auth_string = sprintf('rcmail*sess%sR%s*Chk:%s;%s',
+      $sess_id,
+      $ts,
+      $this->config->get('ip_check') ? $_SERVER['REMOTE_ADDR'] : '***.***.***.***',
+      $_SERVER['HTTP_USER_AGENT']);
+
+    if (function_exists('sha1'))
+      return sha1($auth_string);
+    else
+      return md5($auth_string);
+  }
+
+
+  /**
+   * Encrypt using 3DES
+   *
+   * @param string $clear clear text input
+   * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key'
+   * @param boolean $base64 whether or not to base64_encode() the result before returning
+   *
+   * @return string encrypted text
+   */
+  public function encrypt($clear, $key = 'des_key', $base64 = true)
+  {
+    if (!$clear)
+      return '';
+    /*-
+     * Add a single canary byte to the end of the clear text, which
+     * will help find out how much of padding will need to be removed
+     * upon decryption; see http://php.net/mcrypt_generic#68082
+     */
+    $clear = pack("a*H2", $clear, "80");
+
+    if (function_exists('mcrypt_module_open') &&
+        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")))
+    {
+      $iv = $this->create_iv(mcrypt_enc_get_iv_size($td));
+      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv);
+      $cipher = $iv . mcrypt_generic($td, $clear);
+      mcrypt_generic_deinit($td);
+      mcrypt_module_close($td);
+    }
+    else {
+      @include_once('lib/des.inc');
+
+      if (function_exists('des')) {
+        $des_iv_size = 8;
+        $iv = $this->create_iv($des_iv_size);
+        $cipher = $iv . des($this->config->get_crypto_key($key), $clear, 1, 1, $iv);
+      }
+      else {
+        raise_error(array(
+          'code' => 500, 'type' => 'php',
+          'file' => __FILE__, 'line' => __LINE__,
+          'message' => "Could not perform encryption; make sure Mcrypt is installed or lib/des.inc is available"
+        ), true, true);
+      }
+    }
+
+    if (is_object($this->imap))
+      $this->imap->close();
+
+    return $base64 ? base64_encode($cipher) : $cipher;
+  }
+
+  /**
+   * Decrypt 3DES-encrypted string
+   *
+   * @param string $cipher encrypted text
+   * @param string $key encryption key to retrieve from the configuration, defaults to 'des_key'
+   * @param boolean $base64 whether or not input is base64-encoded
+   *
+   * @return string decrypted text
+   */
+  public function decrypt($cipher, $key = 'des_key', $base64 = true)
+  {
+    if (!$cipher)
+      return '';
+
+    $cipher = $base64 ? base64_decode($cipher) : $cipher;
+
+    if (function_exists('mcrypt_module_open') &&
+        ($td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_CBC, "")))
+    {
+      $iv_size = mcrypt_enc_get_iv_size($td);
+      $iv = substr($cipher, 0, $iv_size);
+
+      // session corruption? (#1485970)
+      if (strlen($iv) < $iv_size)
+        return '';
+
+      $cipher = substr($cipher, $iv_size);
+      mcrypt_generic_init($td, $this->config->get_crypto_key($key), $iv);
+      $clear = mdecrypt_generic($td, $cipher);
+      mcrypt_generic_deinit($td);
+      mcrypt_module_close($td);
+    }
+    else {
+      @include_once('lib/des.inc');
+
+      if (function_exists('des')) {
+        $des_iv_size = 8;
+        $iv = substr($cipher, 0, $des_iv_size);
+        $cipher = substr($cipher, $des_iv_size);
+        $clear = des($this->config->get_crypto_key($key), $cipher, 0, 1, $iv);
+      }
+      else {
+        raise_error(array(
+          'code' => 500, 'type' => 'php',
+          'file' => __FILE__, 'line' => __LINE__,
+          'message' => "Could not perform decryption; make sure Mcrypt is installed or lib/des.inc is available"
+        ), true, true);
+      }
+    }
+
+    /*-
+     * Trim PHP's padding and the canary byte; see note in
+     * rcmail::encrypt() and http://php.net/mcrypt_generic#68082
+     */
+    $clear = substr(rtrim($clear, "\0"), 0, -1);
+
+    return $clear;
+  }
+
+  /**
+   * Generates encryption initialization vector (IV)
+   *
+   * @param int Vector size
+   * @return string Vector string
+   */
+  private function create_iv($size)
+  {
+    // mcrypt_create_iv() can be slow when system lacks entrophy
+    // we'll generate IV vector manually
+    $iv = '';
+    for ($i = 0; $i < $size; $i++)
+        $iv .= chr(mt_rand(0, 255));
+    return $iv;
+  }
+
+  /**
+   * Build a valid URL to this instance of Roundcube
+   *
+   * @param mixed Either a string with the action or url parameters as key-value pairs
+   * @return string Valid application URL
+   */
+  public function url($p)
+  {
+    if (!is_array($p))
+      $p = array('_action' => @func_get_arg(0));
+
+    $task = $p['_task'] ? $p['_task'] : ($p['task'] ? $p['task'] : $this->task);
+    $p['_task'] = $task;
+    unset($p['task']);
+
+    $url = './';
+    $delm = '?';
+    foreach (array_reverse($p) as $key => $val)
+    {
+      if (!empty($val)) {
+        $par = $key[0] == '_' ? $key : '_'.$key;
+        $url .= $delm.urlencode($par).'='.urlencode($val);
+        $delm = '&';
+      }
+    }
+    return $url;
+  }
+
+
+  /**
+   * Helper method to set a cookie with the current path and host settings
+   *
+   * @param string Cookie name
+   * @param string Cookie value
+   * @param string Expiration time
+   */
+  public static function setcookie($name, $value, $exp = 0)
+  {
+    if (headers_sent())
+      return;
+
+    $cookie = session_get_cookie_params();
+
+    setcookie($name, $value, $exp, $cookie['path'], $cookie['domain'],
+      rcube_https_check(), true);
+  }
+}
+
+
index 82ba731e7bfe3200a37ae078ff2acb5fe3d8307c..6579d9d56fef7487263938bd41cd944b1adbd87c 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_browser.php 3989 2010-09-25 13:03:53Z alec $
+ $Id: rcube_browser.php 4626 2011-03-31 12:32:44Z alec $
 
 */
 
@@ -42,7 +42,7 @@ class rcube_browser
         $this->ns4 = strstr($HTTP_USER_AGENT, 'mozilla/4') && !strstr($HTTP_USER_AGENT, 'msie');
         $this->ns  = ($this->ns4 || strstr($HTTP_USER_AGENT, 'netscape'));
         $this->ie  = !$this->opera && strstr($HTTP_USER_AGENT, 'compatible; msie');
-        $this->mz  = strstr($HTTP_USER_AGENT, 'mozilla/5');
+        $this->mz  = !$this->ie && strstr($HTTP_USER_AGENT, 'mozilla/5');
         $this->chrome = strstr($HTTP_USER_AGENT, 'chrome');
         $this->khtml = strstr($HTTP_USER_AGENT, 'khtml');
         $this->safari = !$this->chrome && ($this->khtml || strstr($HTTP_USER_AGENT, 'safari'));
index 9b65846bfa7184db218690a03ba5dbb3d55b05d3..9a09180989a7a8d94ef8d84dd0d3d40a6cfcae3f 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Aleksander Machniak <alec@alec.pl>                            |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_imap.php 4516 2011-02-09 12:46:46Z alec $
+ $Id: rcube_imap.php 4643 2011-04-11 12:24:00Z alec $
 
 */
 
@@ -2426,9 +2426,11 @@ class rcube_imap
      * @param  rcube_message_part $o_part Part object created by get_structure()
      * @param  mixed              $print  True to print part, ressource to write part contents in
      * @param  resource           $fp     File pointer to save the message part
+     * @param  boolean            $skip_charset_conv Disables charset conversion
+     *
      * @return string Message/part body if not printed
      */
-    function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL)
+    function &get_message_part($uid, $part=1, $o_part=NULL, $print=NULL, $fp=NULL, $skip_charset_conv=false)
     {
         // get part encoding if not provided
         if (!is_object($o_part)) {
@@ -2458,10 +2460,13 @@ class rcube_imap
             return true;
         }
 
-        // convert charset (if text or message part) and part's charset is specified
-        if ($body && $o_part->charset
-            && preg_match('/^(text|message)$/', $o_part->ctype_primary)
+        // convert charset (if text or message part)
+        if ($body && !$skip_charset_conv &&
+            preg_match('/^(text|message)$/', $o_part->ctype_primary)
         ) {
+            if (!$o_part->charset || strtoupper($o_part->charset) == 'US-ASCII') {
+                $o_part->charset = $this->default_charset;
+            }
             $body = rcube_charset_convert($body, $o_part->charset);
         }
 
@@ -4344,80 +4349,95 @@ class rcube_imap
      */
     public static function decode_mime_string($input, $fallback=null)
     {
-        // Initialize variable
-        $out = '';
+        if (!empty($fallback)) {
+            $default_charset = $fallback;
+        }
+        else {
+            $default_charset = rcmail::get_instance()->config->get('default_charset', 'ISO-8859-1');
+        }
 
-        // Iterate instead of recursing, this way if there are too many values we don't have stack overflows
         // rfc: all line breaks or other characters not found
         // in the Base64 Alphabet must be ignored by decoding software
         // delete all blanks between MIME-lines, differently we can
         // receive unnecessary blanks and broken utf-8 symbols
         $input = preg_replace("/\?=\s+=\?/", '?==?', $input);
 
-        // Check if there is stuff to decode
-        if (strpos($input, '=?') !== false) {
-            // Loop through the string to decode all occurences of =? ?= into the variable $out
-            while(($pos = strpos($input, '=?')) !== false) {
-                // Append everything that is before the text to be decoded
-                $out .= substr($input, 0, $pos);
-
-                // Get the location of the text to decode
-                $end_cs_pos = strpos($input, "?", $pos+2);
-                $end_en_pos = strpos($input, "?", $end_cs_pos+1);
-                $end_pos = strpos($input, "?=", $end_en_pos+1);
+        // encoded-word regexp
+        $re = '/=\?([^?]+)\?([BbQq])\?([^?\n]*)\?=/';
 
-                // Extract the encoded string
-                $encstr = substr($input, $pos+2, ($end_pos-$pos-2));
-                // Extract the remaining string
-                $input = substr($input, $end_pos+2);
+        // Find all RFC2047's encoded words
+        if (preg_match_all($re, $input, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
+            // Initialize variables
+            $tmp   = array();
+            $out   = '';
+            $start = 0;
 
-                // Decode the string fragement
-                $out .= rcube_imap::_decode_mime_string_part($encstr);
-            }
+            foreach ($matches as $idx => $m) {
+                $pos      = $m[0][1];
+                $charset  = $m[1][0];
+                $encoding = $m[2][0];
+                $text     = $m[3][0];
+                $length   = strlen($m[0][0]);
 
-            // Deocde the rest (if any)
-            if (strlen($input) != 0)
-                $out .= rcube_imap::decode_mime_string($input, $fallback);
+                // Append everything that is before the text to be decoded
+                if ($start != $pos) {
+                    $substr = substr($input, $start, $pos-$start);
+                    $out   .= rcube_charset_convert($substr, $default_charset);
+                    $start  = $pos;
+                }
+                $start += $length;
+
+                // Per RFC2047, each string part "MUST represent an integral number
+                // of characters . A multi-octet character may not be split across
+                // adjacent encoded-words." However, some mailers break this, so we
+                // try to handle characters spanned across parts anyway by iterating
+                // through and aggregating sequential encoded parts with the same
+                // character set and encoding, then perform the decoding on the
+                // aggregation as a whole.
+
+                $tmp[] = $text;
+                if ($next_match = $matches[$idx+1]) {
+                    if ($next_match[0][1] == $start
+                        && $next_match[1][0] == $charset
+                        && $next_match[2][0] == $encoding
+                    ) {
+                        continue;
+                    }
+                }
 
-            // return the results
-            return $out;
-        }
-
-        // no encoding information, use fallback
-        return rcube_charset_convert($input,
-            !empty($fallback) ? $fallback : rcmail::get_instance()->config->get('default_charset', 'ISO-8859-1'));
-    }
+                $count = count($tmp);
+                $text  = '';
 
+                // Decode and join encoded-word's chunks
+                if ($encoding == 'B' || $encoding == 'b') {
+                    // base64 must be decoded a segment at a time
+                    for ($i=0; $i<$count; $i++)
+                        $text .= base64_decode($tmp[$i]);
+                }
+                else { //if ($encoding == 'Q' || $encoding == 'q') {
+                    // quoted printable can be combined and processed at once
+                    for ($i=0; $i<$count; $i++)
+                        $text .= $tmp[$i];
 
-    /**
-     * Decode a part of a mime-encoded string
-     *
-     * @param string $str String to decode
-     * @return string Decoded string
-     * @access private
-     */
-    private function _decode_mime_string_part($str)
-    {
-        $a = explode('?', $str);
-        $count = count($a);
+                    $text = str_replace('_', ' ', $text);
+                    $text = quoted_printable_decode($text);
+                }
 
-        // should be in format "charset?encoding?base64_string"
-        if ($count >= 3) {
-            for ($i=2; $i<$count; $i++)
-                $rest .= $a[$i];
+                $out .= rcube_charset_convert($text, $charset);
+                $tmp = array();
+            }
 
-            if (($a[1]=='B') || ($a[1]=='b'))
-                $rest = base64_decode($rest);
-            else if (($a[1]=='Q') || ($a[1]=='q')) {
-                $rest = str_replace('_', ' ', $rest);
-                $rest = quoted_printable_decode($rest);
+            // add the last part of the input string
+            if ($start != strlen($input)) {
+                $out .= rcube_charset_convert(substr($input, $start), $default_charset);
             }
 
-            return rcube_charset_convert($rest, $a[0]);
+            // return the results
+            return $out;
         }
 
-        // we dont' know what to do with this
-        return $str;
+        // no encoding information, use fallback
+        return rcube_charset_convert($input, $default_charset);
     }
 
 
index 18f1f5da8f00101abc7439b2f68fa76d4f7024f0..e2ee342f82603d8da0769a8697df6fa3ed8b9daf 100644 (file)
@@ -21,7 +21,7 @@
  | Author: Ryo Chijiiwa <Ryo@IlohaMail.org>                              |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_imap_generic.php 4516 2011-02-09 12:46:46Z alec $
+ $Id: rcube_imap_generic.php 4643 2011-04-11 12:24:00Z alec $
 
 */
 
@@ -213,31 +213,26 @@ class rcube_imap_generic
     {
         $line = '';
 
-        if (!$this->fp) {
-            return NULL;
-        }
-
         if (!$size) {
             $size = 1024;
         }
 
         do {
-            if (feof($this->fp)) {
+            if ($this->eof()) {
                 return $line ? $line : NULL;
             }
 
             $buffer = fgets($this->fp, $size);
 
             if ($buffer === false) {
-                @fclose($this->fp);
-                $this->fp = null;
+                $this->closeSocket();
                 break;
             }
             if ($this->_debug) {
                 $this->debug('S: '. rtrim($buffer));
             }
             $line .= $buffer;
-        } while ($buffer[strlen($buffer)-1] != "\n");
+        } while (substr($buffer, -1) != "\n");
 
         return $line;
     }
@@ -267,7 +262,7 @@ class rcube_imap_generic
     {
         $data = '';
         $len  = 0;
-        while ($len < $bytes && !feof($this->fp))
+        while ($len < $bytes && !$this->eof())
         {
             $d = fread($this->fp, $bytes-$len);
             if ($this->_debug) {
@@ -312,8 +307,7 @@ class rcube_imap_generic
             } else if ($res == 'BAD') {
                 $this->errornum = self::ERROR_BAD;
             } else if ($res == 'BYE') {
-                @fclose($this->fp);
-                $this->fp = null;
+                $this->closeSocket();
                 $this->errornum = self::ERROR_BYE;
             }
 
@@ -339,6 +333,32 @@ class rcube_imap_generic
         return self::ERROR_UNKNOWN;
     }
 
+    private function eof()
+    {
+        if (!is_resource($this->fp)) {
+            return true;
+        }
+
+        // If a connection opened by fsockopen() wasn't closed
+        // by the server, feof() will hang.
+        $start = microtime(true);
+
+        if (feof($this->fp) || 
+            ($this->prefs['timeout'] && (microtime(true) - $start > $this->prefs['timeout']))
+        ) {
+            $this->closeSocket();
+            return true;
+        }
+
+        return false;
+    }
+
+    private function closeSocket()
+    {
+        @fclose($this->fp);
+        $this->fp = null;
+    }
+
     function setError($code, $msg='')
     {
         $this->errornum = $code;
@@ -360,8 +380,7 @@ class rcube_imap_generic
         }
         if ($error && preg_match('/^\* (BYE|BAD) /i', $string, $m)) {
             if (strtoupper($m[1]) == 'BYE') {
-                @fclose($this->fp);
-                $this->fp = null;
+                $this->closeSocket();
             }
             return true;
         }
@@ -701,11 +720,12 @@ class rcube_imap_generic
             $host = $this->prefs['ssl_mode'] . '://' . $host;
         }
 
+        if ($this->prefs['timeout'] <= 0) {
+            $this->prefs['timeout'] = ini_get('default_socket_timeout');
+        }
+
         // Connect
-        if ($this->prefs['timeout'] > 0)
-            $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr, $this->prefs['timeout']);
-        else
-            $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr);
+        $this->fp = @fsockopen($host, $this->prefs['port'], $errno, $errstr, $this->prefs['timeout']);
 
         if (!$this->fp) {
             $this->setError(self::ERROR_BAD, sprintf("Could not connect to %s:%d: %s", $host, $this->prefs['port'], $errstr));
@@ -757,6 +777,13 @@ class rcube_imap_generic
                 // Now we're secure, capabilities need to be reread
                 $this->clearCapability();
             }
+
+            // Use best (for security) supported authentication method
+            foreach (array('DIGEST-MD5', 'CRAM-MD5', 'CRAM_MD5', 'PLAIN', 'LOGIN') as $auth_method) {
+                if (in_array($auth_method, $auth_methods)) {
+                    break;
+                }
+            }
         }
 
         // Send ID info
@@ -782,6 +809,13 @@ class rcube_imap_generic
             else if (!$login_disabled) {
                 $auth_methods[] = 'LOGIN';
             }
+\r
+            // Use best (for security) supported authentication method\r
+            foreach (array('DIGEST-MD5', 'CRAM-MD5', 'CRAM_MD5', 'PLAIN', 'LOGIN') as $auth_method) {\r
+                if (in_array($auth_method, $auth_methods)) {\r
+                    break;\r
+                }\r
+            }\r
         }
         else {
             // Prevent from sending credentials in plain text when connection is not secure
@@ -791,32 +825,28 @@ class rcube_imap_generic
                 return false;
             }
             // replace AUTH with CRAM-MD5 for backward compat.
-            $auth_methods[] = $auth_method == 'AUTH' ? 'CRAM-MD5' : $auth_method;
+            if ($auth_method == 'AUTH') {
+                $auth_method = 'CRAM-MD5';
+            }
         }
 
         // pre-login capabilities can be not complete
         $this->capability_readed = false;
 
         // Authenticate
-        foreach ($auth_methods as $method) {
-            switch ($method) {
+        switch ($auth_method) {
             case 'CRAM_MD5':
-                $method = 'CRAM-MD5';
+                $auth_method = 'CRAM-MD5';
             case 'CRAM-MD5':
             case 'DIGEST-MD5':
             case 'PLAIN':
-                $result = $this->authenticate($user, $password, $method);
+                $result = $this->authenticate($user, $password, $auth_method);
                 break;
             case 'LOGIN':
                 $result = $this->login($user, $password);
                 break;
             default:
-                $this->setError(self::ERROR_BAD, "Configuration error. Unknown auth method: $method");
-            }
-
-            if (is_resource($result)) {
-                break;
-            }
+                $this->setError(self::ERROR_BAD, "Configuration error. Unknown auth method: $auth_method");
         }
 
         // Connected and authenticated
@@ -845,8 +875,7 @@ class rcube_imap_generic
             $this->readReply();
         }
 
-        @fclose($this->fp);
-        $this->fp = false;
+        $this->closeSocket();
     }
 
     /**
@@ -935,6 +964,16 @@ class rcube_imap_generic
 
             list($mbox, $items) = $this->tokenizeResponse($response, 2);
 
+            // Fix for #1487859. Some buggy server returns not quoted
+            // folder name with spaces. Let's try to handle this situation
+            if (!is_array($items) && ($pos = strpos($response, '(')) !== false) {
+                $response = substr($response, $pos);
+                $items = $this->tokenizeResponse($response, 1);
+                if (!is_array($items)) {
+                    return $result;
+                }
+            }
+
             for ($i=0, $len=count($items); $i<$len; $i += 2) {
                 $result[$items[$i]] = (int) $items[$i+1];
             }
@@ -1341,7 +1380,7 @@ class rcube_imap_generic
                         $result[$id] = '';
                     }
                 } else if ($mode == 2) {
-                    if (preg_match('/\((UID|RFC822\.SIZE) ([0-9]+)/', $line, $matches)) {
+                    if (preg_match('/(UID|RFC822\.SIZE) ([0-9]+)/', $line, $matches)) {
                         $result[$id] = trim($matches[2]);
                     } else {
                         $result[$id] = 0;
@@ -1540,36 +1579,21 @@ class rcube_imap_generic
                 if (preg_match('/^\* [0-9]+ FETCH \((.*) BODY/sU', $line, $matches)) {
                     $str = $matches[1];
 
-                    // swap parents with quotes, then explode
-                    $str = preg_replace('/[()]/', '"', $str);
-                    $a = rcube_explode_quoted_string(' ', $str);
-
-                    // did we get the right number of replies?
-                    $parts_count = count($a);
-                    if ($parts_count>=6) {
-                        for ($i=0; $i<$parts_count; $i=$i+2) {
-                            if ($a[$i] == 'UID') {
-                                $result[$id]->uid = intval($a[$i+1]);
-                            }
-                            else if ($a[$i] == 'RFC822.SIZE') {
-                                $result[$id]->size = intval($a[$i+1]);
-                            }
-                            else if ($a[$i] == 'INTERNALDATE') {
-                                $time_str = $a[$i+1];
-                            }
-                            else if ($a[$i] == 'FLAGS') {
-                                $flags_str = $a[$i+1];
-                            }
+                    while (list($name, $value) = $this->tokenizeResponse($str, 2)) {
+                        if ($name == 'UID') {
+                            $result[$id]->uid = intval($value);
+                        }
+                        else if ($name == 'RFC822.SIZE') {
+                            $result[$id]->size = intval($value);
+                        }
+                        else if ($name == 'INTERNALDATE') {
+                            $result[$id]->internaldate = $value;
+                            $result[$id]->date         = $value;
+                            $result[$id]->timestamp    = $this->StrToTime($value);
+                        }
+                        else if ($name == 'FLAGS') {
+                            $flags_a = $value;
                         }
-
-                        $time_str = str_replace('"', '', $time_str);
-
-                        // if time is gmt...
-                        $time_str = str_replace('GMT','+0000',$time_str);
-
-                        $result[$id]->internaldate = $time_str;
-                        $result[$id]->timestamp    = $this->StrToTime($time_str);
-                        $result[$id]->date         = $time_str;
                     }
 
                     // BODYSTRUCTURE
@@ -1617,7 +1641,7 @@ class rcube_imap_generic
 
                     // handle FLAGS reply after headers (AOL, Zimbra?)
                     if (preg_match('/\s+FLAGS \((.*)\)\)$/', $line, $matches)) {
-                        $flags_str = $matches[1];
+                        $flags_a = $this->tokenizeResponse($matches[1]);
                         break;
                     }
 
@@ -1641,10 +1665,10 @@ class rcube_imap_generic
 
                     // create array with header field:data
                     while (list($lines_key, $str) = each($lines)) {
-                        list($field, $string) = $this->splitHeaderLine($str);
+                        list($field, $string) = explode(':', $str, 2);
 
                         $field  = strtolower($field);
-                        $string = preg_replace('/\n\s*/', ' ', $string);
+                        $string = preg_replace('/\n[\t\s]*/', ' ', trim($string));
 
                         switch ($field) {
                         case 'date';
@@ -1708,32 +1732,31 @@ class rcube_imap_generic
                 }
 
                 // process flags
-                if (!empty($flags_str)) {
-                    $flags_str = preg_replace('/[\\\"]/', '', $flags_str);
-                    $flags_a   = explode(' ', $flags_str);
-
-                    if (is_array($flags_a)) {
-                        foreach($flags_a as $flag) {
-                            $flag = strtoupper($flag);
-                            if ($flag == 'SEEN') {
-                                $result[$id]->seen = true;
-                            } else if ($flag == 'DELETED') {
-                                $result[$id]->deleted = true;
-                            } else if ($flag == 'RECENT') {
-                                $result[$id]->recent = true;
-                            } else if ($flag == 'ANSWERED') {
-                                $result[$id]->answered = true;
-                            } else if ($flag == '$FORWARDED') {
-                                $result[$id]->forwarded = true;
-                            } else if ($flag == 'DRAFT') {
-                                $result[$id]->is_draft = true;
-                            } else if ($flag == '$MDNSENT') {
-                                $result[$id]->mdn_sent = true;
-                            } else if ($flag == 'FLAGGED') {
-                                 $result[$id]->flagged = true;
-                            }
+                if (!empty($flags_a)) {
+                    foreach ($flags_a as $flag) {
+                        $flag = str_replace('\\', '', $flag);
+                        $result[$id]->flags[] = $flag;
+
+                        switch (strtoupper($flag)) {
+                        case 'SEEN':
+                            $result[$id]->seen = true;
+                            break;
+                        case 'DELETED':
+                            $result[$id]->deleted = true;
+                            break;
+                        case 'ANSWERED':
+                            $result[$id]->answered = true;
+                            break;
+                        case '$FORWARDED':
+                            $result[$id]->forwarded = true;
+                            break;
+                        case '$MDNSENT':
+                            $result[$id]->mdn_sent = true;
+                            break;
+                        case 'FLAGGED':
+                            $result[$id]->flagged = true;
+                            break;
                         }
-                        $result[$id]->flags = $flags_a;
                     }
                 }
             }
@@ -3268,9 +3291,10 @@ class rcube_imap_generic
     {
         // support non-standard "GMTXXXX" literal
         $date = preg_replace('/GMT\s*([+-][0-9]+)/', '\\1', $date);
+
         // if date parsing fails, we have a date in non-rfc format.
         // remove token from the end and try again
-        while ((($ts = @strtotime($date))===false) || ($ts < 0)) {
+        while (($ts = intval(@strtotime($date))) <= 0) {
             $d = explode(' ', $date);
             array_pop($d);
             if (!$d) {
@@ -3284,17 +3308,6 @@ class rcube_imap_generic
         return $ts < 0 ? 0 : $ts;
     }
 
-    private function splitHeaderLine($string)
-    {
-        $pos = strpos($string, ':');
-        if ($pos>0) {
-            $res[0] = substr($string, 0, $pos);
-            $res[1] = trim(substr($string, $pos+1));
-            return $res;
-        }
-        return $string;
-    }
-
     private function parseCapability($str, $trusted=false)
     {
         $str = preg_replace('/^\* CAPABILITY /i', '', $str);
index ab9e64826ef890302b79976f4d7d5d0e29c1d78d..a763f0cd548dbd1d9438c54f20c45b744d655a32 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Lukas Kahwe Smith <smith@pooteeweet.org>                      |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_mdb2.php 4057 2010-10-07 07:03:25Z alec $
+ $Id: rcube_mdb2.php 4643 2011-04-11 12:24:00Z alec $
 
 */
 
@@ -553,15 +553,7 @@ class rcube_mdb2
      */
     function fromunixtime($timestamp)
     {
-        switch($this->db_provider) {
-            case 'mysqli':
-            case 'mysql':
-            case 'sqlite':
-                return sprintf("FROM_UNIXTIME(%d)", $timestamp);
-
-            default:
-                return date("'Y-m-d H:i:s'", $timestamp);
-        }
+        return date("'Y-m-d H:i:s'", $timestamp);
     }
 
 
index 2f862b79ac6896399137576566384481d02624e4..acf4a4ddd08b4fd86583ba090a507d348b07fd73 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_message.php 4516 2011-02-09 12:46:46Z alec $
+ $Id: rcube_message.php 4643 2011-04-11 12:24:00Z alec $
 
 */
 
@@ -725,7 +725,9 @@ class rcube_message
                     $line  = $prefix . rc_wordwrap($line, $length - $level - 2, " \r\n$prefix ");
                 }
                 else if ($line) {
-                    $line = ' ' . rc_wordwrap(rtrim($line), $length - 2, " \r\n ");
+                    $line = rc_wordwrap(rtrim($line), $length - 2, " \r\n");
+                    // space-stuffing
+                    $line = preg_replace('/(^|\r\n)(From| |>)/', '\\1 \\2', $line);
                 }
 
                 $text[$idx] = $line;
index 59ce42379432faf2db4ec6b0d13dcd9bda176808..0bae4a7116f10908258ed7d5649028dffe305d11 100644 (file)
@@ -183,27 +183,12 @@ class rcube_session
   }
 
 
-  public function regenerate_id()
+  public function regenerate_id($destroy=true)
   {
-    $randval = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
-
-    for ($random = '', $i=1; $i <= 32; $i++) {
-      $random .= substr($randval, mt_rand(0,(strlen($randval) - 1)), 1);
-    }
-
-    // use md5 value for id or remove capitals from string $randval
-    $random = md5($random);
-
-    // delete old session record
-    $this->destroy(session_id());
-
-    session_id($random);
-
-    $cookie   = session_get_cookie_params();
-    $lifetime = $cookie['lifetime'] ? time() + $cookie['lifetime'] : 0;
-
-    rcmail::setcookie(session_name(), $random, $lifetime);
+    session_regenerate_id($destroy);
 
+    $this->vars = false;
+    $this->key  = session_id();
     return true;
   }
 
index e795bc48f33197d779bb92520e29eb13fb31d07c..817eef8aa7c2d322ae70d4692ab66bd78a3afa0e 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_smtp.php 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: rcube_smtp.php 4666 2011-04-17 09:34:02Z alec $
 
 */
 
@@ -105,7 +105,7 @@ class rcube_smtp
 
     $this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
 
-    if($RCMAIL->config->get('smtp_debug'))
+    if ($RCMAIL->config->get('smtp_debug'))
       $this->conn->setDebug(true, array($this, 'debug_handler'));
 
     // try to connect to server and exit on failure
@@ -118,6 +118,13 @@ class rcube_smtp
       return false;
     }
 
+    // workaround for timeout bug in Net_SMTP 1.5.[0-1] (#1487843)
+    if (method_exists($this->conn, 'setTimeout')
+      && ($timeout = ini_get('default_socket_timeout'))
+    ) {
+      $this->conn->setTimeout($timeout);
+    }
+
     $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']);
     $smtp_pass = str_replace('%p', $RCMAIL->decrypt($_SESSION['password']), $CONFIG['smtp_pass']);
     $smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
index fc11b73632ae49041acc008eff81fb097ea08e5e..4709c7377f9477470612b94a2b324bf02830fb1e 100755 (executable)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_template.php 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: rcube_template.php 4666 2011-04-17 09:34:02Z alec $
 
  */
 
@@ -373,16 +373,19 @@ class rcube_template extends rcube_html_page
     private function parse($name = 'main', $exit = true)
     {
         $skin_path = $this->config['skin_path'];
-        $plugin = false;
+        $plugin    = false;
+        $realname  = $name;
+        $temp      = explode('.', $name, 2);
         $this->plugin_skin_path = null;
 
-        $temp = explode(".", $name, 2);
         if (count($temp) > 1) {
-            $plugin = $temp[0];
-            $name = $temp[1];
-            $skin_dir = $plugin . '/skins/' . $this->config['skin'];
+            $plugin    = $temp[0];
+            $name      = $temp[1];
+            $skin_dir  = $plugin . '/skins/' . $this->config['skin'];
             $skin_path = $this->plugin_skin_path = $this->app->plugins->dir . $skin_dir;
-            if (!is_dir($skin_path)) {  // fallback to default skin
+
+            // fallback to default skin
+            if (!is_dir($skin_path)) {
                 $skin_dir = $plugin . '/skins/default';
                 $skin_path = $this->plugin_skin_path = $this->app->plugins->dir . $skin_dir;
             }
@@ -390,12 +393,13 @@ class rcube_template extends rcube_html_page
 
         $path = "$skin_path/templates/$name.html";
 
-        if (!is_readable($path) && $this->deprecated_templates[$name]) {
-            $path = "$skin_path/templates/".$this->deprecated_templates[$name].".html";
+        if (!is_readable($path) && $this->deprecated_templates[$realname]) {
+            $path = "$skin_path/templates/".$this->deprecated_templates[$realname].".html";
             if (is_readable($path))
                 raise_error(array('code' => 502, 'type' => 'php',
                     'file' => __FILE__, 'line' => __LINE__,
-                    'message' => "Using deprecated template '".$this->deprecated_templates[$name]."' in ".$this->config['skin_path']."/templates. Please rename to '".$name."'"),
+                    'message' => "Using deprecated template '".$this->deprecated_templates[$realname]
+                        ."' in ".$this->config['skin_path']."/templates. Please rename to '".$realname."'"),
                 true, false);
         }
 
@@ -406,7 +410,7 @@ class rcube_template extends rcube_html_page
                 'type' => 'php',
                 'line' => __LINE__,
                 'file' => __FILE__,
-                'message' => 'Error loading template for '.$name
+                'message' => 'Error loading template for '.$realname
                 ), true, true);
             return false;
         }
@@ -422,7 +426,7 @@ class rcube_template extends rcube_html_page
         $output = $this->parse_xml($output);
 
         // trigger generic hook where plugins can put additional content to the page
-        $hook = $this->app->plugins->exec_hook("render_page", array('template' => $name, 'content' => $output));
+        $hook = $this->app->plugins->exec_hook("render_page", array('template' => $realname, 'content' => $output));
 
         // add debug console
         if ($this->config['debug_level'] & 8) {
index c764b186c2df094cfbf7f3577ebbb7efdd8d6ecf..39a77ada785bd6023e8c1588ffcd952b14abe588 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: rcube_user.php 4290 2010-11-30 13:43:04Z alec $
+ $Id: rcube_user.php 4554 2011-02-16 09:42:31Z alec $
 
 */
 
@@ -359,16 +359,15 @@ class rcube_user
         $dbh = rcmail::get_instance()->get_dbh();
 
         // use BINARY (case-sensitive) comparison on MySQL, other engines are case-sensitive
-        $prefix = preg_match('/^mysql/', $dbh->db_provider) ? 'BINARY ' : '';
+        $mod = preg_match('/^mysql/', $dbh->db_provider) ? 'BINARY' : '';
 
         // query for matching user name
-        $query = "SELECT * FROM ".get_table_name('users')." WHERE mail_host = ? AND %s = ?";
-
-        $sql_result = $dbh->query(sprintf($query, $prefix.'username'), $host, $user);
+        $query = "SELECT * FROM ".get_table_name('users')." WHERE mail_host = ? AND %s = $mod ?";
+        $sql_result = $dbh->query(sprintf($query, 'username'), $host, $user);
 
         // query for matching alias
         if (!($sql_arr = $dbh->fetch_assoc($sql_result))) {
-            $sql_result = $dbh->query(sprintf($query, $prefix.'alias'), $host, $user);
+            $sql_result = $dbh->query(sprintf($query, 'alias'), $host, $user);
             $sql_arr = $dbh->fetch_assoc($sql_result);
         }
 
index 6eb3961211272796c6978290e4ae31cc822f9afb..091584707a1e7ea802b3600633ce775494e90412 100644 (file)
-function rcube_webmail(){this.env={};this.labels={};this.buttons={};this.buttons_sel={};this.gui_objects={};this.gui_containers={};this.commands={};this.command_handlers={};this.onloads=[];this.messages={};this.ref="rcmail";var l=this;this.dblclick_time=500;this.message_time=2E3;this.identifier_expr=RegExp("[^0-9a-z-_]","gi");this.mimetypes=["text/plain","text/html","text/xml","image/jpeg","image/gif","image/png","application/x-javascript","application/pdf","application/x-shockwave-flash"];this.env.keep_alive=
-60;this.env.request_timeout=180;this.env.draft_autosave=0;this.env.comm_path="./";this.env.blankpage="program/blank.gif";$.ajaxSetup({cache:false,error:function(a,b,d){l.http_error(a,b,d)},beforeSend:function(a){a.setRequestHeader("X-Roundcube-Request",l.env.request_token)}});this.set_env=function(a,b){if(a!=null&&typeof a=="object"&&!b)for(var d in a)this.env[d]=a[d];else this.env[a]=b};this.add_label=function(a,b){this.labels[a]=b};this.register_button=function(a,b,d,e,f,g){this.buttons[a]||(this.buttons[a]=
-[]);b={id:b,type:d};if(e)b.act=e;if(f)b.sel=f;if(g)b.over=g;this.buttons[a].push(b)};this.gui_object=function(a,b){this.gui_objects[a]=b};this.gui_container=function(a,b){this.gui_containers[a]=b};this.add_element=function(a,b){this.gui_containers[b]&&this.gui_containers[b].jquery&&this.gui_containers[b].append(a)};this.register_command=function(a,b,d){this.command_handlers[a]=b;d&&this.enable_command(a,true)};this.add_onload=function(a){this.onloads.push(a)};this.init=function(){var a=this;this.task=
-this.env.task;if(!bw.dom||!bw.xmlhttp_test())this.goto_url("error","_code=0x199");else{for(var b in this.gui_containers)this.gui_containers[b]=$("#"+this.gui_containers[b]);for(b in this.gui_objects)this.gui_objects[b]=rcube_find_object(this.gui_objects[b]);this.init_buttons();if(this.is_framed()){parent.rcmail.set_busy(false,null,parent.rcmail.env.frame_lock);parent.rcmail.env.frame_lock=null}this.enable_command("logout","mail","addressbook","settings",true);this.env.permaurl&&this.enable_command("permaurl",
-true);switch(this.task){case "mail":this.enable_command("list","checkmail","compose","add-contact","search","reset-search","collapse-folder",true);if(this.gui_objects.messagelist){this.message_list=new rcube_list_widget(this.gui_objects.messagelist,{multiselect:true,multiexpand:true,draggable:true,keyboard:true,column_movable:this.env.col_movable,dblclick_time:this.dblclick_time});this.message_list.row_init=function(e){a.init_message_row(e)};this.message_list.addEventListener("dblclick",function(e){a.msglist_dbl_click(e)});
-this.message_list.addEventListener("click",function(e){a.msglist_click(e)});this.message_list.addEventListener("keypress",function(e){a.msglist_keypress(e)});this.message_list.addEventListener("select",function(e){a.msglist_select(e)});this.message_list.addEventListener("dragstart",function(e){a.drag_start(e)});this.message_list.addEventListener("dragmove",function(e){a.drag_move(e)});this.message_list.addEventListener("dragend",function(e){a.drag_end(e)});this.message_list.addEventListener("expandcollapse",
-function(e){a.msglist_expand(e)});this.message_list.addEventListener("column_replace",function(e){a.msglist_set_coltypes(e)});document.onmouseup=function(e){return a.doc_mouse_up(e)};this.gui_objects.messagelist.parentNode.onmousedown=function(e){return a.click_on_list(e)};this.message_list.init();this.enable_command("toggle_status","toggle_flag","menu-open","menu-save",true);this.command("list")}if(this.gui_objects.qsearchbox){if(this.env.search_text!=null)this.gui_objects.qsearchbox.value=this.env.search_text;
+function rcube_webmail(){this.env={};this.labels={};this.buttons={};this.buttons_sel={};this.gui_objects={};this.gui_containers={};this.commands={};this.command_handlers={};this.onloads=[];this.messages={};this.ref="rcmail";var j=this;this.dblclick_time=500;this.message_time=2E3;this.identifier_expr=RegExp("[^0-9a-z-_]","gi");this.mimetypes=["text/plain","text/html","text/xml","image/jpeg","image/gif","image/png","application/x-javascript","application/pdf","application/x-shockwave-flash"];this.env.keep_alive=
+60;this.env.request_timeout=180;this.env.draft_autosave=0;this.env.comm_path="./";this.env.blankpage="program/blank.gif";$.ajaxSetup({cache:!1,error:function(a,b,d){j.http_error(a,b,d)},beforeSend:function(a){a.setRequestHeader("X-Roundcube-Request",j.env.request_token)}});this.set_env=function(a,b){if(a!=null&&typeof a=="object"&&!b)for(var d in a)this.env[d]=a[d];else this.env[a]=b};this.add_label=function(a,b){this.labels[a]=b};this.register_button=function(a,b,d,e,f,g){this.buttons[a]||(this.buttons[a]=
+[]);b={id:b,type:d};if(e)b.act=e;if(f)b.sel=f;if(g)b.over=g;this.buttons[a].push(b)};this.gui_object=function(a,b){this.gui_objects[a]=b};this.gui_container=function(a,b){this.gui_containers[a]=b};this.add_element=function(a,b){this.gui_containers[b]&&this.gui_containers[b].jquery&&this.gui_containers[b].append(a)};this.register_command=function(a,b,d){this.command_handlers[a]=b;d&&this.enable_command(a,!0)};this.add_onload=function(a){this.onloads.push(a)};this.init=function(){var a=this;this.task=
+this.env.task;if(!bw.dom||!bw.xmlhttp_test())this.goto_url("error","_code=0x199");else{for(var b in this.gui_containers)this.gui_containers[b]=$("#"+this.gui_containers[b]);for(b in this.gui_objects)this.gui_objects[b]=rcube_find_object(this.gui_objects[b]);this.init_buttons();if(this.is_framed())parent.rcmail.set_busy(!1,null,parent.rcmail.env.frame_lock),parent.rcmail.env.frame_lock=null;this.enable_command("logout","mail","addressbook","settings",!0);this.env.permaurl&&this.enable_command("permaurl",
+!0);switch(this.task){case "mail":this.enable_command("list","checkmail","compose","add-contact","search","reset-search","collapse-folder",!0);if(this.gui_objects.messagelist)this.message_list=new rcube_list_widget(this.gui_objects.messagelist,{multiselect:!0,multiexpand:!0,draggable:!0,keyboard:!0,column_movable:this.env.col_movable,dblclick_time:this.dblclick_time}),this.message_list.row_init=function(b){a.init_message_row(b)},this.message_list.addEventListener("dblclick",function(b){a.msglist_dbl_click(b)}),
+this.message_list.addEventListener("click",function(b){a.msglist_click(b)}),this.message_list.addEventListener("keypress",function(b){a.msglist_keypress(b)}),this.message_list.addEventListener("select",function(b){a.msglist_select(b)}),this.message_list.addEventListener("dragstart",function(b){a.drag_start(b)}),this.message_list.addEventListener("dragmove",function(b){a.drag_move(b)}),this.message_list.addEventListener("dragend",function(b){a.drag_end(b)}),this.message_list.addEventListener("expandcollapse",
+function(b){a.msglist_expand(b)}),this.message_list.addEventListener("column_replace",function(b){a.msglist_set_coltypes(b)}),document.onmouseup=function(b){return a.doc_mouse_up(b)},this.gui_objects.messagelist.parentNode.onmousedown=function(b){return a.click_on_list(b)},this.message_list.init(),this.enable_command("toggle_status","toggle_flag","menu-open","menu-save",!0),this.command("list");if(this.gui_objects.qsearchbox){if(this.env.search_text!=null)this.gui_objects.qsearchbox.value=this.env.search_text;
 $(this.gui_objects.qsearchbox).focusin(function(){rcmail.message_list.blur()})}this.env.trash_mailbox&&this.env.mailbox!=this.env.trash_mailbox&&this.set_alttext("delete","movemessagetotrash");this.env.message_commands=["show","reply","reply-all","reply-list","forward","moveto","copy","delete","open","mark","edit","viewsource","download","print","load-attachment","load-headers"];if(this.env.action=="show"||this.env.action=="preview"){this.enable_command(this.env.message_commands,this.env.uid);this.enable_command("reply-list",
-this.env.list_post);this.env.action=="show"&&this.http_request("pagenav","_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox),this.display_message("","loading"));if(this.env.blockedobjects){if(this.gui_objects.remoteobjectsmsg)this.gui_objects.remoteobjectsmsg.style.display="block";this.enable_command("load-images","always-load",true)}if(this.env.action=="preview"&&this.is_framed()){this.enable_command("compose","add-contact",false);parent.rcmail.show_contentframe(true)}}else if(this.env.action==
-"compose"){this.env.compose_commands=["send-attachment","remove-attachment","send","toggle-editor"];this.env.drafts_mailbox&&this.env.compose_commands.push("savedraft");this.enable_command(this.env.compose_commands,"identities",true);if(this.env.spellcheck){this.env.spellcheck.spelling_state_observer=function(e){l.set_spellcheck_state(e)};this.env.compose_commands.push("spellcheck");this.set_spellcheck_state("ready");$("input[name='_is_html']").val()=="1"&&this.display_spellcheck_controls(false)}document.onmouseup=
-function(e){return a.doc_mouse_up(e)};this.init_messageform()}else this.env.action=="print"&&this.env.uid&&window.print();if(this.gui_objects.mailboxlist){this.env.unread_counts={};this.gui_objects.folderlist=this.gui_objects.mailboxlist;this.http_request("getunread","")}if(this.env.mdn_request&&this.env.uid){b="_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox);confirm(this.get_label("mdnrequest"))?this.http_post("sendmdn",b):this.http_post("mark",b+"&_flag=mdnsent")}break;case "addressbook":if(this.gui_objects.folderlist)this.env.contactfolders=
-$.extend($.extend({},this.env.address_sources),this.env.contactgroups);if(this.gui_objects.contactslist){this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:true,draggable:this.gui_objects.folderlist?true:false,keyboard:true});this.contact_list.row_init=function(e){a.triggerEvent("insertrow",{cid:e.uid,row:e})};this.contact_list.addEventListener("keypress",function(e){a.contactlist_keypress(e)});this.contact_list.addEventListener("select",function(e){a.contactlist_select(e)});
-this.contact_list.addEventListener("dragstart",function(e){a.drag_start(e)});this.contact_list.addEventListener("dragmove",function(e){a.drag_move(e)});this.contact_list.addEventListener("dragend",function(e){a.drag_end(e)});this.contact_list.init();this.env.cid&&this.contact_list.highlight_row(this.env.cid);this.gui_objects.contactslist.parentNode.onmousedown=function(e){return a.click_on_list(e)};document.onmouseup=function(e){return a.doc_mouse_up(e)};this.gui_objects.qsearchbox&&$(this.gui_objects.qsearchbox).focusin(function(){rcmail.contact_list.blur()})}this.set_page_buttons();
-if(this.env.address_sources&&this.env.address_sources[this.env.source]&&!this.env.address_sources[this.env.source].readonly){this.enable_command("add","import",true);this.enable_command("group-create",this.env.address_sources[this.env.source].groups)}if(this.env.cid){this.enable_command("show","edit",true);this.gui_objects.editform&&$("input.groupmember").change(function(){l.http_post(this.checked?"group-addmembers":"group-delmembers","_cid="+urlencode(l.env.cid)+"&_source="+urlencode(l.env.source)+
-"&_gid="+urlencode(this.value))})}if((this.env.action=="add"||this.env.action=="edit")&&this.gui_objects.editform){this.enable_command("save",true);$("input[type='text']").first().select()}else if(this.gui_objects.qsearchbox){this.enable_command("search","reset-search","moveto",true);$(this.gui_objects.qsearchbox).select()}this.contact_list&&this.contact_list.rowcount>0&&this.enable_command("export",true);this.enable_command("list","listgroup",true);break;case "settings":this.enable_command("preferences",
-"identities","save","folders",true);if(this.env.action=="identities")this.enable_command("add",this.env.identities_level<2);else if(this.env.action=="edit-identity"||this.env.action=="add-identity"){this.enable_command("add",this.env.identities_level<2);this.enable_command("save","delete","edit","toggle-editor",true)}else if(this.env.action=="folders")this.enable_command("subscribe","unsubscribe","create-folder","rename-folder",true);else if(this.env.action=="edit-folder"&&this.gui_objects.editform){this.enable_command("save",
-"folder-size",true);parent.rcmail.env.messagecount=this.env.messagecount;parent.rcmail.enable_command("purge",this.env.messagecount);$("input[type='text']").first().select()}if(this.gui_objects.identitieslist){this.identity_list=new rcube_list_widget(this.gui_objects.identitieslist,{multiselect:false,draggable:false,keyboard:false});this.identity_list.addEventListener("select",function(e){a.identity_select(e)});this.identity_list.init();this.identity_list.focus();this.env.iid&&this.identity_list.highlight_row(this.env.iid)}else if(this.gui_objects.sectionslist){this.sections_list=
-new rcube_list_widget(this.gui_objects.sectionslist,{multiselect:false,draggable:false,keyboard:false});this.sections_list.addEventListener("select",function(e){a.section_select(e)});this.sections_list.init();this.sections_list.focus()}else this.gui_objects.subscriptionlist&&this.init_subscription_list();break;case "login":b=$("#rcmloginuser");b.bind("keyup",function(e){return rcmail.login_user_keyup(e)});b.val()==""?b.focus():$("#rcmloginpwd").focus();$("#rcmlogintz").val((new Date).getTimezoneOffset()/
--60);$("form").submit(function(){$("input[type=submit]",this).attr("disabled",true);rcmail.display_message("","loading")});this.enable_command("login",true)}this.loaded=true;this.pending_message&&this.display_message(this.pending_message[0],this.pending_message[1]);if(this.gui_objects.folderlist)this.gui_containers.foldertray=$(this.gui_objects.folderlist);this.triggerEvent("init",{task:this.task,action:this.env.action});for(var d in this.onloads)if(typeof this.onloads[d]=="string")eval(this.onloads[d]);
-else if(typeof this.onloads[d]=="function")this.onloads[d]();this.start_keepalive()}};this.command=function(a,b,d){d&&d.blur&&d.blur();if(this.busy)return false;if(!this.commands[a]){this.is_framed()&&parent.rcmail.command(a,b);return false}if(this.task=="mail"&&this.env.action=="compose"&&$.inArray(a,this.env.compose_commands)<0)if(this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning")))return false;if(typeof this.command_handlers[a]=="function"){a=this.command_handlers[a](b,
-d);return a!==null?a:d?false:true}else if(typeof this.command_handlers[a]=="string"){a=window[this.command_handlers[a]](b,d);return a!==null?a:d?false:true}this.triggerEvent("actionbefore",{props:b,action:a});var e=this.triggerEvent("before"+a,b);if(typeof e!="undefined")if(e===false)return false;else b=e;switch(a){case "login":this.gui_objects.loginform&&this.gui_objects.loginform.submit();break;case "mail":case "addressbook":case "settings":case "logout":this.switch_task(a);break;case "permaurl":if(d&&
-d.href&&d.target)return true;else if(this.env.permaurl)parent.location.href=this.env.permaurl;break;case "menu-open":case "menu-save":this.triggerEvent(a,{props:b});return false;case "open":var f;if(f=this.get_single_uid()){d.href="?_task="+this.env.task+"&_action=show&_mbox="+urlencode(this.env.mailbox)+"&_uid="+f;return true}break;case "list":if(this.task=="mail"){if(!this.env.search_request||b&&b!=this.env.mailbox)this.reset_qsearch();this.list_mailbox(b);if(this.env.trash_mailbox)this.set_alttext("delete",
-this.env.mailbox!=this.env.trash_mailbox?"movemessagetotrash":"deletemessage")}else if(this.task=="addressbook"){if(!this.env.search_request||b!=this.env.source)this.reset_qsearch();this.list_contacts(b);this.enable_command("add","import",this.env.address_sources&&!this.env.address_sources[this.env.source].readonly)}break;case "load-headers":this.load_headers(d);break;case "sort":var g=b;f=this.env.sort_col==g?this.env.sort_order=="ASC"?"DESC":"ASC":"ASC";this.set_list_sorting(g,f);this.list_mailbox("",
-"",g+"_"+f);break;case "nextpage":this.list_page("next");break;case "lastpage":this.list_page("last");break;case "previouspage":this.list_page("prev");break;case "firstpage":this.list_page("first");break;case "expunge":this.env.messagecount&&this.expunge_mailbox(this.env.mailbox);break;case "purge":case "empty-mailbox":this.env.messagecount&&this.purge_mailbox(this.env.mailbox);break;case "show":if(this.task=="mail"){if((f=this.get_single_uid())&&(!this.env.uid||f!=this.env.uid))this.env.mailbox==
-this.env.drafts_mailbox?this.goto_url("compose","_draft_uid="+f+"&_mbox="+urlencode(this.env.mailbox),true):this.show_message(f)}else if(this.task=="addressbook")(g=b?b:this.get_single_cid())&&!(this.env.action=="show"&&g==this.env.cid)&&this.load_contact(g,"show");break;case "add":if(this.task=="addressbook")this.load_contact(0,"add");else if(this.task=="settings"){this.identity_list.clear_selection();this.load_identity(0,"add-identity")}break;case "edit":if(this.task=="addressbook"&&(g=this.get_single_cid()))this.load_contact(g,
-"edit");else if(this.task=="settings"&&b)this.load_identity(b,"edit-identity");else if(this.task=="mail"&&(g=this.get_single_uid())){e=this.env.mailbox==this.env.drafts_mailbox?"_draft_uid=":"_uid=";this.goto_url("compose",e+g+"&_mbox="+urlencode(this.env.mailbox),true)}break;case "save":if(this.gui_objects.editform){f=$("input[name='_pagesize']");g=$("input[name='_name']");e=$("input[name='_email']");if(f.length&&isNaN(parseInt(f.val()))){alert(this.get_label("nopagesizewarning"));f.focus();break}else if(g.length&&
-g.val()==""){alert(this.get_label("nonamewarning"));g.focus();break}else if(e.length&&!rcube_check_email(e.val())){alert(this.get_label("noemailwarning"));e.focus();break}this.gui_objects.editform.submit()}break;case "delete":if(this.task=="mail")this.delete_messages();else if(this.task=="addressbook")this.delete_contacts();else this.task=="settings"&&this.delete_identity();break;case "move":case "moveto":if(this.task=="mail")this.move_messages(b);else this.task=="addressbook"&&this.drag_active&&
-this.copy_contact(null,b);break;case "copy":this.task=="mail"&&this.copy_messages(b);break;case "mark":b&&this.mark_message(b);break;case "toggle_status":if(b&&!b._row)break;g="read";if(b._row.uid){f=b._row.uid;if(this.message_list.rows[f].deleted)g="undelete";else this.message_list.rows[f].unread||(g="unread")}this.mark_message(g,f);break;case "toggle_flag":if(b&&!b._row)break;g="flagged";if(b._row.uid){f=b._row.uid;if(this.message_list.rows[f].flagged)g="unflagged"}this.mark_message(g,f);break;
-case "always-load":if(this.env.uid&&this.env.sender){this.add_contact(urlencode(this.env.sender));window.setTimeout(function(){l.command("load-images")},300);break}case "load-images":this.env.uid&&this.show_message(this.env.uid,true,this.env.action=="preview");break;case "load-attachment":f="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+b.part;if(this.env.uid&&b.mimetype&&$.inArray(b.mimetype,this.mimetypes)>=0){if(b.mimetype=="text/html")f+="&_safe=1";if(this.attachment_win=
-window.open(this.env.comm_path+"&_action=get&"+f+"&_frame=1","rcubemailattachment")){window.setTimeout(function(){l.attachment_win.focus()},10);break}}this.goto_url("get",f+"&_download=1",false);break;case "select-all":this.select_all_mode=b?false:true;this.dummy_select=true;b=="invert"?this.message_list.invert_selection():this.message_list.select_all(b=="page"?"":b);this.dummy_select=null;break;case "select-none":this.select_all_mode=false;this.message_list.clear_selection();break;case "expand-all":this.env.autoexpand_threads=
-1;this.message_list.expand_all();break;case "expand-unread":this.env.autoexpand_threads=2;this.message_list.collapse_all();this.expand_unread();break;case "collapse-all":this.env.autoexpand_threads=0;this.message_list.collapse_all();break;case "nextmessage":this.env.next_uid&&this.show_message(this.env.next_uid,false,this.env.action=="preview");break;case "lastmessage":this.env.last_uid&&this.show_message(this.env.last_uid);break;case "previousmessage":this.env.prev_uid&&this.show_message(this.env.prev_uid,
-false,this.env.action=="preview");break;case "firstmessage":this.env.first_uid&&this.show_message(this.env.first_uid);break;case "checkmail":this.check_for_recent(true);break;case "compose":e=this.env.comm_path+"&_action=compose";if(this.task=="mail"){e+="&_mbox="+urlencode(this.env.mailbox);if(this.env.mailbox==this.env.drafts_mailbox){if(f=this.get_single_uid())e+="&_draft_uid="+f}else if(b)e+="&_to="+urlencode(b)}else if(this.task=="addressbook"){if(b&&b.indexOf("@")>0){e=this.get_task_url("mail",
-e);this.redirect(e+"&_to="+urlencode(b));break}f=[];if(b)f.push(b);else if(this.contact_list){g=this.contact_list.get_selection();for(e=0;e<g.length;e++)f.push(g[e])}f.length&&this.http_request("mailto","_cid="+urlencode(f.join(","))+"&_source="+urlencode(this.env.source),true);break}e=e.replace(/&_framed=1/,"");this.redirect(e);break;case "spellcheck":if(window.tinyMCE&&tinyMCE.get(this.env.composebody))tinyMCE.execCommand("mceSpellCheck",true);else if(this.env.spellcheck&&this.env.spellcheck.spellCheck&&
-this.spellcheck_ready){this.env.spellcheck.spellCheck();this.set_spellcheck_state("checking")}break;case "savedraft":self.clearTimeout(this.save_timer);if(!this.gui_objects.messageform)break;if(!this.env.drafts_mailbox||this.cmp_hash==this.compose_field_hash())break;f=this.gui_objects.messageform;g=this.set_busy(true,"savingmessage");f.target="savetarget";f._draft.value="1";f.action=this.add_url(f.action,"_unlock",g);f.submit();break;case "send":if(!this.gui_objects.messageform)break;if(!this.check_compose_input())break;
-self.clearTimeout(this.save_timer);f=this.gui_objects.messageform;g=this.set_busy(true,"sendingmessage");f.target="savetarget";f._draft.value="";f.action=this.add_url(f.action,"_unlock",g);f.submit();clearTimeout(this.request_timer);break;case "send-attachment":self.clearTimeout(this.save_timer);this.upload_file(b);break;case "insert-sig":this.change_identity($("[name='_from']")[0],true);break;case "reply-all":case "reply-list":case "reply":if(f=this.get_single_uid()){e="_reply_uid="+f+"&_mbox="+
-urlencode(this.env.mailbox);if(a=="reply-all")e+="&_all="+(!b&&this.commands["reply-list"]?"list":"all");else if(a=="reply-list")e+="&_all=list";this.goto_url("compose",e,true)}break;case "forward":if(f=this.get_single_uid())this.goto_url("compose","_forward_uid="+f+"&_mbox="+urlencode(this.env.mailbox),true);break;case "print":if(f=this.get_single_uid()){l.printwin=window.open(this.env.comm_path+"&_action=print&_uid="+f+"&_mbox="+urlencode(this.env.mailbox)+(this.env.safemode?"&_safe=1":""));if(this.printwin){window.setTimeout(function(){l.printwin.focus()},
-20);this.env.action!="show"&&this.mark_message("read",f)}}break;case "viewsource":if(f=this.get_single_uid()){l.sourcewin=window.open(this.env.comm_path+"&_action=viewsource&_uid="+f+"&_mbox="+urlencode(this.env.mailbox));this.sourcewin&&window.setTimeout(function(){l.sourcewin.focus()},20)}break;case "download":if(f=this.get_single_uid())this.goto_url("viewsource","&_uid="+f+"&_mbox="+urlencode(this.env.mailbox)+"&_save=1");break;case "search":if(!b&&this.gui_objects.qsearchbox)b=this.gui_objects.qsearchbox.value;
-if(b){this.qsearch(b);break}case "reset-search":f=this.env.search_request;this.reset_qsearch();if(f&&this.env.mailbox)this.list_mailbox(this.env.mailbox);else f&&this.task=="addressbook"&&this.list_contacts(this.env.source,this.env.group);break;case "listgroup":this.list_contacts(b.source,b.id);break;case "import":if(this.env.action=="import"&&this.gui_objects.importform){if((f=document.getElementById("rcmimportfile"))&&!f.value){alert(this.get_label("selectimportfile"));break}this.gui_objects.importform.submit();
-this.set_busy(true,"importwait");this.lock_form(this.gui_objects.importform,true)}else this.goto_url("import",this.env.source?"_target="+urlencode(this.env.source)+"&":"");break;case "export":if(this.contact_list.rowcount>0){f=this.env.source?"_source="+urlencode(this.env.source)+"&":"";if(this.env.search_request)f+="_search="+this.env.search_request;this.goto_url("export",f)}break;case "preferences":case "identities":case "folders":this.goto_url("settings/"+a);break;default:f=a.replace(/-/g,"_");
-if(this[f]&&typeof this[f]=="function")this[f](b)}this.triggerEvent("after"+a,b);this.triggerEvent("actionafter",{props:b,action:a});return d?false:true};this.enable_command=function(){for(var a=Array.prototype.slice.call(arguments),b=a.pop(),d,e=0;e<a.length;e++){d=a[e];if(typeof d==="string"){this.commands[d]=b;this.set_button(d,b?"act":"pas")}else for(var f in d)a.push(d[f])}};this.set_busy=function(a,b,d){if(a&&b){d=this.get_label(b);if(d==b)d="Loading...";d=this.display_message(d,"loading")}else!a&&
-d&&this.hide_message(d);this.busy=a;this.gui_objects.editform&&this.lock_form(this.gui_objects.editform,a);this.request_timer&&clearTimeout(this.request_timer);if(a&&this.env.request_timeout)this.request_timer=window.setTimeout(function(){l.request_timed_out()},this.env.request_timeout*1E3);return d};this.gettext=this.get_label=function(a,b){return b&&this.labels[b+"."+a]?this.labels[b+"."+a]:this.labels[a]?this.labels[a]:a};this.switch_task=function(a){if(!(this.task===a&&a!="mail")){var b=this.get_task_url(a);
-if(a=="mail")b+="&_mbox=INBOX";this.redirect(b)}};this.get_task_url=function(a,b){if(!b)b=this.env.comm_path;return b.replace(/_task=[a-z]+/,"_task="+a)};this.request_timed_out=function(){this.set_busy(false);this.display_message("Request timed out!","error")};this.reload=function(a){if(this.is_framed())parent.rcmail.reload(a);else if(a)window.setTimeout(function(){rcmail.reload()},a);else if(window.location)location.href=this.env.comm_path+(this.env.action?"&_action="+this.env.action:"")};this.add_url=
-function(a,b,d){d=urlencode(d);if(/(\?.*)$/.test(a)){var e=RegExp.$1,f=RegExp("((\\?|&)"+RegExp.escape(b)+"=[^&]*)");if(f.test(e))e=e.replace(f,RegExp.$2+b+"="+d);else e+="&"+b+"="+d;return a.replace(/(\?.*)$/,e)}else return a+"?"+b+"="+d};this.is_framed=function(){return this.env.framed&&parent.rcmail};this.drag_menu=function(a,b){var d=rcube_event.get_modifier(a),e=$("#"+this.gui_objects.message_dragmenu);if(e&&d==SHIFT_KEY&&this.commands.copy){d=rcube_event.get_mouse_pos(a);this.env.drag_target=
-b;e.css({top:d.y-10+"px",left:d.x-10+"px"}).show();return true}return false};this.drag_menu_action=function(a){var b=$("#"+this.gui_objects.message_dragmenu);b&&b.hide();this.command(a,this.env.drag_target);this.env.drag_target=null};this.drag_start=function(a){var b=this.task=="mail"?this.env.mailboxes:this.env.contactfolders;this.drag_active=true;this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);if(this.gui_objects.folderlist&&b){this.initialBodyScrollTop=
-bw.ie?0:window.pageYOffset;this.initialListScrollTop=this.gui_objects.folderlist.parentNode.scrollTop;var d,e;a=$(this.gui_objects.folderlist);d=a.offset();this.env.folderlist_coords={x1:d.left,y1:d.top,x2:d.left+a.width(),y2:d.top+a.height()};this.env.folder_coords=[];for(var f in b)if(a=this.get_folder_li(f))if(e=a.firstChild.offsetHeight){d=$(a.firstChild).offset();this.env.folder_coords[f]={x1:d.left,y1:d.top,x2:d.left+a.firstChild.offsetWidth,y2:d.top+e,on:0}}}};this.drag_end=function(){this.drag_active=
-false;this.env.last_folder_target=null;if(this.folder_auto_timer){window.clearTimeout(this.folder_auto_timer);this.folder_auto_expand=this.folder_auto_timer=null}if(this.gui_objects.folderlist&&this.env.folder_coords)for(var a in this.env.folder_coords)this.env.folder_coords[a].on&&$(this.get_folder_li(a)).removeClass("droptarget")};this.drag_move=function(a){if(this.gui_objects.folderlist&&this.env.folder_coords){var b=-(this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop)-
-(bw.ie?-document.documentElement.scrollTop:this.initialBodyScrollTop),d,e,f;d="draglayernormal";if(this.contact_list&&this.contact_list.draglayer)f=this.contact_list.draglayer.attr("class");a=rcube_event.get_mouse_pos(a);e=this.env.folderlist_coords;a.y+=b;if(a.x<e.x1||a.x>=e.x2||a.y<e.y1||a.y>=e.y2){if(this.env.last_folder_target){$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget");this.env.folder_coords[this.env.last_folder_target].on=0;this.env.last_folder_target=null}}else for(var g in this.env.folder_coords){e=
-this.env.folder_coords[g];if(a.x>=e.x1&&a.x<e.x2&&a.y>=e.y1&&a.y<e.y2)if(b=this.check_droptarget(g)){d=this.get_folder_li(g);e=$(d.getElementsByTagName("div")[0]);if(e.hasClass("collapsed")){this.folder_auto_timer&&window.clearTimeout(this.folder_auto_timer);this.folder_auto_expand=g;this.folder_auto_timer=window.setTimeout(function(){rcmail.command("collapse-folder",rcmail.folder_auto_expand);rcmail.drag_start(null)},1E3)}else if(this.folder_auto_timer){window.clearTimeout(this.folder_auto_timer);
-this.folder_auto_expand=this.folder_auto_timer=null}$(d).addClass("droptarget");this.env.folder_coords[g].on=1;this.env.last_folder_target=g;d="draglayer"+(b>1?"copy":"normal")}else this.env.last_folder_target=null;else if(e.on){$(this.get_folder_li(g)).removeClass("droptarget");this.env.folder_coords[g].on=0}}d!=f&&this.contact_list&&this.contact_list.draglayer&&this.contact_list.draglayer.attr("class",d)}};this.collapse_folder=function(a){var b=this.get_folder_li(a),d=$(b.getElementsByTagName("div")[0]);
-if(!(!d||!d.hasClass("collapsed")&&!d.hasClass("expanded"))){var e=$(b.getElementsByTagName("ul")[0]);if(d.hasClass("collapsed")){e.show();d.removeClass("collapsed").addClass("expanded");this.set_env("collapsed_folders",this.env.collapsed_folders.replace(RegExp("&"+urlencode(a)+"&"),""))}else{e.hide();d.removeClass("expanded").addClass("collapsed");this.set_env("collapsed_folders",this.env.collapsed_folders+"&"+urlencode(a)+"&");this.env.mailbox.indexOf(a+this.env.delimiter)==0&&this.command("list",
-a)}if(bw.ie6||bw.ie7)if((d=b.nextSibling?b.nextSibling.getElementsByTagName("ul"):null)&&d.length&&(b=d[0])&&b.style&&b.style.display!="none"){b.style.display="none";b.style.display=""}this.http_post("save-pref","_name=collapsed_folders&_value="+urlencode(this.env.collapsed_folders));this.set_unread_count_display(a,false)}};this.doc_mouse_up=function(a){var b,d;if(this.message_list){rcube_mouse_is_over(a,this.message_list.list.parentNode)?this.message_list.focus():this.message_list.blur();d=this.message_list;
-b=this.env.mailboxes}else if(this.contact_list){rcube_mouse_is_over(a,this.contact_list.list.parentNode)?this.contact_list.focus():this.contact_list.blur();d=this.contact_list;b=this.env.contactfolders}else this.ksearch_value&&this.ksearch_blur();if(this.drag_active&&b&&this.env.last_folder_target){b=b[this.env.last_folder_target];$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget");this.env.last_folder_target=null;d.draglayer.hide();this.drag_menu(a,b)||this.command("moveto",
-b)}if(this.buttons_sel){for(var e in this.buttons_sel)typeof e!="function"&&this.button_out(this.buttons_sel[e],e);this.buttons_sel={}}};this.click_on_list=function(){this.gui_objects.qsearchbox&&this.gui_objects.qsearchbox.blur();if(this.message_list)this.message_list.focus();else this.contact_list&&this.contact_list.focus();return true};this.msglist_select=function(a){this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);var b=a.get_single_selection()!=
-null;this.enable_command(this.env.message_commands,b);if(b)if(this.env.mailbox==this.env.drafts_mailbox)this.enable_command("reply","reply-all","reply-list","forward",false);else this.env.messages[a.get_single_selection()].ml||this.enable_command("reply-list",false);this.enable_command("delete","moveto","copy","mark",a.selection.length>0?true:false);if(b||a.selection.length&&a.selection.length!=a.rowcount)this.select_all_mode=false;if(b&&this.env.contentframe&&!a.multi_selecting&&!this.dummy_select)this.preview_timer=
-window.setTimeout(function(){l.msglist_get_preview()},200);else this.env.contentframe&&this.show_contentframe(false)};this.msglist_click=function(a){if(!(a.multi_selecting||!this.env.contentframe))if(a.get_single_selection()&&window.frames&&window.frames[this.env.contentframe])if(window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)>=0){this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);this.preview_timer=window.setTimeout(function(){l.msglist_get_preview()},
-200)}};this.msglist_dbl_click=function(a){this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);if((a=a.get_single_selection())&&this.env.mailbox==this.env.drafts_mailbox)this.goto_url("compose","_draft_uid="+a+"&_mbox="+urlencode(this.env.mailbox),true);else a&&this.show_message(a,false,false)};this.msglist_keypress=function(a){if(a.key_pressed==a.ENTER_KEY)this.command("show");else if(a.key_pressed==a.DELETE_KEY)this.command("delete");
-else if(a.key_pressed==a.BACKSPACE_KEY)this.command("delete");else if(a.key_pressed==33)this.command("previouspage");else if(a.key_pressed==34)this.command("nextpage");else a.shiftkey=false};this.msglist_get_preview=function(){var a=this.get_single_uid();if(a&&this.env.contentframe&&!this.drag_active)this.show_message(a,false,true);else this.env.contentframe&&this.show_contentframe(false)};this.msglist_expand=function(a){if(this.env.messages[a.uid])this.env.messages[a.uid].expanded=a.expanded};this.msglist_set_coltypes=
-function(a){var b,d=a.list.tHead.rows[0].cells;this.env.coltypes=[];for(a=0;a<d.length;a++)if(d[a].id&&d[a].id.match(/^rcm/)){b=d[a].id.replace(/^rcm/,"");this.env.coltypes.push(b=="to"?"from":b)}if((a=$.inArray("flag",this.env.coltypes))>=0)this.set_env("flagged_col",a);if((a=$.inArray("subject",this.env.coltypes))>=0)this.set_env("subject_col",a);this.http_post("save-pref",{_name:"list_cols",_value:this.env.coltypes,_session:"list_attrib/columns"})};this.check_droptarget=function(a){var b=false,
-d=false;if(this.task=="mail")b=this.env.mailboxes[a]&&this.env.mailboxes[a].id!=this.env.mailbox&&!this.env.mailboxes[a].virtual;else if(this.task=="settings")b=a!=this.env.mailbox;else if(this.task=="addressbook")if(a!=this.env.source&&this.env.contactfolders[a])if(this.env.contactfolders[a].type=="group"){d=this.env.contactfolders[a].source;b=this.env.contactfolders[a].id!=this.env.group&&!this.env.contactfolders[d].readonly;d=d!=this.env.source}else{b=!this.env.contactfolders[a].readonly;d=true}return b?
-d?2:1:0};this.init_message_row=function(a){var b,d=this,e=a.uid,f=(this.env.status_col!=null?"status":"msg")+"icn"+a.uid;e&&this.env.messages[e]&&$.extend(a,this.env.messages[e]);if(a.icon=document.getElementById(f)){a.icon._row=a.obj;a.icon.onmousedown=function(g){d.command("toggle_status",this);rcube_event.cancel(g)}}a.msgicon=this.env.status_col!=null?document.getElementById("msgicn"+a.uid):a.icon;if(this.env.flagged_col!=null&&(a.flagicon=document.getElementById("flagicn"+a.uid))){a.flagicon._row=
-a.obj;a.flagicon.onmousedown=function(g){d.command("toggle_flag",this);rcube_event.cancel(g)}}if(!a.depth&&a.has_children&&(b=document.getElementById("rcmexpando"+a.uid))){a.expando=b;b.onmousedown=function(g){return d.expand_message_row(g,e)}}this.triggerEvent("insertrow",{uid:e,row:a})};this.add_message_row=function(a,b,d,e){if(!this.gui_objects.messagelist||!this.message_list)return false;this.env.messages[a]||(this.env.messages[a]={});$.extend(this.env.messages[a],{deleted:d.deleted?1:0,replied:d.replied?
-1:0,unread:d.unread?1:0,forwarded:d.forwarded?1:0,flagged:d.flagged?1:0,has_children:d.has_children?1:0,depth:d.depth?d.depth:0,unread_children:d.unread_children?d.unread_children:0,parent_uid:d.parent_uid?d.parent_uid:0,selected:this.select_all_mode||this.message_list.in_selection(a),ml:d.ml?1:0,ctype:d.ctype,flags:d.extra_flags});var f,g=expando="",h=this.message_list,k=h.rows;f=this.env.messages[a];var j="message"+(this.gui_objects.messagelist.tBodies[0].rows.length%2?" even":" odd")+(d.unread?
-" unread":"")+(d.deleted?" deleted":"")+(d.flagged?" flagged":"")+(d.unread_children&&!d.unread&&!this.env.autoexpand_threads?" unroot":"")+(f.selected?" selected":""),m=document.createElement("tr"),n=document.createElement("td");m.id="rcmrow"+a;m.className=j;j="msgicon";if(this.env.status_col===null){j+=" status";if(d.deleted)j+=" deleted";else if(d.unread)j+=" unread";else if(d.unread_children>0)j+=" unreadchildren"}if(d.replied)j+=" replied";if(d.forwarded)j+=" forwarded";f.selected&&!h.in_selection(a)&&
-h.selection.push(a);if(this.env.threading){n=f.depth*15;if(f.depth)if(k[f.parent_uid]&&k[f.parent_uid].expanded===false||(this.env.autoexpand_threads==0||this.env.autoexpand_threads==2)&&(!k[f.parent_uid]||!k[f.parent_uid].expanded)){m.style.display="none";f.expanded=false}else f.expanded=true;else if(f.has_children)if(typeof f.expanded=="undefined"&&(this.env.autoexpand_threads==1||this.env.autoexpand_threads==2&&f.unread_children))f.expanded=true;if(n)g+='<span id="rcmtab'+a+'" class="branch" style="width:'+
-n+'px;">&nbsp;&nbsp;</span>';if(f.has_children&&!f.depth)expando='<div id="rcmexpando'+a+'" class="'+(f.expanded?"expanded":"collapsed")+'">&nbsp;&nbsp;</div>'}g+='<span id="msgicn'+a+'" class="'+j+'">&nbsp;</span>';if(!bw.ie&&b.subject){n=d.mbox==this.env.drafts_mailbox?"_draft_uid":"_uid";b.subject='<a href="./?_task=mail&_action='+(d.mbox==this.env.drafts_mailbox?"compose":"show")+"&_mbox="+urlencode(d.mbox)+"&"+n+"="+a+'" onclick="return rcube_event.cancel(event)" onmouseover="rcube_webmail.long_subject_title(this,'+
-(f.depth+1)+')">'+b.subject+"</a>"}for(var o in this.env.coltypes){f=this.env.coltypes[o];n=document.createElement("td");n.className=String(f).toLowerCase();if(f=="flag"){j=d.flagged?"flagged":"unflagged";f='<span id="flagicn'+a+'" class="'+j+'">&nbsp;</span>'}else if(f=="attachment")f=/application\/|multipart\/m/.test(d.ctype)?'<span class="attachment">&nbsp;</span>':/multipart\/report/.test(d.ctype)?'<span class="report">&nbsp;</span>':"&nbsp;";else if(f=="status"){j=d.deleted?"deleted":d.unread?
-"unread":d.unread_children>0?"unreadchildren":"msgicon";f='<span id="statusicn'+a+'" class="'+j+'">&nbsp;</span>'}else f=f=="threads"?expando:f=="subject"?g+b[f]:b[f];n.innerHTML=f;m.appendChild(n)}h.insert_row(m,e);if(e&&this.env.pagesize&&h.rowcount>this.env.pagesize){a=h.get_last_row();h.remove_row(a);h.clear_selection(a)}};this.set_list_sorting=function(a,b){$("#rcm"+this.env.sort_col).removeClass("sorted"+this.env.sort_order.toUpperCase());a&&$("#rcm"+a).addClass("sorted"+b);this.env.sort_col=
-a;this.env.sort_order=b};this.set_list_options=function(a,b,d,e){var f,g="";if(typeof b=="undefined")b=this.env.sort_col;if(!d)d=this.env.sort_order;if(this.env.sort_col!=b||this.env.sort_order!=d){f=1;this.set_list_sorting(b,d)}if(this.env.threading!=e){f=1;g+="&_threads="+e}if(a&&a.length){var h,k,j=[],m=this.env.coltypes;for(e=0;e<m.length;e++){k=m[e]=="to"?"from":m[e];h=$.inArray(k,a);if(h!=-1){j.push(k);delete a[h]}}for(e=0;e<a.length;e++)a[e]&&j.push(a[e]);if(j.join()!=m.join()){f=1;g+="&_cols="+
-j.join(",")}}f&&this.list_mailbox("","",b+"_"+d,g)};this.show_message=function(a,b,d){if(a){var e=window,f=d?"preview":"show",g="&_action="+f+"&_uid="+a+"&_mbox="+urlencode(this.env.mailbox);if(d&&this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){e=window.frames[this.env.contentframe];g+="&_framed=1"}if(b)g+="&_safe=1";if(this.env.search_request)g+="&_search="+this.env.search_request;if(f=="preview"&&String(e.location.href).indexOf(g)>=0)this.show_contentframe(true);else{if(!this.env.frame_lock)(this.is_framed()?
-parent.rcmail:this).env.frame_lock=this.set_busy(true,"loading");e.location.href=this.env.comm_path+g;if(f=="preview"&&this.message_list&&this.message_list.rows[a]&&this.message_list.rows[a].unread&&this.env.preview_pane_mark_read>=0)this.preview_read_timer=window.setTimeout(function(){l.set_message(a,"unread",false);l.update_thread_root(a,"read");if(l.env.unread_counts[l.env.mailbox]){l.env.unread_counts[l.env.mailbox]-=1;l.set_unread_count(l.env.mailbox,l.env.unread_counts[l.env.mailbox],l.env.mailbox==
-"INBOX")}l.env.preview_pane_mark_read>0&&l.http_post("mark","_uid="+a+"&_flag=read&_quiet=1")},this.env.preview_pane_mark_read*1E3)}}};this.show_contentframe=function(a){var b,d;if(this.env.contentframe&&(b=$("#"+this.env.contentframe))&&b.length)if(!a&&(d=window.frames[this.env.contentframe])){if(d.location&&d.location.href.indexOf(this.env.blankpage)<0)d.location.href=this.env.blankpage}else if(!bw.safari&&!bw.konq)b[a?"show":"hide"]();!a&&this.busy&&this.set_busy(false,null,this.env.frame_lock)};
-this.list_page=function(a){if(a=="next")a=this.env.current_page+1;else if(a=="last")a=this.env.pagecount;else if(a=="prev"&&this.env.current_page>1)a=this.env.current_page-1;else if(a=="first"&&this.env.current_page>1)a=1;if(a>0&&a<=this.env.pagecount){this.env.current_page=a;if(this.task=="mail")this.list_mailbox(this.env.mailbox,a);else this.task=="addressbook"&&this.list_contacts(this.env.source,this.env.group,a)}};this.filter_mailbox=function(a){var b,d=this.set_busy(true,"searching");if(this.gui_objects.qsearchbox)b=
-this.gui_objects.qsearchbox.value;this.clear_message_list();this.env.current_page=1;this.http_request("search","_filter="+a+(b?"&_q="+urlencode(b):"")+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):""),d)};this.list_mailbox=function(a,b,d,e){var f="",g=window;a||(a=this.env.mailbox?this.env.mailbox:"INBOX");if(e)f+=e;if(d)f+="&_sort="+d;if(this.env.search_request)f+="&_search="+this.env.search_request;if(this.env.mailbox!=a){b=1;this.env.current_page=b;this.select_all_mode=false}this.clear_message_list();
-if(a!=this.env.mailbox||a==this.env.mailbox&&!b&&!d)f+="&_refresh=1";this.select_folder(a,this.env.mailbox);this.env.mailbox=a;if(this.gui_objects.messagelist)this.list_mailbox_remote(a,b,f);else{if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){g=window.frames[this.env.contentframe];f+="&_framed=1"}if(a){this.set_busy(true,"loading");g.location.href=this.env.comm_path+"&_mbox="+urlencode(a)+(b?"&_page="+b:"")+f}}};this.clear_message_list=function(){this.env.messages=
-{};this.last_selected=0;this.show_contentframe(false);this.message_list&&this.message_list.clear(true)};this.list_mailbox_remote=function(a,b,d){this.message_list.clear();a="_mbox="+urlencode(a)+(b?"&_page="+b:"");b=this.set_busy(true,"loading");this.http_request("list",a+d,b)};this.update_selection=function(){var a=this.message_list.selection,b=this.message_list.rows,d,e=[];for(d in a)b[a[d]]&&e.push(a[d]);this.message_list.selection=e};this.expand_unread=function(){for(var a,b=this.gui_objects.messagelist.tBodies[0].firstChild;b;){if(b.nodeType==
-1&&(a=this.message_list.rows[b.uid])&&a.unread_children){this.message_list.expand_all(a);this.set_unread_children(a.uid)}b=b.nextSibling}return false};this.expand_message_row=function(a,b){var d=this.message_list.rows[b];d.expanded=!d.expanded;this.set_unread_children(b);d.expanded=!d.expanded;this.message_list.expand_row(a,b)};this.expand_threads=function(){if(!(!this.env.threading||!this.env.autoexpand_threads||!this.message_list))switch(this.env.autoexpand_threads){case 2:this.expand_unread();
-break;case 1:this.message_list.expand_all()}};this.init_threads=function(a){for(var b=0,d=a.length;b<d;b++)this.add_tree_icons(a[b]);this.expand_threads()};this.add_tree_icons=function(a){var b,d,e,f,g=[],h=[],k,j=this.message_list.rows;for(k=a?j[a]?j[a].obj:null:this.message_list.list.tBodies[0].firstChild;k;){if(k.nodeType==1&&(d=j[k.uid]))if(d.depth){for(b=g.length-1;b>=0;b--){e=g[b].length;if(e>d.depth){f=e-d.depth;g[b][f]&2||(g[b][f]=g[b][f]?g[b][f]+2:2)}else if(e==d.depth)g[b][0]&2||(g[b][0]+=
-2);if(d.depth>e)break}g.push(Array(d.depth));g[g.length-1][0]=1;h.push(d.uid)}else{if(g.length){for(b in g)this.set_tree_icons(h[b],g[b]);g=[];h=[]}if(a&&k!=j[a].obj)break}k=k.nextSibling}if(g.length)for(b in g)this.set_tree_icons(h[b],g[b])};this.set_tree_icons=function(a,b){var d,e=[],f="",g=b.length;for(d=0;d<g;d++)if(b[d]>2)e.push({"class":"l3",width:15});else if(b[d]>1)e.push({"class":"l2",width:15});else if(b[d]>0)e.push({"class":"l1",width:15});else if(e.length&&!e[e.length-1]["class"])e[e.length-
-1].width+=15;else e.push({"class":null,width:15});for(d=e.length-1;d>=0;d--)f+=e[d]["class"]?'<div class="tree '+e[d]["class"]+'" />':'<div style="width:'+e[d].width+'px" />';f&&$("#rcmtab"+a).html(f)};this.update_thread_root=function(a,b){if(this.env.threading){var d=this.message_list.find_root(a);if(a!=d){var e=this.message_list.rows[d];if(b=="read"&&e.unread_children)e.unread_children--;else if(b=="unread"&&e.has_children)e.unread_children=e.unread_children?e.unread_children+1:1;else return;this.set_message_icon(d);
-this.set_unread_children(d)}}};this.update_thread=function(a){if(!this.env.threading)return 0;var b,d=0,e=this.message_list.rows,f=e[a],g=e[a].depth,h=[];if(f.depth){if(f.unread){a=this.message_list.find_root(a);e[a].unread_children--;this.set_unread_children(a)}}else d--;a=f.parent_uid;for(f=f.obj.nextSibling;f;){if(f.nodeType==1&&(b=e[f.uid])){if(!b.depth||b.depth<=g)break;b.depth--;$("#rcmtab"+b.uid).width(b.depth*15).html("");if(b.depth){if(b.depth==g)b.parent_uid=a;b.unread&&h.length&&h[h.length-
-1].unread_children++}else{d++;b.parent_uid=0;if(b.has_children){$("#rcmrow"+b.uid+" .leaf:first").attr("id","rcmexpando"+b.uid).attr("class",b.obj.style.display!="none"?"expanded":"collapsed").bind("mousedown",{uid:b.uid,p:this},function(k){return k.data.p.expand_message_row(k,k.data.uid)});b.unread_children=0;h.push(b)}b.obj.style.display=="none"&&$(b.obj).show()}}f=f.nextSibling}for(b=0;b<h.length;b++)this.set_unread_children(h[b].uid);return d};this.delete_excessive_thread_rows=function(){for(var a=
-this.message_list.rows,b=this.message_list.list.tBodies[0].firstChild,d=this.env.pagesize+1;b;){if(b.nodeType==1&&(r=a[b.uid])){!r.depth&&d&&d--;d||this.message_list.remove_row(b.uid)}b=b.nextSibling}};this.set_message_icon=function(a){var b=this.message_list.rows[a];if(!b)return false;if(b.icon){a="msgicon";if(b.deleted)a+=" deleted";else if(b.unread)a+=" unread";else if(b.unread_children)a+=" unreadchildren";if(b.msgicon==b.icon){if(b.replied)a+=" replied";if(b.forwarded)a+=" forwarded";a+=" status"}b.icon.className=
-a}if(b.msgicon&&b.msgicon!=b.icon){a="msgicon";if(!b.unread&&b.unread_children)a+=" unreadchildren";if(b.replied)a+=" replied";if(b.forwarded)a+=" forwarded";b.msgicon.className=a}if(b.flagicon){a=b.flagged?"flagged":"unflagged";b.flagicon.className=a}};this.set_message_status=function(a,b,d){a=this.message_list.rows[a];if(!a)return false;if(b=="unread")a.unread=d;else if(b=="deleted")a.deleted=d;else if(b=="replied")a.replied=d;else if(b=="forwarded")a.forwarded=d;else if(b=="flagged")a.flagged=
-d};this.set_message=function(a,b,d){var e=this.message_list.rows[a];if(!e)return false;b&&this.set_message_status(a,b,d);b=$(e.obj);if(e.unread&&!b.hasClass("unread"))b.addClass("unread");else!e.unread&&b.hasClass("unread")&&b.removeClass("unread");if(e.deleted&&!b.hasClass("deleted"))b.addClass("deleted");else!e.deleted&&b.hasClass("deleted")&&b.removeClass("deleted");if(e.flagged&&!b.hasClass("flagged"))b.addClass("flagged");else!e.flagged&&b.hasClass("flagged")&&b.removeClass("flagged");this.set_unread_children(a);
-this.set_message_icon(a)};this.set_unread_children=function(a){a=this.message_list.rows[a];a.parent_uid||(!a.unread&&a.unread_children&&!a.expanded?$(a.obj).addClass("unroot"):$(a.obj).removeClass("unroot"))};this.copy_messages=function(a){if(a&&typeof a=="object")a=a.id;if(!(!a||a==this.env.mailbox||!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){var b=[],d=this.display_message(this.get_label("copyingmessage"),"loading");a="&_target_mbox="+urlencode(a)+"&_from="+
-(this.env.action?this.env.action:"");if(this.env.uid)b[0]=this.env.uid;else{var e=this.message_list.get_selection(),f;for(f in e)b.push(e[f])}a+="&_uid="+this.uids_to_list(b);this.http_post("copy","_mbox="+urlencode(this.env.mailbox)+a,d)}};this.move_messages=function(a){if(a&&typeof a=="object")a=a.id;if(!(!a||a==this.env.mailbox||!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){var b=false;a="&_target_mbox="+urlencode(a)+"&_from="+(this.env.action?this.env.action:
-"");if(this.env.action=="show")b=this.set_busy(true,"movingmessage");else this.show_contentframe(false);this.enable_command(this.env.message_commands,false);this._with_selected_messages("moveto",b,a)}};this.delete_messages=function(){var a=this.message_list?$.merge([],this.message_list.get_selection()):[];if(this.env.uid||a.length){for(var b,d=0,e=a.length;d<e;d++){b=a[d];this.message_list.rows[b].has_children&&!this.message_list.rows[b].expanded&&this.message_list.select_childs(b)}if(this.env.flag_for_deletion){this.mark_message("delete");
-return false}else if(!this.env.trash_mailbox||this.env.mailbox==this.env.trash_mailbox)this.permanently_remove_messages();else if(this.message_list&&this.message_list.shiftkey)confirm(this.get_label("deletemessagesconfirm"))&&this.permanently_remove_messages();else this.move_messages(this.env.trash_mailbox);return true}};this.permanently_remove_messages=function(){if(!(!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){this.show_contentframe(false);this._with_selected_messages("delete",
-false,"&_from="+(this.env.action?this.env.action:""))}};this._with_selected_messages=function(a,b,d){var e=[],f=0;if(this.env.uid)e[0]=this.env.uid;else{var g,h,k,j=[],m=this.message_list.get_selection();g=0;for(len=m.length;g<len;g++){h=m[g];e.push(h);if(this.env.threading){f+=this.update_thread(h);k=this.message_list.find_root(h);k!=h&&$.inArray(k,j)<0&&j.push(k)}this.message_list.remove_row(h,this.env.display_next&&g==m.length-1)}this.env.display_next||this.message_list.clear_selection();g=0;for(len=
-j.length;g<len;g++)this.add_tree_icons(j[g])}if(this.env.search_request)d+="&_search="+this.env.search_request;if(this.env.display_next&&this.env.next_uid)d+="&_next_uid="+this.env.next_uid;if(f<0)d+="&_count="+f*-1;else f>0&&this.delete_excessive_thread_rows();d+="&_uid="+this.uids_to_list(e);b||(b=this.display_message(this.get_label(a=="moveto"?"movingmessage":"deletingmessage"),"loading"));this.http_post(a,"_mbox="+urlencode(this.env.mailbox)+d,b)};this.mark_message=function(a,b){var d=[],e=[],
-f,g,h;h=this.message_list?this.message_list.get_selection():[];if(b)d[0]=b;else if(this.env.uid)d[0]=this.env.uid;else if(this.message_list){g=0;for(f=h.length;g<f;g++)d.push(h[g])}if(this.message_list){g=0;for(f=d.length;g<f;g++){h=d[g];if(a=="read"&&this.message_list.rows[h].unread||a=="unread"&&!this.message_list.rows[h].unread||a=="delete"&&!this.message_list.rows[h].deleted||a=="undelete"&&this.message_list.rows[h].deleted||a=="flagged"&&!this.message_list.rows[h].flagged||a=="unflagged"&&this.message_list.rows[h].flagged)e.push(h)}}else e=
-d;if(e.length||this.select_all_mode)switch(a){case "read":case "unread":this.toggle_read_status(a,e);break;case "delete":case "undelete":this.toggle_delete_status(e);break;case "flagged":case "unflagged":this.toggle_flagged_status(a,d)}};this.toggle_read_status=function(a,b){for(var d=0;d<b.length;d++)this.set_message(b[d],"unread",a=="unread"?true:false);d="_uid="+this.uids_to_list(b)+"&_flag="+a;var e=this.display_message(this.get_label("markingmessage"),"loading");if(this.env.search_request)d+=
-"&_search="+this.env.search_request;this.http_post("mark",d,e);for(d=0;d<b.length;d++)this.update_thread_root(b[d],a)};this.toggle_flagged_status=function(a,b){for(var d=0;d<b.length;d++)this.set_message(b[d],"flagged",a=="flagged"?true:false);d="_uid="+this.uids_to_list(b)+"&_flag="+a;var e=this.display_message(this.get_label("markingmessage"),"loading");if(this.env.search_request)d+="&_search="+this.env.search_request;this.http_post("mark",d,e)};this.toggle_delete_status=function(a){var b=this.message_list?
-this.message_list.rows:[];if(a.length==1){!b.length||b[a[0]]&&!b[a[0]].deleted?this.flag_as_deleted(a):this.flag_as_undeleted(a);return true}for(var d,e=true,f=0,g=a.length;f<g;f++){d=a[f];if(b[d]&&!b[d].deleted){e=false;break}}e?this.flag_as_undeleted(a):this.flag_as_deleted(a);return true};this.flag_as_undeleted=function(a){for(var b=0,d=a.length;b<d;b++)this.set_message(a[b],"deleted",false);a="_uid="+this.uids_to_list(a)+"&_flag=undelete";b=this.display_message(this.get_label("markingmessage"),
-"loading");if(this.env.search_request)a+="&_search="+this.env.search_request;this.http_post("mark",a,b);return true};this.flag_as_deleted=function(a){var b="",d=[];b=this.message_list?this.message_list.rows:[];for(var e=0,f=0,g=a.length;f<g;f++){uid=a[f];if(b[uid]){if(b[uid].unread)d[d.length]=uid;if(this.env.skip_deleted){e+=this.update_thread(uid);this.message_list.remove_row(uid,this.env.display_next&&f==this.message_list.selection.length-1)}else this.set_message(uid,"deleted",true)}}if(this.env.skip_deleted&&
-this.message_list){this.env.display_next||this.message_list.clear_selection();e<0||e>0&&this.delete_excessive_thread_rows()}b="&_from="+(this.env.action?this.env.action:"");lock=this.display_message(this.get_label("markingmessage"),"loading");if(d.length)b+="&_ruid="+this.uids_to_list(d);if(this.env.skip_deleted)if(this.env.display_next&&this.env.next_uid)b+="&_next_uid="+this.env.next_uid;if(this.env.search_request)b+="&_search="+this.env.search_request;this.http_post("mark","_uid="+this.uids_to_list(a)+
-"&_flag=delete"+b,lock);return true};this.flag_deleted_as_read=function(a){for(var b=this.message_list?this.message_list.rows:[],d=String(a).split(","),e=0;e<d.length;e++){a=d[e];b[a]&&this.set_message(a,"unread",false)}};this.uids_to_list=function(a){return this.select_all_mode?"*":a.join(",")};this.expunge_mailbox=function(a){var b=false,d="_mbox="+urlencode(a);if(a==this.env.mailbox){b=this.set_busy(true,"loading");d+="&_reload=1"}this.http_post("expunge",d,b)};this.purge_mailbox=function(a){var b=
-false,d="_mbox="+urlencode(a);if(!confirm(this.get_label("purgefolderconfirm")))return false;if(a==this.env.mailbox){b=this.set_busy(true,"loading");d+="&_reload=1"}this.http_post("purge",d,b)};this.purge_mailbox_test=function(){return this.env.messagecount&&(this.env.mailbox==this.env.trash_mailbox||this.env.mailbox==this.env.junk_mailbox||this.env.mailbox.match("^"+RegExp.escape(this.env.trash_mailbox)+RegExp.escape(this.env.delimiter))||this.env.mailbox.match("^"+RegExp.escape(this.env.junk_mailbox)+
-RegExp.escape(this.env.delimiter)))};this.login_user_keyup=function(a){var b=rcube_event.get_keycode(a),d=$("#rcmloginpwd");if(b==13&&d.length&&!d.val()){d.focus();return rcube_event.cancel(a)}return true};this.init_messageform=function(){if(!this.gui_objects.messageform)return false;var a=$("[name='_from']"),b=$("[name='_to']"),d=$("input[name='_subject']"),e=$("[name='_message']").get(0),f=$("input[name='_is_html']").val()=="1",g=["cc","bcc","replyto","followupto"];this.init_address_input_events(b);
-for(var h in g)this.init_address_input_events($("[name='_"+g[h]+"']"));if(!f){this.set_caret_pos(e,this.env.top_posting?0:$(e).val().length);a.attr("type")=="select-one"&&$("input[name='_draft_saveid']").val()==""&&this.change_identity(a[0])}if(b.val()=="")b.focus();else if(d.val()=="")d.focus();else e&&e.focus();this.env.compose_focus_elem=document.activeElement;this.compose_field_hash(true);this.auto_save_start()};this.init_address_input_events=function(a){a[bw.ie||bw.safari||bw.chrome?"keydown":
-"keypress"](function(b){return l.ksearch_keydown(b,this)}).attr("autocomplete","off")};this.check_compose_input=function(){var a,b=$("[name='_to']"),d=$("[name='_cc']"),e=$("[name='_bcc']"),f=$("[name='_from']"),g=$("[name='_subject']"),h=$("[name='_message']");if(f.attr("type")=="text"&&!rcube_check_email(f.val(),true)){alert(this.get_label("nosenderwarning"));f.focus();return false}d=b.val()?b.val():d.val()?d.val():e.val();if(!rcube_check_email(d.replace(/^\s+/,"").replace(/[\s,;]+$/,""),true)){alert(this.get_label("norecipientwarning"));
-b.focus();return false}for(var k in this.env.attachments)if(typeof this.env.attachments[k]=="object"&&!this.env.attachments[k].complete){alert(this.get_label("notuploadedwarning"));return false}if(g.val()==""){b=prompt(this.get_label("nosubjectwarning"),this.get_label("nosubject"));if(!b&&b!==""){g.focus();return false}else g.val(b?b:this.get_label("nosubject"))}this.stop_spellchecking();if(window.tinyMCE)a=tinyMCE.get(this.env.composebody);if(!a&&h.val()==""&&!confirm(this.get_label("nobodywarning"))){h.focus();
-return false}else if(a){if(!a.getContent()&&!confirm(this.get_label("nobodywarning"))){a.focus();return false}tinyMCE.triggerSave()}return true};this.toggle_editor=function(a){if(a.mode=="html"){this.display_spellcheck_controls(false);this.plain2html($("#"+a.id).val(),a.id);tinyMCE.execCommand("mceAddControl",false,a.id)}else{var b=tinyMCE.get(a.id);b.plugins.spellchecker&&b.plugins.spellchecker.active&&b.execCommand("mceSpellCheck",false);if(b=b.getContent()){if(!confirm(this.get_label("editorwarning")))return false;
-this.html2plain(b,a.id)}tinyMCE.execCommand("mceRemoveControl",false,a.id);this.display_spellcheck_controls(true)}return true};this.stop_spellchecking=function(){var a;if(window.tinyMCE&&(a=tinyMCE.get(this.env.composebody)))a.plugins.spellchecker&&a.plugins.spellchecker.active&&a.execCommand("mceSpellCheck");else if((a=this.env.spellcheck)&&!this.spellcheck_ready){$(a.spell_span).trigger("click");this.set_spellcheck_state("ready")}};this.display_spellcheck_controls=function(a){if(this.env.spellcheck){a||
-this.stop_spellchecking();$(this.env.spellcheck.spell_container).css("visibility",a?"visible":"hidden")}};this.set_spellcheck_state=function(a){this.spellcheck_ready=a=="ready"||a=="no_error_found";this.enable_command("spellcheck",this.spellcheck_ready)};this.set_draft_id=function(a){$("input[name='_draft_saveid']").val(a)};this.auto_save_start=function(){if(this.env.draft_autosave)this.save_timer=self.setTimeout(function(){l.command("savedraft")},this.env.draft_autosave*1E3);this.busy=false};this.compose_field_hash=
-function(a){var b=$("[name='_to']").val(),d=$("[name='_cc']").val(),e=$("[name='_bcc']").val(),f=$("[name='_subject']").val(),g="";if(b)g+=b+":";if(d)g+=d+":";if(e)g+=e+":";if(f)g+=f+":";b=tinyMCE.get(this.env.composebody);g+=b?b.getContent():$("[name='_message']").val();if(this.env.attachments)for(var h in this.env.attachments)g+=h;if(a)this.cmp_hash=g;return g};this.change_identity=function(a,b){if(!a||!a.options)return false;if(!b)b=this.env.show_sig;var d,e=-1,f=a.options[a.selectedIndex].value,
-g=$("[name='_message']"),h=g.val(),k=$("input[name='_is_html']").val()=="1",j=this.env.identity;d=this.env.sig_above&&(this.env.compose_mode=="reply"||this.env.compose_mode=="forward")?"---":"-- ";if(this.env.signatures&&this.env.signatures[f]){this.enable_command("insert-sig",true);this.env.compose_commands.push("insert-sig")}else this.enable_command("insert-sig",false);if(k){if(b&&this.env.signatures){e=tinyMCE.get(this.env.composebody);g=e.dom.get("_rc_sig");if(!g){j=e.getBody();h=e.getDoc();g=
-h.createElement("div");g.setAttribute("id","_rc_sig");if(this.env.sig_above){e.getWin().focus();e=e.selection.getNode();if(e.nodeName=="BODY"){j.insertBefore(g,j.firstChild);j.insertBefore(h.createElement("br"),j.firstChild)}else{j.insertBefore(g,e.nextSibling);j.insertBefore(h.createElement("br"),e.nextSibling)}}else{bw.ie&&j.appendChild(h.createElement("br"));j.appendChild(g)}}if(this.env.signatures[f]){if(this.env.signatures[f].is_html){j=this.env.signatures[f].text;this.env.signatures[f].plain_text.match(/^--[ -]\r?\n/)||
-(j=d+"<br />"+j)}else{j=this.env.signatures[f].text;j.match(/^--[ -]\r?\n/)||(j=d+"\n"+j);j="<pre>"+j+"</pre>"}g.innerHTML=j}}}else{if(b&&j&&this.env.signatures&&this.env.signatures[j]){j=this.env.signatures[j].is_html?this.env.signatures[j].plain_text:this.env.signatures[j].text;j=j.replace(/\r\n/g,"\n");j.match(/^--[ -]\n/)||(j=d+"\n"+j);e=this.env.sig_above?h.indexOf(j):h.lastIndexOf(j);if(e>=0)h=h.substring(0,e)+h.substring(e+j.length,h.length)}if(b&&this.env.signatures&&this.env.signatures[f]){j=
-this.env.signatures[f].is_html?this.env.signatures[f].plain_text:this.env.signatures[f].text;j=j.replace(/\r\n/g,"\n");j.match(/^--[ -]\n/)||(j=d+"\n"+j);if(this.env.sig_above)if(e>=0){h=h.substring(0,e)+j+h.substring(e,h.length);d=e-1}else if(pos=this.get_caret_pos(g.get(0))){h=h.substring(0,pos)+"\n"+j+"\n\n"+h.substring(pos,h.length);d=pos}else{d=0;h="\n\n"+j+"\n\n"+h.replace(/^[\r\n]+/,"")}else{h=h.replace(/[\r\n]+$/,"");d=!this.env.top_posting&&h.length?h.length+1:0;h+="\n\n"+j}}else d=this.env.top_posting?
-0:h.length;g.val(h);this.set_caret_pos(g.get(0),d)}this.env.identity=f;return true};this.upload_file=function(a){if(!a)return false;for(var b=false,d=0;d<a.elements.length;d++)if(a.elements[d].type=="file"&&a.elements[d].value){b=true;break}if(b){b=(new Date).getTime();d="rcmupload"+b;if(document.all)document.body.insertAdjacentHTML("BeforeEnd",'<iframe name="'+d+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>');else{var e=document.createElement("iframe");e.name=d;
-e.style.border="none";e.style.width=0;e.style.height=0;e.style.visibility="hidden";document.body.appendChild(e)}$(d).bind("load",{ts:b},function(f){var g,h="";try{if(this.contentDocument)g=this.contentDocument;else if(this.contentWindow)g=this.contentWindow.document;h=g.childNodes[0].innerHTML}catch(k){}if(!h.match(/add2attachment/)&&(!bw.opera||rcmail.env.uploadframe&&rcmail.env.uploadframe==f.data.ts)){h.match(/display_message/)||rcmail.display_message(rcmail.get_label("fileuploaderror"),"error");
-rcmail.remove_from_attachment_list(f.data.ts)}if(bw.opera)rcmail.env.uploadframe=f.data.ts});a.target=d;a.action=this.env.comm_path+"&_action=upload&_uploadid="+b;a.setAttribute("enctype","multipart/form-data");a.submit();e=this.get_label("uploading");if(this.env.loadingicon)e='<img src="'+this.env.loadingicon+'" alt="" />'+e;if(this.env.cancelicon)e='<a title="'+this.get_label("cancel")+'" onclick="return rcmail.cancel_attachment_upload(\''+b+"', '"+d+'\');" href="#cancelupload"><img src="'+this.env.cancelicon+
-'" alt="" /></a>'+e;this.add2attachment_list(b,{name:"",html:e,complete:false})}this.gui_objects.attachmentform=a;return true};this.add2attachment_list=function(a,b,d){if(!this.gui_objects.attachmentlist)return false;var e=$("<li>").attr("id",a).html(b.html),f;d&&(f=document.getElementById(d))?e.replaceAll(f):e.appendTo(this.gui_objects.attachmentlist);d&&this.env.attachments[d]&&delete this.env.attachments[d];this.env.attachments[a]=b;return true};this.remove_from_attachment_list=function(a){this.env.attachments[a]&&
-delete this.env.attachments[a];if(!this.gui_objects.attachmentlist)return false;var b=this.gui_objects.attachmentlist.getElementsByTagName("li");for(i=0;i<b.length;i++)b[i].id==a&&this.gui_objects.attachmentlist.removeChild(b[i])};this.remove_attachment=function(a){a&&this.env.attachments[a]&&this.http_post("remove-attachment","_file="+urlencode(a));return true};this.cancel_attachment_upload=function(a,b){if(!a||!b)return false;this.remove_from_attachment_list(a);$("iframe[name='"+b+"']").remove();
-return false};this.add_contact=function(a){a&&this.http_post("addcontact","_address="+a);return true};this.qsearch=function(a){if(a!=""){var b="";if(this.message_list){this.clear_message_list();if(this.env.search_mods){var d=this.env.search_mods[this.env.mailbox]?this.env.search_mods[this.env.mailbox]:this.env.search_mods["*"];if(d){var e=[],f;for(f in d)e.push(f);b+="&_headers="+e.join(",")}}}else if(this.contact_list){this.contact_list.clear(true);this.show_contentframe(false)}if(this.gui_objects.search_filter)b+=
-"&_filter="+this.gui_objects.search_filter.value;this.env.current_page=1;d=this.set_busy(true,"searching");this.http_request("search","_q="+urlencode(a)+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):"")+(this.env.source?"&_source="+urlencode(this.env.source):"")+(this.env.group?"&_gid="+urlencode(this.env.group):"")+(b?b:""),d)}return true};this.reset_qsearch=function(){if(this.gui_objects.qsearchbox)this.gui_objects.qsearchbox.value="";this.env.search_request=null;return true};this.sent_successfully=
-function(a,b){this.display_message(b,a);window.setTimeout(function(){l.list_mailbox()},500)};this.ksearch_keydown=function(a,b){this.ksearch_timer&&clearTimeout(this.ksearch_timer);var d;d=rcube_event.get_keycode(a);var e=rcube_event.get_modifier(a);switch(d){case 38:case 40:if(!this.ksearch_pane)break;e=d==38?1:0;d=document.getElementById("rcmksearchSelected");if(!d)d=this.ksearch_pane.__ul.firstChild;if(d)this.ksearch_select(e?d.previousSibling:d.nextSibling);return rcube_event.cancel(a);case 9:if(e==
-SHIFT_KEY)break;case 13:if(this.ksearch_selected===null||!this.ksearch_input||!this.ksearch_value)break;this.insert_recipient(this.ksearch_selected);this.ksearch_hide();return rcube_event.cancel(a);case 27:this.ksearch_hide();break;case 37:case 39:if(e!=SHIFT_KEY)return}this.ksearch_timer=window.setTimeout(function(){l.ksearch_get_results()},200);this.ksearch_input=b;return true};this.ksearch_select=function(a){var b=$("#rcmksearchSelected");b[0]&&a&&b.removeAttr("id").removeClass("selected");if(a){$(a).attr("id",
-"rcmksearchSelected").addClass("selected");this.ksearch_selected=a._rcm_id}};this.insert_recipient=function(a){if(this.env.contacts[a]&&this.ksearch_input){var b=this.ksearch_input.value,d=this.get_caret_pos(this.ksearch_input);d=b.lastIndexOf(this.ksearch_value,d);var e="",f=b.substring(0,d);b=b.substring(d+this.ksearch_value.length,b.length);if(typeof this.env.contacts[a]=="object"&&this.env.contacts[a].id){e+=this.env.contacts[a].name+", ";this.group2expand=$.extend({},this.env.contacts[a]);this.group2expand.input=
-this.ksearch_input;this.http_request("group-expand","_source="+urlencode(this.env.contacts[a].source)+"&_gid="+urlencode(this.env.contacts[a].id),false)}else if(typeof this.env.contacts[a]=="string")e=this.env.contacts[a]+", ";this.ksearch_input.value=f+e+b;d+=e.length;this.ksearch_input.setSelectionRange&&this.ksearch_input.setSelectionRange(d,d)}};this.replace_group_recipients=function(a,b){if(this.group2expand&&this.group2expand.id==a){this.group2expand.input.value=this.group2expand.input.value.replace(this.group2expand.name,
-b);this.group2expand=null}};this.ksearch_get_results=function(){var a=this.ksearch_input?this.ksearch_input.value:null;if(a!==null){this.ksearch_pane&&this.ksearch_pane.is(":visible")&&this.ksearch_pane.hide();var b=this.get_caret_pos(this.ksearch_input),d=a.lastIndexOf(",",b-1);a=a.substring(d+1,b);b=this.env.autocomplete_min_length;a=$.trim(a);if(a!=this.ksearch_value)if(a.length<b){if(!this.env.acinfo){a=this.get_label("autocompletechars");a=a.replace("$min",b);this.env.acinfo=this.display_message(a)}}else{this.env.acinfo&&
-a.length==b&&this.hide_message(this.env.acinfo);b=this.ksearch_value;this.ksearch_value=a;if(a.length)if(!(b&&b.length&&this.env.contacts&&!this.env.contacts.length&&a.indexOf(b)==0)){b=this.display_message(this.get_label("searching"),"loading");this.http_post("autocomplete","_search="+urlencode(a),b)}}}};this.ksearch_query_results=function(a,b){if(!(this.ksearch_value&&b!=this.ksearch_value)){this.env.contacts=a?a:[];this.ksearch_display_results(this.env.contacts)}};this.ksearch_display_results=
-function(a){if(a.length&&this.ksearch_input&&this.ksearch_value){var b,d,e,f=this.ksearch_value;if(!this.ksearch_pane){b=$("<ul>");this.ksearch_pane=$("<div>").attr("id","rcmKSearchpane").css({position:"absolute","z-index":3E4}).append(b).appendTo(document.body);this.ksearch_pane.__ul=b[0]}b=this.ksearch_pane.__ul;b.innerHTML="";for(i=0;i<a.length;i++){e=typeof a[i]=="object"?a[i].name:a[i];d=document.createElement("LI");d.innerHTML=e.replace(RegExp("("+RegExp.escape(f)+")","ig"),"##$1%%").replace(/</g,
-"&lt;").replace(/>/g,"&gt;").replace(/##([^%]+)%%/g,"<b>$1</b>");d.onmouseover=function(){l.ksearch_select(this)};d.onmouseup=function(){l.ksearch_click(this)};d._rcm_id=i;b.appendChild(d)}$(b.firstChild).attr("id","rcmksearchSelected").addClass("selected");this.ksearch_selected=0;a=$(this.ksearch_input).offset();this.ksearch_pane.css({left:a.left+"px",top:a.top+this.ksearch_input.offsetHeight+"px"}).show()}else this.ksearch_hide()};this.ksearch_click=function(a){this.ksearch_input&&this.ksearch_input.focus();
-this.insert_recipient(a._rcm_id);this.ksearch_hide()};this.ksearch_blur=function(){this.ksearch_timer&&clearTimeout(this.ksearch_timer);this.ksearch_value="";this.ksearch_input=null;this.ksearch_hide()};this.ksearch_hide=function(){this.ksearch_selected=null;this.ksearch_pane&&this.ksearch_pane.hide()};this.contactlist_keypress=function(a){a.key_pressed==a.DELETE_KEY&&this.command("delete")};this.contactlist_select=function(a){this.preview_timer&&clearTimeout(this.preview_timer);var b,d=this;if(b=
-a.get_single_selection())this.preview_timer=window.setTimeout(function(){d.load_contact(b,"show")},200);else this.env.contentframe&&this.show_contentframe(false);this.enable_command("compose",a.selection.length>0);this.enable_command("edit",b&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly?true:false);this.enable_command("delete",a.selection.length&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly);return false};this.list_contacts=function(a,
-b,d){var e="",f=window;if(!a)a=this.env.source;if(d&&this.current_page==d&&a==this.env.source&&b==this.env.group)return false;if(a!=this.env.source){d=this.env.current_page=1;this.reset_qsearch()}else if(b!=this.env.group)d=this.env.current_page=1;this.select_folder(b?"G"+a+b:a,this.env.group?"G"+this.env.source+this.env.group:this.env.source);this.env.source=a;this.env.group=b;if(this.gui_objects.contactslist)this.list_contacts_remote(a,b,d);else{if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){f=
-window.frames[this.env.contentframe];e="&_framed=1"}if(b)e+="&_gid="+b;if(d)e+="&_page="+d;if(this.env.search_request)e+="&_search="+this.env.search_request;this.set_busy(true,"loading");f.location.href=this.env.comm_path+(a?"&_source="+urlencode(a):"")+e}};this.list_contacts_remote=function(a,b,d){this.contact_list.clear(true);this.show_contentframe(false);this.enable_command("delete","compose",false);d=(a?"_source="+urlencode(a):"")+(d?(a?"&":"")+"_page="+d:"");var e=this.set_busy(true,"loading");
-this.env.source=a;if(this.env.group=b)d+="&_gid="+b;if(this.env.search_request)d+="&_search="+this.env.search_request;this.http_request("list",d,e)};this.load_contact=function(a,b,d){var e="",f=window;if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){e="&_framed=1";f=window.frames[this.env.contentframe];this.show_contentframe(true)}else if(d)return false;if(b&&(a||b=="add")&&!this.drag_active){if(this.env.group)e+="&_gid="+urlencode(this.env.group);this.set_busy(true);
-f.location.href=this.env.comm_path+"&_action="+b+"&_source="+urlencode(this.env.source)+"&_cid="+urlencode(a)+e}return true};this.copy_contact=function(a,b){a||(a=this.contact_list.get_selection().join(","));if(b.type=="group"&&b.source==this.env.source)this.http_post("group-addmembers","_cid="+urlencode(a)+"&_source="+urlencode(this.env.source)+"&_gid="+urlencode(b.id));else if(b.type=="group"&&!this.env.address_sources[b.source].readonly)this.http_post("copy","_cid="+urlencode(a)+"&_source="+urlencode(this.env.source)+
-"&_to="+urlencode(b.source)+"&_togid="+urlencode(b.id)+(this.env.group?"&_gid="+urlencode(this.env.group):""));else if(b.id!=this.env.source&&a&&this.env.address_sources[b.id]&&!this.env.address_sources[b.id].readonly)this.http_post("copy","_cid="+urlencode(a)+"&_source="+urlencode(this.env.source)+"&_to="+urlencode(b.id)+(this.env.group?"&_gid="+urlencode(this.env.group):""))};this.delete_contacts=function(){var a=this.contact_list.get_selection();if((a.length||this.env.cid)&&confirm(this.get_label("deletecontactconfirm"))){var b,
-d=[],e="";if(this.env.cid)d.push(this.env.cid);else{for(var f=0;f<a.length;f++){b=a[f];d.push(b);this.contact_list.remove_row(b,f==a.length-1)}a.length==1&&this.show_contentframe(false)}if(this.env.group)e+="&_gid="+urlencode(this.env.group);if(this.env.search_request)e+="&_search="+this.env.search_request;this.http_post("delete","_cid="+urlencode(d.join(","))+"&_source="+urlencode(this.env.source)+"&_from="+(this.env.action?this.env.action:"")+e);return true}};this.update_contact_row=function(a,
-b,d){var e;if(this.contact_list.rows[a]&&(e=this.contact_list.rows[a].obj)){for(var f=0;f<b.length;f++)e.cells[f]&&$(e.cells[f]).html(b[f]);if(d){e.id="rcmrow"+d;this.contact_list.remove_row(a);this.contact_list.init_row(e);this.contact_list.selection[0]=d;e.style.display=""}return true}return false};this.add_contact_row=function(a,b){if(!this.gui_objects.contactslist||!this.gui_objects.contactslist.tBodies[0])return false;var d=this.gui_objects.contactslist.tBodies[0].rows.length%2,e=document.createElement("tr");
-e.id="rcmrow"+a;e.className="contact "+(d?"even":"odd");if(this.contact_list.in_selection(a))e.className+=" selected";for(var f in b){col=document.createElement("td");col.className=String(f).toLowerCase();col.innerHTML=b[f];e.appendChild(col)}this.contact_list.insert_row(e);this.enable_command("export",this.contact_list.rowcount>0)};this.group_create=function(){if(this.gui_objects.folderlist&&this.env.address_sources[this.env.source].groups){if(!this.name_input){this.name_input=$("<input>").attr("type",
-"text");this.name_input.bind("keydown",function(a){return rcmail.add_input_keydown(a)});this.name_input_li=$("<li>").addClass("contactgroup").append(this.name_input);this.name_input_li.insertAfter(this.get_folder_li(this.env.source))}this.name_input.select().focus()}};this.group_rename=function(){if(this.env.group&&this.gui_objects.folderlist){if(!this.name_input){this.enable_command("list","listgroup",false);this.name_input=$("<input>").attr("type","text").val(this.env.contactgroups["G"+this.env.source+
-this.env.group].name);this.name_input.bind("keydown",function(d){return rcmail.add_input_keydown(d)});this.env.group_renaming=true;var a,b=this.get_folder_li(this.env.source+this.env.group,"rcmliG");if(b&&(a=b.firstChild))$(a).hide().before(this.name_input)}this.name_input.select().focus()}};this.group_delete=function(){this.env.group&&this.http_post("group-delete","_source="+urlencode(this.env.source)+"&_gid="+urlencode(this.env.group),true)};this.remove_group_item=function(a){var b,d="G"+a.source+
-a.id;if(b=this.get_folder_li(d)){this.triggerEvent("group_delete",{source:a.source,id:a.id,li:b});b.parentNode.removeChild(b);delete this.env.contactfolders[d];delete this.env.contactgroups[d]}this.list_contacts(a.source,0)};this.add_input_keydown=function(a){a=rcube_event.get_keycode(a);if(a==13){if(a=this.name_input.val()){var b=this.set_busy(true,"loading");this.env.group_renaming?this.http_post("group-rename","_source="+urlencode(this.env.source)+"&_gid="+urlencode(this.env.group)+"&_name="+urlencode(a),
-b):this.http_post("group-create","_source="+urlencode(this.env.source)+"&_name="+urlencode(a),b)}return false}else a==27&&this.reset_add_input();return true};this.reset_add_input=function(){if(this.name_input){if(this.env.group_renaming){this.name_input.parent().children().last().show();this.env.group_renaming=false}this.name_input.remove();this.name_input_li&&this.name_input_li.remove();this.name_input=this.name_input_li=null}this.enable_command("list","listgroup",true)};this.insert_contact_group=
-function(a){this.reset_add_input();a.type="group";var b="G"+a.source+a.id;this.env.contactfolders[b]=this.env.contactgroups[b]=a;var d=$("<a>").attr("href","#").bind("click",function(){return rcmail.command("listgroup",a,this)}).html(a.name);b=$("<li>").attr("id","rcmli"+b).addClass("contactgroup").append(d).insertAfter(this.get_folder_li(a.source));this.triggerEvent("group_insert",{id:a.id,source:a.source,name:a.name,li:b[0]})};this.update_contact_group=function(a){this.reset_add_input();var b="G"+
-a.source+a.id,d,e=this.get_folder_li(b);if(e&&(d=e.firstChild)&&d.tagName.toLowerCase()=="a")d.innerHTML=a.name;this.env.contactfolders[b].name=this.env.contactgroups[b].name=a.name;this.triggerEvent("group_update",{id:a.id,source:a.source,name:a.name,li:e[0]})};this.init_subscription_list=function(){var a=this;this.subscription_list=new rcube_list_widget(this.gui_objects.subscriptionlist,{multiselect:false,draggable:true,keyboard:false,toggleselect:true});this.subscription_list.addEventListener("select",
-function(b){a.subscription_select(b)});this.subscription_list.addEventListener("dragstart",function(){a.drag_active=true});this.subscription_list.addEventListener("dragend",function(b){a.subscription_move_folder(b)});this.subscription_list.row_init=function(b){b.obj.onmouseover=function(){a.focus_subscription(b.id)};b.obj.onmouseout=function(){a.unfocus_subscription(b.id)}};this.subscription_list.init()};this.section_select=function(a){if(a=a.get_single_selection()){var b="",d=window;this.set_busy(true);
-if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){b="&_framed=1";d=window.frames[this.env.contentframe]}d.location.href=this.env.comm_path+"&_action=edit-prefs&_section="+a+b}return true};this.identity_select=function(a){if(a=a.get_single_selection())this.load_identity(a,"edit-identity")};this.load_identity=function(a,b){if(b=="edit-identity"&&(!a||a==this.env.iid))return false;var d="",e=window;if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){d=
-"&_framed=1";e=window.frames[this.env.contentframe];document.getElementById(this.env.contentframe).style.visibility="inherit"}if(b&&(a||b=="add-identity")){this.set_busy(true);e.location.href=this.env.comm_path+"&_action="+b+"&_iid="+a+d}return true};this.delete_identity=function(a){var b=this.identity_list.get_selection();if(b.length||this.env.iid){a||(a=this.env.iid?this.env.iid:b[0]);this.goto_url("delete-identity","_iid="+a+"&_token="+this.env.request_token,true);return true}};this.focus_subscription=
-function(a){var b,d,e=RegExp.escape(this.env.delimiter),f=RegExp("["+e+"]?[^"+e+"]+$");if(this.drag_active&&this.env.mailbox&&(b=document.getElementById(a)))if(this.env.subscriptionrows[a]&&(d=this.env.subscriptionrows[a][0])){if(this.check_droptarget(d)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.mailbox)][2]&&d!=this.env.mailbox.replace(f,"")&&!d.match(RegExp("^"+RegExp.escape(this.env.mailbox+this.env.delimiter)))){this.set_env("dstfolder",d);$(b).addClass("droptarget")}}else if(this.env.mailbox.match(RegExp(e))){this.set_env("dstfolder",
-this.env.delimiter);$(this.subscription_list.frame).addClass("droptarget")}};this.unfocus_subscription=function(a){var b=$("#"+a);this.set_env("dstfolder",null);this.env.subscriptionrows[a]&&b[0]?b.removeClass("droptarget"):$(this.subscription_list.frame).removeClass("droptarget")};this.subscription_select=function(a){var b,d;if(a&&(b=a.get_single_selection())&&(d=this.env.subscriptionrows["rcmrow"+b])){this.set_env("mailbox",d[0]);this.show_folder(d[0]);this.enable_command("delete-folder",!d[2])}else{this.env.mailbox=
-null;this.show_contentframe(false);this.enable_command("delete-folder","purge",false)}};this.subscription_move_folder=function(){var a=RegExp.escape(this.env.delimiter),b;if(this.env.mailbox&&this.env.dstfolder&&this.env.dstfolder!=this.env.mailbox&&this.env.dstfolder!=this.env.mailbox.replace(RegExp("["+a+"]?[^"+a+"]+$"),"")){b=RegExp("[^"+a+"]*["+a+"]","g");a=this.set_busy(true,"foldermoving");b=this.env.mailbox.replace(b,"");b=this.env.dstfolder==this.env.delimiter?b:this.env.dstfolder+this.env.delimiter+
-b;this.http_post("rename-folder","_folder_oldname="+urlencode(this.env.mailbox)+"&_folder_newname="+urlencode(b),a)}this.drag_active=false;this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder))};this.create_folder=function(){this.show_folder("",this.env.mailbox)};this.delete_folder=function(a){if((a=this.env.subscriptionrows[this.get_folder_row_id(a?a:this.env.mailbox)][0])&&confirm(this.get_label("deletefolderconfirm"))){var b=this.set_busy(true,"folderdeleting");this.http_post("delete-folder",
-"_mbox="+urlencode(a),b)}};this.add_folder_row=function(a,b,d,e){if(!this.gui_objects.subscriptionlist)return false;var f,g;for(g in this.env.subscriptionrows)if(this.env.subscriptionrows[g]!=null&&!this.env.subscriptionrows[g][2]){f=g;break}var h;g=this.gui_objects.subscriptionlist.tBodies[0];var k="rcmrow"+(g.childNodes.length+1),j=this.subscription_list.get_single_selection();if(d&&d.id)f=k=d.id;if(!k||!f||!(h=document.getElementById(f))){this.goto_url("folders");return false}f=this.clone_table_row(h);
-f.id=k;e&&(e=this.get_folder_row_id(e))?g.insertBefore(f,document.getElementById(e)):g.appendChild(f);d&&g.removeChild(d);this.env.subscriptionrows[f.id]=[a,b,0];f.cells[0].innerHTML=b;if(!d){f.cells[1].innerHTML="*";$('input[name="_subscribed[]"]',f).val(a).attr("checked",true)}this.init_subscription_list();j&&document.getElementById("rcmrow"+j)&&this.subscription_list.select_row(j);document.getElementById(k).scrollIntoView&&document.getElementById(k).scrollIntoView()};this.replace_folder_row=function(a,
-b,d,e){a=this.get_folder_row_id(a);a=document.getElementById(a);this.add_folder_row(b,d,a,e)};this.remove_folder_row=function(a){var b;if((a=this.get_folder_row_id(a))&&(b=document.getElementById(a)))b.style.display="none"};this.subscribe=function(a){if(a){var b=this.display_message(this.get_label("foldersubscribing"),"loading");this.http_post("subscribe","_mbox="+urlencode(a),b)}};this.unsubscribe=function(a){if(a){var b=this.display_message(this.get_label("folderunsubscribing"),"loading");this.http_post("unsubscribe",
-"_mbox="+urlencode(a),b)}};this.get_folder_row_id=function(a){for(var b in this.env.subscriptionrows)if(this.env.subscriptionrows[b]&&this.env.subscriptionrows[b][0]==a)break;return b};this.clone_table_row=function(a){for(var b,d,e=document.createElement("tr"),f=0;f<a.cells.length;f++){b=a.cells[f];d=document.createElement("td");if(b.className)d.className=b.className;b.align&&d.setAttribute("align",b.align);d.innerHTML=b.innerHTML;e.appendChild(d)}return e};this.show_folder=function(a,b,d){var e=
-window;a="&_action=edit-folder&_mbox="+urlencode(a);if(b)a+="&_path="+urlencode(b);if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]){e=window.frames[this.env.contentframe];a+="&_framed=1"}if(String(e.location.href).indexOf(a)>=0&&!d)this.show_contentframe(true);else{if(!this.env.frame_lock)(parent.rcmail?parent.rcmail:this).env.frame_lock=this.set_busy(true,"loading");e.location.href=this.env.comm_path+a}};this.disable_subscription=function(a){(a=this.get_folder_row_id(a))&&
-$('input[name="_subscribed[]"]',$("#"+a)).attr("disabled",true)};this.folder_size=function(a){var b=this.set_busy(true,"loading");this.http_post("folder-size","_mbox="+urlencode(a),b)};this.folder_size_update=function(a){$("#folder-size").replaceWith(a)};this.set_page_buttons=function(){this.enable_command("nextpage","lastpage",this.env.pagecount>this.env.current_page);this.enable_command("previouspage","firstpage",this.env.current_page>1)};this.init_buttons=function(){for(var a in this.buttons)if(typeof a==
-"string")for(var b=0;b<this.buttons[a].length;b++){var d=this.buttons[a][b],e=document.getElementById(d.id);if(e){var f=false;if(d.type=="image"){e=e.parentNode;f=true}e._command=a;e._id=d.id;if(d.sel){e.onmousedown=function(){return rcmail.button_sel(this._command,this._id)};e.onmouseup=function(){return rcmail.button_out(this._command,this._id)};if(f)(new Image).src=d.sel}if(d.over){e.onmouseover=function(){return rcmail.button_over(this._command,this._id)};e.onmouseout=function(){return rcmail.button_out(this._command,
-this._id)};if(f)(new Image).src=d.over}}}};this.set_button=function(a,b){var d,e,f=this.buttons[a];if(!f||!f.length)return false;for(var g=0;g<f.length;g++){d=f[g];if((e=document.getElementById(d.id))&&d.type=="image"&&!d.status){d.pas=e._original_src?e._original_src:e.src;if(e.runtimeStyle&&e.runtimeStyle.filter&&e.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))d.pas=RegExp.$1}else if(e&&!d.status)d.pas=String(e.className);if(e&&d.type=="image"&&d[b]){d.status=b;e.src=d[b]}else if(e&&typeof d[b]!=
-"undefined"){d.status=b;e.className=d[b]}if(e&&d.type=="input"){d.status=b;e.disabled=!b}}};this.set_alttext=function(a,b){if(this.buttons[a]&&this.buttons[a].length)for(var d,e,f,g=0;g<this.buttons[a].length;g++){d=this.buttons[a][g];e=document.getElementById(d.id);if(d.type=="image"&&e){e.setAttribute("alt",this.get_label(b));if((f=e.parentNode)&&f.tagName.toLowerCase()=="a")f.setAttribute("title",this.get_label(b))}else e&&e.setAttribute("title",this.get_label(b))}};this.button_over=function(a,
-b){var d,e,f=this.buttons[a];if(!f||!f.length)return false;for(var g=0;g<f.length;g++){d=f[g];if(d.id==b&&d.status=="act")if((e=document.getElementById(d.id))&&d.over)if(d.type=="image")e.src=d.over;else e.className=d.over}};this.button_sel=function(a,b){var d,e,f=this.buttons[a];if(f&&f.length)for(var g=0;g<f.length;g++){d=f[g];if(d.id==b&&d.status=="act"){if((e=document.getElementById(d.id))&&d.sel)if(d.type=="image")e.src=d.sel;else e.className=d.sel;this.buttons_sel[b]=a}}};this.button_out=function(a,
-b){var d,e,f=this.buttons[a];if(f&&f.length)for(var g=0;g<f.length;g++){d=f[g];if(d.id==b&&d.status=="act")if((e=document.getElementById(d.id))&&d.act)if(d.type=="image")e.src=d.act;else e.className=d.act}};this.set_pagetitle=function(a){if(a&&document.title)document.title=a};this.display_message=function(a,b){if(this.is_framed())return parent.rcmail.display_message(a,b);if(!this.gui_objects.message){if(b!="loading")this.pending_message=[a,b];return false}b=b?b:"notice";var d=this,e=a,f=b+(new Date).getTime(),
-g=this.message_time*(b=="error"||b=="warning"?2:1);if(b=="loading"){e="loading";g=this.env.request_timeout*1E3;a||(a=this.get_label("loading"))}if(this.messages[e]){this.messages[e].obj&&this.messages[e].obj.html(a);b=="loading"&&this.messages[e].labels.push({id:f,msg:a});this.messages[e].elements.push(f);window.setTimeout(function(){d.hide_message(f,b=="loading")},g);return f}var h=$("<div>").addClass(b).html(a).data("key",e);$(this.gui_objects.message).append(h).show();this.messages[e]={obj:h,elements:[f]};
-if(b=="loading")this.messages[e].labels=[{id:f,msg:a}];else h.click(function(){return d.hide_message(h)});window.setTimeout(function(){d.hide_message(f,b=="loading")},g);return f};this.hide_message=function(a,b){if(this.is_framed())return parent.rcmail.hide_message(a,b);var d,e,f,g,h=this.messages;if(typeof a=="object"){$(a)[b?"fadeOut":"hide"]();g=$(a).data("key");this.messages[g]&&delete this.messages[g]}else for(d in h)for(e in h[d].elements)if(h[d]&&h[d].elements[e]==a){h[d].elements.splice(e,
-1);if(h[d].elements.length){if(d=="loading")for(f in h[d].labels){if(h[d].labels[f].id==a)delete h[d].labels[f];else g=h[d].labels[f].msg;h[d].obj.html(g)}}else{h[d].obj[b?"fadeOut":"hide"]();delete h[d]}}};this.select_folder=function(a,b,d){if(this.gui_objects.folderlist){var e;if(e=this.get_folder_li(b,d))$(e).removeClass("selected").removeClass("unfocused");if(e=this.get_folder_li(a,d))$(e).removeClass("unfocused").addClass("selected");this.triggerEvent("selectfolder",{folder:a,old:b,prefix:d})}};
-this.get_folder_li=function(a,b){b||(b="rcmli");if(this.gui_objects.folderlist){a=String(a).replace(this.identifier_expr,"_");return document.getElementById(b+a)}return null};this.set_message_coltypes=function(a,b){this.env.coltypes=a;var d=this.gui_objects.messagelist?this.gui_objects.messagelist.tHead:null,e,f,g,h;if(d){if(b){f=document.createElement("thead");g=document.createElement("tr");c=0;for(h=b.length;c<h;c++){e=document.createElement("td");e.innerHTML=b[c].html;if(b[c].id)e.id=b[c].id;if(b[c].className)e.className=
-b[c].className;g.appendChild(e)}f.appendChild(g);d.parentNode.replaceChild(f,d);d=f}g=0;for(h=this.env.coltypes.length;g<h;g++){f=this.env.coltypes[g];if((e=d.rows[0].cells[g])&&(f=="from"||f=="to")){e.id="rcm"+f;if(e.firstChild&&e.firstChild.tagName.toLowerCase()=="a"){e=e.firstChild;e.onclick=function(){return rcmail.command("sort",this.__col,this)};e.__col=f}e.innerHTML=this.get_label(f)}}}this.env.subject_col=null;this.env.flagged_col=null;this.env.status_col=null;if((g=$.inArray("subject",this.env.coltypes))>=
-0){this.set_env("subject_col",g);if(this.message_list)this.message_list.subject_col=g}if((g=$.inArray("flag",this.env.coltypes))>=0)this.set_env("flagged_col",g);if((g=$.inArray("status",this.env.coltypes))>=0)this.set_env("status_col",g);this.message_list.init_header()};this.set_rowcount=function(a){$(this.gui_objects.countdisplay).html(a);this.set_page_buttons()};this.set_mailboxname=function(a){if(this.gui_objects.mailboxname&&a)this.gui_objects.mailboxname.innerHTML=a};this.set_quota=function(a){if(a&&
-this.gui_objects.quotadisplay)typeof a=="object"&&a.type=="image"?this.percent_indicator(this.gui_objects.quotadisplay,a):$(this.gui_objects.quotadisplay).html(a)};this.set_unread_count=function(a,b,d){if(!this.gui_objects.mailboxlist)return false;this.env.unread_counts[a]=b;this.set_unread_count_display(a,d)};this.set_unread_count_display=function(a,b){var d,e,f,g,h,k;if(f=this.get_folder_li(a)){g=this.env.unread_counts[a]?this.env.unread_counts[a]:0;e=f.getElementsByTagName("a")[0];d=/\s+\([0-9]+\)$/i;
-h=0;if((k=f.getElementsByTagName("div")[0])&&k.className.match(/collapsed/))for(var j in this.env.unread_counts)if(j.indexOf(a+this.env.delimiter)==0)h+=this.env.unread_counts[j];if(g&&e.innerHTML.match(d))e.innerHTML=e.innerHTML.replace(d," ("+g+")");else if(g)e.innerHTML+=" ("+g+")";else e.innerHTML=e.innerHTML.replace(d,"");d=RegExp(RegExp.escape(this.env.delimiter)+"[^"+RegExp.escape(this.env.delimiter)+"]+$");a.match(d)&&this.set_unread_count_display(a.replace(d,""),false);g+h>0?$(f).addClass("unread"):
-$(f).removeClass("unread")}d=/^\([0-9]+\)\s+/i;if(b&&document.title){e="";e=String(document.title);e=g&&e.match(d)?e.replace(d,"("+g+") "):g?"("+g+") "+e:e.replace(d,"");this.set_pagetitle(e)}};this.new_message_focus=function(){this.env.framed&&window.parent?window.parent.focus():window.focus()};this.toggle_prefer_html=function(a){var b;if(b=document.getElementById("rcmfd_addrbook_show_images"))b.disabled=!a.checked};this.toggle_preview_pane=function(a){var b;if(b=document.getElementById("rcmfd_preview_pane_mark_read"))b.disabled=
-!a.checked};this.set_headers=function(a){this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&a&&$(this.gui_objects.all_headers_box).html(a).show()};this.load_headers=function(a){if(!(!this.gui_objects.all_headers_row||!this.gui_objects.all_headers_box||!this.env.uid)){$(a).removeClass("show-headers").addClass("hide-headers");$(this.gui_objects.all_headers_row).show();a.onclick=function(){rcmail.hide_headers(a)};this.gui_objects.all_headers_box.innerHTML||this.http_post("headers","_uid="+
-this.env.uid,this.display_message(this.get_label("loading"),"loading"))}};this.hide_headers=function(a){if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box){$(a).removeClass("hide-headers").addClass("show-headers");$(this.gui_objects.all_headers_row).hide();a.onclick=function(){rcmail.load_headers(a)}}};this.percent_indicator=function(a,b){if(!b||!a)return false;var d=b.width?b.width:this.env.indicator_width?this.env.indicator_width:100,e=b.height?b.height:this.env.indicator_height?
-this.env.indicator_height:14,f=b.percent?Math.abs(parseInt(b.percent)):0,g=parseInt(f/100*d),h=$(a).position();h.top=Math.max(0,h.top);this.env.indicator_width=d;this.env.indicator_height=e;if(g>d){g=d;f=100}if(b.title)b.title=this.get_label("quota")+": "+b.title;var k=$("<div>");k.css({position:"absolute",top:h.top,left:h.left,width:d+"px",height:e+"px",zIndex:100,lineHeight:e+"px"}).attr("title",b.title).addClass("quota_text").html(f+"%");var j=$("<div>");j.css({position:"absolute",top:h.top+1,
-left:h.left+1,width:g+"px",height:e+"px",zIndex:99});g=$("<div>");g.css({position:"absolute",top:h.top+1,left:h.left+1,width:d+"px",height:e+"px",zIndex:98}).addClass("quota_bg");if(f>=80){k.addClass(" quota_text_high");j.addClass("quota_high")}else if(f>=55){k.addClass(" quota_text_mid");j.addClass("quota_mid")}else{k.addClass(" quota_text_normal");j.addClass("quota_low")}$(a).html("").append(j).append(g).append(k);$("#quotaimg").attr("title",b.title)};this.html2plain=function(a,b){var d=this,e=
-this.set_busy(true,"converting");console.log("HTTP POST: ?_task=utils&_action=html2text");$.ajax({type:"POST",url:"?_task=utils&_action=html2text",data:a,contentType:"application/octet-stream",error:function(f,g,h){d.http_error(f,g,h,e)},success:function(f){d.set_busy(false,null,e);$(document.getElementById(b)).val(f);console.log(f)}})};this.plain2html=function(a,b){var d=this.set_busy(true,"converting");$(document.getElementById(b)).val("<pre>"+a+"</pre>");this.set_busy(false,null,d)};this.redirect=
-function(a,b){if(b||b===null)this.set_busy(true);if(this.env.framed&&window.parent)parent.location.href=a;else location.href=a};this.goto_url=function(a,b,d){var e=this.env.comm_path;b=b?"&"+b:"";if(a.match(/([a-z]+)\/([a-z-_]+)/)){a=RegExp.$2;e=e.replace(/\_task=[a-z]+/,"_task="+RegExp.$1)}this.redirect(e+"&_action="+a+b,d)};this.http_request=function(a,b,d){var e=this.env.comm_path;if(a.match(/([a-z]+)\/([a-z-_]+)/)){a=RegExp.$2;e=e.replace(/\_task=[a-z]+/,"_task="+RegExp.$1)}var f=this.triggerEvent("request"+
-a,b);if(typeof f!="undefined")if(f===false)return false;else b=f;e+="&_remote=1&_action="+a+(b?"&":"")+b;console.log("HTTP GET: "+e);$.ajax({type:"GET",url:e,data:{_unlock:d?d:0},dataType:"json",success:function(g){l.http_response(g)},error:function(g,h,k){rcmail.http_error(g,h,k,d)}})};this.http_post=function(a,b,d){var e=this.env.comm_path;if(a.match(/([a-z]+)\/([a-z-_]+)/)){a=RegExp.$2;e=e.replace(/\_task=[a-z]+/,"_task="+RegExp.$1)}e+="&_action="+a;if(b&&typeof b=="object"){b._remote=1;b._unlock=
-d?d:0}else b+=(b?"&":"")+"_remote=1"+(d?"&_unlock="+d:"");a=this.triggerEvent("request"+a,b);if(typeof a!="undefined")if(a===false)return false;else b=a;console.log("HTTP POST: "+e);$.ajax({type:"POST",url:e,data:b,dataType:"json",success:function(f){l.http_response(f)},error:function(f,g,h){rcmail.http_error(f,g,h,d)}})};this.http_response=function(a){if(a){a.unlock&&this.set_busy(false);this.triggerEvent("responsebefore",{response:a});this.triggerEvent("responsebefore"+a.action,{response:a});a.env&&
-this.set_env(a.env);if(typeof a.texts=="object")for(var b in a.texts)typeof a.texts[b]=="string"&&this.add_label(b,a.texts[b]);if(a.exec){console.log(a.exec);eval(a.exec)}if(a.callbacks&&a.callbacks.length)for(b=0;b<a.callbacks.length;b++)this.triggerEvent(a.callbacks[b][0],a.callbacks[b][1]);switch(a.action){case "delete":if(this.task=="addressbook"){b=this.contact_list.get_selection();this.enable_command("compose",b&&this.contact_list.rows[b]);this.enable_command("delete","edit",b&&this.contact_list.rows[b]&&
-this.env.address_sources&&!this.env.address_sources[this.env.source].readonly);this.enable_command("export",this.contact_list&&this.contact_list.rowcount>0)}case "moveto":if(this.env.action=="show"){this.enable_command(this.env.message_commands,true);this.env.list_post||this.enable_command("reply-list",false)}else this.task=="addressbook"&&this.triggerEvent("listupdate",{folder:this.env.source,rowcount:this.contact_list.rowcount});case "purge":case "expunge":if(this.task=="mail"){if(!this.env.messagecount){this.env.contentframe&&
-this.show_contentframe(false);this.enable_command(this.env.message_commands,"purge","expunge","select-all","select-none","sort","expand-all","expand-unread","collapse-all",false)}this.message_list&&this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount})}break;case "check-recent":case "getunread":case "search":case "list":if(this.task=="mail"){this.enable_command("show","expunge","select-all","select-none","sort",this.env.messagecount>0);this.enable_command("purge",
-this.purge_mailbox_test());this.enable_command("expand-all","expand-unread","collapse-all",this.env.threading&&this.env.messagecount);if(a.action=="list"||a.action=="search"){this.msglist_select(this.message_list);this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount})}}else if(this.task=="addressbook"){this.enable_command("export",this.contact_list&&this.contact_list.rowcount>0);if(a.action=="list"||a.action=="search"){this.enable_command("group-create",this.env.address_sources[this.env.source].groups&&
-!this.env.address_sources[this.env.source].readonly);this.enable_command("group-rename","group-delete",this.env.address_sources[this.env.source].groups&&this.env.group&&!this.env.address_sources[this.env.source].readonly);this.triggerEvent("listupdate",{folder:this.env.source,rowcount:this.contact_list.rowcount})}}}a.unlock&&this.hide_message(a.unlock);this.triggerEvent("responseafter",{response:a});this.triggerEvent("responseafter"+a.action,{response:a})}};this.http_error=function(a,b,d,e){b=a.statusText;
-this.set_busy(false,null,e);a.abort();b&&this.display_message(this.get_label("servererror")+" ("+b+")","error")};this.start_keepalive=function(){this._int&&clearInterval(this._int);if(this.env.keep_alive&&!this.env.framed&&this.task=="mail"&&this.gui_objects.mailboxlist)this._int=setInterval(function(){l.check_for_recent(false)},this.env.keep_alive*1E3);else if(this.env.keep_alive&&!this.env.framed&&this.task!="login"&&this.env.action!="print")this._int=setInterval(function(){l.send_keep_alive()},
-this.env.keep_alive*1E3)};this.send_keep_alive=function(){this.http_request("keep-alive","_t="+(new Date).getTime())};this.check_for_recent=function(a){if(!this.busy){var b,d="_t="+(new Date).getTime()+"&_mbox="+urlencode(this.env.mailbox);if(a){b=this.set_busy(true,"checkingmail");d+="&_refresh=1";this.start_keepalive()}if(this.gui_objects.messagelist)d+="&_list=1";if(this.gui_objects.quotadisplay)d+="&_quota=1";if(this.env.search_request)d+="&_search="+this.env.search_request;this.http_request("check-recent",
-d,b)}};this.get_single_uid=function(){return this.env.uid?this.env.uid:this.message_list?this.message_list.get_single_selection():null};this.get_single_cid=function(){return this.env.cid?this.env.cid:this.contact_list?this.contact_list.get_single_selection():null};this.get_caret_pos=function(a){if(typeof a.selectionEnd!="undefined")return a.selectionEnd;else if(document.selection&&document.selection.createRange){var b=document.selection.createRange();if(b.parentElement()!=a)return 0;var d=b.duplicate();
-a.tagName=="TEXTAREA"?d.moveToElementText(a):d.expand("textedit");d.setEndPoint("EndToStart",b);b=d.text.length;return b<=a.value.length?b:-1}else return a.value.length};this.set_caret_pos=function(a,b){if(a.setSelectionRange)a.setSelectionRange(b,b);else if(a.createTextRange){var d=a.createTextRange();d.collapse(true);d.moveEnd("character",b);d.moveStart("character",b);d.select()}};this.lock_form=function(a,b){if(a&&a.elements){var d,e,f;if(b)this.disabled_form_elements=[];d=0;for(e=a.elements.length;d<
-e;d++){f=a.elements[d];if(f.type!="hidden")if(b&&f.disabled)this.disabled_form_elements.push(f);else if(b||$.inArray(f,this.disabled_form_elements)<0)f.disabled=b}}}}rcube_webmail.long_subject_title=function(l,a){if(!l.title){var b=$(l);if(b.width()+a*15>b.parent().width())l.title=b.html()}};rcube_webmail.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;rcube_webmail.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;
-rcube_webmail.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;
+this.env.list_post);this.env.action=="show"&&this.http_request("pagenav","_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox),this.display_message("","loading"));if(this.env.blockedobjects){if(this.gui_objects.remoteobjectsmsg)this.gui_objects.remoteobjectsmsg.style.display="block";this.enable_command("load-images","always-load",!0)}this.env.action=="preview"&&this.is_framed()&&(this.enable_command("compose","add-contact",!1),parent.rcmail.show_contentframe(!0))}else if(this.env.action=="compose"){this.env.compose_commands=
+["send-attachment","remove-attachment","send","toggle-editor"];this.env.drafts_mailbox&&this.env.compose_commands.push("savedraft");this.enable_command(this.env.compose_commands,"identities",!0);if(this.env.spellcheck)this.env.spellcheck.spelling_state_observer=function(a){j.set_spellcheck_state(a)},this.env.compose_commands.push("spellcheck"),this.set_spellcheck_state("ready"),$("input[name='_is_html']").val()=="1"&&this.display_spellcheck_controls(!1);document.onmouseup=function(b){return a.doc_mouse_up(b)};
+this.init_messageform()}else this.env.action=="print"&&this.env.uid&&window.print();if(this.gui_objects.mailboxlist)this.env.unread_counts={},this.gui_objects.folderlist=this.gui_objects.mailboxlist,this.http_request("getunread","");this.env.mdn_request&&this.env.uid&&(b="_uid="+this.env.uid+"&_mbox="+urlencode(this.env.mailbox),confirm(this.get_label("mdnrequest"))?this.http_post("sendmdn",b):this.http_post("mark",b+"&_flag=mdnsent"));break;case "addressbook":if(this.gui_objects.folderlist)this.env.contactfolders=
+$.extend($.extend({},this.env.address_sources),this.env.contactgroups);if(this.gui_objects.contactslist)this.contact_list=new rcube_list_widget(this.gui_objects.contactslist,{multiselect:!0,draggable:this.gui_objects.folderlist?!0:!1,keyboard:!0}),this.contact_list.row_init=function(b){a.triggerEvent("insertrow",{cid:b.uid,row:b})},this.contact_list.addEventListener("keypress",function(b){a.contactlist_keypress(b)}),this.contact_list.addEventListener("select",function(b){a.contactlist_select(b)}),
+this.contact_list.addEventListener("dragstart",function(b){a.drag_start(b)}),this.contact_list.addEventListener("dragmove",function(b){a.drag_move(b)}),this.contact_list.addEventListener("dragend",function(b){a.drag_end(b)}),this.contact_list.init(),this.env.cid&&this.contact_list.highlight_row(this.env.cid),this.gui_objects.contactslist.parentNode.onmousedown=function(b){return a.click_on_list(b)},document.onmouseup=function(b){return a.doc_mouse_up(b)},this.gui_objects.qsearchbox&&$(this.gui_objects.qsearchbox).focusin(function(){rcmail.contact_list.blur()});
+this.set_page_buttons();this.env.address_sources&&this.env.address_sources[this.env.source]&&!this.env.address_sources[this.env.source].readonly&&(this.enable_command("add","import",!0),this.enable_command("group-create",this.env.address_sources[this.env.source].groups));this.env.cid&&(this.enable_command("show","edit",!0),this.gui_objects.editform&&$("input.groupmember").change(function(){j.http_post(this.checked?"group-addmembers":"group-delmembers","_cid="+urlencode(j.env.cid)+"&_source="+urlencode(j.env.source)+
+"&_gid="+urlencode(this.value))}));(this.env.action=="add"||this.env.action=="edit")&&this.gui_objects.editform?(this.enable_command("save",!0),$("input[type='text']").first().select()):this.gui_objects.qsearchbox&&(this.enable_command("search","reset-search","moveto",!0),$(this.gui_objects.qsearchbox).select());this.contact_list&&this.contact_list.rowcount>0&&this.enable_command("export",!0);this.enable_command("list","listgroup",!0);break;case "settings":this.enable_command("preferences","identities",
+"save","folders",!0);if(this.env.action=="identities")this.enable_command("add",this.env.identities_level<2);else if(this.env.action=="edit-identity"||this.env.action=="add-identity")this.enable_command("add",this.env.identities_level<2),this.enable_command("save","delete","edit","toggle-editor",!0);else if(this.env.action=="folders")this.enable_command("subscribe","unsubscribe","create-folder","rename-folder",!0);else if(this.env.action=="edit-folder"&&this.gui_objects.editform)this.enable_command("save",
+"folder-size",!0),parent.rcmail.env.messagecount=this.env.messagecount,parent.rcmail.enable_command("purge",this.env.messagecount),$("input[type='text']").first().select();this.gui_objects.identitieslist?(this.identity_list=new rcube_list_widget(this.gui_objects.identitieslist,{multiselect:!1,draggable:!1,keyboard:!1}),this.identity_list.addEventListener("select",function(b){a.identity_select(b)}),this.identity_list.init(),this.identity_list.focus(),this.env.iid&&this.identity_list.highlight_row(this.env.iid)):
+this.gui_objects.sectionslist?(this.sections_list=new rcube_list_widget(this.gui_objects.sectionslist,{multiselect:!1,draggable:!1,keyboard:!1}),this.sections_list.addEventListener("select",function(b){a.section_select(b)}),this.sections_list.init(),this.sections_list.focus()):this.gui_objects.subscriptionlist&&this.init_subscription_list();break;case "login":b=$("#rcmloginuser"),b.bind("keyup",function(a){return rcmail.login_user_keyup(a)}),b.val()==""?b.focus():$("#rcmloginpwd").focus(),$("#rcmlogintz").val((new Date).getTimezoneOffset()/
+-60),$("form").submit(function(){$("input[type=submit]",this).attr("disabled",!0);rcmail.display_message("","loading")}),this.enable_command("login",!0)}this.loaded=!0;this.pending_message&&this.display_message(this.pending_message[0],this.pending_message[1]);if(this.gui_objects.folderlist)this.gui_containers.foldertray=$(this.gui_objects.folderlist);this.triggerEvent("init",{task:this.task,action:this.env.action});for(var d in this.onloads)if(typeof this.onloads[d]=="string")eval(this.onloads[d]);
+else if(typeof this.onloads[d]=="function")this.onloads[d]();this.start_keepalive()}};this.command=function(a,b,d){d&&d.blur&&d.blur();if(this.busy)return!1;if(!this.commands[a])return this.is_framed()&&parent.rcmail.command(a,b),!1;if(this.task=="mail"&&this.env.action=="compose"&&$.inArray(a,this.env.compose_commands)<0&&this.cmp_hash!=this.compose_field_hash()&&!confirm(this.get_label("notsentwarning")))return!1;if(typeof this.command_handlers[a]=="function")return a=this.command_handlers[a](b,
+d),a!==null?a:d?!1:!0;else if(typeof this.command_handlers[a]=="string")return a=window[this.command_handlers[a]](b,d),a!==null?a:d?!1:!0;this.triggerEvent("actionbefore",{props:b,action:a});var e=this.triggerEvent("before"+a,b);if(typeof e!="undefined")if(e===!1)return!1;else b=e;switch(a){case "login":this.gui_objects.loginform&&this.gui_objects.loginform.submit();break;case "mail":case "addressbook":case "settings":case "logout":this.switch_task(a);break;case "permaurl":if(d&&d.href&&d.target)return!0;
+else if(this.env.permaurl)parent.location.href=this.env.permaurl;break;case "menu-open":case "menu-save":return this.triggerEvent(a,{props:b}),!1;case "open":var f;if(f=this.get_single_uid())return d.href="?_task="+this.env.task+"&_action=show&_mbox="+urlencode(this.env.mailbox)+"&_uid="+f,!0;break;case "list":this.task=="mail"?((!this.env.search_request||b&&b!=this.env.mailbox)&&this.reset_qsearch(),this.list_mailbox(b),this.env.trash_mailbox&&this.set_alttext("delete",this.env.mailbox!=this.env.trash_mailbox?
+"movemessagetotrash":"deletemessage")):this.task=="addressbook"&&((!this.env.search_request||b!=this.env.source)&&this.reset_qsearch(),this.list_contacts(b),this.enable_command("add","import",this.env.address_sources&&!this.env.address_sources[this.env.source].readonly));break;case "load-headers":this.load_headers(d);break;case "sort":var g=b;f=this.env.sort_col==g?this.env.sort_order=="ASC"?"DESC":"ASC":"ASC";this.set_list_sorting(g,f);this.list_mailbox("","",g+"_"+f);break;case "nextpage":this.list_page("next");
+break;case "lastpage":this.list_page("last");break;case "previouspage":this.list_page("prev");break;case "firstpage":this.list_page("first");break;case "expunge":this.env.messagecount&&this.expunge_mailbox(this.env.mailbox);break;case "purge":case "empty-mailbox":this.env.messagecount&&this.purge_mailbox(this.env.mailbox);break;case "show":if(this.task=="mail"){if((f=this.get_single_uid())&&(!this.env.uid||f!=this.env.uid))this.env.mailbox==this.env.drafts_mailbox?this.goto_url("compose","_draft_uid="+
+f+"&_mbox="+urlencode(this.env.mailbox),!0):this.show_message(f)}else this.task=="addressbook"&&(g=b?b:this.get_single_cid())&&!(this.env.action=="show"&&g==this.env.cid)&&this.load_contact(g,"show");break;case "add":this.task=="addressbook"?this.load_contact(0,"add"):this.task=="settings"&&(this.identity_list.clear_selection(),this.load_identity(0,"add-identity"));break;case "edit":if(this.task=="addressbook"&&(g=this.get_single_cid()))this.load_contact(g,"edit");else if(this.task=="settings"&&b)this.load_identity(b,
+"edit-identity");else if(this.task=="mail"&&(g=this.get_single_uid()))e=this.env.mailbox==this.env.drafts_mailbox?"_draft_uid=":"_uid=",this.goto_url("compose",e+g+"&_mbox="+urlencode(this.env.mailbox),!0);break;case "save":if(this.gui_objects.editform){f=$("input[name='_pagesize']");g=$("input[name='_name']");e=$("input[name='_email']");if(f.length&&isNaN(parseInt(f.val()))){alert(this.get_label("nopagesizewarning"));f.focus();break}else if(g.length&&g.val()==""){alert(this.get_label("nonamewarning"));
+g.focus();break}else if(e.length&&!rcube_check_email(e.val())){alert(this.get_label("noemailwarning"));e.focus();break}this.gui_objects.editform.submit()}break;case "delete":this.task=="mail"?this.delete_messages():this.task=="addressbook"?this.delete_contacts():this.task=="settings"&&this.delete_identity();break;case "move":case "moveto":this.task=="mail"?this.move_messages(b):this.task=="addressbook"&&this.drag_active&&this.copy_contact(null,b);break;case "copy":this.task=="mail"&&this.copy_messages(b);
+break;case "mark":b&&this.mark_message(b);break;case "toggle_status":if(b&&!b._row)break;g="read";if(b._row.uid)f=b._row.uid,this.message_list.rows[f].deleted?g="undelete":this.message_list.rows[f].unread||(g="unread");this.mark_message(g,f);break;case "toggle_flag":if(b&&!b._row)break;g="flagged";if(b._row.uid)f=b._row.uid,this.message_list.rows[f].flagged&&(g="unflagged");this.mark_message(g,f);break;case "always-load":if(this.env.uid&&this.env.sender){this.add_contact(urlencode(this.env.sender));
+window.setTimeout(function(){j.command("load-images")},300);break}case "load-images":this.env.uid&&this.show_message(this.env.uid,!0,this.env.action=="preview");break;case "load-attachment":f="_mbox="+urlencode(this.env.mailbox)+"&_uid="+this.env.uid+"&_part="+b.part;if(this.env.uid&&b.mimetype&&$.inArray(b.mimetype,this.mimetypes)>=0&&(b.mimetype=="text/html"&&(f+="&_safe=1"),this.attachment_win=window.open(this.env.comm_path+"&_action=get&"+f+"&_frame=1","rcubemailattachment"))){window.setTimeout(function(){j.attachment_win.focus()},
+10);break}this.goto_url("get",f+"&_download=1",!1);break;case "select-all":this.select_all_mode=b?!1:!0;this.dummy_select=!0;b=="invert"?this.message_list.invert_selection():this.message_list.select_all(b=="page"?"":b);this.dummy_select=null;break;case "select-none":this.select_all_mode=!1;this.message_list.clear_selection();break;case "expand-all":this.env.autoexpand_threads=1;this.message_list.expand_all();break;case "expand-unread":this.env.autoexpand_threads=2;this.message_list.collapse_all();
+this.expand_unread();break;case "collapse-all":this.env.autoexpand_threads=0;this.message_list.collapse_all();break;case "nextmessage":this.env.next_uid&&this.show_message(this.env.next_uid,!1,this.env.action=="preview");break;case "lastmessage":this.env.last_uid&&this.show_message(this.env.last_uid);break;case "previousmessage":this.env.prev_uid&&this.show_message(this.env.prev_uid,!1,this.env.action=="preview");break;case "firstmessage":this.env.first_uid&&this.show_message(this.env.first_uid);
+break;case "checkmail":this.check_for_recent(!0);break;case "compose":e=this.env.comm_path+"&_action=compose";if(this.task=="mail")if(e+="&_mbox="+urlencode(this.env.mailbox),this.env.mailbox==this.env.drafts_mailbox){if(f=this.get_single_uid())e+="&_draft_uid="+f}else b&&(e+="&_to="+urlencode(b));else if(this.task=="addressbook"){if(b&&b.indexOf("@")>0){e=this.get_task_url("mail",e);this.redirect(e+"&_to="+urlencode(b));break}f=[];if(b)f.push(b);else if(this.contact_list){g=this.contact_list.get_selection();
+for(e=0;e<g.length;e++)f.push(g[e])}f.length&&this.http_request("mailto","_cid="+urlencode(f.join(","))+"&_source="+urlencode(this.env.source),!0);break}e=e.replace(/&_framed=1/,"");this.redirect(e);break;case "spellcheck":window.tinyMCE&&tinyMCE.get(this.env.composebody)?tinyMCE.execCommand("mceSpellCheck",!0):this.env.spellcheck&&this.env.spellcheck.spellCheck&&this.spellcheck_ready&&(this.env.spellcheck.spellCheck(),this.set_spellcheck_state("checking"));break;case "savedraft":self.clearTimeout(this.save_timer);
+if(!this.gui_objects.messageform)break;if(!this.env.drafts_mailbox||this.cmp_hash==this.compose_field_hash())break;f=this.gui_objects.messageform;g=this.set_busy(!0,"savingmessage");f.target="savetarget";f._draft.value="1";f.action=this.add_url(f.action,"_unlock",g);f.submit();break;case "send":if(!this.gui_objects.messageform)break;if(!this.check_compose_input())break;self.clearTimeout(this.save_timer);f=this.gui_objects.messageform;g=this.set_busy(!0,"sendingmessage");f.target="savetarget";f._draft.value=
+"";f.action=this.add_url(f.action,"_unlock",g);f.submit();clearTimeout(this.request_timer);break;case "send-attachment":self.clearTimeout(this.save_timer);this.upload_file(b);break;case "insert-sig":this.change_identity($("[name='_from']")[0],!0);break;case "reply-all":case "reply-list":case "reply":if(f=this.get_single_uid())e="_reply_uid="+f+"&_mbox="+urlencode(this.env.mailbox),a=="reply-all"?e+="&_all="+(!b&&this.commands["reply-list"]?"list":"all"):a=="reply-list"&&(e+="&_all=list"),this.goto_url("compose",
+e,!0);break;case "forward":(f=this.get_single_uid())&&this.goto_url("compose","_forward_uid="+f+"&_mbox="+urlencode(this.env.mailbox),!0);break;case "print":if(f=this.get_single_uid())j.printwin=window.open(this.env.comm_path+"&_action=print&_uid="+f+"&_mbox="+urlencode(this.env.mailbox)+(this.env.safemode?"&_safe=1":"")),this.printwin&&(window.setTimeout(function(){j.printwin.focus()},20),this.env.action!="show"&&this.mark_message("read",f));break;case "viewsource":if(f=this.get_single_uid())j.sourcewin=
+window.open(this.env.comm_path+"&_action=viewsource&_uid="+f+"&_mbox="+urlencode(this.env.mailbox)),this.sourcewin&&window.setTimeout(function(){j.sourcewin.focus()},20);break;case "download":(f=this.get_single_uid())&&this.goto_url("viewsource","&_uid="+f+"&_mbox="+urlencode(this.env.mailbox)+"&_save=1");break;case "search":if(!b&&this.gui_objects.qsearchbox)b=this.gui_objects.qsearchbox.value;if(b){this.qsearch(b);break}case "reset-search":f=this.env.search_request;this.reset_qsearch();f&&this.env.mailbox?
+this.list_mailbox(this.env.mailbox):f&&this.task=="addressbook"&&this.list_contacts(this.env.source,this.env.group);break;case "listgroup":this.list_contacts(b.source,b.id);break;case "import":if(this.env.action=="import"&&this.gui_objects.importform){if((f=document.getElementById("rcmimportfile"))&&!f.value){alert(this.get_label("selectimportfile"));break}this.gui_objects.importform.submit();this.set_busy(!0,"importwait");this.lock_form(this.gui_objects.importform,!0)}else this.goto_url("import",
+this.env.source?"_target="+urlencode(this.env.source)+"&":"");break;case "export":this.contact_list.rowcount>0&&(f=this.env.source?"_source="+urlencode(this.env.source)+"&":"",this.env.search_request&&(f+="_search="+this.env.search_request),this.goto_url("export",f));break;case "preferences":case "identities":case "folders":this.goto_url("settings/"+a);break;default:if(f=a.replace(/-/g,"_"),this[f]&&typeof this[f]=="function")this[f](b)}this.triggerEvent("after"+a,b);this.triggerEvent("actionafter",
+{props:b,action:a});return d?!1:!0};this.enable_command=function(){for(var a=Array.prototype.slice.call(arguments),b=a.pop(),d,e=0;e<a.length;e++)if(d=a[e],typeof d==="string")this.commands[d]=b,this.set_button(d,b?"act":"pas");else for(var f in d)a.push(d[f])};this.set_busy=function(a,b,d){a&&b?(d=this.get_label(b),d==b&&(d="Loading..."),d=this.display_message(d,"loading")):!a&&d&&this.hide_message(d);this.busy=a;this.gui_objects.editform&&this.lock_form(this.gui_objects.editform,a);this.request_timer&&
+clearTimeout(this.request_timer);if(a&&this.env.request_timeout)this.request_timer=window.setTimeout(function(){j.request_timed_out()},this.env.request_timeout*1E3);return d};this.gettext=this.get_label=function(a,b){return b&&this.labels[b+"."+a]?this.labels[b+"."+a]:this.labels[a]?this.labels[a]:a};this.switch_task=function(a){if(!(this.task===a&&a!="mail")){var b=this.get_task_url(a);a=="mail"&&(b+="&_mbox=INBOX");this.redirect(b)}};this.get_task_url=function(a,b){if(!b)b=this.env.comm_path;return b.replace(/_task=[a-z]+/,
+"_task="+a)};this.request_timed_out=function(){this.set_busy(!1);this.display_message("Request timed out!","error")};this.reload=function(a){if(this.is_framed())parent.rcmail.reload(a);else if(a)window.setTimeout(function(){rcmail.reload()},a);else if(window.location)location.href=this.env.comm_path+(this.env.action?"&_action="+this.env.action:"")};this.add_url=function(a,b,d){d=urlencode(d);if(/(\?.*)$/.test(a)){var e=RegExp.$1,f=RegExp("((\\?|&)"+RegExp.escape(b)+"=[^&]*)");f.test(e)?e=e.replace(f,
+RegExp.$2+b+"="+d):e+="&"+b+"="+d;return a.replace(/(\?.*)$/,e)}else return a+"?"+b+"="+d};this.is_framed=function(){return this.env.framed&&parent.rcmail};this.drag_menu=function(a,b){var d=rcube_event.get_modifier(a),e=$("#"+this.gui_objects.message_dragmenu);if(e&&d==SHIFT_KEY&&this.commands.copy)return d=rcube_event.get_mouse_pos(a),this.env.drag_target=b,e.css({top:d.y-10+"px",left:d.x-10+"px"}).show(),!0;return!1};this.drag_menu_action=function(a){var b=$("#"+this.gui_objects.message_dragmenu);
+b&&b.hide();this.command(a,this.env.drag_target);this.env.drag_target=null};this.drag_start=function(a){var b=this.task=="mail"?this.env.mailboxes:this.env.contactfolders;this.drag_active=!0;this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);if(this.gui_objects.folderlist&&b){this.initialBodyScrollTop=bw.ie?0:window.pageYOffset;this.initialListScrollTop=this.gui_objects.folderlist.parentNode.scrollTop;var d,e,a=$(this.gui_objects.folderlist);
+d=a.offset();this.env.folderlist_coords={x1:d.left,y1:d.top,x2:d.left+a.width(),y2:d.top+a.height()};this.env.folder_coords=[];for(var f in b)if(a=this.get_folder_li(f))if(e=a.firstChild.offsetHeight)d=$(a.firstChild).offset(),this.env.folder_coords[f]={x1:d.left,y1:d.top,x2:d.left+a.firstChild.offsetWidth,y2:d.top+e,on:0}}};this.drag_end=function(){this.drag_active=!1;this.env.last_folder_target=null;if(this.folder_auto_timer)window.clearTimeout(this.folder_auto_timer),this.folder_auto_expand=this.folder_auto_timer=
+null;if(this.gui_objects.folderlist&&this.env.folder_coords)for(var a in this.env.folder_coords)this.env.folder_coords[a].on&&$(this.get_folder_li(a)).removeClass("droptarget")};this.drag_move=function(a){if(this.gui_objects.folderlist&&this.env.folder_coords){var b=-(this.initialListScrollTop-this.gui_objects.folderlist.parentNode.scrollTop)-(bw.ie?-document.documentElement.scrollTop:this.initialBodyScrollTop),d,e,f;d="draglayernormal";this.contact_list&&this.contact_list.draglayer&&(f=this.contact_list.draglayer.attr("class"));
+a=rcube_event.get_mouse_pos(a);e=this.env.folderlist_coords;a.y+=b;if(a.x<e.x1||a.x>=e.x2||a.y<e.y1||a.y>=e.y2){if(this.env.last_folder_target)$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget"),this.env.folder_coords[this.env.last_folder_target].on=0,this.env.last_folder_target=null}else for(var g in this.env.folder_coords)if(e=this.env.folder_coords[g],a.x>=e.x1&&a.x<e.x2&&a.y>=e.y1&&a.y<e.y2)if(b=this.check_droptarget(g)){d=this.get_folder_li(g);e=$(d.getElementsByTagName("div")[0]);
+if(e.hasClass("collapsed"))this.folder_auto_timer&&window.clearTimeout(this.folder_auto_timer),this.folder_auto_expand=g,this.folder_auto_timer=window.setTimeout(function(){rcmail.command("collapse-folder",rcmail.folder_auto_expand);rcmail.drag_start(null)},1E3);else if(this.folder_auto_timer)window.clearTimeout(this.folder_auto_timer),this.folder_auto_expand=this.folder_auto_timer=null;$(d).addClass("droptarget");this.env.folder_coords[g].on=1;this.env.last_folder_target=g;d="draglayer"+(b>1?"copy":
+"normal")}else this.env.last_folder_target=null;else if(e.on)$(this.get_folder_li(g)).removeClass("droptarget"),this.env.folder_coords[g].on=0;d!=f&&this.contact_list&&this.contact_list.draglayer&&this.contact_list.draglayer.attr("class",d)}};this.collapse_folder=function(a){var b=this.get_folder_li(a),d=$(b.getElementsByTagName("div")[0]);if(d&&(d.hasClass("collapsed")||d.hasClass("expanded"))){var e=$(b.getElementsByTagName("ul")[0]);d.hasClass("collapsed")?(e.show(),d.removeClass("collapsed").addClass("expanded"),
+this.set_env("collapsed_folders",this.env.collapsed_folders.replace(RegExp("&"+urlencode(a)+"&"),""))):(e.hide(),d.removeClass("expanded").addClass("collapsed"),this.set_env("collapsed_folders",this.env.collapsed_folders+"&"+urlencode(a)+"&"),this.env.mailbox.indexOf(a+this.env.delimiter)==0&&this.command("list",a));if(bw.ie6||bw.ie7)if((d=b.nextSibling?b.nextSibling.getElementsByTagName("ul"):null)&&d.length&&(b=d[0])&&b.style&&b.style.display!="none")b.style.display="none",b.style.display="";this.http_post("save-pref",
+"_name=collapsed_folders&_value="+urlencode(this.env.collapsed_folders));this.set_unread_count_display(a,!1)}};this.doc_mouse_up=function(a){var b,d;this.message_list?(rcube_mouse_is_over(a,this.message_list.list.parentNode)?this.message_list.focus():this.message_list.blur(),d=this.message_list,b=this.env.mailboxes):this.contact_list?(rcube_mouse_is_over(a,this.contact_list.list.parentNode)?this.contact_list.focus():this.contact_list.blur(),d=this.contact_list,b=this.env.contactfolders):this.ksearch_value&&
+this.ksearch_blur();if(this.drag_active&&b&&this.env.last_folder_target)b=b[this.env.last_folder_target],$(this.get_folder_li(this.env.last_folder_target)).removeClass("droptarget"),this.env.last_folder_target=null,d.draglayer.hide(),this.drag_menu(a,b)||this.command("moveto",b);if(this.buttons_sel){for(var e in this.buttons_sel)typeof e!="function"&&this.button_out(this.buttons_sel[e],e);this.buttons_sel={}}};this.click_on_list=function(){this.gui_objects.qsearchbox&&this.gui_objects.qsearchbox.blur();
+this.message_list?this.message_list.focus():this.contact_list&&this.contact_list.focus();return!0};this.msglist_select=function(a){this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);var b=a.get_single_selection()!=null;this.enable_command(this.env.message_commands,b);b&&(this.env.mailbox==this.env.drafts_mailbox?this.enable_command("reply","reply-all","reply-list","forward",!1):this.env.messages[a.get_single_selection()].ml||this.enable_command("reply-list",
+!1));this.enable_command("delete","moveto","copy","mark",a.selection.length>0?!0:!1);if(b||a.selection.length&&a.selection.length!=a.rowcount)this.select_all_mode=!1;b&&this.env.contentframe&&!a.multi_selecting&&!this.dummy_select?this.preview_timer=window.setTimeout(function(){j.msglist_get_preview()},200):this.env.contentframe&&this.show_contentframe(!1)};this.msglist_click=function(a){if(!a.multi_selecting&&this.env.contentframe&&a.get_single_selection()&&window.frames&&window.frames[this.env.contentframe]&&
+window.frames[this.env.contentframe].location.href.indexOf(this.env.blankpage)>=0)this.preview_timer&&clearTimeout(this.preview_timer),this.preview_read_timer&&clearTimeout(this.preview_read_timer),this.preview_timer=window.setTimeout(function(){j.msglist_get_preview()},200)};this.msglist_dbl_click=function(a){this.preview_timer&&clearTimeout(this.preview_timer);this.preview_read_timer&&clearTimeout(this.preview_read_timer);(a=a.get_single_selection())&&this.env.mailbox==this.env.drafts_mailbox?this.goto_url("compose",
+"_draft_uid="+a+"&_mbox="+urlencode(this.env.mailbox),!0):a&&this.show_message(a,!1,!1)};this.msglist_keypress=function(a){a.key_pressed==a.ENTER_KEY?this.command("show"):a.key_pressed==a.DELETE_KEY?this.command("delete"):a.key_pressed==a.BACKSPACE_KEY?this.command("delete"):a.key_pressed==33?this.command("previouspage"):a.key_pressed==34?this.command("nextpage"):a.shiftkey=!1};this.msglist_get_preview=function(){var a=this.get_single_uid();a&&this.env.contentframe&&!this.drag_active?this.show_message(a,
+!1,!0):this.env.contentframe&&this.show_contentframe(!1)};this.msglist_expand=function(a){if(this.env.messages[a.uid])this.env.messages[a.uid].expanded=a.expanded};this.msglist_set_coltypes=function(a){var b,d,e=a.list.tHead.rows[0].cells;this.env.coltypes=[];for(a=0;a<e.length;a++)e[a].id&&e[a].id.match(/^rcm/)&&(d=e[a].id.replace(/^rcm/,""),this.env.coltypes.push(d=="to"?"from":d));(b=$.inArray("flag",this.env.coltypes))>=0&&this.set_env("flagged_col",b);(b=$.inArray("subject",this.env.coltypes))>=
+0&&this.set_env("subject_col",b);this.http_post("save-pref",{_name:"list_cols",_value:this.env.coltypes,_session:"list_attrib/columns"})};this.check_droptarget=function(a){var b=!1,d=!1;if(this.task=="mail")b=this.env.mailboxes[a]&&this.env.mailboxes[a].id!=this.env.mailbox&&!this.env.mailboxes[a].virtual;else if(this.task=="settings")b=a!=this.env.mailbox;else if(this.task=="addressbook"&&a!=this.env.source&&this.env.contactfolders[a])this.env.contactfolders[a].type=="group"?(d=this.env.contactfolders[a].source,
+b=this.env.contactfolders[a].id!=this.env.group&&!this.env.contactfolders[d].readonly,d=d!=this.env.source):(b=!this.env.contactfolders[a].readonly,d=!0);return b?d?2:1:0};this.init_message_row=function(a){var b,d=this,e=a.uid,f=(this.env.status_col!=null?"status":"msg")+"icn"+a.uid;e&&this.env.messages[e]&&$.extend(a,this.env.messages[e]);if(a.icon=document.getElementById(f))a.icon._row=a.obj,a.icon.onmousedown=function(a){d.command("toggle_status",this);rcube_event.cancel(a)};a.msgicon=this.env.status_col!=
+null?document.getElementById("msgicn"+a.uid):a.icon;if(this.env.flagged_col!=null&&(a.flagicon=document.getElementById("flagicn"+a.uid)))a.flagicon._row=a.obj,a.flagicon.onmousedown=function(a){d.command("toggle_flag",this);rcube_event.cancel(a)};if(!a.depth&&a.has_children&&(b=document.getElementById("rcmexpando"+a.uid)))a.expando=b,b.onmousedown=function(a){return d.expand_message_row(a,e)};this.triggerEvent("insertrow",{uid:e,row:a})};this.add_message_row=function(a,b,d,e){if(!this.gui_objects.messagelist||
+!this.message_list)return!1;this.env.messages[a]||(this.env.messages[a]={});$.extend(this.env.messages[a],{deleted:d.deleted?1:0,replied:d.replied?1:0,unread:d.unread?1:0,forwarded:d.forwarded?1:0,flagged:d.flagged?1:0,has_children:d.has_children?1:0,depth:d.depth?d.depth:0,unread_children:d.unread_children?d.unread_children:0,parent_uid:d.parent_uid?d.parent_uid:0,selected:this.select_all_mode||this.message_list.in_selection(a),ml:d.ml?1:0,ctype:d.ctype,flags:d.extra_flags});var f,g=expando="",h=
+this.message_list,l=h.rows;f=this.env.messages[a];var k="message"+(this.gui_objects.messagelist.tBodies[0].rows.length%2?" even":" odd")+(d.unread?" unread":"")+(d.deleted?" deleted":"")+(d.flagged?" flagged":"")+(d.unread_children&&!d.unread&&!this.env.autoexpand_threads?" unroot":"")+(f.selected?" selected":""),j=document.createElement("tr"),m=document.createElement("td");j.id="rcmrow"+a;j.className=k;k="msgicon";this.env.status_col===null&&(k+=" status",d.deleted?k+=" deleted":d.unread?k+=" unread":
+d.unread_children>0&&(k+=" unreadchildren"));d.replied&&(k+=" replied");d.forwarded&&(k+=" forwarded");f.selected&&!h.in_selection(a)&&h.selection.push(a);if(this.env.threading){m=f.depth*15;if(f.depth)l[f.parent_uid]&&l[f.parent_uid].expanded===!1||(this.env.autoexpand_threads==0||this.env.autoexpand_threads==2)&&(!l[f.parent_uid]||!l[f.parent_uid].expanded)?(j.style.display="none",f.expanded=!1):f.expanded=!0;else if(f.has_children&&typeof f.expanded=="undefined"&&(this.env.autoexpand_threads==
+1||this.env.autoexpand_threads==2&&f.unread_children))f.expanded=!0;m&&(g+='<span id="rcmtab'+a+'" class="branch" style="width:'+m+'px;">&nbsp;&nbsp;</span>');f.has_children&&!f.depth&&(expando='<div id="rcmexpando'+a+'" class="'+(f.expanded?"expanded":"collapsed")+'">&nbsp;&nbsp;</div>')}g+='<span id="msgicn'+a+'" class="'+k+'">&nbsp;</span>';if(!bw.ie&&b.subject)m=d.mbox==this.env.drafts_mailbox?"_draft_uid":"_uid",b.subject='<a href="./?_task=mail&_action='+(d.mbox==this.env.drafts_mailbox?"compose":
+"show")+"&_mbox="+urlencode(d.mbox)+"&"+m+"="+a+'" onclick="return rcube_event.cancel(event)" onmouseover="rcube_webmail.long_subject_title(this,'+(f.depth+1)+')">'+b.subject+"</a>";for(var o in this.env.coltypes)f=this.env.coltypes[o],m=document.createElement("td"),m.className=String(f).toLowerCase(),f=="flag"?(k=d.flagged?"flagged":"unflagged",f='<span id="flagicn'+a+'" class="'+k+'">&nbsp;</span>'):f=="attachment"?f=/application\/|multipart\/m/.test(d.ctype)?'<span class="attachment">&nbsp;</span>':
+/multipart\/report/.test(d.ctype)?'<span class="report">&nbsp;</span>':"&nbsp;":f=="status"?(k=d.deleted?"deleted":d.unread?"unread":d.unread_children>0?"unreadchildren":"msgicon",f='<span id="statusicn'+a+'" class="'+k+'">&nbsp;</span>'):f=f=="threads"?expando:f=="subject"?g+b[f]:b[f],m.innerHTML=f,j.appendChild(m);h.insert_row(j,e);e&&this.env.pagesize&&h.rowcount>this.env.pagesize&&(a=h.get_last_row(),h.remove_row(a),h.clear_selection(a))};this.set_list_sorting=function(a,b){$("#rcm"+this.env.sort_col).removeClass("sorted"+
+this.env.sort_order.toUpperCase());a&&$("#rcm"+a).addClass("sorted"+b);this.env.sort_col=a;this.env.sort_order=b};this.set_list_options=function(a,b,d,e){var f,g="";if(typeof b=="undefined")b=this.env.sort_col;if(!d)d=this.env.sort_order;if(this.env.sort_col!=b||this.env.sort_order!=d)f=1,this.set_list_sorting(b,d);this.env.threading!=e&&(f=1,g+="&_threads="+e);if(a&&a.length){for(var h,l,k=[],j=this.env.coltypes,e=0;e<j.length;e++)l=j[e]=="to"?"from":j[e],h=$.inArray(l,a),h!=-1&&(k.push(l),delete a[h]);
+for(e=0;e<a.length;e++)a[e]&&k.push(a[e]);k.join()!=j.join()&&(f=1,g+="&_cols="+k.join(","))}f&&this.list_mailbox("","",b+"_"+d,g)};this.show_message=function(a,b,d){if(a){var e=window,f=d?"preview":"show",g="&_action="+f+"&_uid="+a+"&_mbox="+urlencode(this.env.mailbox);d&&this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]&&(e=window.frames[this.env.contentframe],g+="&_framed=1");b&&(g+="&_safe=1");this.env.search_request&&(g+="&_search="+this.env.search_request);if(f=="preview"&&
+String(e.location.href).indexOf(g)>=0)this.show_contentframe(!0);else{if(!this.env.frame_lock)(this.is_framed()?parent.rcmail:this).env.frame_lock=this.set_busy(!0,"loading");e.location.href=this.env.comm_path+g;if(f=="preview"&&this.message_list&&this.message_list.rows[a]&&this.message_list.rows[a].unread&&this.env.preview_pane_mark_read>=0)this.preview_read_timer=window.setTimeout(function(){j.set_message(a,"unread",!1);j.update_thread_root(a,"read");j.env.unread_counts[j.env.mailbox]&&(j.env.unread_counts[j.env.mailbox]-=
+1,j.set_unread_count(j.env.mailbox,j.env.unread_counts[j.env.mailbox],j.env.mailbox=="INBOX"));j.env.preview_pane_mark_read>0&&j.http_post("mark","_uid="+a+"&_flag=read&_quiet=1")},this.env.preview_pane_mark_read*1E3)}}};this.show_contentframe=function(a){var b,d;if(this.env.contentframe&&(b=$("#"+this.env.contentframe))&&b.length)if(!a&&(d=window.frames[this.env.contentframe])){if(d.location&&d.location.href.indexOf(this.env.blankpage)<0)d.location.href=this.env.blankpage}else if(!bw.safari&&!bw.konq)b[a?
+"show":"hide"]();!a&&this.busy&&this.set_busy(!1,null,this.env.frame_lock)};this.list_page=function(a){a=="next"?a=this.env.current_page+1:a=="last"?a=this.env.pagecount:a=="prev"&&this.env.current_page>1?a=this.env.current_page-1:a=="first"&&this.env.current_page>1&&(a=1);if(a>0&&a<=this.env.pagecount)this.env.current_page=a,this.task=="mail"?this.list_mailbox(this.env.mailbox,a):this.task=="addressbook"&&this.list_contacts(this.env.source,this.env.group,a)};this.filter_mailbox=function(a){var b,
+d=this.set_busy(!0,"searching");if(this.gui_objects.qsearchbox)b=this.gui_objects.qsearchbox.value;this.clear_message_list();this.env.current_page=1;this.http_request("search","_filter="+a+(b?"&_q="+urlencode(b):"")+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):""),d)};this.list_mailbox=function(a,b,d,e){var f="",g=window;a||(a=this.env.mailbox?this.env.mailbox:"INBOX");e&&(f+=e);d&&(f+="&_sort="+d);this.env.search_request&&(f+="&_search="+this.env.search_request);if(this.env.mailbox!=a)b=
+1,this.env.current_page=b,this.select_all_mode=!1;this.clear_message_list();if(a!=this.env.mailbox||a==this.env.mailbox&&!b&&!d)f+="&_refresh=1";this.select_folder(a,this.env.mailbox);this.env.mailbox=a;if(this.gui_objects.messagelist)this.list_mailbox_remote(a,b,f);else if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]&&(g=window.frames[this.env.contentframe],f+="&_framed=1"),a)this.set_busy(!0,"loading"),g.location.href=this.env.comm_path+"&_mbox="+urlencode(a)+(b?"&_page="+
+b:"")+f};this.clear_message_list=function(){this.env.messages={};this.last_selected=0;this.show_contentframe(!1);this.message_list&&this.message_list.clear(!0)};this.list_mailbox_remote=function(a,b,d){this.message_list.clear();a="_mbox="+urlencode(a)+(b?"&_page="+b:"");b=this.set_busy(!0,"loading");this.http_request("list",a+d,b)};this.update_selection=function(){var a=this.message_list.selection,b=this.message_list.rows,d,e=[];for(d in a)b[a[d]]&&e.push(a[d]);this.message_list.selection=e};this.expand_unread=
+function(){for(var a,b=this.gui_objects.messagelist.tBodies[0].firstChild;b;){if(b.nodeType==1&&(a=this.message_list.rows[b.uid])&&a.unread_children)this.message_list.expand_all(a),this.set_unread_children(a.uid);b=b.nextSibling}return!1};this.expand_message_row=function(a,b){var d=this.message_list.rows[b];d.expanded=!d.expanded;this.set_unread_children(b);d.expanded=!d.expanded;this.message_list.expand_row(a,b)};this.expand_threads=function(){if(this.env.threading&&this.env.autoexpand_threads&&
+this.message_list)switch(this.env.autoexpand_threads){case 2:this.expand_unread();break;case 1:this.message_list.expand_all()}};this.init_threads=function(a){for(var b=0,d=a.length;b<d;b++)this.add_tree_icons(a[b]);this.expand_threads()};this.add_tree_icons=function(a){var b,d,e,f,g=[],h=[],l,k=this.message_list.rows;for(l=a?k[a]?k[a].obj:null:this.message_list.list.tBodies[0].firstChild;l;){if(l.nodeType==1&&(d=k[l.uid]))if(d.depth){for(b=g.length-1;b>=0;b--)if(e=g[b].length,e>d.depth?(f=e-d.depth,
+g[b][f]&2||(g[b][f]=g[b][f]?g[b][f]+2:2)):e==d.depth&&(g[b][0]&2||(g[b][0]+=2)),d.depth>e)break;g.push(Array(d.depth));g[g.length-1][0]=1;h.push(d.uid)}else{if(g.length){for(b in g)this.set_tree_icons(h[b],g[b]);g=[];h=[]}if(a&&l!=k[a].obj)break}l=l.nextSibling}if(g.length)for(b in g)this.set_tree_icons(h[b],g[b])};this.set_tree_icons=function(a,b){var d,e=[],f="",g=b.length;for(d=0;d<g;d++)b[d]>2?e.push({"class":"l3",width:15}):b[d]>1?e.push({"class":"l2",width:15}):b[d]>0?e.push({"class":"l1",width:15}):
+e.length&&!e[e.length-1]["class"]?e[e.length-1].width+=15:e.push({"class":null,width:15});for(d=e.length-1;d>=0;d--)f+=e[d]["class"]?'<div class="tree '+e[d]["class"]+'" />':'<div style="width:'+e[d].width+'px" />';f&&$("#rcmtab"+a).html(f)};this.update_thread_root=function(a,b){if(this.env.threading){var d=this.message_list.find_root(a);if(a!=d){var e=this.message_list.rows[d];if(b=="read"&&e.unread_children)e.unread_children--;else if(b=="unread"&&e.has_children)e.unread_children=e.unread_children?
+e.unread_children+1:1;else return;this.set_message_icon(d);this.set_unread_children(d)}}};this.update_thread=function(a){if(!this.env.threading)return 0;var b,d=0,e=this.message_list.rows,f=e[a],g=e[a].depth,h=[];f.depth?f.unread&&(a=this.message_list.find_root(a),e[a].unread_children--,this.set_unread_children(a)):d--;a=f.parent_uid;for(f=f.obj.nextSibling;f;){if(f.nodeType==1&&(b=e[f.uid])){if(!b.depth||b.depth<=g)break;b.depth--;$("#rcmtab"+b.uid).width(b.depth*15).html("");if(b.depth){if(b.depth==
+g)b.parent_uid=a;b.unread&&h.length&&h[h.length-1].unread_children++}else{d++;b.parent_uid=0;if(b.has_children)$("#rcmrow"+b.uid+" .leaf:first").attr("id","rcmexpando"+b.uid).attr("class",b.obj.style.display!="none"?"expanded":"collapsed").bind("mousedown",{uid:b.uid,p:this},function(a){return a.data.p.expand_message_row(a,a.data.uid)}),b.unread_children=0,h.push(b);b.obj.style.display=="none"&&$(b.obj).show()}}f=f.nextSibling}for(b=0;b<h.length;b++)this.set_unread_children(h[b].uid);return d};this.delete_excessive_thread_rows=
+function(){for(var a=this.message_list.rows,b=this.message_list.list.tBodies[0].firstChild,d=this.env.pagesize+1;b;){if(b.nodeType==1&&(r=a[b.uid]))!r.depth&&d&&d--,d||this.message_list.remove_row(b.uid);b=b.nextSibling}};this.set_message_icon=function(a){var b=this.message_list.rows[a];if(!b)return!1;if(b.icon)a="msgicon",b.deleted?a+=" deleted":b.unread?a+=" unread":b.unread_children&&(a+=" unreadchildren"),b.msgicon==b.icon&&(b.replied&&(a+=" replied"),b.forwarded&&(a+=" forwarded"),a+=" status"),
+b.icon.className=a;if(b.msgicon&&b.msgicon!=b.icon)a="msgicon",!b.unread&&b.unread_children&&(a+=" unreadchildren"),b.replied&&(a+=" replied"),b.forwarded&&(a+=" forwarded"),b.msgicon.className=a;if(b.flagicon)a=b.flagged?"flagged":"unflagged",b.flagicon.className=a};this.set_message_status=function(a,b,d){a=this.message_list.rows[a];if(!a)return!1;if(b=="unread")a.unread=d;else if(b=="deleted")a.deleted=d;else if(b=="replied")a.replied=d;else if(b=="forwarded")a.forwarded=d;else if(b=="flagged")a.flagged=
+d};this.set_message=function(a,b,d){var e=this.message_list.rows[a];if(!e)return!1;b&&this.set_message_status(a,b,d);b=$(e.obj);e.unread&&!b.hasClass("unread")?b.addClass("unread"):!e.unread&&b.hasClass("unread")&&b.removeClass("unread");e.deleted&&!b.hasClass("deleted")?b.addClass("deleted"):!e.deleted&&b.hasClass("deleted")&&b.removeClass("deleted");e.flagged&&!b.hasClass("flagged")?b.addClass("flagged"):!e.flagged&&b.hasClass("flagged")&&b.removeClass("flagged");this.set_unread_children(a);this.set_message_icon(a)};
+this.set_unread_children=function(a){a=this.message_list.rows[a];a.parent_uid||(!a.unread&&a.unread_children&&!a.expanded?$(a.obj).addClass("unroot"):$(a.obj).removeClass("unroot"))};this.copy_messages=function(a){if(a&&typeof a=="object")a=a.id;if(a&&!(a==this.env.mailbox||!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){var b=[],d=this.display_message(this.get_label("copyingmessage"),"loading"),a="&_target_mbox="+urlencode(a)+"&_from="+(this.env.action?this.env.action:
+"");if(this.env.uid)b[0]=this.env.uid;else{var e=this.message_list.get_selection(),f;for(f in e)b.push(e[f])}a+="&_uid="+this.uids_to_list(b);this.http_post("copy","_mbox="+urlencode(this.env.mailbox)+a,d)}};this.move_messages=function(a){if(a&&typeof a=="object")a=a.id;if(a&&!(a==this.env.mailbox||!this.env.uid&&(!this.message_list||!this.message_list.get_selection().length))){var b=!1,a="&_target_mbox="+urlencode(a)+"&_from="+(this.env.action?this.env.action:"");this.env.action=="show"?b=this.set_busy(!0,
+"movingmessage"):this.show_contentframe(!1);this.enable_command(this.env.message_commands,!1);this._with_selected_messages("moveto",b,a)}};this.delete_messages=function(){var a=this.message_list?$.merge([],this.message_list.get_selection()):[];if(this.env.uid||a.length){for(var b,d=0,e=a.length;d<e;d++)b=a[d],this.message_list.rows[b].has_children&&!this.message_list.rows[b].expanded&&this.message_list.select_childs(b);if(this.env.flag_for_deletion)return this.mark_message("delete"),!1;else!this.env.trash_mailbox||
+this.env.mailbox==this.env.trash_mailbox?this.permanently_remove_messages():this.message_list&&this.message_list.shiftkey?confirm(this.get_label("deletemessagesconfirm"))&&this.permanently_remove_messages():this.move_messages(this.env.trash_mailbox);return!0}};this.permanently_remove_messages=function(){if(this.env.uid||this.message_list&&this.message_list.get_selection().length)this.show_contentframe(!1),this._with_selected_messages("delete",!1,"&_from="+(this.env.action?this.env.action:""))};this._with_selected_messages=
+function(a,b,d){var e=[],f=0;if(this.env.uid)e[0]=this.env.uid;else{var g,h,j,k=[],n=this.message_list.get_selection();g=0;for(len=n.length;g<len;g++)h=n[g],e.push(h),this.env.threading&&(f+=this.update_thread(h),j=this.message_list.find_root(h),j!=h&&$.inArray(j,k)<0&&k.push(j)),this.message_list.remove_row(h,this.env.display_next&&g==n.length-1);this.env.display_next||this.message_list.clear_selection();g=0;for(len=k.length;g<len;g++)this.add_tree_icons(k[g])}this.env.search_request&&(d+="&_search="+
+this.env.search_request);this.env.display_next&&this.env.next_uid&&(d+="&_next_uid="+this.env.next_uid);f<0?d+="&_count="+f*-1:f>0&&this.delete_excessive_thread_rows();d+="&_uid="+this.uids_to_list(e);b||(b=this.display_message(this.get_label(a=="moveto"?"movingmessage":"deletingmessage"),"loading"));this.http_post(a,"_mbox="+urlencode(this.env.mailbox)+d,b)};this.mark_message=function(a,b){var d=[],e=[],f,g,h;h=this.message_list?this.message_list.get_selection():[];if(b)d[0]=b;else if(this.env.uid)d[0]=
+this.env.uid;else if(this.message_list){g=0;for(f=h.length;g<f;g++)d.push(h[g])}if(this.message_list){g=0;for(f=d.length;g<f;g++)h=d[g],(a=="read"&&this.message_list.rows[h].unread||a=="unread"&&!this.message_list.rows[h].unread||a=="delete"&&!this.message_list.rows[h].deleted||a=="undelete"&&this.message_list.rows[h].deleted||a=="flagged"&&!this.message_list.rows[h].flagged||a=="unflagged"&&this.message_list.rows[h].flagged)&&e.push(h)}else e=d;if(e.length||this.select_all_mode)switch(a){case "read":case "unread":this.toggle_read_status(a,
+e);break;case "delete":case "undelete":this.toggle_delete_status(e);break;case "flagged":case "unflagged":this.toggle_flagged_status(a,d)}};this.toggle_read_status=function(a,b){for(var d=0;d<b.length;d++)this.set_message(b[d],"unread",a=="unread"?!0:!1);var d="_uid="+this.uids_to_list(b)+"&_flag="+a,e=this.display_message(this.get_label("markingmessage"),"loading");this.env.search_request&&(d+="&_search="+this.env.search_request);this.http_post("mark",d,e);for(d=0;d<b.length;d++)this.update_thread_root(b[d],
+a)};this.toggle_flagged_status=function(a,b){for(var d=0;d<b.length;d++)this.set_message(b[d],"flagged",a=="flagged"?!0:!1);var d="_uid="+this.uids_to_list(b)+"&_flag="+a,e=this.display_message(this.get_label("markingmessage"),"loading");this.env.search_request&&(d+="&_search="+this.env.search_request);this.http_post("mark",d,e)};this.toggle_delete_status=function(a){var b=this.message_list?this.message_list.rows:[];if(a.length==1)return!b.length||b[a[0]]&&!b[a[0]].deleted?this.flag_as_deleted(a):
+this.flag_as_undeleted(a),!0;for(var d,e=!0,f=0,g=a.length;f<g;f++)if(d=a[f],b[d]&&!b[d].deleted){e=!1;break}e?this.flag_as_undeleted(a):this.flag_as_deleted(a);return!0};this.flag_as_undeleted=function(a){for(var b=0,d=a.length;b<d;b++)this.set_message(a[b],"deleted",!1);a="_uid="+this.uids_to_list(a)+"&_flag=undelete";b=this.display_message(this.get_label("markingmessage"),"loading");this.env.search_request&&(a+="&_search="+this.env.search_request);this.http_post("mark",a,b);return!0};this.flag_as_deleted=
+function(a){for(var b="",d=[],b=this.message_list?this.message_list.rows:[],e=0,f=0,g=a.length;f<g;f++)uid=a[f],b[uid]&&(b[uid].unread&&(d[d.length]=uid),this.env.skip_deleted?(e+=this.update_thread(uid),this.message_list.remove_row(uid,this.env.display_next&&f==this.message_list.selection.length-1)):this.set_message(uid,"deleted",!0));this.env.skip_deleted&&this.message_list&&(this.env.display_next||this.message_list.clear_selection(),e<0||e>0&&this.delete_excessive_thread_rows());b="&_from="+(this.env.action?
+this.env.action:"");lock=this.display_message(this.get_label("markingmessage"),"loading");d.length&&(b+="&_ruid="+this.uids_to_list(d));this.env.skip_deleted&&this.env.display_next&&this.env.next_uid&&(b+="&_next_uid="+this.env.next_uid);this.env.search_request&&(b+="&_search="+this.env.search_request);this.http_post("mark","_uid="+this.uids_to_list(a)+"&_flag=delete"+b,lock);return!0};this.flag_deleted_as_read=function(a){for(var b=this.message_list?this.message_list.rows:[],d=String(a).split(","),
+e=0;e<d.length;e++)a=d[e],b[a]&&this.set_message(a,"unread",!1)};this.uids_to_list=function(a){return this.select_all_mode?"*":a.join(",")};this.expunge_mailbox=function(a){var b=!1,d="_mbox="+urlencode(a);a==this.env.mailbox&&(b=this.set_busy(!0,"loading"),d+="&_reload=1");this.http_post("expunge",d,b)};this.purge_mailbox=function(a){var b=!1,d="_mbox="+urlencode(a);if(!confirm(this.get_label("purgefolderconfirm")))return!1;a==this.env.mailbox&&(b=this.set_busy(!0,"loading"),d+="&_reload=1");this.http_post("purge",
+d,b)};this.purge_mailbox_test=function(){return this.env.messagecount&&(this.env.mailbox==this.env.trash_mailbox||this.env.mailbox==this.env.junk_mailbox||this.env.mailbox.match("^"+RegExp.escape(this.env.trash_mailbox)+RegExp.escape(this.env.delimiter))||this.env.mailbox.match("^"+RegExp.escape(this.env.junk_mailbox)+RegExp.escape(this.env.delimiter)))};this.login_user_keyup=function(a){var b=rcube_event.get_keycode(a),d=$("#rcmloginpwd");if(b==13&&d.length&&!d.val())return d.focus(),rcube_event.cancel(a);
+return!0};this.init_messageform=function(){if(!this.gui_objects.messageform)return!1;var a=$("[name='_from']"),b=$("[name='_to']"),d=$("input[name='_subject']"),e=$("[name='_message']").get(0),f=$("input[name='_is_html']").val()=="1",g=["cc","bcc","replyto","followupto"];this.init_address_input_events(b);for(var h in g)this.init_address_input_events($("[name='_"+g[h]+"']"));f||(this.set_caret_pos(e,this.env.top_posting?0:$(e).val().length),a.attr("type")=="select-one"&&$("input[name='_draft_saveid']").val()==
+""&&this.change_identity(a[0]));b.val()==""?b.focus():d.val()==""?d.focus():e&&e.focus();this.env.compose_focus_elem=document.activeElement;this.compose_field_hash(!0);this.auto_save_start()};this.init_address_input_events=function(a){a[bw.ie||bw.safari||bw.chrome?"keydown":"keypress"](function(a){return j.ksearch_keydown(a,this)}).attr("autocomplete","off")};this.check_compose_input=function(){var a,b=$("[name='_to']"),d=$("[name='_cc']"),e=$("[name='_bcc']"),f=$("[name='_from']"),g=$("[name='_subject']"),
+h=$("[name='_message']");if(f.attr("type")=="text"&&!rcube_check_email(f.val(),!0))return alert(this.get_label("nosenderwarning")),f.focus(),!1;d=b.val()?b.val():d.val()?d.val():e.val();if(!rcube_check_email(d.replace(/^\s+/,"").replace(/[\s,;]+$/,""),!0))return alert(this.get_label("norecipientwarning")),b.focus(),!1;for(var j in this.env.attachments)if(typeof this.env.attachments[j]=="object"&&!this.env.attachments[j].complete)return alert(this.get_label("notuploadedwarning")),!1;if(g.val()=="")if(b=
+prompt(this.get_label("nosubjectwarning"),this.get_label("nosubject")),!b&&b!=="")return g.focus(),!1;else g.val(b?b:this.get_label("nosubject"));this.stop_spellchecking();window.tinyMCE&&(a=tinyMCE.get(this.env.composebody));if(!a&&h.val()==""&&!confirm(this.get_label("nobodywarning")))return h.focus(),!1;else if(a){if(!a.getContent()&&!confirm(this.get_label("nobodywarning")))return a.focus(),!1;tinyMCE.triggerSave()}return!0};this.toggle_editor=function(a){if(a.mode=="html")this.display_spellcheck_controls(!1),
+this.plain2html($("#"+a.id).val(),a.id),tinyMCE.execCommand("mceAddControl",!1,a.id);else{var b=tinyMCE.get(a.id);b.plugins.spellchecker&&b.plugins.spellchecker.active&&b.execCommand("mceSpellCheck",!1);if(b=b.getContent()){if(!confirm(this.get_label("editorwarning")))return!1;this.html2plain(b,a.id)}tinyMCE.execCommand("mceRemoveControl",!1,a.id);this.display_spellcheck_controls(!0)}return!0};this.stop_spellchecking=function(){var a;if(window.tinyMCE&&(a=tinyMCE.get(this.env.composebody)))a.plugins.spellchecker&&
+a.plugins.spellchecker.active&&a.execCommand("mceSpellCheck");else if((a=this.env.spellcheck)&&!this.spellcheck_ready)$(a.spell_span).trigger("click"),this.set_spellcheck_state("ready")};this.display_spellcheck_controls=function(a){this.env.spellcheck&&(a||this.stop_spellchecking(),$(this.env.spellcheck.spell_container).css("visibility",a?"visible":"hidden"))};this.set_spellcheck_state=function(a){this.spellcheck_ready=a=="ready"||a=="no_error_found";this.enable_command("spellcheck",this.spellcheck_ready)};
+this.set_draft_id=function(a){$("input[name='_draft_saveid']").val(a)};this.auto_save_start=function(){if(this.env.draft_autosave)this.save_timer=self.setTimeout(function(){j.command("savedraft")},this.env.draft_autosave*1E3);this.busy=!1};this.compose_field_hash=function(a){var b,d="",e=$("[name='_to']").val(),f=$("[name='_cc']").val(),g=$("[name='_bcc']").val(),h=$("[name='_subject']").val();e&&(d+=e+":");f&&(d+=f+":");g&&(d+=g+":");h&&(d+=h+":");d+=window.tinyMCE&&(b=tinyMCE.get(this.env.composebody))?
+b.getContent():$("[name='_message']").val();if(this.env.attachments)for(var j in this.env.attachments)d+=j;if(a)this.cmp_hash=d;return d};this.change_identity=function(a,b){if(!a||!a.options)return!1;if(!b)b=this.env.show_sig;var d,e=-1,f=a.options[a.selectedIndex].value,g=$("[name='_message']"),h=g.val(),j=$("input[name='_is_html']").val()=="1",k=this.env.identity;d=this.env.sig_above&&(this.env.compose_mode=="reply"||this.env.compose_mode=="forward")?"---":"-- ";this.env.signatures&&this.env.signatures[f]?
+(this.enable_command("insert-sig",!0),this.env.compose_commands.push("insert-sig")):this.enable_command("insert-sig",!1);if(j){if(b&&this.env.signatures&&(e=tinyMCE.get(this.env.composebody),g=e.dom.get("_rc_sig"),g||(k=e.getBody(),h=e.getDoc(),g=h.createElement("div"),g.setAttribute("id","_rc_sig"),this.env.sig_above?(e.getWin().focus(),e=e.selection.getNode(),e.nodeName=="BODY"?(k.insertBefore(g,k.firstChild),k.insertBefore(h.createElement("br"),k.firstChild)):(k.insertBefore(g,e.nextSibling),k.insertBefore(h.createElement("br"),
+e.nextSibling))):(bw.ie&&k.appendChild(h.createElement("br")),k.appendChild(g))),this.env.signatures[f]))this.env.signatures[f].is_html?(k=this.env.signatures[f].text,this.env.signatures[f].plain_text.match(/^--[ -]\r?\n/)||(k=d+"<br />"+k)):(k=this.env.signatures[f].text,k.match(/^--[ -]\r?\n/)||(k=d+"\n"+k),k="<pre>"+k+"</pre>"),g.innerHTML=k}else b&&k&&this.env.signatures&&this.env.signatures[k]&&(k=this.env.signatures[k].is_html?this.env.signatures[k].plain_text:this.env.signatures[k].text,k=
+k.replace(/\r\n/g,"\n"),k.match(/^--[ -]\n/)||(k=d+"\n"+k),e=this.env.sig_above?h.indexOf(k):h.lastIndexOf(k),e>=0&&(h=h.substring(0,e)+h.substring(e+k.length,h.length))),b&&this.env.signatures&&this.env.signatures[f]?(k=this.env.signatures[f].is_html?this.env.signatures[f].plain_text:this.env.signatures[f].text,k=k.replace(/\r\n/g,"\n"),k.match(/^--[ -]\n/)||(k=d+"\n"+k),this.env.sig_above?e>=0?(h=h.substring(0,e)+k+h.substring(e,h.length),d=e-1):(pos=this.get_caret_pos(g.get(0)))?(h=h.substring(0,
+pos)+"\n"+k+"\n\n"+h.substring(pos,h.length),d=pos):(d=0,h="\n\n"+k+"\n\n"+h.replace(/^[\r\n]+/,"")):(h=h.replace(/[\r\n]+$/,""),d=!this.env.top_posting&&h.length?h.length+1:0,h+="\n\n"+k)):d=this.env.top_posting?0:h.length,g.val(h),this.set_caret_pos(g.get(0),d);this.env.identity=f;return!0};this.upload_file=function(a){if(!a)return!1;for(var b=!1,d=0;d<a.elements.length;d++)if(a.elements[d].type=="file"&&a.elements[d].value){b=!0;break}if(b){b=(new Date).getTime();d="rcmupload"+b;if(document.all)document.body.insertAdjacentHTML("BeforeEnd",
+'<iframe name="'+d+'" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>');else{var e=document.createElement("iframe");e.name=d;e.style.border="none";e.style.width=0;e.style.height=0;e.style.visibility="hidden";document.body.appendChild(e)}$(d).bind("load",{ts:b},function(a){var b,d="";try{if(this.contentDocument)b=this.contentDocument;else if(this.contentWindow)b=this.contentWindow.document;d=b.childNodes[0].innerHTML}catch(e){}if(!d.match(/add2attachment/)&&(!bw.opera||
+rcmail.env.uploadframe&&rcmail.env.uploadframe==a.data.ts))d.match(/display_message/)||rcmail.display_message(rcmail.get_label("fileuploaderror"),"error"),rcmail.remove_from_attachment_list(a.data.ts);if(bw.opera)rcmail.env.uploadframe=a.data.ts});a.target=d;a.action=this.env.comm_path+"&_action=upload&_uploadid="+b;a.setAttribute("enctype","multipart/form-data");a.submit();e=this.get_label("uploading");this.env.loadingicon&&(e='<img src="'+this.env.loadingicon+'" alt="" />'+e);this.env.cancelicon&&
+(e='<a title="'+this.get_label("cancel")+'" onclick="return rcmail.cancel_attachment_upload(\''+b+"', '"+d+'\');" href="#cancelupload"><img src="'+this.env.cancelicon+'" alt="" /></a>'+e);this.add2attachment_list(b,{name:"",html:e,complete:!1})}this.gui_objects.attachmentform=a;return!0};this.add2attachment_list=function(a,b,d){if(!this.gui_objects.attachmentlist)return!1;var e=$("<li>").attr("id",a).html(b.html),f;d&&(f=document.getElementById(d))?e.replaceAll(f):e.appendTo(this.gui_objects.attachmentlist);
+d&&this.env.attachments[d]&&delete this.env.attachments[d];this.env.attachments[a]=b;return!0};this.remove_from_attachment_list=function(a){this.env.attachments[a]&&delete this.env.attachments[a];if(!this.gui_objects.attachmentlist)return!1;var b=this.gui_objects.attachmentlist.getElementsByTagName("li");for(i=0;i<b.length;i++)b[i].id==a&&this.gui_objects.attachmentlist.removeChild(b[i])};this.remove_attachment=function(a){a&&this.env.attachments[a]&&this.http_post("remove-attachment","_file="+urlencode(a));
+return!0};this.cancel_attachment_upload=function(a,b){if(!a||!b)return!1;this.remove_from_attachment_list(a);$("iframe[name='"+b+"']").remove();return!1};this.add_contact=function(a){a&&this.http_post("addcontact","_address="+a);return!0};this.qsearch=function(a){if(a!=""){var b="";if(this.message_list){if(this.clear_message_list(),this.env.search_mods){var d=this.env.search_mods[this.env.mailbox]?this.env.search_mods[this.env.mailbox]:this.env.search_mods["*"];if(d){var e=[],f;for(f in d)e.push(f);
+b+="&_headers="+e.join(",")}}}else this.contact_list&&(this.contact_list.clear(!0),this.show_contentframe(!1));this.gui_objects.search_filter&&(b+="&_filter="+this.gui_objects.search_filter.value);this.env.current_page=1;d=this.set_busy(!0,"searching");this.http_request("search","_q="+urlencode(a)+(this.env.mailbox?"&_mbox="+urlencode(this.env.mailbox):"")+(this.env.source?"&_source="+urlencode(this.env.source):"")+(this.env.group?"&_gid="+urlencode(this.env.group):"")+(b?b:""),d)}return!0};this.reset_qsearch=
+function(){if(this.gui_objects.qsearchbox)this.gui_objects.qsearchbox.value="";this.env.search_request=null;return!0};this.sent_successfully=function(a,b){this.display_message(b,a);window.setTimeout(function(){j.list_mailbox()},500)};this.ksearch_keydown=function(a,b){this.ksearch_timer&&clearTimeout(this.ksearch_timer);var d;d=rcube_event.get_keycode(a);var e=rcube_event.get_modifier(a);switch(d){case 38:case 40:if(!this.ksearch_pane)break;e=d==38?1:0;d=document.getElementById("rcmksearchSelected");
+if(!d)d=this.ksearch_pane.__ul.firstChild;d&&this.ksearch_select(e?d.previousSibling:d.nextSibling);return rcube_event.cancel(a);case 9:if(e==SHIFT_KEY)break;case 13:if(this.ksearch_selected===null||!this.ksearch_input||!this.ksearch_value)break;this.insert_recipient(this.ksearch_selected);this.ksearch_hide();return rcube_event.cancel(a);case 27:this.ksearch_hide();break;case 37:case 39:if(e!=SHIFT_KEY)return}this.ksearch_timer=window.setTimeout(function(){j.ksearch_get_results()},200);this.ksearch_input=
+b;return!0};this.ksearch_select=function(a){var b=$("#rcmksearchSelected");b[0]&&a&&b.removeAttr("id").removeClass("selected");if(a)$(a).attr("id","rcmksearchSelected").addClass("selected"),this.ksearch_selected=a._rcm_id};this.insert_recipient=function(a){if(this.env.contacts[a]&&this.ksearch_input){var b=this.ksearch_input.value,d=this.get_caret_pos(this.ksearch_input),d=b.lastIndexOf(this.ksearch_value,d),e="",f=b.substring(0,d),b=b.substring(d+this.ksearch_value.length,b.length);typeof this.env.contacts[a]==
+"object"&&this.env.contacts[a].id?(e+=this.env.contacts[a].name+", ",this.group2expand=$.extend({},this.env.contacts[a]),this.group2expand.input=this.ksearch_input,this.http_request("group-expand","_source="+urlencode(this.env.contacts[a].source)+"&_gid="+urlencode(this.env.contacts[a].id),!1)):typeof this.env.contacts[a]=="string"&&(e=this.env.contacts[a]+", ");this.ksearch_input.value=f+e+b;d+=e.length;this.ksearch_input.setSelectionRange&&this.ksearch_input.setSelectionRange(d,d)}};this.replace_group_recipients=
+function(a,b){if(this.group2expand&&this.group2expand.id==a)this.group2expand.input.value=this.group2expand.input.value.replace(this.group2expand.name,b),this.group2expand=null};this.ksearch_get_results=function(){var a=this.ksearch_input?this.ksearch_input.value:null;if(a!==null){this.ksearch_pane&&this.ksearch_pane.is(":visible")&&this.ksearch_pane.hide();var b=this.get_caret_pos(this.ksearch_input),d=a.lastIndexOf(",",b-1),a=a.substring(d+1,b),b=this.env.autocomplete_min_length,a=$.trim(a);if(a!=
+this.ksearch_value)if(a.length<b){if(!this.env.acinfo)a=this.get_label("autocompletechars"),a=a.replace("$min",b),this.env.acinfo=this.display_message(a)}else if(this.env.acinfo&&a.length==b&&this.hide_message(this.env.acinfo),b=this.ksearch_value,this.ksearch_value=a,a.length&&(!b||!b.length||!this.env.contacts||this.env.contacts.length||a.indexOf(b)!=0))b=this.display_message(this.get_label("searching"),"loading"),this.http_post("autocomplete","_search="+urlencode(a),b)}};this.ksearch_query_results=
+function(a,b){if(!(this.ksearch_value&&b!=this.ksearch_value))this.env.contacts=a?a:[],this.ksearch_display_results(this.env.contacts)};this.ksearch_display_results=function(a){if(a.length&&this.ksearch_input&&this.ksearch_value){var b,d,e,f=this.ksearch_value;if(!this.ksearch_pane)b=$("<ul>"),this.ksearch_pane=$("<div>").attr("id","rcmKSearchpane").css({position:"absolute","z-index":3E4}).append(b).appendTo(document.body),this.ksearch_pane.__ul=b[0];b=this.ksearch_pane.__ul;b.innerHTML="";for(i=
+0;i<a.length;i++)e=typeof a[i]=="object"?a[i].name:a[i],d=document.createElement("LI"),d.innerHTML=e.replace(RegExp("("+RegExp.escape(f)+")","ig"),"##$1%%").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/##([^%]+)%%/g,"<b>$1</b>"),d.onmouseover=function(){j.ksearch_select(this)},d.onmouseup=function(){j.ksearch_click(this)},d._rcm_id=i,b.appendChild(d);$(b.firstChild).attr("id","rcmksearchSelected").addClass("selected");this.ksearch_selected=0;a=$(this.ksearch_input).offset();this.ksearch_pane.css({left:a.left+
+"px",top:a.top+this.ksearch_input.offsetHeight+"px"}).show()}else this.ksearch_hide()};this.ksearch_click=function(a){this.ksearch_input&&this.ksearch_input.focus();this.insert_recipient(a._rcm_id);this.ksearch_hide()};this.ksearch_blur=function(){this.ksearch_timer&&clearTimeout(this.ksearch_timer);this.ksearch_value="";this.ksearch_input=null;this.ksearch_hide()};this.ksearch_hide=function(){this.ksearch_selected=null;this.ksearch_pane&&this.ksearch_pane.hide()};this.contactlist_keypress=function(a){a.key_pressed==
+a.DELETE_KEY&&this.command("delete")};this.contactlist_select=function(a){this.preview_timer&&clearTimeout(this.preview_timer);var b,d=this;(b=a.get_single_selection())?this.preview_timer=window.setTimeout(function(){d.load_contact(b,"show")},200):this.env.contentframe&&this.show_contentframe(!1);this.enable_command("compose",a.selection.length>0);this.enable_command("edit",b&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly?!0:!1);this.enable_command("delete",a.selection.length&&
+this.env.address_sources&&!this.env.address_sources[this.env.source].readonly);return!1};this.list_contacts=function(a,b,d){var e="",f=window;if(!a)a=this.env.source;if(d&&this.current_page==d&&a==this.env.source&&b==this.env.group)return!1;if(a!=this.env.source)d=this.env.current_page=1,this.reset_qsearch();else if(b!=this.env.group)d=this.env.current_page=1;this.select_folder(b?"G"+a+b:a,this.env.group?"G"+this.env.source+this.env.group:this.env.source);this.env.source=a;this.env.group=b;this.gui_objects.contactslist?
+this.list_contacts_remote(a,b,d):(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]&&(f=window.frames[this.env.contentframe],e="&_framed=1"),b&&(e+="&_gid="+b),d&&(e+="&_page="+d),this.env.search_request&&(e+="&_search="+this.env.search_request),this.set_busy(!0,"loading"),f.location.href=this.env.comm_path+(a?"&_source="+urlencode(a):"")+e)};this.list_contacts_remote=function(a,b,d){this.contact_list.clear(!0);this.show_contentframe(!1);this.enable_command("delete","compose",
+!1);var d=(a?"_source="+urlencode(a):"")+(d?(a?"&":"")+"_page="+d:""),e=this.set_busy(!0,"loading");this.env.source=a;(this.env.group=b)&&(d+="&_gid="+b);this.env.search_request&&(d+="&_search="+this.env.search_request);this.http_request("list",d,e)};this.load_contact=function(a,b,d){var e="",f=window;if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe])e="&_framed=1",f=window.frames[this.env.contentframe],this.show_contentframe(!0);else if(d)return!1;if(b&&(a||b=="add")&&
+!this.drag_active)this.env.group&&(e+="&_gid="+urlencode(this.env.group)),this.set_busy(!0),f.location.href=this.env.comm_path+"&_action="+b+"&_source="+urlencode(this.env.source)+"&_cid="+urlencode(a)+e;return!0};this.copy_contact=function(a,b){a||(a=this.contact_list.get_selection().join(","));b.type=="group"&&b.source==this.env.source?this.http_post("group-addmembers","_cid="+urlencode(a)+"&_source="+urlencode(this.env.source)+"&_gid="+urlencode(b.id)):b.type=="group"&&!this.env.address_sources[b.source].readonly?
+this.http_post("copy","_cid="+urlencode(a)+"&_source="+urlencode(this.env.source)+"&_to="+urlencode(b.source)+"&_togid="+urlencode(b.id)+(this.env.group?"&_gid="+urlencode(this.env.group):"")):b.id!=this.env.source&&a&&this.env.address_sources[b.id]&&!this.env.address_sources[b.id].readonly&&this.http_post("copy","_cid="+urlencode(a)+"&_source="+urlencode(this.env.source)+"&_to="+urlencode(b.id)+(this.env.group?"&_gid="+urlencode(this.env.group):""))};this.delete_contacts=function(){var a=this.contact_list.get_selection();
+if((a.length||this.env.cid)&&confirm(this.get_label("deletecontactconfirm"))){var b,d=[],e="";if(this.env.cid)d.push(this.env.cid);else{for(var f=0;f<a.length;f++)b=a[f],d.push(b),this.contact_list.remove_row(b,f==a.length-1);a.length==1&&this.show_contentframe(!1)}this.env.group&&(e+="&_gid="+urlencode(this.env.group));this.env.search_request&&(e+="&_search="+this.env.search_request);this.http_post("delete","_cid="+urlencode(d.join(","))+"&_source="+urlencode(this.env.source)+"&_from="+(this.env.action?
+this.env.action:"")+e);return!0}};this.update_contact_row=function(a,b,d){var e;if(this.contact_list.rows[a]&&(e=this.contact_list.rows[a].obj)){for(var f=0;f<b.length;f++)e.cells[f]&&$(e.cells[f]).html(b[f]);if(d)e.id="rcmrow"+d,this.contact_list.remove_row(a),this.contact_list.init_row(e),this.contact_list.selection[0]=d,e.style.display="";return!0}return!1};this.add_contact_row=function(a,b){if(!this.gui_objects.contactslist||!this.gui_objects.contactslist.tBodies[0])return!1;var d=this.gui_objects.contactslist.tBodies[0].rows.length%
+2,e=document.createElement("tr");e.id="rcmrow"+a;e.className="contact "+(d?"even":"odd");this.contact_list.in_selection(a)&&(e.className+=" selected");for(var f in b)col=document.createElement("td"),col.className=String(f).toLowerCase(),col.innerHTML=b[f],e.appendChild(col);this.contact_list.insert_row(e);this.enable_command("export",this.contact_list.rowcount>0)};this.group_create=function(){if(this.gui_objects.folderlist&&this.env.address_sources[this.env.source].groups){if(!this.name_input)this.name_input=
+$("<input>").attr("type","text"),this.name_input.bind("keydown",function(a){return rcmail.add_input_keydown(a)}),this.name_input_li=$("<li>").addClass("contactgroup").append(this.name_input),this.name_input_li.insertAfter(this.get_folder_li(this.env.source));this.name_input.select().focus()}};this.group_rename=function(){if(this.env.group&&this.gui_objects.folderlist){if(!this.name_input){this.enable_command("list","listgroup",!1);this.name_input=$("<input>").attr("type","text").val(this.env.contactgroups["G"+
+this.env.source+this.env.group].name);this.name_input.bind("keydown",function(a){return rcmail.add_input_keydown(a)});this.env.group_renaming=!0;var a,b=this.get_folder_li(this.env.source+this.env.group,"rcmliG");b&&(a=b.firstChild)&&$(a).hide().before(this.name_input)}this.name_input.select().focus()}};this.group_delete=function(){this.env.group&&this.http_post("group-delete","_source="+urlencode(this.env.source)+"&_gid="+urlencode(this.env.group),!0)};this.remove_group_item=function(a){var b,d=
+"G"+a.source+a.id;if(b=this.get_folder_li(d))this.triggerEvent("group_delete",{source:a.source,id:a.id,li:b}),b.parentNode.removeChild(b),delete this.env.contactfolders[d],delete this.env.contactgroups[d];this.list_contacts(a.source,0)};this.add_input_keydown=function(a){a=rcube_event.get_keycode(a);if(a==13){if(a=this.name_input.val()){var b=this.set_busy(!0,"loading");this.env.group_renaming?this.http_post("group-rename","_source="+urlencode(this.env.source)+"&_gid="+urlencode(this.env.group)+"&_name="+
+urlencode(a),b):this.http_post("group-create","_source="+urlencode(this.env.source)+"&_name="+urlencode(a),b)}return!1}else a==27&&this.reset_add_input();return!0};this.reset_add_input=function(){if(this.name_input){if(this.env.group_renaming)this.name_input.parent().children().last().show(),this.env.group_renaming=!1;this.name_input.remove();this.name_input_li&&this.name_input_li.remove();this.name_input=this.name_input_li=null}this.enable_command("list","listgroup",!0)};this.insert_contact_group=
+function(a){this.reset_add_input();a.type="group";var b="G"+a.source+a.id;this.env.contactfolders[b]=this.env.contactgroups[b]=a;var d=$("<a>").attr("href","#").bind("click",function(){return rcmail.command("listgroup",a,this)}).html(a.name),b=$("<li>").attr("id","rcmli"+b).addClass("contactgroup").append(d).insertAfter(this.get_folder_li(a.source));this.triggerEvent("group_insert",{id:a.id,source:a.source,name:a.name,li:b[0]})};this.update_contact_group=function(a){this.reset_add_input();var b="G"+
+a.source+a.id,d,e=this.get_folder_li(b);if(e&&(d=e.firstChild)&&d.tagName.toLowerCase()=="a")d.innerHTML=a.name;this.env.contactfolders[b].name=this.env.contactgroups[b].name=a.name;this.triggerEvent("group_update",{id:a.id,source:a.source,name:a.name,li:e[0]})};this.init_subscription_list=function(){var a=this;this.subscription_list=new rcube_list_widget(this.gui_objects.subscriptionlist,{multiselect:!1,draggable:!0,keyboard:!1,toggleselect:!0});this.subscription_list.addEventListener("select",function(b){a.subscription_select(b)});
+this.subscription_list.addEventListener("dragstart",function(){a.drag_active=!0});this.subscription_list.addEventListener("dragend",function(b){a.subscription_move_folder(b)});this.subscription_list.row_init=function(b){b.obj.onmouseover=function(){a.focus_subscription(b.id)};b.obj.onmouseout=function(){a.unfocus_subscription(b.id)}};this.subscription_list.init()};this.section_select=function(a){if(a=a.get_single_selection()){var b="",d=window;this.set_busy(!0);this.env.contentframe&&window.frames&&
+window.frames[this.env.contentframe]&&(b="&_framed=1",d=window.frames[this.env.contentframe]);d.location.href=this.env.comm_path+"&_action=edit-prefs&_section="+a+b}return!0};this.identity_select=function(a){var b;(b=a.get_single_selection())&&this.load_identity(b,"edit-identity")};this.load_identity=function(a,b){if(b=="edit-identity"&&(!a||a==this.env.iid))return!1;var d="",e=window;if(this.env.contentframe&&window.frames&&window.frames[this.env.contentframe])d="&_framed=1",e=window.frames[this.env.contentframe],
+document.getElementById(this.env.contentframe).style.visibility="inherit";if(b&&(a||b=="add-identity"))this.set_busy(!0),e.location.href=this.env.comm_path+"&_action="+b+"&_iid="+a+d;return!0};this.delete_identity=function(a){var b=this.identity_list.get_selection();if(b.length||this.env.iid)return a||(a=this.env.iid?this.env.iid:b[0]),this.goto_url("delete-identity","_iid="+a+"&_token="+this.env.request_token,!0),!0};this.focus_subscription=function(a){var b,d,e=RegExp.escape(this.env.delimiter),
+f=RegExp("["+e+"]?[^"+e+"]+$");if(this.drag_active&&this.env.mailbox&&(b=document.getElementById(a)))this.env.subscriptionrows[a]&&(d=this.env.subscriptionrows[a][0])?this.check_droptarget(d)&&!this.env.subscriptionrows[this.get_folder_row_id(this.env.mailbox)][2]&&d!=this.env.mailbox.replace(f,"")&&!d.match(RegExp("^"+RegExp.escape(this.env.mailbox+this.env.delimiter)))&&(this.set_env("dstfolder",d),$(b).addClass("droptarget")):this.env.mailbox.match(RegExp(e))&&(this.set_env("dstfolder",this.env.delimiter),
+$(this.subscription_list.frame).addClass("droptarget"))};this.unfocus_subscription=function(a){var b=$("#"+a);this.set_env("dstfolder",null);this.env.subscriptionrows[a]&&b[0]?b.removeClass("droptarget"):$(this.subscription_list.frame).removeClass("droptarget")};this.subscription_select=function(a){var b,d;a&&(b=a.get_single_selection())&&(d=this.env.subscriptionrows["rcmrow"+b])?(this.set_env("mailbox",d[0]),this.show_folder(d[0]),this.enable_command("delete-folder",!d[2])):(this.env.mailbox=null,
+this.show_contentframe(!1),this.enable_command("delete-folder","purge",!1))};this.subscription_move_folder=function(){var a=RegExp.escape(this.env.delimiter),b;this.env.mailbox&&this.env.dstfolder&&this.env.dstfolder!=this.env.mailbox&&this.env.dstfolder!=this.env.mailbox.replace(RegExp("["+a+"]?[^"+a+"]+$"),"")&&(b=RegExp("[^"+a+"]*["+a+"]","g"),a=this.set_busy(!0,"foldermoving"),b=this.env.mailbox.replace(b,""),b=this.env.dstfolder==this.env.delimiter?b:this.env.dstfolder+this.env.delimiter+b,this.http_post("rename-folder",
+"_folder_oldname="+urlencode(this.env.mailbox)+"&_folder_newname="+urlencode(b),a));this.drag_active=!1;this.unfocus_subscription(this.get_folder_row_id(this.env.dstfolder))};this.create_folder=function(){this.show_folder("",this.env.mailbox)};this.delete_folder=function(a){if((a=this.env.subscriptionrows[this.get_folder_row_id(a?a:this.env.mailbox)][0])&&confirm(this.get_label("deletefolderconfirm"))){var b=this.set_busy(!0,"folderdeleting");this.http_post("delete-folder","_mbox="+urlencode(a),b)}};
+this.add_folder_row=function(a,b,d,e){if(!this.gui_objects.subscriptionlist)return!1;var f,g;for(g in this.env.subscriptionrows)if(this.env.subscriptionrows[g]!=null&&!this.env.subscriptionrows[g][2]){f=g;break}var h;g=this.gui_objects.subscriptionlist.tBodies[0];var j="rcmrow"+(g.childNodes.length+1),k=this.subscription_list.get_single_selection();if(d&&d.id)f=j=d.id;if(!j||!f||!(h=document.getElementById(f)))return this.goto_url("folders"),!1;f=this.clone_table_row(h);f.id=j;e&&(e=this.get_folder_row_id(e))?
+g.insertBefore(f,document.getElementById(e)):g.appendChild(f);d&&g.removeChild(d);this.env.subscriptionrows[f.id]=[a,b,0];f.cells[0].innerHTML=b;if(!d)f.cells[1].innerHTML="*",$('input[name="_subscribed[]"]',f).val(a).attr("checked",!0);this.init_subscription_list();k&&document.getElementById("rcmrow"+k)&&this.subscription_list.select_row(k);document.getElementById(j).scrollIntoView&&document.getElementById(j).scrollIntoView()};this.replace_folder_row=function(a,b,d,e){a=this.get_folder_row_id(a);
+a=document.getElementById(a);this.add_folder_row(b,d,a,e)};this.remove_folder_row=function(a){var b;if((a=this.get_folder_row_id(a))&&(b=document.getElementById(a)))b.style.display="none"};this.subscribe=function(a){if(a){var b=this.display_message(this.get_label("foldersubscribing"),"loading");this.http_post("subscribe","_mbox="+urlencode(a),b)}};this.unsubscribe=function(a){if(a){var b=this.display_message(this.get_label("folderunsubscribing"),"loading");this.http_post("unsubscribe","_mbox="+urlencode(a),
+b)}};this.get_folder_row_id=function(a){for(var b in this.env.subscriptionrows)if(this.env.subscriptionrows[b]&&this.env.subscriptionrows[b][0]==a)break;return b};this.clone_table_row=function(a){for(var b,d,e=document.createElement("tr"),f=0;f<a.cells.length;f++){b=a.cells[f];d=document.createElement("td");if(b.className)d.className=b.className;b.align&&d.setAttribute("align",b.align);d.innerHTML=b.innerHTML;e.appendChild(d)}return e};this.show_folder=function(a,b,d){var e=window,a="&_action=edit-folder&_mbox="+
+urlencode(a);b&&(a+="&_path="+urlencode(b));this.env.contentframe&&window.frames&&window.frames[this.env.contentframe]&&(e=window.frames[this.env.contentframe],a+="&_framed=1");if(String(e.location.href).indexOf(a)>=0&&!d)this.show_contentframe(!0);else{if(!this.env.frame_lock)(parent.rcmail?parent.rcmail:this).env.frame_lock=this.set_busy(!0,"loading");e.location.href=this.env.comm_path+a}};this.disable_subscription=function(a){(a=this.get_folder_row_id(a))&&$('input[name="_subscribed[]"]',$("#"+
+a)).attr("disabled",!0)};this.folder_size=function(a){var b=this.set_busy(!0,"loading");this.http_post("folder-size","_mbox="+urlencode(a),b)};this.folder_size_update=function(a){$("#folder-size").replaceWith(a)};this.set_page_buttons=function(){this.enable_command("nextpage","lastpage",this.env.pagecount>this.env.current_page);this.enable_command("previouspage","firstpage",this.env.current_page>1)};this.init_buttons=function(){for(var a in this.buttons)if(typeof a=="string")for(var b=0;b<this.buttons[a].length;b++){var d=
+this.buttons[a][b],e=document.getElementById(d.id);if(e){var f=!1;if(d.type=="image")e=e.parentNode,f=!0;e._command=a;e._id=d.id;if(d.sel&&(e.onmousedown=function(){return rcmail.button_sel(this._command,this._id)},e.onmouseup=function(){return rcmail.button_out(this._command,this._id)},f))(new Image).src=d.sel;if(d.over&&(e.onmouseover=function(){return rcmail.button_over(this._command,this._id)},e.onmouseout=function(){return rcmail.button_out(this._command,this._id)},f))(new Image).src=d.over}}};
+this.set_button=function(a,b){var d,e,f=this.buttons[a];if(!f||!f.length)return!1;for(var g=0;g<f.length;g++){d=f[g];if((e=document.getElementById(d.id))&&d.type=="image"&&!d.status){if(d.pas=e._original_src?e._original_src:e.src,e.runtimeStyle&&e.runtimeStyle.filter&&e.runtimeStyle.filter.match(/src=['"]([^'"]+)['"]/))d.pas=RegExp.$1}else if(e&&!d.status)d.pas=String(e.className);if(e&&d.type=="image"&&d[b])d.status=b,e.src=d[b];else if(e&&typeof d[b]!="undefined")d.status=b,e.className=d[b];if(e&&
+d.type=="input")d.status=b,e.disabled=!b}};this.set_alttext=function(a,b){if(this.buttons[a]&&this.buttons[a].length)for(var d,e,f,g=0;g<this.buttons[a].length;g++)d=this.buttons[a][g],e=document.getElementById(d.id),d.type=="image"&&e?(e.setAttribute("alt",this.get_label(b)),(f=e.parentNode)&&f.tagName.toLowerCase()=="a"&&f.setAttribute("title",this.get_label(b))):e&&e.setAttribute("title",this.get_label(b))};this.button_over=function(a,b){var d,e,f=this.buttons[a];if(!f||!f.length)return!1;for(var g=
+0;g<f.length;g++)if(d=f[g],d.id==b&&d.status=="act"&&(e=document.getElementById(d.id))&&d.over)d.type=="image"?e.src=d.over:e.className=d.over};this.button_sel=function(a,b){var d,e,f=this.buttons[a];if(f&&f.length)for(var g=0;g<f.length;g++)if(d=f[g],d.id==b&&d.status=="act"){if((e=document.getElementById(d.id))&&d.sel)d.type=="image"?e.src=d.sel:e.className=d.sel;this.buttons_sel[b]=a}};this.button_out=function(a,b){var d,e,f=this.buttons[a];if(f&&f.length)for(var g=0;g<f.length;g++)if(d=f[g],d.id==
+b&&d.status=="act"&&(e=document.getElementById(d.id))&&d.act)d.type=="image"?e.src=d.act:e.className=d.act};this.set_pagetitle=function(a){if(a&&document.title)document.title=a};this.display_message=function(a,b){if(this.is_framed())return parent.rcmail.display_message(a,b);if(!this.gui_objects.message){if(b!="loading")this.pending_message=[a,b];return!1}var b=b?b:"notice",d=this,e=a,f=b+(new Date).getTime(),g=this.message_time*(b=="error"||b=="warning"?2:1);b=="loading"&&(e="loading",g=this.env.request_timeout*
+1E3,a||(a=this.get_label("loading")));if(this.messages[e])return this.messages[e].obj&&this.messages[e].obj.html(a),b=="loading"&&this.messages[e].labels.push({id:f,msg:a}),this.messages[e].elements.push(f),window.setTimeout(function(){d.hide_message(f,b=="loading")},g),f;var h=$("<div>").addClass(b).html(a).data("key",e);$(this.gui_objects.message).append(h).show();this.messages[e]={obj:h,elements:[f]};b=="loading"?this.messages[e].labels=[{id:f,msg:a}]:h.click(function(){return d.hide_message(h)});
+window.setTimeout(function(){d.hide_message(f,b=="loading")},g);return f};this.hide_message=function(a,b){if(this.is_framed())return parent.rcmail.hide_message(a,b);var d,e,f,g,h=this.messages;if(typeof a=="object")$(a)[b?"fadeOut":"hide"](),g=$(a).data("key"),this.messages[g]&&delete this.messages[g];else for(d in h)for(e in h[d].elements)if(h[d]&&h[d].elements[e]==a)if(h[d].elements.splice(e,1),h[d].elements.length){if(d=="loading")for(f in h[d].labels)h[d].labels[f].id==a?delete h[d].labels[f]:
+g=h[d].labels[f].msg,h[d].obj.html(g)}else h[d].obj[b?"fadeOut":"hide"](),delete h[d]};this.select_folder=function(a,b,d){if(this.gui_objects.folderlist){var e,f;(e=this.get_folder_li(b,d))&&$(e).removeClass("selected").addClass("unfocused");(f=this.get_folder_li(a,d))&&$(f).removeClass("unfocused").addClass("selected");this.triggerEvent("selectfolder",{folder:a,old:b,prefix:d})}};this.get_folder_li=function(a,b){b||(b="rcmli");if(this.gui_objects.folderlist)return a=String(a).replace(this.identifier_expr,
+"_"),document.getElementById(b+a);return null};this.set_message_coltypes=function(a,b){var d=this.message_list,e=d?d.list.tHead:null,f,g,h,j;this.env.coltypes=a;if(e){if(b){g=document.createElement("thead");h=document.createElement("tr");c=0;for(j=b.length;c<j;c++){f=document.createElement("td");f.innerHTML=b[c].html;if(b[c].id)f.id=b[c].id;if(b[c].className)f.className=b[c].className;h.appendChild(f)}g.appendChild(h);e.parentNode.replaceChild(g,e);e=g}h=0;for(j=this.env.coltypes.length;h<j;h++)if(g=
+this.env.coltypes[h],(f=e.rows[0].cells[h])&&(g=="from"||g=="to")){f.id="rcm"+g;if(f.firstChild&&f.firstChild.tagName.toLowerCase()=="a")f=f.firstChild,f.onclick=function(){return rcmail.command("sort",this.__col,this)},f.__col=g;f.innerHTML=this.get_label(g)}}this.env.subject_col=null;this.env.flagged_col=null;this.env.status_col=null;if((h=$.inArray("subject",this.env.coltypes))>=0)if(this.set_env("subject_col",h),d)d.subject_col=h;(h=$.inArray("flag",this.env.coltypes))>=0&&this.set_env("flagged_col",
+h);(h=$.inArray("status",this.env.coltypes))>=0&&this.set_env("status_col",h);d&&d.init_header()};this.set_rowcount=function(a){$(this.gui_objects.countdisplay).html(a);this.set_page_buttons()};this.set_mailboxname=function(a){if(this.gui_objects.mailboxname&&a)this.gui_objects.mailboxname.innerHTML=a};this.set_quota=function(a){a&&this.gui_objects.quotadisplay&&(typeof a=="object"&&a.type=="image"?this.percent_indicator(this.gui_objects.quotadisplay,a):$(this.gui_objects.quotadisplay).html(a))};
+this.set_unread_count=function(a,b,d){if(!this.gui_objects.mailboxlist)return!1;this.env.unread_counts[a]=b;this.set_unread_count_display(a,d)};this.set_unread_count_display=function(a,b){var d,e,f,g,h,j;if(f=this.get_folder_li(a)){g=this.env.unread_counts[a]?this.env.unread_counts[a]:0;e=f.getElementsByTagName("a")[0];d=/\s+\([0-9]+\)$/i;h=0;if((j=f.getElementsByTagName("div")[0])&&j.className.match(/collapsed/))for(var k in this.env.unread_counts)k.indexOf(a+this.env.delimiter)==0&&(h+=this.env.unread_counts[k]);
+g&&e.innerHTML.match(d)?e.innerHTML=e.innerHTML.replace(d," ("+g+")"):g?e.innerHTML+=" ("+g+")":e.innerHTML=e.innerHTML.replace(d,"");d=RegExp(RegExp.escape(this.env.delimiter)+"[^"+RegExp.escape(this.env.delimiter)+"]+$");a.match(d)&&this.set_unread_count_display(a.replace(d,""),!1);g+h>0?$(f).addClass("unread"):$(f).removeClass("unread")}d=/^\([0-9]+\)\s+/i;b&&document.title&&(e="",e=String(document.title),e=g&&e.match(d)?e.replace(d,"("+g+") "):g?"("+g+") "+e:e.replace(d,""),this.set_pagetitle(e))};
+this.new_message_focus=function(){this.env.framed&&window.parent?window.parent.focus():window.focus()};this.toggle_prefer_html=function(a){var b;if(b=document.getElementById("rcmfd_addrbook_show_images"))b.disabled=!a.checked};this.toggle_preview_pane=function(a){var b;if(b=document.getElementById("rcmfd_preview_pane_mark_read"))b.disabled=!a.checked};this.set_headers=function(a){this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&a&&$(this.gui_objects.all_headers_box).html(a).show()};
+this.load_headers=function(a){if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box&&this.env.uid)$(a).removeClass("show-headers").addClass("hide-headers"),$(this.gui_objects.all_headers_row).show(),a.onclick=function(){rcmail.hide_headers(a)},this.gui_objects.all_headers_box.innerHTML||this.http_post("headers","_uid="+this.env.uid,this.display_message(this.get_label("loading"),"loading"))};this.hide_headers=function(a){if(this.gui_objects.all_headers_row&&this.gui_objects.all_headers_box)$(a).removeClass("hide-headers").addClass("show-headers"),
+$(this.gui_objects.all_headers_row).hide(),a.onclick=function(){rcmail.load_headers(a)}};this.percent_indicator=function(a,b){if(!b||!a)return!1;var d=b.width?b.width:this.env.indicator_width?this.env.indicator_width:100,e=b.height?b.height:this.env.indicator_height?this.env.indicator_height:14,f=b.percent?Math.abs(parseInt(b.percent)):0,g=parseInt(f/100*d),h=$(a).position();h.top=Math.max(0,h.top);this.env.indicator_width=d;this.env.indicator_height=e;g>d&&(g=d,f=100);if(b.title)b.title=this.get_label("quota")+
+": "+b.title;var j=$("<div>");j.css({position:"absolute",top:h.top,left:h.left,width:d+"px",height:e+"px",zIndex:100,lineHeight:e+"px"}).attr("title",b.title).addClass("quota_text").html(f+"%");var k=$("<div>");k.css({position:"absolute",top:h.top+1,left:h.left+1,width:g+"px",height:e+"px",zIndex:99});g=$("<div>");g.css({position:"absolute",top:h.top+1,left:h.left+1,width:d+"px",height:e+"px",zIndex:98}).addClass("quota_bg");f>=80?(j.addClass(" quota_text_high"),k.addClass("quota_high")):f>=55?(j.addClass(" quota_text_mid"),
+k.addClass("quota_mid")):(j.addClass(" quota_text_normal"),k.addClass("quota_low"));$(a).html("").append(k).append(g).append(j);$("#quotaimg").attr("title",b.title)};this.html2plain=function(a,b){var d=this,e=this.set_busy(!0,"converting");console.log("HTTP POST: ?_task=utils&_action=html2text");$.ajax({type:"POST",url:"?_task=utils&_action=html2text",data:a,contentType:"application/octet-stream",error:function(a,b,h){d.http_error(a,b,h,e)},success:function(a){d.set_busy(!1,null,e);$(document.getElementById(b)).val(a);
+console.log(a)}})};this.plain2html=function(a,b){var d=this.set_busy(!0,"converting");$(document.getElementById(b)).val("<pre>"+a+"</pre>");this.set_busy(!1,null,d)};this.redirect=function(a,b){(b||b===null)&&this.set_busy(!0);this.env.framed&&window.parent?parent.location.href=a:location.href=a};this.goto_url=function(a,b,d){var e=this.env.comm_path,b=b?"&"+b:"";if(a.match(/([a-z]+)\/([a-z-_]+)/))a=RegExp.$2,e=e.replace(/\_task=[a-z]+/,"_task="+RegExp.$1);this.redirect(e+"&_action="+a+b,d)};this.http_request=
+function(a,b,d){var e=this.env.comm_path;if(a.match(/([a-z]+)\/([a-z-_]+)/))a=RegExp.$2,e=e.replace(/\_task=[a-z]+/,"_task="+RegExp.$1);var f=this.triggerEvent("request"+a,b);if(typeof f!="undefined")if(f===!1)return!1;else b=f;e+="&_remote=1&_action="+a+(b?"&":"")+b;console.log("HTTP GET: "+e);$.ajax({type:"GET",url:e,data:{_unlock:d?d:0},dataType:"json",success:function(a){j.http_response(a)},error:function(a,b,e){rcmail.http_error(a,b,e,d)}})};this.http_post=function(a,b,d){var e=this.env.comm_path;
+if(a.match(/([a-z]+)\/([a-z-_]+)/))a=RegExp.$2,e=e.replace(/\_task=[a-z]+/,"_task="+RegExp.$1);e+="&_action="+a;b&&typeof b=="object"?(b._remote=1,b._unlock=d?d:0):b+=(b?"&":"")+"_remote=1"+(d?"&_unlock="+d:"");a=this.triggerEvent("request"+a,b);if(typeof a!="undefined")if(a===!1)return!1;else b=a;console.log("HTTP POST: "+e);$.ajax({type:"POST",url:e,data:b,dataType:"json",success:function(a){j.http_response(a)},error:function(a,b,e){rcmail.http_error(a,b,e,d)}})};this.http_response=function(a){if(a){a.unlock&&
+this.set_busy(!1);this.triggerEvent("responsebefore",{response:a});this.triggerEvent("responsebefore"+a.action,{response:a});a.env&&this.set_env(a.env);if(typeof a.texts=="object")for(var b in a.texts)typeof a.texts[b]=="string"&&this.add_label(b,a.texts[b]);a.exec&&(console.log(a.exec),eval(a.exec));if(a.callbacks&&a.callbacks.length)for(b=0;b<a.callbacks.length;b++)this.triggerEvent(a.callbacks[b][0],a.callbacks[b][1]);switch(a.action){case "delete":this.task=="addressbook"&&(b=this.contact_list.get_selection(),
+this.enable_command("compose",b&&this.contact_list.rows[b]),this.enable_command("delete","edit",b&&this.contact_list.rows[b]&&this.env.address_sources&&!this.env.address_sources[this.env.source].readonly),this.enable_command("export",this.contact_list&&this.contact_list.rowcount>0));case "moveto":this.env.action=="show"?(this.enable_command(this.env.message_commands,!0),this.env.list_post||this.enable_command("reply-list",!1)):this.task=="addressbook"&&this.triggerEvent("listupdate",{folder:this.env.source,
+rowcount:this.contact_list.rowcount});case "purge":case "expunge":this.task=="mail"&&(this.env.messagecount||(this.env.contentframe&&this.show_contentframe(!1),this.enable_command(this.env.message_commands,"purge","expunge","select-all","select-none","sort","expand-all","expand-unread","collapse-all",!1)),this.message_list&&this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount}));break;case "check-recent":case "getunread":case "search":case "list":if(this.task==
+"mail"){if(this.enable_command("show","expunge","select-all","select-none","sort",this.env.messagecount>0),this.enable_command("purge",this.purge_mailbox_test()),this.enable_command("expand-all","expand-unread","collapse-all",this.env.threading&&this.env.messagecount),a.action=="list"||a.action=="search")this.msglist_select(this.message_list),this.triggerEvent("listupdate",{folder:this.env.mailbox,rowcount:this.message_list.rowcount})}else if(this.task=="addressbook"&&(this.enable_command("export",
+this.contact_list&&this.contact_list.rowcount>0),a.action=="list"||a.action=="search"))this.enable_command("group-create",this.env.address_sources[this.env.source].groups&&!this.env.address_sources[this.env.source].readonly),this.enable_command("group-rename","group-delete",this.env.address_sources[this.env.source].groups&&this.env.group&&!this.env.address_sources[this.env.source].readonly),this.triggerEvent("listupdate",{folder:this.env.source,rowcount:this.contact_list.rowcount})}a.unlock&&this.hide_message(a.unlock);
+this.triggerEvent("responseafter",{response:a});this.triggerEvent("responseafter"+a.action,{response:a})}};this.http_error=function(a,b,d,e){b=a.statusText;this.set_busy(!1,null,e);a.abort();b&&this.display_message(this.get_label("servererror")+" ("+b+")","error")};this.start_keepalive=function(){this._int&&clearInterval(this._int);if(this.env.keep_alive&&!this.env.framed&&this.task=="mail"&&this.gui_objects.mailboxlist)this._int=setInterval(function(){j.check_for_recent(!1)},this.env.keep_alive*
+1E3);else if(this.env.keep_alive&&!this.env.framed&&this.task!="login"&&this.env.action!="print")this._int=setInterval(function(){j.send_keep_alive()},this.env.keep_alive*1E3)};this.send_keep_alive=function(){this.http_request("keep-alive","_t="+(new Date).getTime())};this.check_for_recent=function(a){if(!this.busy){var b,d="_t="+(new Date).getTime()+"&_mbox="+urlencode(this.env.mailbox);a&&(b=this.set_busy(!0,"checkingmail"),d+="&_refresh=1",this.start_keepalive());this.gui_objects.messagelist&&
+(d+="&_list=1");this.gui_objects.quotadisplay&&(d+="&_quota=1");this.env.search_request&&(d+="&_search="+this.env.search_request);this.http_request("check-recent",d,b)}};this.get_single_uid=function(){return this.env.uid?this.env.uid:this.message_list?this.message_list.get_single_selection():null};this.get_single_cid=function(){return this.env.cid?this.env.cid:this.contact_list?this.contact_list.get_single_selection():null};this.get_caret_pos=function(a){if(typeof a.selectionEnd!="undefined")return a.selectionEnd;
+else if(document.selection&&document.selection.createRange){var b=document.selection.createRange();if(b.parentElement()!=a)return 0;var d=b.duplicate();a.tagName=="TEXTAREA"?d.moveToElementText(a):d.expand("textedit");d.setEndPoint("EndToStart",b);b=d.text.length;return b<=a.value.length?b:-1}else return a.value.length};this.set_caret_pos=function(a,b){if(a.setSelectionRange)a.setSelectionRange(b,b);else if(a.createTextRange){var d=a.createTextRange();d.collapse(!0);d.moveEnd("character",b);d.moveStart("character",
+b);d.select()}};this.lock_form=function(a,b){if(a&&a.elements){var d,e,f;if(b)this.disabled_form_elements=[];d=0;for(e=a.elements.length;d<e;d++)if(f=a.elements[d],f.type!="hidden")if(b&&f.disabled)this.disabled_form_elements.push(f);else if(b||$.inArray(f,this.disabled_form_elements)<0)f.disabled=b}}}rcube_webmail.long_subject_title=function(j,a){if(!j.title){var b=$(j);if(b.width()+a*15>b.parent().width())j.title=b.html()}};rcube_webmail.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;
+rcube_webmail.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;rcube_webmail.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;
index 45dac5e6504f417e462e2a3580f2d86375eaf59d..472dc6e8b5b62c065abe1b79803b0877271ac076 100644 (file)
@@ -14,7 +14,7 @@
  | Requires: jquery.js, common.js, list.js                               |
  +-----------------------------------------------------------------------+
 
-  $Id: app.js 4469 2011-01-29 14:55:12Z thomasb $
+  $Id: app.js 4666 2011-04-17 09:34:02Z alec $
 */
 
 
@@ -2994,11 +2994,11 @@ function rcube_webmail()
   this.compose_field_hash = function(save)
   {
     // check input fields
-    var value_to = $("[name='_to']").val();
-    var value_cc = $("[name='_cc']").val();
-    var value_bcc = $("[name='_bcc']").val();
-    var value_subject = $("[name='_subject']").val();
-    var str = '';
+    var ed, str = '',
+      value_to = $("[name='_to']").val(),
+      value_cc = $("[name='_cc']").val(),
+      value_bcc = $("[name='_bcc']").val(),
+      value_subject = $("[name='_subject']").val();
 
     if (value_to)
       str += value_to+':';
@@ -3009,9 +3009,8 @@ function rcube_webmail()
     if (value_subject)
       str += value_subject+':';
 
-    var editor = tinyMCE.get(this.env.composebody);
-    if (editor)
-      str += editor.getContent();
+    if (window.tinyMCE && (ed = tinyMCE.get(this.env.composebody)))
+      str += ed.getContent();
     else
       str += $("[name='_message']").val();
 
@@ -4622,7 +4621,7 @@ function rcube_webmail()
       var current_li, target_li;
 
       if ((current_li = this.get_folder_li(old, prefix))) {
-        $(current_li).removeClass('selected').removeClass('unfocused');
+        $(current_li).removeClass('selected').addClass('unfocused');
       }
       if ((target_li = this.get_folder_li(name, prefix))) {
         $(target_li).removeClass('unfocused').addClass('selected');
@@ -4651,17 +4650,18 @@ function rcube_webmail()
   // and for setting some message list global variables
   this.set_message_coltypes = function(coltypes, repl)
   {
-    this.env.coltypes = coltypes;
+    var list = this.message_list,
+      thead = list ? list.list.tHead : null,
+      cell, col, n, len, th, tr;
 
-    // set correct list titles
-    var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null,
-      cell, col, n, len;
+    this.env.coltypes = coltypes;
 
     // replace old column headers
     if (thead) {
       if (repl) {
-        var th = document.createElement('thead'),
-          tr = document.createElement('tr');
+        th = document.createElement('thead');
+        tr = document.createElement('tr');
+
         for (c=0, len=repl.length; c < len; c++) {
           cell = document.createElement('td');
           cell.innerHTML = repl[c].html;
@@ -4695,15 +4695,16 @@ function rcube_webmail()
 
     if ((n = $.inArray('subject', this.env.coltypes)) >= 0) {
       this.set_env('subject_col', n);
-      if (this.message_list)
-        this.message_list.subject_col = n;
+      if (list)
+        list.subject_col = n;
     }
     if ((n = $.inArray('flag', this.env.coltypes)) >= 0)
       this.set_env('flagged_col', n);
     if ((n = $.inArray('status', this.env.coltypes)) >= 0)
       this.set_env('status_col', n);
 
-    this.message_list.init_header();
+    if (list)
+      list.init_header();
   };
 
   // replace content of row count display
index 7f068b4a37100d3f468d26fa069e55cdbac4267e..6c3caa7d97dc5e77e906d24e95d8b320ab3dd322 100644 (file)
@@ -1,25 +1,25 @@
 var CONTROL_KEY=1,SHIFT_KEY=2,CONTROL_SHIFT_KEY=3;
 function roundcube_browser(){var a=navigator;this.ver=parseFloat(a.appVersion);this.appver=a.appVersion;this.agent=a.userAgent;this.agent_lc=a.userAgent.toLowerCase();this.name=a.appName;this.vendor=a.vendor?a.vendor:"";this.vendver=a.vendorSub?parseFloat(a.vendorSub):0;this.product=a.product?a.product:"";this.platform=String(a.platform).toLowerCase();this.lang=a.language?a.language.substring(0,2):a.browserLanguage?a.browserLanguage.substring(0,2):a.systemLanguage?a.systemLanguage.substring(0,2):
-"en";this.win=this.platform.indexOf("win")>=0;this.mac=this.platform.indexOf("mac")>=0;this.linux=this.platform.indexOf("linux")>=0;this.unix=this.platform.indexOf("unix")>=0;this.dom=document.getElementById?true:false;this.dom2=document.addEventListener&&document.removeEventListener;this.ie4=(this.ie=document.all&&!window.opera)&&!this.dom;this.ie5=this.dom&&this.appver.indexOf("MSIE 5")>0;this.ie8=this.dom&&this.appver.indexOf("MSIE 8")>0;this.ie7=this.dom&&this.appver.indexOf("MSIE 7")>0;this.ie6=
-this.dom&&!this.ie8&&!this.ie7&&this.appver.indexOf("MSIE 6")>0;this.mz=this.dom&&this.ver>=5;this.ns6=(this.ns=this.ver<5&&this.name=="Netscape"||this.ver>=5&&this.vendor.indexOf("Netscape")>=0)&&parseInt(this.vendver)==6;this.ns7=this.ns&&parseInt(this.vendver)==7;this.chrome=this.agent_lc.indexOf("chrome")>0;this.safari=!this.chrome&&(this.agent_lc.indexOf("safari")>0||this.agent_lc.indexOf("applewebkit")>0);this.konq=this.agent_lc.indexOf("konqueror")>0;this.iphone=this.safari&&this.agent_lc.indexOf("iphone")>
-0;this.ipad=this.safari&&this.agent_lc.indexOf("ipad")>0;if((this.opera=window.opera?true:false)&&window.RegExp)this.vendver=/opera(\s|\/)([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$2):-1;else if(this.chrome&&window.RegExp)this.vendver=/chrome\/([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0;else if(!this.vendver&&this.safari)this.vendver=/(safari|applewebkit)\/([0-9]+)/.test(this.agent_lc)?parseInt(RegExp.$2):0;else if(!this.vendver&&this.mz||this.agent.indexOf("Camino")>0)this.vendver=
+"en";this.win=this.platform.indexOf("win")>=0;this.mac=this.platform.indexOf("mac")>=0;this.linux=this.platform.indexOf("linux")>=0;this.unix=this.platform.indexOf("unix")>=0;this.dom=document.getElementById?!0:!1;this.dom2=document.addEventListener&&document.removeEventListener;this.ie4=(this.ie=document.all&&!window.opera)&&!this.dom;this.ie5=this.dom&&this.appver.indexOf("MSIE 5")>0;this.ie8=this.dom&&this.appver.indexOf("MSIE 8")>0;this.ie7=this.dom&&this.appver.indexOf("MSIE 7")>0;this.ie6=this.dom&&
+!this.ie8&&!this.ie7&&this.appver.indexOf("MSIE 6")>0;this.mz=this.dom&&this.ver>=5;this.ns6=(this.ns=this.ver<5&&this.name=="Netscape"||this.ver>=5&&this.vendor.indexOf("Netscape")>=0)&&parseInt(this.vendver)==6;this.ns7=this.ns&&parseInt(this.vendver)==7;this.chrome=this.agent_lc.indexOf("chrome")>0;this.safari=!this.chrome&&(this.agent_lc.indexOf("safari")>0||this.agent_lc.indexOf("applewebkit")>0);this.konq=this.agent_lc.indexOf("konqueror")>0;this.iphone=this.safari&&this.agent_lc.indexOf("iphone")>
+0;this.ipad=this.safari&&this.agent_lc.indexOf("ipad")>0;if((this.opera=window.opera?!0:!1)&&window.RegExp)this.vendver=/opera(\s|\/)([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$2):-1;else if(this.chrome&&window.RegExp)this.vendver=/chrome\/([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0;else if(!this.vendver&&this.safari)this.vendver=/(safari|applewebkit)\/([0-9]+)/.test(this.agent_lc)?parseInt(RegExp.$2):0;else if(!this.vendver&&this.mz||this.agent.indexOf("Camino")>0)this.vendver=
 /rv:([0-9\.]+)/.test(this.agent)?parseFloat(RegExp.$1):0;else if(this.ie&&window.RegExp)this.vendver=/msie\s+([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0;else if(this.konq&&window.RegExp)this.vendver=/khtml\/([0-9\.]+)/.test(this.agent_lc)?parseFloat(RegExp.$1):0;if(this.safari&&/;\s+([a-z]{2})-[a-z]{2}\)/.test(this.agent_lc))this.lang=RegExp.$1;this.dhtml=this.ie4&&this.win||this.ie5||this.ie6||this.ns4||this.mz;this.vml=this.win&&this.ie&&this.dom&&!this.opera;this.pngalpha=this.mz||
-this.opera&&this.vendver>=6||this.ie&&this.mac&&this.vendver>=5||this.ie&&this.win&&this.vendver>=5.5||this.safari;this.opacity=this.mz||this.ie&&this.vendver>=5.5&&!this.opera||this.safari&&this.vendver>=100;this.cookies=a.cookieEnabled;this.xmlhttp_test=function(){var b=new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");return this.xmlhttp=window.XMLHttpRequest||window.ActiveXObject&&b()};this.set_html_class=function(){var b=" js";if(this.ie){b+=
-" ie";if(this.ie5)b+=" ie5";else if(this.ie6)b+=" ie6";else if(this.ie7)b+=" ie7";else if(this.ie8)b+=" ie8"}else if(this.opera)b+=" opera";else if(this.konq)b+=" konqueror";else if(this.safari)b+=" safari";if(this.chrome)b+=" chrome";else if(this.iphone)b+=" iphone";else if(this.ipad)b+=" ipad";else if(this.ns6)b+=" netscape6";else if(this.ns7)b+=" netscape7";if(document.documentElement)document.documentElement.className+=b}}
-var rcube_event={get_target:function(a){return(a=a||window.event)&&a.target?a.target:a.srcElement},get_keycode:function(a){return(a=a||window.event)&&a.keyCode?a.keyCode:a&&a.which?a.which:0},get_button:function(a){return(a=a||window.event)&&typeof a.button!="undefined"?a.button:a&&a.which?a.which:0},get_modifier:function(a){var b=0;a=a||window.event;if(bw.mac&&a){b+=(a.metaKey&&CONTROL_KEY)+(a.shiftKey&&SHIFT_KEY);return b}if(a){b+=(a.ctrlKey&&CONTROL_KEY)+(a.shiftKey&&SHIFT_KEY);return b}},get_mouse_pos:function(a){if(!a)a=
-window.event;var b=a.pageX?a.pageX:a.clientX,c=a.pageY?a.pageY:a.clientY;if(document.body&&document.all){b+=document.body.scrollLeft;c+=document.body.scrollTop}if(a._offset){b+=a._offset.left;c+=a._offset.top}return{x:b,y:c}},add_listener:function(a){if(a.object&&a.method){if(!a.element)a.element=document;if(!a.object._rc_events)a.object._rc_events=[];var b=a.event+"*"+a.method;a.object._rc_events[b]||(a.object._rc_events[b]=function(c){return a.object[a.method](c)});if(a.element.addEventListener)a.element.addEventListener(a.event,
-a.object._rc_events[b],false);else if(a.element.attachEvent){a.element.detachEvent("on"+a.event,a.object._rc_events[b]);a.element.attachEvent("on"+a.event,a.object._rc_events[b])}else a.element["on"+a.event]=a.object._rc_events[b]}},remove_listener:function(a){if(!a.element)a.element=document;var b=a.event+"*"+a.method;if(a.object&&a.object._rc_events&&a.object._rc_events[b])if(a.element.removeEventListener)a.element.removeEventListener(a.event,a.object._rc_events[b],false);else if(a.element.detachEvent)a.element.detachEvent("on"+
-a.event,a.object._rc_events[b]);else a.element["on"+a.event]=null},cancel:function(a){a=a?a:window.event;a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();a.cancelBubble=true;return a.returnValue=false},touchevent:function(a){return{pageX:a.pageX,pageY:a.pageY,offsetX:a.pageX-a.target.offsetLeft,offsetY:a.pageY-a.target.offsetTop,target:a.target,istouch:true}}};function rcube_event_engine(){this._events={}}
-rcube_event_engine.prototype={addEventListener:function(a,b,c){if(!this._events)this._events={};this._events[a]||(this._events[a]=[]);this._events[a][this._events[a].length]={func:b,obj:c?c:window}},removeEventListener:function(a,b,c){if(typeof c=="undefined")c=window;for(var d,e=0;this._events&&this._events[a]&&e<this._events[a].length;e++)if((d=this._events[a][e])&&d.func==b&&d.obj==c)this._events[a][e]=null},triggerEvent:function(a,b){var c,d;if(typeof b=="undefined")b=this;else if(typeof b=="object")b.event=
-a;if(this._events&&this._events[a]&&!this._event_exec){this._event_exec=true;for(var e=0;e<this._events[a].length;e++)if(d=this._events[a][e]){if(typeof d.func=="function")c=d.func.call?d.func.call(d.obj,b):d.func(b);else if(typeof d.obj[d.func]=="function")c=d.obj[d.func](b);if(typeof c!="undefined"&&!c)break}}this._event_exec=false;return c}};
-function rcube_layer(a,b){this.name=a;this.create=function(c){var d=c.x?c.x:0,e=c.y?c.y:0,f=c.width,g=c.height,i=c.zindex,j=c.vis;c=c.parent;var h=document.createElement("DIV");with(h){a=this.name;with(style){position="absolute";visibility=j?j==2?"inherit":"visible":"hidden";left=d+"px";top=e+"px";if(f)width=f.toString().match(/\%$/)?f:f+"px";if(g)height=g.toString().match(/\%$/)?g:g+"px";if(i)zIndex=i}}c?c.appendChild(h):document.body.appendChild(h);this.elm=h};if(b!=null){this.create(b);this.name=
-this.elm.id}else this.elm=document.getElementById(a);if(!this.elm)return false;this.css=this.elm.style;this.event=this.elm;this.width=this.elm.offsetWidth;this.height=this.elm.offsetHeight;this.x=parseInt(this.elm.offsetLeft);this.y=parseInt(this.elm.offsetTop);this.visible=this.css.visibility=="visible"||this.css.visibility=="show"||this.css.visibility=="inherit"?true:false;this.move=function(c,d){this.x=c;this.y=d;this.css.left=Math.round(this.x)+"px";this.css.top=Math.round(this.y)+"px"};this.resize=
-function(c,d){this.css.width=c+"px";this.css.height=d+"px";this.width=c;this.height=d};this.show=function(c){if(c==1){this.css.visibility="visible";this.visible=true}else if(c==2){this.css.visibility="inherit";this.visible=true}else{this.css.visibility="hidden";this.visible=false}};this.write=function(c){this.elm.innerHTML=c}}
+this.opera&&this.vendver>=6||this.ie&&this.mac&&this.vendver>=5||this.ie&&this.win&&this.vendver>=5.5||this.safari;this.opacity=this.mz||this.ie&&this.vendver>=5.5&&!this.opera||this.safari&&this.vendver>=100;this.cookies=a.cookieEnabled;this.xmlhttp_test=function(){var a=new Function("try{var o=new ActiveXObject('Microsoft.XMLHTTP');return true;}catch(err){return false;}");return this.xmlhttp=window.XMLHttpRequest||window.ActiveXObject&&a()};this.set_html_class=function(){var a=" js";this.ie?(a+=
+" ie",this.ie5?a+=" ie5":this.ie6?a+=" ie6":this.ie7?a+=" ie7":this.ie8&&(a+=" ie8")):this.opera?a+=" opera":this.konq?a+=" konqueror":this.safari&&(a+=" safari");this.chrome?a+=" chrome":this.iphone?a+=" iphone":this.ipad?a+=" ipad":this.ns6?a+=" netscape6":this.ns7&&(a+=" netscape7");document.documentElement&&(document.documentElement.className+=a)}}
+var rcube_event={get_target:function(a){return(a=a||window.event)&&a.target?a.target:a.srcElement},get_keycode:function(a){return(a=a||window.event)&&a.keyCode?a.keyCode:a&&a.which?a.which:0},get_button:function(a){return(a=a||window.event)&&typeof a.button!="undefined"?a.button:a&&a.which?a.which:0},get_modifier:function(a){var b=0,a=a||window.event;if(bw.mac&&a)return b+=(a.metaKey&&CONTROL_KEY)+(a.shiftKey&&SHIFT_KEY),b;if(a)return b+=(a.ctrlKey&&CONTROL_KEY)+(a.shiftKey&&SHIFT_KEY),b},get_mouse_pos:function(a){if(!a)a=
+window.event;var b=a.pageX?a.pageX:a.clientX,c=a.pageY?a.pageY:a.clientY;document.body&&document.all&&(b+=document.body.scrollLeft,c+=document.body.scrollTop);a._offset&&(b+=a._offset.left,c+=a._offset.top);return{x:b,y:c}},add_listener:function(a){if(a.object&&a.method){if(!a.element)a.element=document;if(!a.object._rc_events)a.object._rc_events=[];var b=a.event+"*"+a.method;a.object._rc_events[b]||(a.object._rc_events[b]=function(c){return a.object[a.method](c)});a.element.addEventListener?a.element.addEventListener(a.event,
+a.object._rc_events[b],!1):a.element.attachEvent?(a.element.detachEvent("on"+a.event,a.object._rc_events[b]),a.element.attachEvent("on"+a.event,a.object._rc_events[b])):a.element["on"+a.event]=a.object._rc_events[b]}},remove_listener:function(a){if(!a.element)a.element=document;var b=a.event+"*"+a.method;a.object&&a.object._rc_events&&a.object._rc_events[b]&&(a.element.removeEventListener?a.element.removeEventListener(a.event,a.object._rc_events[b],!1):a.element.detachEvent?a.element.detachEvent("on"+
+a.event,a.object._rc_events[b]):a.element["on"+a.event]=null)},cancel:function(a){a=a?a:window.event;a.preventDefault&&a.preventDefault();a.stopPropagation&&a.stopPropagation();a.cancelBubble=!0;return a.returnValue=!1},touchevent:function(a){return{pageX:a.pageX,pageY:a.pageY,offsetX:a.pageX-a.target.offsetLeft,offsetY:a.pageY-a.target.offsetTop,target:a.target,istouch:!0}}};function rcube_event_engine(){this._events={}}
+rcube_event_engine.prototype={addEventListener:function(a,b,c){if(!this._events)this._events={};this._events[a]||(this._events[a]=[]);this._events[a][this._events[a].length]={func:b,obj:c?c:window}},removeEventListener:function(a,b,c){typeof c=="undefined"&&(c=window);for(var d,e=0;this._events&&this._events[a]&&e<this._events[a].length;e++)if((d=this._events[a][e])&&d.func==b&&d.obj==c)this._events[a][e]=null},triggerEvent:function(a,b){var c,d;if(typeof b=="undefined")b=this;else if(typeof b=="object")b.event=
+a;if(this._events&&this._events[a]&&!this._event_exec){this._event_exec=!0;for(var e=0;e<this._events[a].length;e++)if(d=this._events[a][e])if(typeof d.func=="function"?c=d.func.call?d.func.call(d.obj,b):d.func(b):typeof d.obj[d.func]=="function"&&(c=d.obj[d.func](b)),typeof c!="undefined"&&!c)break}this._event_exec=!1;return c}};
+function rcube_layer(a,b){this.name=a;this.create=function(c){var b=c.x?c.x:0,e=c.y?c.y:0,f=c.width,g=c.height,i=c.zindex,j=c.vis,c=c.parent,h=document.createElement("DIV");with(h){a=this.name;with(style)position="absolute",visibility=j?j==2?"inherit":"visible":"hidden",left=b+"px",top=e+"px",f&&(width=f.toString().match(/\%$/)?f:f+"px"),g&&(height=g.toString().match(/\%$/)?g:g+"px"),i&&(zIndex=i)}c?c.appendChild(h):document.body.appendChild(h);this.elm=h};b!=null?(this.create(b),this.name=this.elm.id):
+this.elm=document.getElementById(a);if(!this.elm)return!1;this.css=this.elm.style;this.event=this.elm;this.width=this.elm.offsetWidth;this.height=this.elm.offsetHeight;this.x=parseInt(this.elm.offsetLeft);this.y=parseInt(this.elm.offsetTop);this.visible=this.css.visibility=="visible"||this.css.visibility=="show"||this.css.visibility=="inherit"?!0:!1;this.move=function(a,b){this.x=a;this.y=b;this.css.left=Math.round(this.x)+"px";this.css.top=Math.round(this.y)+"px"};this.resize=function(a,b){this.css.width=
+a+"px";this.css.height=b+"px";this.width=a;this.height=b};this.show=function(a){a==1?(this.css.visibility="visible",this.visible=!0):a==2?(this.css.visibility="inherit",this.visible=!0):(this.css.visibility="hidden",this.visible=!1)};this.write=function(a){this.elm.innerHTML=a}}
 function rcube_check_email(a,b){if(a&&window.RegExp)return(b?RegExp("(^|<|[,;s\n])((([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22))*\\x40([^@\\x2e]+\\x2e)+([a-z]{2,}|xn--[a-z0-9]{2,}))|(mailtest\\x40(\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631|\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5|\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66|\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae|\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e|\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8|\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8|\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc|\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435|\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8|\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8)))($|>|[,;s\n])","i"):
 RegExp("^((([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22))*\\x40([^@\\x2e]+\\x2e)+([a-z]{2,}|xn--[a-z0-9]{2,}))|(mailtest\\x40(\\u0645\\u062b\\u0627\\u0644\\x2e\\u0625\\u062e\\u062a\\u0628\\u0627\\u0631|\\u4f8b\\u5b50\\x2e\\u6d4b\\u8bd5|\\u4f8b\\u5b50\\x2e\\u6e2c\\u8a66|\\u03c0\\u03b1\\u03c1\\u03ac\\u03b4\\u03b5\\u03b9\\u03b3\\u03bc\\u03b1\\x2e\\u03b4\\u03bf\\u03ba\\u03b9\\u03bc\\u03ae|\\u0909\\u0926\\u093e\\u0939\\u0930\\u0923\\x2e\\u092a\\u0930\\u0940\\u0915\\u094d\\u0937\\u093e|\\u4f8b\\u3048\\x2e\\u30c6\\u30b9\\u30c8|\\uc2e4\\ub840\\x2e\\ud14c\\uc2a4\\ud2b8|\\u0645\\u062b\\u0627\\u0644\\x2e\\u0622\\u0632\\u0645\\u0627\\u06cc\\u0634\u06cc|\\u043f\\u0440\\u0438\\u043c\\u0435\\u0440\\x2e\\u0438\\u0441\\u043f\\u044b\\u0442\\u0430\\u043d\\u0438\\u0435|\\u0b89\\u0ba4\\u0bbe\\u0bb0\\u0ba3\\u0bae\\u0bcd\\x2e\\u0baa\\u0bb0\\u0bbf\\u0b9f\\u0bcd\\u0b9a\\u0bc8|\\u05d1\\u05f2\\u05b7\\u05e9\\u05e4\\u05bc\\u05d9\\u05dc\\x2e\\u05d8\\u05e2\\u05e1\\u05d8)))$",
-"i")).test(a)?true:false;return false}function rcube_clone_object(a){var b={},c;for(c in a)b[c]=a[c]&&typeof a[c]=="object"?clone_object(a[c]):a[c];return b}function urlencode(a){return window.encodeURIComponent?encodeURIComponent(a):escape(a)}
-function rcube_find_object(a,b){var c,d;b||(b=document);if(b.getElementsByName&&(c=b.getElementsByName(a)))d=c[0];if(!d&&b.getElementById)d=b.getElementById(a);if(!d&&b.all)d=b.all[a];if(!d&&b.images.length)d=b.images[a];if(!d&&b.forms.length)for(c=0;c<b.forms.length;c++)if(b.forms[c].name==a)d=b.forms[c];else if(b.forms[c].elements[a])d=b.forms[c].elements[a];if(!d&&b.layers){if(b.layers[a])d=b.layers[a];for(c=0;!d&&c<b.layers.length;c++)d=rcube_find_object(a,b.layers[c].document)}return d}
+"i")).test(a)?!0:!1;return!1}function rcube_clone_object(a){var b={},c;for(c in a)b[c]=a[c]&&typeof a[c]=="object"?clone_object(a[c]):a[c];return b}function urlencode(a){return window.encodeURIComponent?encodeURIComponent(a):escape(a)}
+function rcube_find_object(a,b){var c,d;b||(b=document);if(b.getElementsByName&&(c=b.getElementsByName(a)))d=c[0];!d&&b.getElementById&&(d=b.getElementById(a));!d&&b.all&&(d=b.all[a]);!d&&b.images.length&&(d=b.images[a]);if(!d&&b.forms.length)for(c=0;c<b.forms.length;c++)b.forms[c].name==a?d=b.forms[c]:b.forms[c].elements[a]&&(d=b.forms[c].elements[a]);if(!d&&b.layers){b.layers[a]&&(d=b.layers[a]);for(c=0;!d&&c<b.layers.length;c++)d=rcube_find_object(a,b.layers[c].document)}return d}
 function rcube_mouse_is_over(a,b){var c=rcube_event.get_mouse_pos(a),d=$(b).offset();return c.x>=d.left&&c.x<d.left+b.offsetWidth&&c.y>=d.top&&c.y<d.top+b.offsetHeight}function setCookie(a,b,c,d,e,f){a=a+"="+escape(b)+(c?"; expires="+c.toGMTString():"")+(d?"; path="+d:"")+(e?"; domain="+e:"")+(f?"; secure":"");document.cookie=a}
-function getCookie(a){var b=document.cookie;a+="=";var c=b.indexOf("; "+a);if(c==-1){c=b.indexOf(a);if(c!=0)return null}else c+=2;var d=document.cookie.indexOf(";",c);if(d==-1)d=b.length;return unescape(b.substring(c+a.length,d))}roundcube_browser.prototype.set_cookie=setCookie;roundcube_browser.prototype.get_cookie=getCookie;
-function rcube_console(){this.log=function(a){var b=rcube_find_object("dbgconsole");if(b){a+=a.charAt(a.length-1)=="\n"?"--------------------------------------\n":"\n--------------------------------------\n";if(bw.konq){b.innerText+=a;b.value=b.innerText}else b.value+=a}};this.reset=function(){var a=rcube_find_object("dbgconsole");if(a)a.innerText=a.value=""}}var bw=new roundcube_browser;bw.set_html_class();window.console||(console=new rcube_console);
-RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};if(bw.ie){document._getElementById=document.getElementById;document.getElementById=function(a){var b=0,c=document._getElementById(a);if(c&&c.id!=a)for(;(c=document.all[b])&&c.id!=a;)b++;return c}};
+function getCookie(a){var b=document.cookie;a+="=";var c=b.indexOf("; "+a);if(c==-1){if(c=b.indexOf(a),c!=0)return null}else c+=2;var d=document.cookie.indexOf(";",c);if(d==-1)d=b.length;return unescape(b.substring(c+a.length,d))}roundcube_browser.prototype.set_cookie=setCookie;roundcube_browser.prototype.get_cookie=getCookie;
+function rcube_console(){this.log=function(a){var b=rcube_find_object("dbgconsole");if(b)a+=a.charAt(a.length-1)=="\n"?"--------------------------------------\n":"\n--------------------------------------\n",bw.konq?(b.innerText+=a,b.value=b.innerText):b.value+=a};this.reset=function(){var a=rcube_find_object("dbgconsole");if(a)a.innerText=a.value=""}}var bw=new roundcube_browser;bw.set_html_class();window.console||(console=new rcube_console);
+RegExp.escape=function(a){return String(a).replace(/([.*+?^=!:${}()|[\]\/\\])/g,"\\$1")};if(bw.ie)document._getElementById=document.getElementById,document.getElementById=function(a){var b=0,c=document._getElementById(a);if(c&&c.id!=a)for(;(c=document.all[b])&&c.id!=a;)b++;return c};
index c0f53b194ac3d60e5c423d523879055a83b6b9bd..20d78ee4831cef3279f5126dbc022c24e2f0b9a9 100644 (file)
@@ -1,38 +1,38 @@
 var SPELL_CUR_LANG=null,GOOGIE_DEFAULT_LANG="en";
-function GoogieSpell(x,y){var m=this,u=getCookie("language");GOOGIE_CUR_LANG=u!=null?u:GOOGIE_DEFAULT_LANG;this.array_keys=function(a){var c=[],b;for(b in a)c.push([b]);return c};this.img_dir=x;this.server_url=y;this.lang_to_word=this.org_lang_to_word={da:"Dansk",de:"Deutsch",en:"English",es:"Espa&#241;ol",fr:"Fran&#231;ais",it:"Italiano",nl:"Nederlands",pl:"Polski",pt:"Portugu&#234;s",fi:"Suomi",sv:"Svenska"};this.langlist_codes=this.array_keys(this.lang_to_word);this.show_change_lang_pic=true;this.change_lang_pic_placement=
-"right";this.report_state_change=true;this.el_scroll_top=this.ta_scroll_top=0;this.lang_chck_spell="Check spelling";this.lang_revert="Revert to";this.lang_close="Close";this.lang_rsm_edt="Resume editing";this.lang_no_error_found="No spelling errors found";this.lang_no_suggestions="No suggestions";this.show_spell_img=false;this.decoration=true;this.use_close_btn=false;this.report_ta_not_found=this.edit_layer_dbl_click=true;this.custom_no_spelling_error=this.custom_ajax_error=null;this.custom_menu_builder=
-[];this.custom_item_evaulator=null;this.extra_menu_items=[];this.custom_spellcheck_starter=null;this.main_controller=true;this.all_errors_fixed_observer=this.show_menu_observer=this.spelling_state_observer=this.lang_state_observer=null;this.use_focus=false;this.focus_link_b=this.focus_link_t=null;this.cnt_errors_fixed=this.cnt_errors=0;$(document).bind("click",function(a){a=$(a.target);a.attr("googie_action_btn")!="1"&&m.isLangWindowShown()&&m.hideLangWindow();a.attr("googie_action_btn")!="1"&&m.isErrorWindowShown()&&
-m.hideErrorWindow()});this.decorateTextarea=function(a){if(this.text_area=typeof a=="string"?document.getElementById(a):a){if(!this.spell_container&&this.decoration){a=document.createElement("table");var c=document.createElement("tbody"),b=document.createElement("tr"),d=document.createElement("td"),e=this.isDefined(this.force_width)?this.force_width:this.text_area.offsetWidth,f=this.isDefined(this.force_height)?this.force_height:16;b.appendChild(d);c.appendChild(b);$(a).append(c).insertBefore(this.text_area).width("100%").height(f);
-$(d).height(f).width(e).css("text-align","right");this.spell_container=d}this.checkSpellingState()}else this.report_ta_not_found&&alert("Text area not found")};this.setSpellContainer=function(a){this.spell_container=typeof a=="string"?document.getElementById(a):a};this.setLanguages=function(a){this.lang_to_word=a;this.langlist_codes=this.array_keys(a)};this.setCurrentLanguage=function(a){GOOGIE_CUR_LANG=a;var c=new Date;c.setTime(c.getTime()+31536E6);setCookie("language",a,c)};this.setForceWidthHeight=
-function(a,c){this.force_width=a;this.force_height=c};this.setDecoration=function(a){this.decoration=a};this.dontUseCloseButtons=function(){this.use_close_btn=false};this.appendNewMenuItem=function(a,c,b){this.extra_menu_items.push([a,c,b])};this.appendCustomMenuBuilder=function(a,c){this.custom_menu_builder.push([a,c])};this.setFocus=function(){try{this.focus_link_b.focus();this.focus_link_t.focus();return true}catch(a){return false}};this.setStateChanged=function(a){this.state=a;this.spelling_state_observer!=
+function GoogieSpell(s,t){var l=this,r=getCookie("language");GOOGIE_CUR_LANG=r!=null?r:GOOGIE_DEFAULT_LANG;this.array_keys=function(a){var b=[],c;for(c in a)b.push([c]);return b};this.img_dir=s;this.server_url=t;this.lang_to_word=this.org_lang_to_word={da:"Dansk",de:"Deutsch",en:"English",es:"Espa&#241;ol",fr:"Fran&#231;ais",it:"Italiano",nl:"Nederlands",pl:"Polski",pt:"Portugu&#234;s",fi:"Suomi",sv:"Svenska"};this.langlist_codes=this.array_keys(this.lang_to_word);this.show_change_lang_pic=!0;this.change_lang_pic_placement=
+"right";this.report_state_change=!0;this.el_scroll_top=this.ta_scroll_top=0;this.lang_chck_spell="Check spelling";this.lang_revert="Revert to";this.lang_close="Close";this.lang_rsm_edt="Resume editing";this.lang_no_error_found="No spelling errors found";this.lang_no_suggestions="No suggestions";this.show_spell_img=!1;this.decoration=!0;this.use_close_btn=!1;this.report_ta_not_found=this.edit_layer_dbl_click=!0;this.custom_no_spelling_error=this.custom_ajax_error=null;this.custom_menu_builder=[];this.custom_item_evaulator=
+null;this.extra_menu_items=[];this.custom_spellcheck_starter=null;this.main_controller=!0;this.all_errors_fixed_observer=this.show_menu_observer=this.spelling_state_observer=this.lang_state_observer=null;this.use_focus=!1;this.focus_link_b=this.focus_link_t=null;this.cnt_errors_fixed=this.cnt_errors=0;$(document).bind("click",function(a){a=$(a.target);a.attr("googie_action_btn")!="1"&&l.isLangWindowShown()&&l.hideLangWindow();a.attr("googie_action_btn")!="1"&&l.isErrorWindowShown()&&l.hideErrorWindow()});
+this.decorateTextarea=function(a){if(this.text_area=typeof a=="string"?document.getElementById(a):a){if(!this.spell_container&&this.decoration){var a=document.createElement("table"),b=document.createElement("tbody"),c=document.createElement("tr"),d=document.createElement("td"),e=this.isDefined(this.force_width)?this.force_width:this.text_area.offsetWidth,f=this.isDefined(this.force_height)?this.force_height:16;c.appendChild(d);b.appendChild(c);$(a).append(b).insertBefore(this.text_area).width("100%").height(f);
+$(d).height(f).width(e).css("text-align","right");this.spell_container=d}this.checkSpellingState()}else this.report_ta_not_found&&alert("Text area not found")};this.setSpellContainer=function(a){this.spell_container=typeof a=="string"?document.getElementById(a):a};this.setLanguages=function(a){this.lang_to_word=a;this.langlist_codes=this.array_keys(a)};this.setCurrentLanguage=function(a){GOOGIE_CUR_LANG=a;var b=new Date;b.setTime(b.getTime()+31536E6);setCookie("language",a,b)};this.setForceWidthHeight=
+function(a,b){this.force_width=a;this.force_height=b};this.setDecoration=function(a){this.decoration=a};this.dontUseCloseButtons=function(){this.use_close_btn=!1};this.appendNewMenuItem=function(a,b,c){this.extra_menu_items.push([a,b,c])};this.appendCustomMenuBuilder=function(a,b){this.custom_menu_builder.push([a,b])};this.setFocus=function(){try{return this.focus_link_b.focus(),this.focus_link_t.focus(),!0}catch(a){return!1}};this.setStateChanged=function(a){this.state=a;this.spelling_state_observer!=
 null&&this.report_state_change&&this.spelling_state_observer(a,this)};this.setReportStateChange=function(a){this.report_state_change=a};this.getUrl=function(){return this.server_url+GOOGIE_CUR_LANG};this.escapeSpecial=function(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")};this.createXMLReq=function(a){return'<?xml version="1.0" encoding="utf-8" ?><spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1"><text>'+a+"</text></spellrequest>"};
-this.spellCheck=function(a){this.cnt_errors=this.cnt_errors_fixed=0;this.setStateChanged("checking_spell");this.main_controller&&this.appendIndicator(this.spell_span);this.error_links=[];this.ta_scroll_top=this.text_area.scrollTop;this.ignore=a;this.hideLangWindow();if($(this.text_area).val()==""||a){this.custom_no_spelling_error?this.custom_no_spelling_error(this):this.flashNoSpellingErrorState();this.removeIndicator()}else{this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight);
-this.createErrorWindow();$("body").append(this.error_window);try{netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead")}catch(c){}this.main_controller&&$(this.spell_span).unbind("click");this.orginal_text=$(this.text_area).val();a=this.escapeSpecial(this.orginal_text);var b=this;$.ajax({type:"POST",url:this.getUrl(),data:this.createXMLReq(a),dataType:"text",error:function(){b.custom_ajax_error?b.custom_ajax_error(b):alert("An error was encountered on the server. Please try again later.");
-if(b.main_controller){$(b.spell_span).remove();b.removeIndicator()}b.checkSpellingState()},success:function(d){b.results=b.parseResult(d);if(d.match(/<c.*>/)!=null){b.showErrorsInIframe();b.resumeEditingState()}else b.custom_no_spelling_error?b.custom_no_spelling_error(b):b.flashNoSpellingErrorState();b.removeIndicator()}})}};this.parseResult=function(a){var c=/\w+="(\d+|true)"/g,b=/\t/g;a=a.match(/<c[^>]*>[^<]*<\/c>/g);var d=[];if(a==null)return d;for(var e=0,f=a.length;e<f;e++){var j=[];this.errorFound();
-j.attrs=[];for(var g,h,n=a[e].match(c),k=0;k<n.length;k++){g=n[k].split(/=/);h=g[1].replace(/"/g,"");j.attrs[g[0]]=h!="true"?parseInt(h):h}j.suggestions=[];g=a[e].replace(/<[^>]*>/g,"").split(b);for(h=0;h<g.length;h++)g[h]!=""&&j.suggestions.push(g[h]);d.push(j)}return d};this.createErrorWindow=function(){this.error_window=document.createElement("div");$(this.error_window).addClass("googie_window popupmenu").attr("googie_action_btn","1")};this.isErrorWindowShown=function(){return $(this.error_window).is(":visible")};
-this.hideErrorWindow=function(){$(this.error_window).hide();$(this.error_window_iframe).hide()};this.updateOrginalText=function(a,c,b,d){var e=this.orginal_text.substring(0,a);a=this.orginal_text.substring(a+c.length);c=b.length-c.length;this.orginal_text=e+b+a;$(this.text_area).val(this.orginal_text);b=0;for(e=this.results.length;b<e;b++)if(b!=d&&b>d)this.results[b].attrs.o+=c};this.saveOldValue=function(a,c){a.is_changed=true;a.old_value=c};this.createListSeparator=function(){var a=document.createElement("td"),
-c=document.createElement("tr");$(a).html(" ").attr("googie_action_btn","1").css({cursor:"default","font-size":"3px","border-top":"1px solid #ccc","padding-top":"3px"});c.appendChild(a);return c};this.correctError=function(a,c,b,d){var e=c.innerHTML;b=b.nodeType==3?b.nodeValue:b.innerHTML;var f=this.results[a].attrs.o;if(d){d=c.previousSibling.innerHTML;c.previousSibling.innerHTML=d.slice(0,d.length-1);e=" "+e;f--}this.hideErrorWindow();this.updateOrginalText(f,e,b,a);$(c).html(b).css("color","green").attr("is_corrected",
-true);this.results[a].attrs.l=b.length;this.isDefined(c.old_value)||this.saveOldValue(c,e);this.errorFixed()};this.showErrorWindow=function(a,c){this.show_menu_observer&&this.show_menu_observer(this);var b=this,d=$(a).offset(),e=document.createElement("table"),f=document.createElement("tbody");$(this.error_window).html("");$(e).addClass("googie_list").attr("googie_action_btn","1");for(var j=false,g=0;g<this.custom_menu_builder.length;g++){var h=this.custom_menu_builder[g];if(h[0](this.results[c])){j=
-h[1](this,f,a);break}}if(!j){j=this.results[c].suggestions;var n=this.results[c].attrs.o;g=this.results[c].attrs.l;var k,l;if(j.length==0){h=document.createElement("tr");k=document.createElement("td");l=document.createElement("span");$(l).text(this.lang_no_suggestions);$(k).attr("googie_action_btn","1").css("cursor","default");k.appendChild(l);h.appendChild(k);f.appendChild(h)}var r=0;for(g=j.length;r<g;r++){h=document.createElement("tr");k=document.createElement("td");l=document.createElement("span");
-$(l).html(j[r]);$(k).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout).bind("click",function(p){b.correctError(c,a,p.target.firstChild)});k.appendChild(l);h.appendChild(k);f.appendChild(h)}if(a.is_changed&&a.innerHTML!=a.old_value){var s=a.old_value;j=document.createElement("tr");g=document.createElement("td");h=document.createElement("span");$(h).addClass("googie_list_revert").html(this.lang_revert+" "+s);$(g).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout).bind("click",
-function(){b.updateOrginalText(n,a.innerHTML,s,c);$(a).attr("is_corrected",true).css("color","#b91414").html(s);b.hideErrorWindow()});g.appendChild(h);j.appendChild(g);f.appendChild(j)}j=document.createElement("tr");g=document.createElement("td");var o=document.createElement("input");h=document.createElement("img");k=document.createElement("form");l=function(){if(o.value!=""){b.isDefined(a.old_value)||b.saveOldValue(a,a.innerHTML);b.updateOrginalText(n,a.innerHTML,o.value,c);$(a).attr("is_corrected",
-true).css("color","green").html(o.value);b.hideErrorWindow()}return false};$(o).width(120).css({margin:0,padding:0});$(o).val(a.innerHTML).attr("googie_action_btn","1");$(g).css("cursor","default").attr("googie_action_btn","1");$(h).attr("src",this.img_dir+"ok.gif").width(32).height(16).css({cursor:"pointer","margin-left":"2px","margin-right":"2px"}).bind("click",l);$(k).attr("googie_action_btn","1").css({margin:0,padding:0,cursor:"default","white-space":"nowrap"}).bind("submit",l);k.appendChild(o);
-k.appendChild(h);g.appendChild(k);j.appendChild(g);f.appendChild(j);this.extra_menu_items.length>0&&f.appendChild(this.createListSeparator());var t=function(p){if(p<b.extra_menu_items.length){var q=b.extra_menu_items[p];if(!q[2]||q[2](a,b)){var v=document.createElement("tr"),w=document.createElement("td");$(w).html(q[0]).bind("mouseover",b.item_onmouseover).bind("mouseout",b.item_onmouseout).bind("click",function(){return q[1](a,b)});v.appendChild(w);f.appendChild(v)}t(p+1)}};t(0);t=null;this.use_close_btn&&
-f.appendChild(this.createCloseButton(this.hideErrorWindow))}e.appendChild(f);this.error_window.appendChild(e);g=$(this.error_window).height();e=$(this.error_window).width();h=$(document).height();j=$(document).width();g=d.top+g+20<h?d.top+20:d.top-g;d=d.left+e<j?d.left:d.left-e;$(this.error_window).css({top:g+"px",left:d+"px"}).show();if($.browser.msie){if(!this.error_window_iframe){d=$("<iframe>").css({position:"absolute","z-index":-1});$("body").append(d);this.error_window_iframe=d}$(this.error_window_iframe).css({top:this.error_window.offsetTop,
-left:this.error_window.offsetLeft,width:this.error_window.offsetWidth,height:this.error_window.offsetHeight}).show()}};this.createEditLayer=function(a,c){this.edit_layer=document.createElement("div");$(this.edit_layer).addClass("googie_edit_layer").attr("id","googie_edit_layer").width("auto").height(c);this.text_area.nodeName.toLowerCase()!="input"||$(this.text_area).val()==""?$(this.edit_layer).css("overflow","auto").height(c-4):$(this.edit_layer).css("overflow","hidden");var b=this;this.edit_layer_dbl_click&&
-$(this.edit_layer).dblclick(function(d){if(d.target.className!="googie_link"&&!b.isErrorWindowShown()){b.resumeEditing();var e=function(){$(b.text_area).focus();e=null};window.setTimeout(e,10)}return false})};this.resumeEditing=function(){this.setStateChanged("ready");if(this.edit_layer)this.el_scroll_top=this.edit_layer.scrollTop;this.hideErrorWindow();this.main_controller&&$(this.spell_span).removeClass().addClass("googie_no_style");if(!this.ignore){if(this.use_focus){$(this.focus_link_t).remove();
-$(this.focus_link_b).remove()}$(this.edit_layer).remove();$(this.text_area).show();if(this.el_scroll_top!=undefined)this.text_area.scrollTop=this.el_scroll_top}this.checkSpellingState(false)};this.createErrorLink=function(a,c){var b=document.createElement("span"),d=this,e=function(){d.showErrorWindow(b,c);e=null;return false};$(b).html(a).addClass("googie_link").bind("click",e).attr({googie_action_btn:"1",g_id:c,is_corrected:false});return b};this.createPart=function(a){if(a==" ")return document.createTextNode(" ");
-a=this.escapeSpecial(a);a=a.replace(/\n/g,"<br>");a=a.replace(/    /g," &nbsp;");a=a.replace(/^ /g,"&nbsp;");a=a.replace(/ $/g,"&nbsp;");var c=document.createElement("span");$(c).html(a);return c};this.showErrorsInIframe=function(){var a=document.createElement("div"),c=0,b=this.results;if(b.length>0){for(var d=0,e=b.length;d<e;d++){var f=b[d].attrs.o,j=b[d].attrs.l,g=this.createPart(this.orginal_text.substring(c,f));a.appendChild(g);c+=f-c;f=this.createErrorLink(this.orginal_text.substr(f,j),d);this.error_links.push(f);
-a.appendChild(f);c+=j}c=this.createPart(this.orginal_text.substr(c,this.orginal_text.length));a.appendChild(c)}else a.innerHTML=this.orginal_text;$(a).css("text-align","left");var h=this;this.custom_item_evaulator&&$.map(this.error_links,function(n){h.custom_item_evaulator(h,n)});$(this.edit_layer).append(a);$(this.text_area).hide();$(this.edit_layer).insertBefore(this.text_area);if(this.use_focus){this.focus_link_t=this.createFocusLink("focus_t");this.focus_link_b=this.createFocusLink("focus_b");
-$(this.focus_link_t).insertBefore(this.edit_layer);$(this.focus_link_b).insertAfter(this.edit_layer)}};this.createLangWindow=function(){this.language_window=document.createElement("div");$(this.language_window).addClass("googie_window popupmenu").width(100).attr("googie_action_btn","1");var a=document.createElement("table"),c=document.createElement("tbody"),b=this,d,e,f;$(a).addClass("googie_list").width("100%");this.lang_elms=[];for(i=0;i<this.langlist_codes.length;i++){d=document.createElement("tr");
-e=document.createElement("td");f=document.createElement("span");$(f).text(this.lang_to_word[this.langlist_codes[i]]);this.lang_elms.push(e);$(e).attr("googieId",this.langlist_codes[i]).bind("click",function(){b.deHighlightCurSel();b.setCurrentLanguage($(this).attr("googieId"));b.lang_state_observer!=null&&b.lang_state_observer();b.highlightCurSel();b.hideLangWindow()}).bind("mouseover",function(){if(this.className!="googie_list_selected")this.className="googie_list_onhover"}).bind("mouseout",function(){if(this.className!=
-"googie_list_selected")this.className="googie_list_onout"});e.appendChild(f);d.appendChild(e);c.appendChild(d)}this.use_close_btn&&c.appendChild(this.createCloseButton(function(){b.hideLangWindow.apply(b)}));this.highlightCurSel();a.appendChild(c);this.language_window.appendChild(a)};this.isLangWindowShown=function(){return $(this.language_window).is(":visible")};this.hideLangWindow=function(){$(this.language_window).hide();$(this.switch_lan_pic).removeClass().addClass("googie_lang_3d_on")};this.showLangWindow=
-function(a){this.show_menu_observer&&this.show_menu_observer(this);this.createLangWindow();$("body").append(this.language_window);var c=$(a).offset(),b=$(a).height(),d=$(a).width();a=$(this.language_window).height();var e=$(document).height();d=this.change_lang_pic_placement=="right"?c.left-100+d:c.left+d;c=c.top+a<e?c.top+b:c.top-a-4;$(this.language_window).css({top:c+"px",left:d+"px"}).show();this.highlightCurSel()};this.deHighlightCurSel=function(){$(this.lang_cur_elm).removeClass().addClass("googie_list_onout")};
-this.highlightCurSel=function(){if(GOOGIE_CUR_LANG==null)GOOGIE_CUR_LANG=GOOGIE_DEFAULT_LANG;for(var a=0;a<this.lang_elms.length;a++)if($(this.lang_elms[a]).attr("googieId")==GOOGIE_CUR_LANG){this.lang_elms[a].className="googie_list_selected";this.lang_cur_elm=this.lang_elms[a]}else this.lang_elms[a].className="googie_list_onout"};this.createChangeLangPic=function(){var a=$("<img>").attr({src:this.img_dir+"change_lang.gif",alt:"Change language",googie_action_btn:"1"}),c=document.createElement("span");
-m=this;$(c).addClass("googie_lang_3d_on").append(a).bind("click",function(){var b=this.tagName.toLowerCase()=="img"?this.parentNode:this;if($(b).hasClass("googie_lang_3d_click")){b.className="googie_lang_3d_on";m.hideLangWindow()}else{b.className="googie_lang_3d_click";m.showLangWindow(b)}});return c};this.createSpellDiv=function(){var a=document.createElement("span");$(a).addClass("googie_check_spelling_link").text(this.lang_chck_spell);this.show_spell_img&&$(a).append(" ").append($("<img>").attr("src",
-this.img_dir+"spellc.gif"));return a};this.flashNoSpellingErrorState=function(a){this.setStateChanged("no_error_found");var c=this;if(this.main_controller){var b;b=a?function(){a();c.checkSpellingState()}:function(){c.checkSpellingState()};var d=$("<span>").text(this.lang_no_error_found);$(this.switch_lan_pic).hide();$(this.spell_span).empty().append(d).removeClass().addClass("googie_check_spelling_ok");window.setTimeout(b,1E3)}};this.resumeEditingState=function(){this.setStateChanged("resume_editing");
-if(this.main_controller){var a=$("<span>").text(this.lang_rsm_edt),c=this;$(this.switch_lan_pic).hide();$(this.spell_span).empty().unbind().append(a).bind("click",function(){c.resumeEditing()}).removeClass().addClass("googie_resume_editing")}try{this.edit_layer.scrollTop=this.ta_scroll_top}catch(b){}};this.checkSpellingState=function(a){a&&this.setStateChanged("ready");this.switch_lan_pic=this.show_change_lang_pic?this.createChangeLangPic():document.createElement("span");a=this.createSpellDiv();var c=
-this;this.custom_spellcheck_starter?$(a).bind("click",function(){c.custom_spellcheck_starter()}):$(a).bind("click",function(){c.spellCheck()});if(this.main_controller)this.change_lang_pic_placement=="left"?$(this.spell_container).empty().append(this.switch_lan_pic).append(" ").append(a):$(this.spell_container).empty().append(a).append(" ").append(this.switch_lan_pic);this.spell_span=a};this.isDefined=function(a){return a!="undefined"&&a!=null};this.errorFixed=function(){this.cnt_errors_fixed++;if(this.all_errors_fixed_observer)if(this.cnt_errors_fixed==
-this.cnt_errors){this.hideErrorWindow();this.all_errors_fixed_observer()}};this.errorFound=function(){this.cnt_errors++};this.createCloseButton=function(a){return this.createButton(this.lang_close,"googie_list_close",a)};this.createButton=function(a,c,b){var d=document.createElement("tr"),e=document.createElement("td"),f;if(c){f=document.createElement("span");$(f).addClass(c).html(a)}else f=document.createTextNode(a);$(e).bind("click",b).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout);
-e.appendChild(f);d.appendChild(e);return d};this.removeIndicator=function(){window.rcmail&&rcmail.set_busy(false,null,this.rc_msg_id)};this.appendIndicator=function(){if(window.rcmail)this.rc_msg_id=rcmail.set_busy(true,"checking")};this.createFocusLink=function(a){var c=document.createElement("a");$(c).attr({href:"javascript:;",name:a});return c};this.item_onmouseover=function(){if(this.className!="googie_list_revert"&&this.className!="googie_list_close")this.className="googie_list_onhover";else this.parentNode.className=
-"googie_list_onhover"};this.item_onmouseout=function(){if(this.className!="googie_list_revert"&&this.className!="googie_list_close")this.className="googie_list_onout";else this.parentNode.className="googie_list_onout"}};
+this.spellCheck=function(a){this.cnt_errors=this.cnt_errors_fixed=0;this.setStateChanged("checking_spell");this.main_controller&&this.appendIndicator(this.spell_span);this.error_links=[];this.ta_scroll_top=this.text_area.scrollTop;this.ignore=a;this.hideLangWindow();if($(this.text_area).val()==""||a)this.custom_no_spelling_error?this.custom_no_spelling_error(this):this.flashNoSpellingErrorState(),this.removeIndicator();else{this.createEditLayer(this.text_area.offsetWidth,this.text_area.offsetHeight);
+this.createErrorWindow();$("body").append(this.error_window);try{netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead")}catch(b){}this.main_controller&&$(this.spell_span).unbind("click");this.orginal_text=$(this.text_area).val();var a=this.escapeSpecial(this.orginal_text),c=this;$.ajax({type:"POST",url:this.getUrl(),data:this.createXMLReq(a),dataType:"text",error:function(){c.custom_ajax_error?c.custom_ajax_error(c):alert("An error was encountered on the server. Please try again later.");
+c.main_controller&&($(c.spell_span).remove(),c.removeIndicator());c.checkSpellingState()},success:function(a){c.results=c.parseResult(a);a.match(/<c.*>/)!=null?(c.showErrorsInIframe(),c.resumeEditingState()):c.custom_no_spelling_error?c.custom_no_spelling_error(c):c.flashNoSpellingErrorState();c.removeIndicator()}})}};this.parseResult=function(a){var b=/\w+="(\d+|true)"/g,c=/\t/g,a=a.match(/<c[^>]*>[^<]*<\/c>/g),d=[];if(a==null)return d;for(var e=0,f=a.length;e<f;e++){var j=[];this.errorFound();j.attrs=
+[];for(var g,h,l=a[e].match(b),k=0;k<l.length;k++)g=l[k].split(/=/),h=g[1].replace(/"/g,""),j.attrs[g[0]]=h!="true"?parseInt(h):h;j.suggestions=[];g=a[e].replace(/<[^>]*>/g,"").split(c);for(h=0;h<g.length;h++)g[h]!=""&&j.suggestions.push(g[h]);d.push(j)}return d};this.createErrorWindow=function(){this.error_window=document.createElement("div");$(this.error_window).addClass("googie_window popupmenu").attr("googie_action_btn","1")};this.isErrorWindowShown=function(){return $(this.error_window).is(":visible")};
+this.hideErrorWindow=function(){$(this.error_window).hide();$(this.error_window_iframe).hide()};this.updateOrginalText=function(a,b,c,d){var e=this.orginal_text.substring(0,a),a=this.orginal_text.substring(a+b.length),b=c.length-b.length;this.orginal_text=e+c+a;$(this.text_area).val(this.orginal_text);c=0;for(e=this.results.length;c<e;c++)c!=d&&c>d&&(this.results[c].attrs.o+=b)};this.saveOldValue=function(a,b){a.is_changed=!0;a.old_value=b};this.createListSeparator=function(){var a=document.createElement("td"),
+b=document.createElement("tr");$(a).html(" ").attr("googie_action_btn","1").css({cursor:"default","font-size":"3px","border-top":"1px solid #ccc","padding-top":"3px"});b.appendChild(a);return b};this.correctError=function(a,b,c,d){var e=b.innerHTML,c=c.nodeType==3?c.nodeValue:c.innerHTML,f=this.results[a].attrs.o;if(d)d=b.previousSibling.innerHTML,b.previousSibling.innerHTML=d.slice(0,d.length-1),e=" "+e,f--;this.hideErrorWindow();this.updateOrginalText(f,e,c,a);$(b).html(c).css("color","green").attr("is_corrected",
+!0);this.results[a].attrs.l=c.length;this.isDefined(b.old_value)||this.saveOldValue(b,e);this.errorFixed()};this.showErrorWindow=function(a,b){this.show_menu_observer&&this.show_menu_observer(this);var c=this,d=$(a).offset(),e=document.createElement("table"),f=document.createElement("tbody");$(this.error_window).html("");$(e).addClass("googie_list").attr("googie_action_btn","1");for(var j=!1,g=0;g<this.custom_menu_builder.length;g++){var h=this.custom_menu_builder[g];if(h[0](this.results[b])){j=h[1](this,
+f,a);break}}if(!j){var j=this.results[b].suggestions,l=this.results[b].attrs.o,g=this.results[b].attrs.l,k,m;j.length==0&&(h=document.createElement("tr"),k=document.createElement("td"),m=document.createElement("span"),$(m).text(this.lang_no_suggestions),$(k).attr("googie_action_btn","1").css("cursor","default"),k.appendChild(m),h.appendChild(k),f.appendChild(h));for(var o=0,g=j.length;o<g;o++)h=document.createElement("tr"),k=document.createElement("td"),m=document.createElement("span"),$(m).html(j[o]),
+$(k).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout).bind("click",function(d){c.correctError(b,a,d.target.firstChild)}),k.appendChild(m),h.appendChild(k),f.appendChild(h);if(a.is_changed&&a.innerHTML!=a.old_value){var p=a.old_value,j=document.createElement("tr"),g=document.createElement("td"),h=document.createElement("span");$(h).addClass("googie_list_revert").html(this.lang_revert+" "+p);$(g).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout).bind("click",
+function(){c.updateOrginalText(l,a.innerHTML,p,b);$(a).attr("is_corrected",!0).css("color","#b91414").html(p);c.hideErrorWindow()});g.appendChild(h);j.appendChild(g);f.appendChild(j)}var j=document.createElement("tr"),g=document.createElement("td"),n=document.createElement("input"),h=document.createElement("img");k=document.createElement("form");m=function(){n.value!=""&&(c.isDefined(a.old_value)||c.saveOldValue(a,a.innerHTML),c.updateOrginalText(l,a.innerHTML,n.value,b),$(a).attr("is_corrected",
+!0).css("color","green").html(n.value),c.hideErrorWindow());return!1};$(n).width(120).css({margin:0,padding:0});$(n).val(a.innerHTML).attr("googie_action_btn","1");$(g).css("cursor","default").attr("googie_action_btn","1");$(h).attr("src",this.img_dir+"ok.gif").width(32).height(16).css({cursor:"pointer","margin-left":"2px","margin-right":"2px"}).bind("click",m);$(k).attr("googie_action_btn","1").css({margin:0,padding:0,cursor:"default","white-space":"nowrap"}).bind("submit",m);k.appendChild(n);k.appendChild(h);
+g.appendChild(k);j.appendChild(g);f.appendChild(j);this.extra_menu_items.length>0&&f.appendChild(this.createListSeparator());var q=function(b){if(b<c.extra_menu_items.length){var d=c.extra_menu_items[b];if(!d[2]||d[2](a,c)){var e=document.createElement("tr"),g=document.createElement("td");$(g).html(d[0]).bind("mouseover",c.item_onmouseover).bind("mouseout",c.item_onmouseout).bind("click",function(){return d[1](a,c)});e.appendChild(g);f.appendChild(e)}q(b+1)}};q(0);q=null;this.use_close_btn&&f.appendChild(this.createCloseButton(this.hideErrorWindow))}e.appendChild(f);
+this.error_window.appendChild(e);g=$(this.error_window).height();e=$(this.error_window).width();h=$(document).height();j=$(document).width();g=d.top+g+20<h?d.top+20:d.top-g;d=d.left+e<j?d.left:d.left-e;$(this.error_window).css({top:g+"px",left:d+"px"}).show();if($.browser.msie){if(!this.error_window_iframe)d=$("<iframe>").css({position:"absolute","z-index":-1}),$("body").append(d),this.error_window_iframe=d;$(this.error_window_iframe).css({top:this.error_window.offsetTop,left:this.error_window.offsetLeft,
+width:this.error_window.offsetWidth,height:this.error_window.offsetHeight}).show()}};this.createEditLayer=function(a,b){this.edit_layer=document.createElement("div");$(this.edit_layer).addClass("googie_edit_layer").attr("id","googie_edit_layer").width("auto").height(b);this.text_area.nodeName.toLowerCase()!="input"||$(this.text_area).val()==""?$(this.edit_layer).css("overflow","auto").height(b-4):$(this.edit_layer).css("overflow","hidden");var c=this;this.edit_layer_dbl_click&&$(this.edit_layer).dblclick(function(a){if(a.target.className!=
+"googie_link"&&!c.isErrorWindowShown()){c.resumeEditing();var b=function(){$(c.text_area).focus();b=null};window.setTimeout(b,10)}return!1})};this.resumeEditing=function(){this.setStateChanged("ready");if(this.edit_layer)this.el_scroll_top=this.edit_layer.scrollTop;this.hideErrorWindow();this.main_controller&&$(this.spell_span).removeClass().addClass("googie_no_style");if(!this.ignore&&(this.use_focus&&($(this.focus_link_t).remove(),$(this.focus_link_b).remove()),$(this.edit_layer).remove(),$(this.text_area).show(),
+this.el_scroll_top!=void 0))this.text_area.scrollTop=this.el_scroll_top;this.checkSpellingState(!1)};this.createErrorLink=function(a,b){var c=document.createElement("span"),d=this,e=function(){d.showErrorWindow(c,b);e=null;return!1};$(c).html(a).addClass("googie_link").bind("click",e).attr({googie_action_btn:"1",g_id:b,is_corrected:!1});return c};this.createPart=function(a){if(a==" ")return document.createTextNode(" ");var a=this.escapeSpecial(a),a=a.replace(/\n/g,"<br>"),a=a.replace(/    /g," &nbsp;"),
+a=a.replace(/^ /g,"&nbsp;"),a=a.replace(/ $/g,"&nbsp;"),b=document.createElement("span");$(b).html(a);return b};this.showErrorsInIframe=function(){var a=document.createElement("div"),b=0,c=this.results;if(c.length>0){for(var d=0,e=c.length;d<e;d++){var f=c[d].attrs.o,j=c[d].attrs.l,g=this.createPart(this.orginal_text.substring(b,f));a.appendChild(g);b+=f-b;f=this.createErrorLink(this.orginal_text.substr(f,j),d);this.error_links.push(f);a.appendChild(f);b+=j}b=this.createPart(this.orginal_text.substr(b,
+this.orginal_text.length));a.appendChild(b)}else a.innerHTML=this.orginal_text;$(a).css("text-align","left");var h=this;this.custom_item_evaulator&&$.map(this.error_links,function(a){h.custom_item_evaulator(h,a)});$(this.edit_layer).append(a);$(this.text_area).hide();$(this.edit_layer).insertBefore(this.text_area);if(this.use_focus)this.focus_link_t=this.createFocusLink("focus_t"),this.focus_link_b=this.createFocusLink("focus_b"),$(this.focus_link_t).insertBefore(this.edit_layer),$(this.focus_link_b).insertAfter(this.edit_layer)};
+this.createLangWindow=function(){this.language_window=document.createElement("div");$(this.language_window).addClass("googie_window popupmenu").width(100).attr("googie_action_btn","1");var a=document.createElement("table"),b=document.createElement("tbody"),c=this,d,e,f;$(a).addClass("googie_list").width("100%");this.lang_elms=[];for(i=0;i<this.langlist_codes.length;i++)d=document.createElement("tr"),e=document.createElement("td"),f=document.createElement("span"),$(f).text(this.lang_to_word[this.langlist_codes[i]]),
+this.lang_elms.push(e),$(e).attr("googieId",this.langlist_codes[i]).bind("click",function(){c.deHighlightCurSel();c.setCurrentLanguage($(this).attr("googieId"));c.lang_state_observer!=null&&c.lang_state_observer();c.highlightCurSel();c.hideLangWindow()}).bind("mouseover",function(){if(this.className!="googie_list_selected")this.className="googie_list_onhover"}).bind("mouseout",function(){if(this.className!="googie_list_selected")this.className="googie_list_onout"}),e.appendChild(f),d.appendChild(e),
+b.appendChild(d);this.use_close_btn&&b.appendChild(this.createCloseButton(function(){c.hideLangWindow.apply(c)}));this.highlightCurSel();a.appendChild(b);this.language_window.appendChild(a)};this.isLangWindowShown=function(){return $(this.language_window).is(":visible")};this.hideLangWindow=function(){$(this.language_window).hide();$(this.switch_lan_pic).removeClass().addClass("googie_lang_3d_on")};this.showLangWindow=function(a){this.show_menu_observer&&this.show_menu_observer(this);this.createLangWindow();
+$("body").append(this.language_window);var b=$(a).offset(),c=$(a).height(),d=$(a).width(),a=$(this.language_window).height(),e=$(document).height(),d=this.change_lang_pic_placement=="right"?b.left-100+d:b.left+d,b=b.top+a<e?b.top+c:b.top-a-4;$(this.language_window).css({top:b+"px",left:d+"px"}).show();this.highlightCurSel()};this.deHighlightCurSel=function(){$(this.lang_cur_elm).removeClass().addClass("googie_list_onout")};this.highlightCurSel=function(){GOOGIE_CUR_LANG==null&&(GOOGIE_CUR_LANG=GOOGIE_DEFAULT_LANG);
+for(var a=0;a<this.lang_elms.length;a++)$(this.lang_elms[a]).attr("googieId")==GOOGIE_CUR_LANG?(this.lang_elms[a].className="googie_list_selected",this.lang_cur_elm=this.lang_elms[a]):this.lang_elms[a].className="googie_list_onout"};this.createChangeLangPic=function(){var a=$("<img>").attr({src:this.img_dir+"change_lang.gif",alt:"Change language",googie_action_btn:"1"}),b=document.createElement("span");l=this;$(b).addClass("googie_lang_3d_on").append(a).bind("click",function(){var a=this.tagName.toLowerCase()==
+"img"?this.parentNode:this;$(a).hasClass("googie_lang_3d_click")?(a.className="googie_lang_3d_on",l.hideLangWindow()):(a.className="googie_lang_3d_click",l.showLangWindow(a))});return b};this.createSpellDiv=function(){var a=document.createElement("span");$(a).addClass("googie_check_spelling_link").text(this.lang_chck_spell);this.show_spell_img&&$(a).append(" ").append($("<img>").attr("src",this.img_dir+"spellc.gif"));return a};this.flashNoSpellingErrorState=function(a){this.setStateChanged("no_error_found");
+var b=this;if(this.main_controller){var c;c=a?function(){a();b.checkSpellingState()}:function(){b.checkSpellingState()};var d=$("<span>").text(this.lang_no_error_found);$(this.switch_lan_pic).hide();$(this.spell_span).empty().append(d).removeClass().addClass("googie_check_spelling_ok");window.setTimeout(c,1E3)}};this.resumeEditingState=function(){this.setStateChanged("resume_editing");if(this.main_controller){var a=$("<span>").text(this.lang_rsm_edt),b=this;$(this.switch_lan_pic).hide();$(this.spell_span).empty().unbind().append(a).bind("click",
+function(){b.resumeEditing()}).removeClass().addClass("googie_resume_editing")}try{this.edit_layer.scrollTop=this.ta_scroll_top}catch(c){}};this.checkSpellingState=function(a){a&&this.setStateChanged("ready");this.switch_lan_pic=this.show_change_lang_pic?this.createChangeLangPic():document.createElement("span");var a=this.createSpellDiv(),b=this;this.custom_spellcheck_starter?$(a).bind("click",function(){b.custom_spellcheck_starter()}):$(a).bind("click",function(){b.spellCheck()});this.main_controller&&
+(this.change_lang_pic_placement=="left"?$(this.spell_container).empty().append(this.switch_lan_pic).append(" ").append(a):$(this.spell_container).empty().append(a).append(" ").append(this.switch_lan_pic));this.spell_span=a};this.isDefined=function(a){return a!="undefined"&&a!=null};this.errorFixed=function(){this.cnt_errors_fixed++;this.all_errors_fixed_observer&&this.cnt_errors_fixed==this.cnt_errors&&(this.hideErrorWindow(),this.all_errors_fixed_observer())};this.errorFound=function(){this.cnt_errors++};
+this.createCloseButton=function(a){return this.createButton(this.lang_close,"googie_list_close",a)};this.createButton=function(a,b,c){var d=document.createElement("tr"),e=document.createElement("td"),f;b?(f=document.createElement("span"),$(f).addClass(b).html(a)):f=document.createTextNode(a);$(e).bind("click",c).bind("mouseover",this.item_onmouseover).bind("mouseout",this.item_onmouseout);e.appendChild(f);d.appendChild(e);return d};this.removeIndicator=function(){window.rcmail&&rcmail.set_busy(!1,
+null,this.rc_msg_id)};this.appendIndicator=function(){if(window.rcmail)this.rc_msg_id=rcmail.set_busy(!0,"checking")};this.createFocusLink=function(a){var b=document.createElement("a");$(b).attr({href:"javascript:;",name:a});return b};this.item_onmouseover=function(){this.className!="googie_list_revert"&&this.className!="googie_list_close"?this.className="googie_list_onhover":this.parentNode.className="googie_list_onhover"};this.item_onmouseout=function(){this.className!="googie_list_revert"&&this.className!=
+"googie_list_close"?this.className="googie_list_onout":this.parentNode.className="googie_list_onout"}};
index 5792ff907c20234e79c07607dc7e5211eff9f803..00410b7263f1ae97eba6141cee05644bdc2ca58b 100644 (file)
@@ -1,40 +1,39 @@
-function rcube_list_widget(a,b){this.ENTER_KEY=13;this.DELETE_KEY=46;this.BACKSPACE_KEY=8;this.list=a?a:null;this.frame=null;this.rows=[];this.selection=[];this.colcount=this.rowcount=0;this.subject_col=-1;this.col_drag_active=this.drag_active=this.dont_select=this.toggleselect=this.keyboard=this.column_movable=this.draggable=this.multi_selecting=this.multiexpand=this.multiselect=this.shiftkey=false;this.column_fixed=null;this.shift_start=this.last_selected=0;this.focused=this.in_selection_before=
-false;this.drag_mouse_start=null;this.dblclick_time=600;this.row_init=function(){};if(b&&typeof b=="object")for(var c in b)this[c]=b[c]}
-rcube_list_widget.prototype={init:function(){if(this.list&&this.list.tBodies[0]){this.rows=[];this.rowcount=0;var a,b,c=this.list.tBodies[0].rows;a=0;for(b=c.length;a<b;a++){this.init_row(c[a]);this.rowcount++}this.init_header();this.frame=this.list.parentNode;if(this.keyboard){rcube_event.add_listener({event:bw.opera?"keypress":"keydown",object:this,method:"key_press"});rcube_event.add_listener({event:"keydown",object:this,method:"key_down"})}}},init_row:function(a){if(a&&String(a.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)){var b=
-this,c=RegExp.$1;a.uid=c;this.rows[c]={uid:c,id:a.id,obj:a};a.onmousedown=function(d){return b.drag_row(d,this.uid)};a.onmouseup=function(d){return b.click_row(d,this.uid)};if(bw.iphone||bw.ipad){a.addEventListener("touchstart",function(d){if(d.touches.length==1)b.drag_row(rcube_event.touchevent(d.touches[0]),this.uid)||d.preventDefault()},false);a.addEventListener("touchend",function(d){if(d.changedTouches.length==1)b.click_row(rcube_event.touchevent(d.changedTouches[0]),this.uid)||d.preventDefault()},
-false)}if(document.all)a.onselectstart=function(){return false};this.row_init(this.rows[c])}},init_header:function(){if(this.list&&this.list.tHead){this.colcount=0;var a,b,c=this;if(this.column_movable&&this.list.tHead&&this.list.tHead.rows)for(b=0;b<this.list.tHead.rows[0].cells.length;b++)if(this.column_fixed!=b){a=this.list.tHead.rows[0].cells[b];a.onmousedown=function(d){return c.drag_column(d,this)};this.colcount++}}},clear:function(a){this.list.insertBefore(document.createElement("tbody"),this.list.tBodies[0]);
-this.list.removeChild(this.list.tBodies[1]);this.rows=[];this.rowcount=0;a&&this.clear_selection()},remove_row:function(a,b){if(this.rows[a].obj)this.rows[a].obj.style.display="none";b&&this.select_next();delete this.rows[a];this.rowcount--},insert_row:function(a,b){var c=this.list.tBodies[0];b&&c.rows.length?c.insertBefore(a,c.firstChild):c.appendChild(a);this.init_row(a);this.rowcount++},focus:function(a){var b;this.focused=true;for(var c in this.selection){b=this.selection[c];this.rows[b]&&this.rows[b].obj&&
-$(this.rows[b].obj).addClass("selected").removeClass("unfocused")}$("*:focus",window).blur();$("iframe").each(function(){this.blur()});if(a||(a=window.event))rcube_event.cancel(a)},blur:function(){var a;this.focused=false;for(var b in this.selection){a=this.selection[b];this.rows[a]&&this.rows[a].obj&&$(this.rows[a].obj).removeClass("selected").addClass("unfocused")}},drag_column:function(a,b){if(this.colcount>1){this.drag_start=true;this.drag_mouse_start=rcube_event.get_mouse_pos(a);rcube_event.add_listener({event:"mousemove",
-object:this,method:"column_drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.add_dragfix();for(var c=0;c<this.list.tHead.rows[0].cells.length;c++)if(b==this.list.tHead.rows[0].cells[c]){this.selected_column=c;break}}return false},drag_row:function(a,b){var c=rcube_event.get_target(a),d=c.tagName.toLowerCase();if(this.dont_select||c&&(d=="input"||d=="img"))return true;if(rcube_event.get_button(a)==2)return true;this.in_selection_before=this.in_selection(b)?
-b:false;if(!this.in_selection_before){c=rcube_event.get_modifier(a);this.select_row(b,c,false)}if(this.draggable&&this.selection.length){this.drag_start=true;this.drag_mouse_start=rcube_event.get_mouse_pos(a);rcube_event.add_listener({event:"mousemove",object:this,method:"drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"drag_mouse_up"});if(bw.iphone||bw.ipad){rcube_event.add_listener({event:"touchmove",object:this,method:"drag_mouse_move"});rcube_event.add_listener({event:"touchend",
-object:this,method:"drag_mouse_up"})}this.add_dragfix()}return false},click_row:function(a,b){var c=(new Date).getTime(),d=rcube_event.get_modifier(a),e=rcube_event.get_target(a),f=e.tagName.toLowerCase();if(e&&(f=="input"||f=="img"))return true;if(this.dont_select)return this.dont_select=false;e=c-this.rows[b].clicked<this.dblclick_time;!this.drag_active&&this.in_selection_before==b&&!e&&this.select_row(b,d,false);this.in_selection_before=this.drag_start=false;this.rows&&e&&this.in_selection(b)?
-this.triggerEvent("dblclick"):this.triggerEvent("click");if(!this.drag_active){this.del_dragfix();rcube_event.cancel(a)}this.rows[b].clicked=c;return false},find_root:function(a){var b=this.rows[a];return b&&b.parent_uid?this.find_root(b.parent_uid):a},expand_row:function(a,b){var c=this.rows[b],d=rcube_event.get_target(a),e=rcube_event.get_modifier(a);this.dont_select=true;c.clicked=0;if(c.expanded){d.className="collapsed";e==CONTROL_KEY||this.multiexpand?this.collapse_all(c):this.collapse(c)}else{d.className=
-"expanded";e==CONTROL_KEY||this.multiexpand?this.expand_all(c):this.expand(c)}},collapse:function(a){a.expanded=false;this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded});var b=a.depth;a=a?a.obj.nextSibling:null;for(var c;a;){if(a.nodeType==1){if((c=this.rows[a.uid])&&c.depth<=b)break;$(a).css("display","none");if(c.expanded){c.expanded=false;this.triggerEvent("expandcollapse",{uid:c.uid,expanded:c.expanded})}}a=a.nextSibling}return false},expand:function(a){var b,c,d;if(a){a.expanded=
-true;b=a.depth;c=a.obj.nextSibling;this.update_expando(a.uid,true);this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded})}else{c=this.list.tBodies[0].firstChild;d=b=0}for(;c;){if(c.nodeType==1){var e=this.rows[c.uid];if(e){if(a&&(!e.depth||e.depth<=b))break;if(e.parent_uid){var f=this.rows[e.parent_uid];if(f&&f.expanded){if(a&&f==a||d>=f.depth-1){d=f.depth;$(c).css("display","");e.expanded=true;this.triggerEvent("expandcollapse",{uid:e.uid,expanded:e.expanded})}}else if(a&&(!f||f.depth<=
-b))break}}}c=c.nextSibling}return false},collapse_all:function(a){var b,c,d;if(a){a.expanded=false;b=a.depth;c=a.obj.nextSibling;this.update_expando(a.uid);this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded});if(b&&this.multiexpand)return false}else{c=this.list.tBodies[0].firstChild;b=0}for(;c;){if(c.nodeType==1)if(d=this.rows[c.uid]){if(a&&(!d.depth||d.depth<=b))break;if(a||d.depth)$(c).css("display","none");if(d.has_children&&d.expanded){d.expanded=false;this.update_expando(d.uid,
-false);this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded})}}c=c.nextSibling}return false},expand_all:function(a){var b,c,d;if(a){a.expanded=true;b=a.depth;c=a.obj.nextSibling;this.update_expando(a.uid,true);this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded})}else{c=this.list.tBodies[0].firstChild;b=0}for(;c;){if(c.nodeType==1)if(d=this.rows[c.uid]){if(a&&d.depth<=b)break;$(c).css("display","");if(d.has_children&&!d.expanded){d.expanded=true;this.update_expando(d.uid,
-true);this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded})}}c=c.nextSibling}return false},update_expando:function(a,b){var c=document.getElementById("rcmexpando"+a);if(c)c.className=b?"expanded":"collapsed"},get_next_row:function(){if(!this.rows)return false;var a=this.rows[this.last_selected];for(a=a?a.obj.nextSibling:null;a&&(a.nodeType!=1||a.style.display=="none");)a=a.nextSibling;return a},get_prev_row:function(){if(!this.rows)return false;var a=this.rows[this.last_selected];for(a=
-a?a.obj.previousSibling:null;a&&(a.nodeType!=1||a.style.display=="none");)a=a.previousSibling;return a},get_first_row:function(){if(this.rowcount){var a,b,c=this.list.tBodies[0].rows;a=0;for(b=c.length-1;a<b;a++)if(c[a].id&&String(c[a].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null)return RegExp.$1}return null},get_last_row:function(){if(this.rowcount){var a,b=this.list.tBodies[0].rows;for(a=b.length-1;a>=0;a--)if(b[a].id&&String(b[a].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&
-this.rows[RegExp.$1]!=null)return RegExp.$1}return null},select_row:function(a,b,c){var d=this.selection.join(",");this.multiselect||(b=0);if(!this.shift_start)this.shift_start=a;if(b){switch(b){case SHIFT_KEY:this.shift_select(a,false);break;case CONTROL_KEY:c||this.highlight_row(a,true);break;case CONTROL_SHIFT_KEY:this.shift_select(a,true);break;default:this.highlight_row(a,false)}this.multi_selecting=true}else{this.shift_start=a;this.highlight_row(a,false);this.multi_selecting=false}this.selection.join(",")!=
-d&&this.triggerEvent("select");this.last_selected!=0&&this.rows[this.last_selected]&&$(this.rows[this.last_selected].obj).removeClass("focused");if(this.toggleselect&&this.last_selected==a){this.clear_selection();a=null}else $(this.rows[a].obj).addClass("focused");if(!this.selection.length)this.shift_start=null;this.last_selected=a},select:function(a){this.select_row(a,false);this.scrollto(a)},select_next:function(){var a=this.get_next_row(),b=this.get_prev_row();(a=a?a:b)&&this.select_row(a.uid,
-false,false)},select_first:function(a){var b=this.get_first_row();if(b&&a){this.shift_select(b,a);this.triggerEvent("select");this.scrollto(b)}else b&&this.select(b)},select_last:function(a){var b=this.get_last_row();if(b&&a){this.shift_select(b,a);this.triggerEvent("select");this.scrollto(b)}else b&&this.select(b)},select_childs:function(a){if(this.rows[a]&&this.rows[a].has_children){var b=this.rows[a].depth;for(a=this.rows[a].obj.nextSibling;a;){if(a.nodeType==1)if(r=this.rows[a.uid]){if(!r.depth||
-r.depth<=b)break;this.in_selection(r.uid)||this.select_row(r.uid,CONTROL_KEY)}a=a.nextSibling}}},shift_select:function(a,b){if(!this.rows[this.shift_start]||!this.selection.length)this.shift_start=a;var c=this.rows[this.shift_start].obj.rowIndex,d=this.rows[a].obj.rowIndex,e=c<d?c:d;c=c>d?c:d;for(var f in this.rows)if(this.rows[f].obj.rowIndex>=e&&this.rows[f].obj.rowIndex<=c)this.in_selection(f)||this.highlight_row(f,true);else this.in_selection(f)&&!b&&this.highlight_row(f,true)},in_selection:function(a){for(var b in this.selection)if(this.selection[b]==
-a)return true;return false},select_all:function(a){if(!this.rows||!this.rows.length)return false;var b=this.selection.join(",");this.selection=[];for(var c in this.rows)if(!a||this.rows[c][a]==true){this.last_selected=c;this.highlight_row(c,true)}else $(this.rows[c].obj).removeClass("selected").removeClass("unfocused");this.selection.join(",")!=b&&this.triggerEvent("select");this.focus();return true},invert_selection:function(){if(!this.rows||!this.rows.length)return false;var a=this.selection.join(","),
-b;for(b in this.rows)this.highlight_row(b,true);this.selection.join(",")!=a&&this.triggerEvent("select");this.focus();return true},clear_selection:function(a){var b=this.selection.length;if(a)for(var c in this.selection){if(this.selection[c]==a){this.selection.splice(c,1);break}}else{for(c in this.selection)this.rows[this.selection[c]]&&$(this.rows[this.selection[c]].obj).removeClass("selected").removeClass("unfocused");this.selection=[]}b&&!this.selection.length&&this.triggerEvent("select")},get_selection:function(){return this.selection},
-get_single_selection:function(){return this.selection.length==1?this.selection[0]:null},highlight_row:function(a,b){if(this.rows[a]&&!b){if(this.selection.length>1||!this.in_selection(a)){this.clear_selection();this.selection[0]=a;$(this.rows[a].obj).addClass("selected")}}else if(this.rows[a])if(this.in_selection(a)){var c=$.inArray(a,this.selection),d=this.selection.slice(0,c);c=this.selection.slice(c+1,this.selection.length);this.selection=d.concat(c);$(this.rows[a].obj).removeClass("selected").removeClass("unfocused")}else{this.selection[this.selection.length]=
-a;$(this.rows[a].obj).addClass("selected")}},key_press:function(a){if(this.focused!=true)return true;var b=rcube_event.get_keycode(a),c=rcube_event.get_modifier(a);switch(b){case 40:case 38:case 63233:case 63232:rcube_event.cancel(a);return this.use_arrow_key(b,c);case 61:case 107:case 109:case 32:rcube_event.cancel(a);a=this.use_plusminus_key(b,c);this.key_pressed=b;this.triggerEvent("keypress");return a;case 36:this.select_first(c);return rcube_event.cancel(a);case 35:this.select_last(c);return rcube_event.cancel(a);
-default:this.shiftkey=a.shiftKey;this.key_pressed=b;this.triggerEvent("keypress");if(this.key_pressed==this.BACKSPACE_KEY)return rcube_event.cancel(a)}return true},key_down:function(a){switch(rcube_event.get_keycode(a)){case 27:if(this.drag_active)return this.drag_mouse_up(a);if(this.col_drag_active){this.selected_column=null;return this.column_drag_mouse_up(a)}case 40:case 38:case 63233:case 63232:case 61:case 107:case 109:case 32:if(!rcube_event.get_modifier(a)&&this.focused)return rcube_event.cancel(a)}return true},
-use_arrow_key:function(a,b){var c;if(a==40||a==63233)c=this.get_next_row();else if(a==38||a==63232)c=this.get_prev_row();if(c){this.select_row(c.uid,b,true);this.scrollto(c.uid)}return false},use_plusminus_key:function(a,b){var c=this.rows[this.last_selected];if(c){if(a==32)a=c.expanded?109:61;if(a==61||a==107)b==CONTROL_KEY||this.multiexpand?this.expand_all(c):this.expand(c);else b==CONTROL_KEY||this.multiexpand?this.collapse_all(c):this.collapse(c);this.update_expando(c.uid,c.expanded);return false}},
-scrollto:function(a){var b=this.rows[a].obj;if(b&&this.frame){var c=Number(b.offsetTop);if(!c&&this.rows[a].parent_uid){this.expand_all(this.rows[this.find_root(this.rows[a].uid)]);c=Number(b.offsetTop)}if(c<Number(this.frame.scrollTop))this.frame.scrollTop=c;else if(c+Number(b.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight))this.frame.scrollTop=c+Number(b.offsetHeight)-Number(this.frame.offsetHeight)}},drag_mouse_move:function(a){if(a.type=="touchmove")if(a.changedTouches.length==
-1)a=rcube_event.touchevent(a.changedTouches[0]);else return rcube_event.cancel(a);if(this.drag_start){var b=rcube_event.get_mouse_pos(a);if(!this.drag_mouse_start||Math.abs(b.x-this.drag_mouse_start.x)<3&&Math.abs(b.y-this.drag_mouse_start.y)<3)return false;if(!this.draglayer)this.draglayer=$("<div>").attr("id","rcmdraglayer").css({position:"absolute",display:"none","z-index":2E3}).appendTo(document.body);var c,d,e=$.merge([],this.selection);for(c in e){d=e[c];this.rows[d].has_children&&!this.rows[d].expanded&&
-this.select_childs(d)}this.draglayer.html("");for(c=0;c<this.selection.length;c++){if(c>12){this.draglayer.append("...");break}if(e=this.rows[this.selection[c]].obj)for(d=b=0;d<e.childNodes.length;d++)if(e.childNodes[d].nodeName=="TD"){if(c==0)this.drag_start_pos=$(e.childNodes[d]).offset();if(this.subject_col<0||this.subject_col>=0&&this.subject_col==b){var f,g,h=e.childNodes[d].childNodes;for(b=0;b<h.length;b++)if((g=e.childNodes[d].childNodes[b])&&(g.nodeType==3||g.nodeName=="A"))f=g;if(!f)break;
-d=$(f).text();d=$.trim(d);d=d.length>50?d.substring(0,50)+"...":d;this.draglayer.append($("<div>").text(d));break}b++}}this.draglayer.show();this.drag_active=true;this.triggerEvent("dragstart")}if(this.drag_active&&this.draglayer){c=rcube_event.get_mouse_pos(a);this.draglayer.css({left:c.x+20+"px",top:c.y-5+(bw.ie?document.documentElement.scrollTop:0)+"px"});this.triggerEvent("dragmove",a?a:window.event)}return this.drag_start=false},drag_mouse_up:function(a){document.onmousemove=null;if(a.type==
-"touchend")if(a.changedTouches.length!=1)return rcube_event.cancel(a);if(this.draglayer&&this.draglayer.is(":visible"))this.drag_start_pos?this.draglayer.animate(this.drag_start_pos,300,"swing").hide(20):this.draglayer.hide();this.drag_active&&this.focus();this.drag_active=false;rcube_event.remove_listener({event:"mousemove",object:this,method:"drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"drag_mouse_up"});if(bw.iphone||bw.ipad){rcube_event.remove_listener({event:"touchmove",
-object:this,method:"drag_mouse_move"});rcube_event.remove_listener({event:"touchend",object:this,method:"drag_mouse_up"})}this.del_dragfix();this.triggerEvent("dragend");return rcube_event.cancel(a)},column_drag_mouse_move:function(a){if(this.drag_start){var b;b=rcube_event.get_mouse_pos(a);if(!this.drag_mouse_start||Math.abs(b.x-this.drag_mouse_start.x)<3&&Math.abs(b.y-this.drag_mouse_start.y)<3)return false;if(!this.col_draglayer){b=$(this.list).offset();var c=this.list.tHead.rows[0].cells;this.col_draglayer=
-$("<div>").attr("id","rcmcoldraglayer").css(b).css({position:"absolute","z-index":2001,"background-color":"white",opacity:0.75,height:this.frame.offsetHeight-2+"px",width:this.frame.offsetWidth-2+"px"}).appendTo(document.body).append($("<div>").attr("id","rcmcolumnindicator").css({position:"absolute","border-right":"2px dotted #555","z-index":2002,height:this.frame.offsetHeight-2+"px"}));this.cols=[];this.list_pos=this.list_min_pos=b.left;for(b=0;b<c.length;b++){this.cols[b]=c[b].offsetWidth;if(this.column_fixed!==
-null&&b<=this.column_fixed)this.list_min_pos+=this.cols[b]}}this.col_draglayer.show();this.col_drag_active=true;this.triggerEvent("column_dragstart")}if(this.col_drag_active&&this.col_draglayer){c=0;var d=rcube_event.get_mouse_pos(a);for(b=0;b<this.cols.length;b++)if(d.x>=this.cols[b]/2+this.list_pos+c)c+=this.cols[b];else break;if(b==0&&this.list_min_pos>d.x)c=this.list_min_pos-this.list_pos;else if(!this.list.rowcount&&b==this.cols.length)c-=2;$("#rcmcolumnindicator").css({width:c+"px"});this.triggerEvent("column_dragmove",
-a?a:window.event)}return this.drag_start=false},column_drag_mouse_up:function(a){document.onmousemove=null;if(this.col_draglayer){this.col_draglayer.remove();this.col_draglayer=null}this.col_drag_active&&this.focus();this.col_drag_active=false;rcube_event.remove_listener({event:"mousemove",object:this,method:"column_drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.del_dragfix();if(this.selected_column!==null&&this.cols&&this.cols.length){var b,
-c=0,d=rcube_event.get_mouse_pos(a);for(b=0;b<this.cols.length;b++)if(d.x>=this.cols[b]/2+this.list_pos+c)c+=this.cols[b];else break;b!=this.selected_column&&b!=this.selected_column+1&&this.column_replace(this.selected_column,b)}this.triggerEvent("column_dragend");return rcube_event.cancel(a)},add_dragfix:function(){$("iframe").each(function(){$('<div class="iframe-dragdrop-fix"></div>').css({background:"#fff",width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",
-zIndex:1E3}).css($(this).offset()).appendTo(document.body)})},del_dragfix:function(){$("div.iframe-dragdrop-fix").each(function(){this.parentNode.removeChild(this)})},column_replace:function(a,b){var c=this.list.tHead.rows[0].cells,d=c[a],e=c[b],f=document.createElement("td");e?c[0].parentNode.insertBefore(f,e):c[0].parentNode.appendChild(f);c[0].parentNode.replaceChild(d,f);for(r=0;r<this.list.tBodies[0].rows.length;r++){row=this.list.tBodies[0].rows[r];d=row.cells[a];e=row.cells[b];f=document.createElement("td");
-e?row.insertBefore(f,e):row.appendChild(f);row.replaceChild(d,f)}if(this.subject_col==a)this.subject_col=b>a?b-1:b;else if(this.subject_col<a&&b<=this.subject_col)this.subject_col++;else this.subject_col>a&&b>=this.subject_col&&this.subject_col--;this.triggerEvent("column_replace")}};rcube_list_widget.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;rcube_list_widget.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;
-rcube_list_widget.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;
+function rcube_list_widget(a,b){this.ENTER_KEY=13;this.DELETE_KEY=46;this.BACKSPACE_KEY=8;this.list=a?a:null;this.frame=null;this.rows=[];this.selection=[];this.colcount=this.rowcount=0;this.subject_col=-1;this.col_drag_active=this.drag_active=this.dont_select=this.toggleselect=this.keyboard=this.column_movable=this.draggable=this.multi_selecting=this.multiexpand=this.multiselect=this.shiftkey=!1;this.column_fixed=null;this.shift_start=this.last_selected=0;this.focused=this.in_selection_before=!1;
+this.drag_mouse_start=null;this.dblclick_time=600;this.row_init=function(){};if(b&&typeof b=="object")for(var c in b)this[c]=b[c]}
+rcube_list_widget.prototype={init:function(){if(this.list&&this.list.tBodies[0]){this.rows=[];this.rowcount=0;var a,b,c=this.list.tBodies[0].rows;a=0;for(b=c.length;a<b;a++)this.init_row(c[a]),this.rowcount++;this.init_header();this.frame=this.list.parentNode;this.keyboard&&(rcube_event.add_listener({event:bw.opera?"keypress":"keydown",object:this,method:"key_press"}),rcube_event.add_listener({event:"keydown",object:this,method:"key_down"}))}},init_row:function(a){if(a&&String(a.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)){var b=
+this,c=RegExp.$1;a.uid=c;this.rows[c]={uid:c,id:a.id,obj:a};a.onmousedown=function(a){return b.drag_row(a,this.uid)};a.onmouseup=function(a){return b.click_row(a,this.uid)};if(bw.iphone||bw.ipad)a.addEventListener("touchstart",function(a){a.touches.length==1&&(b.drag_row(rcube_event.touchevent(a.touches[0]),this.uid)||a.preventDefault())},!1),a.addEventListener("touchend",function(a){a.changedTouches.length==1&&(b.click_row(rcube_event.touchevent(a.changedTouches[0]),this.uid)||a.preventDefault())},
+!1);if(document.all)a.onselectstart=function(){return!1};this.row_init(this.rows[c])}},init_header:function(){if(this.list&&this.list.tHead){this.colcount=0;var a,b,c=this;if(this.column_movable&&this.list.tHead&&this.list.tHead.rows)for(b=0;b<this.list.tHead.rows[0].cells.length;b++)if(this.column_fixed!=b)a=this.list.tHead.rows[0].cells[b],a.onmousedown=function(a){return c.drag_column(a,this)},this.colcount++}},clear:function(a){this.list.insertBefore(document.createElement("tbody"),this.list.tBodies[0]);
+this.list.removeChild(this.list.tBodies[1]);this.rows=[];this.rowcount=0;a&&this.clear_selection();if(this.frame)this.frame.scrollTop=0},remove_row:function(a,b){if(this.rows[a].obj)this.rows[a].obj.style.display="none";b&&this.select_next();delete this.rows[a];this.rowcount--},insert_row:function(a,b){var c=this.list.tBodies[0];b&&c.rows.length?c.insertBefore(a,c.firstChild):c.appendChild(a);this.init_row(a);this.rowcount++},focus:function(a){var b,c;this.focused=!0;for(b in this.selection)c=this.selection[b],
+this.rows[c]&&this.rows[c].obj&&$(this.rows[c].obj).addClass("selected").removeClass("unfocused");$("*:focus",window).blur();$("iframe").each(function(){this.blur()});(a||(a=window.event))&&rcube_event.cancel(a)},blur:function(){var a,b;this.focused=!1;for(a in this.selection)b=this.selection[a],this.rows[b]&&this.rows[b].obj&&$(this.rows[b].obj).removeClass("selected").addClass("unfocused")},drag_column:function(a,b){if(this.colcount>1){this.drag_start=!0;this.drag_mouse_start=rcube_event.get_mouse_pos(a);
+rcube_event.add_listener({event:"mousemove",object:this,method:"column_drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.add_dragfix();for(var c=0;c<this.list.tHead.rows[0].cells.length;c++)if(b==this.list.tHead.rows[0].cells[c]){this.selected_column=c;break}}return!1},drag_row:function(a,b){var c=rcube_event.get_target(a),d=c.tagName.toLowerCase();if(this.dont_select||c&&(d=="input"||d=="img"))return!0;if(rcube_event.get_button(a)==2)return!0;
+this.in_selection_before=this.in_selection(b)?b:!1;this.in_selection_before||(c=rcube_event.get_modifier(a),this.select_row(b,c,!1));if(this.draggable&&this.selection.length){this.drag_start=!0;this.drag_mouse_start=rcube_event.get_mouse_pos(a);rcube_event.add_listener({event:"mousemove",object:this,method:"drag_mouse_move"});rcube_event.add_listener({event:"mouseup",object:this,method:"drag_mouse_up"});if(bw.iphone||bw.ipad)rcube_event.add_listener({event:"touchmove",object:this,method:"drag_mouse_move"}),
+rcube_event.add_listener({event:"touchend",object:this,method:"drag_mouse_up"});this.add_dragfix()}return!1},click_row:function(a,b){var c=(new Date).getTime(),d=rcube_event.get_modifier(a),e=rcube_event.get_target(a),f=e.tagName.toLowerCase();if(e&&(f=="input"||f=="img"))return!0;if(this.dont_select)return this.dont_select=!1;e=c-this.rows[b].clicked<this.dblclick_time;!this.drag_active&&this.in_selection_before==b&&!e&&this.select_row(b,d,!1);this.in_selection_before=this.drag_start=!1;this.rows&&
+e&&this.in_selection(b)?this.triggerEvent("dblclick"):this.triggerEvent("click");this.drag_active||(this.del_dragfix(),rcube_event.cancel(a));this.rows[b].clicked=c;return!1},find_root:function(a){var b=this.rows[a];return b&&b.parent_uid?this.find_root(b.parent_uid):a},expand_row:function(a,b){var c=this.rows[b],d=rcube_event.get_target(a),e=rcube_event.get_modifier(a);this.dont_select=!0;c.clicked=0;c.expanded?(d.className="collapsed",e==CONTROL_KEY||this.multiexpand?this.collapse_all(c):this.collapse(c)):
+(d.className="expanded",e==CONTROL_KEY||this.multiexpand?this.expand_all(c):this.expand(c))},collapse:function(a){a.expanded=!1;this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded});for(var b=a.depth,a=a?a.obj.nextSibling:null,c;a;){if(a.nodeType==1){if((c=this.rows[a.uid])&&c.depth<=b)break;$(a).css("display","none");if(c.expanded)c.expanded=!1,this.triggerEvent("expandcollapse",{uid:c.uid,expanded:c.expanded})}a=a.nextSibling}return!1},expand:function(a){var b,c,d,e,f;a?(a.expanded=
+!0,d=a.depth,e=a.obj.nextSibling,this.update_expando(a.uid,!0),this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded})):(e=this.list.tBodies[0].firstChild,f=d=0);for(;e;){if(e.nodeType==1&&(b=this.rows[e.uid])){if(a&&(!b.depth||b.depth<=d))break;if(b.parent_uid)if((c=this.rows[b.parent_uid])&&c.expanded){if(a&&c==a||f>=c.depth-1)f=c.depth,$(e).css("display",""),b.expanded=!0,this.triggerEvent("expandcollapse",{uid:b.uid,expanded:b.expanded})}else if(a&&(!c||c.depth<=d))break}e=e.nextSibling}return!1},
+collapse_all:function(a){var b,c,d;if(a){if(a.expanded=!1,b=a.depth,c=a.obj.nextSibling,this.update_expando(a.uid),this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded}),b&&this.multiexpand)return!1}else c=this.list.tBodies[0].firstChild,b=0;for(;c;){if(c.nodeType==1&&(d=this.rows[c.uid])){if(a&&(!d.depth||d.depth<=b))break;(a||d.depth)&&$(c).css("display","none");if(d.has_children&&d.expanded)d.expanded=!1,this.update_expando(d.uid,!1),this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded})}c=
+c.nextSibling}return!1},expand_all:function(a){var b,c,d;a?(a.expanded=!0,b=a.depth,c=a.obj.nextSibling,this.update_expando(a.uid,!0),this.triggerEvent("expandcollapse",{uid:a.uid,expanded:a.expanded})):(c=this.list.tBodies[0].firstChild,b=0);for(;c;){if(c.nodeType==1&&(d=this.rows[c.uid])){if(a&&d.depth<=b)break;$(c).css("display","");if(d.has_children&&!d.expanded)d.expanded=!0,this.update_expando(d.uid,!0),this.triggerEvent("expandcollapse",{uid:d.uid,expanded:d.expanded})}c=c.nextSibling}return!1},
+update_expando:function(a,b){var c=document.getElementById("rcmexpando"+a);if(c)c.className=b?"expanded":"collapsed"},get_next_row:function(){if(!this.rows)return!1;for(var a=this.rows[this.last_selected],a=a?a.obj.nextSibling:null;a&&(a.nodeType!=1||a.style.display=="none");)a=a.nextSibling;return a},get_prev_row:function(){if(!this.rows)return!1;for(var a=this.rows[this.last_selected],a=a?a.obj.previousSibling:null;a&&(a.nodeType!=1||a.style.display=="none");)a=a.previousSibling;return a},get_first_row:function(){if(this.rowcount){var a,
+b,c=this.list.tBodies[0].rows;a=0;for(b=c.length-1;a<b;a++)if(c[a].id&&String(c[a].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null)return RegExp.$1}return null},get_last_row:function(){if(this.rowcount){var a,b=this.list.tBodies[0].rows;for(a=b.length-1;a>=0;a--)if(b[a].id&&String(b[a].id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)&&this.rows[RegExp.$1]!=null)return RegExp.$1}return null},select_row:function(a,b,c){var d=this.selection.join(",");this.multiselect||(b=0);if(!this.shift_start)this.shift_start=
+a;if(b){switch(b){case SHIFT_KEY:this.shift_select(a,!1);break;case CONTROL_KEY:c||this.highlight_row(a,!0);break;case CONTROL_SHIFT_KEY:this.shift_select(a,!0);break;default:this.highlight_row(a,!1)}this.multi_selecting=!0}else this.shift_start=a,this.highlight_row(a,!1),this.multi_selecting=!1;this.selection.join(",")!=d&&this.triggerEvent("select");this.last_selected!=0&&this.rows[this.last_selected]&&$(this.rows[this.last_selected].obj).removeClass("focused");this.toggleselect&&this.last_selected==
+a?(this.clear_selection(),a=null):$(this.rows[a].obj).addClass("focused");if(!this.selection.length)this.shift_start=null;this.last_selected=a},select:function(a){this.select_row(a,!1);this.scrollto(a)},select_next:function(){var a=this.get_next_row(),b=this.get_prev_row();(a=a?a:b)&&this.select_row(a.uid,!1,!1)},select_first:function(a){var b=this.get_first_row();b&&(a?(this.shift_select(b,a),this.triggerEvent("select"),this.scrollto(b)):this.select(b))},select_last:function(a){var b=this.get_last_row();
+b&&(a?(this.shift_select(b,a),this.triggerEvent("select"),this.scrollto(b)):this.select(b))},select_childs:function(a){if(this.rows[a]&&this.rows[a].has_children)for(var b=this.rows[a].depth,a=this.rows[a].obj.nextSibling;a;){if(a.nodeType==1&&(r=this.rows[a.uid])){if(!r.depth||r.depth<=b)break;this.in_selection(r.uid)||this.select_row(r.uid,CONTROL_KEY)}a=a.nextSibling}},shift_select:function(a,b){if(!this.rows[this.shift_start]||!this.selection.length)this.shift_start=a;var c,d=this.rows[this.shift_start].obj.rowIndex,
+e=this.rows[a].obj.rowIndex,f=d<e?d:e,d=d>e?d:e;for(c in this.rows)this.rows[c].obj.rowIndex>=f&&this.rows[c].obj.rowIndex<=d?this.in_selection(c)||this.highlight_row(c,!0):this.in_selection(c)&&!b&&this.highlight_row(c,!0)},in_selection:function(a){for(var b in this.selection)if(this.selection[b]==a)return!0;return!1},select_all:function(a){if(!this.rows||!this.rows.length)return!1;var b,c=this.selection.join(",");this.selection=[];for(b in this.rows)!a||this.rows[b][a]==!0?(this.last_selected=b,
+this.highlight_row(b,!0)):$(this.rows[b].obj).removeClass("selected").removeClass("unfocused");this.selection.join(",")!=c&&this.triggerEvent("select");this.focus();return!0},invert_selection:function(){if(!this.rows||!this.rows.length)return!1;var a,b=this.selection.join(",");for(a in this.rows)this.highlight_row(a,!0);this.selection.join(",")!=b&&this.triggerEvent("select");this.focus();return!0},clear_selection:function(a){var b,c=this.selection.length;if(a)for(b in this.selection){if(this.selection[b]==
+a){this.selection.splice(b,1);break}}else{for(b in this.selection)this.rows[this.selection[b]]&&$(this.rows[this.selection[b]].obj).removeClass("selected").removeClass("unfocused");this.selection=[]}c&&!this.selection.length&&this.triggerEvent("select")},get_selection:function(){return this.selection},get_single_selection:function(){return this.selection.length==1?this.selection[0]:null},highlight_row:function(a,b){if(this.rows[a]&&!b){if(this.selection.length>1||!this.in_selection(a))this.clear_selection(),
+this.selection[0]=a,$(this.rows[a].obj).addClass("selected")}else if(this.rows[a])if(this.in_selection(a)){var c=$.inArray(a,this.selection),d=this.selection.slice(0,c),c=this.selection.slice(c+1,this.selection.length);this.selection=d.concat(c);$(this.rows[a].obj).removeClass("selected").removeClass("unfocused")}else this.selection[this.selection.length]=a,$(this.rows[a].obj).addClass("selected")},key_press:function(a){if(this.focused!=!0)return!0;var b=rcube_event.get_keycode(a),c=rcube_event.get_modifier(a);
+switch(b){case 40:case 38:case 63233:case 63232:return rcube_event.cancel(a),this.use_arrow_key(b,c);case 61:case 107:case 109:case 32:return rcube_event.cancel(a),a=this.use_plusminus_key(b,c),this.key_pressed=b,this.triggerEvent("keypress"),a;case 36:return this.select_first(c),rcube_event.cancel(a);case 35:return this.select_last(c),rcube_event.cancel(a);default:if(this.shiftkey=a.shiftKey,this.key_pressed=b,this.triggerEvent("keypress"),this.key_pressed==this.BACKSPACE_KEY)return rcube_event.cancel(a)}return!0},
+key_down:function(a){switch(rcube_event.get_keycode(a)){case 27:if(this.drag_active)return this.drag_mouse_up(a);if(this.col_drag_active)return this.selected_column=null,this.column_drag_mouse_up(a);case 40:case 38:case 63233:case 63232:case 61:case 107:case 109:case 32:if(!rcube_event.get_modifier(a)&&this.focused)return rcube_event.cancel(a)}return!0},use_arrow_key:function(a,b){var c;if(a==40||a==63233)c=this.get_next_row();else if(a==38||a==63232)c=this.get_prev_row();c&&(this.select_row(c.uid,
+b,!0),this.scrollto(c.uid));return!1},use_plusminus_key:function(a,b){var c=this.rows[this.last_selected];if(c)return a==32&&(a=c.expanded?109:61),a==61||a==107?b==CONTROL_KEY||this.multiexpand?this.expand_all(c):this.expand(c):b==CONTROL_KEY||this.multiexpand?this.collapse_all(c):this.collapse(c),this.update_expando(c.uid,c.expanded),!1},scrollto:function(a){var b=this.rows[a].obj;if(b&&this.frame){var c=Number(b.offsetTop);!c&&this.rows[a].parent_uid&&(this.expand_all(this.rows[this.find_root(this.rows[a].uid)]),
+c=Number(b.offsetTop));if(c<Number(this.frame.scrollTop))this.frame.scrollTop=c;else if(c+Number(b.offsetHeight)>Number(this.frame.scrollTop)+Number(this.frame.offsetHeight))this.frame.scrollTop=c+Number(b.offsetHeight)-Number(this.frame.offsetHeight)}},drag_mouse_move:function(a){if(a.type=="touchmove")if(a.changedTouches.length==1)a=rcube_event.touchevent(a.changedTouches[0]);else return rcube_event.cancel(a);if(this.drag_start){var b=rcube_event.get_mouse_pos(a);if(!this.drag_mouse_start||Math.abs(b.x-
+this.drag_mouse_start.x)<3&&Math.abs(b.y-this.drag_mouse_start.y)<3)return!1;if(!this.draglayer)this.draglayer=$("<div>").attr("id","rcmdraglayer").css({position:"absolute",display:"none","z-index":2E3}).appendTo(document.body);var c,d,e=$.merge([],this.selection);for(c in e)d=e[c],this.rows[d].has_children&&!this.rows[d].expanded&&this.select_childs(d);this.draglayer.html("");for(c=0;c<this.selection.length;c++){if(c>12){this.draglayer.append("...");break}if(e=this.rows[this.selection[c]].obj)for(d=
+b=0;d<e.childNodes.length;d++)if(e.childNodes[d].nodeName=="TD"){if(c==0)this.drag_start_pos=$(e.childNodes[d]).offset();if(this.subject_col<0||this.subject_col>=0&&this.subject_col==b){for(var f,g,h=e.childNodes[d].childNodes,b=0;b<h.length;b++)if((g=e.childNodes[d].childNodes[b])&&(g.nodeType==3||g.nodeName=="A"))f=g;if(!f)break;d=$(f).text();d=$.trim(d);d=d.length>50?d.substring(0,50)+"...":d;this.draglayer.append($("<div>").text(d));break}b++}}this.draglayer.show();this.drag_active=!0;this.triggerEvent("dragstart")}this.drag_active&&
+this.draglayer&&(c=rcube_event.get_mouse_pos(a),this.draglayer.css({left:c.x+20+"px",top:c.y-5+(bw.ie?document.documentElement.scrollTop:0)+"px"}),this.triggerEvent("dragmove",a?a:window.event));return this.drag_start=!1},drag_mouse_up:function(a){document.onmousemove=null;if(a.type=="touchend"&&a.changedTouches.length!=1)return rcube_event.cancel(a);this.draglayer&&this.draglayer.is(":visible")&&(this.drag_start_pos?this.draglayer.animate(this.drag_start_pos,300,"swing").hide(20):this.draglayer.hide());
+this.drag_active&&this.focus();this.drag_active=!1;rcube_event.remove_listener({event:"mousemove",object:this,method:"drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"drag_mouse_up"});if(bw.iphone||bw.ipad)rcube_event.remove_listener({event:"touchmove",object:this,method:"drag_mouse_move"}),rcube_event.remove_listener({event:"touchend",object:this,method:"drag_mouse_up"});this.del_dragfix();this.triggerEvent("dragend");return rcube_event.cancel(a)},column_drag_mouse_move:function(a){if(this.drag_start){var b;
+b=rcube_event.get_mouse_pos(a);if(!this.drag_mouse_start||Math.abs(b.x-this.drag_mouse_start.x)<3&&Math.abs(b.y-this.drag_mouse_start.y)<3)return!1;if(!this.col_draglayer){b=$(this.list).offset();var c=this.list.tHead.rows[0].cells;this.col_draglayer=$("<div>").attr("id","rcmcoldraglayer").css(b).css({position:"absolute","z-index":2001,"background-color":"white",opacity:0.75,height:this.frame.offsetHeight-2+"px",width:this.frame.offsetWidth-2+"px"}).appendTo(document.body).append($("<div>").attr("id",
+"rcmcolumnindicator").css({position:"absolute","border-right":"2px dotted #555","z-index":2002,height:this.frame.offsetHeight-2+"px"}));this.cols=[];this.list_pos=this.list_min_pos=b.left;for(b=0;b<c.length;b++)this.cols[b]=c[b].offsetWidth,this.column_fixed!==null&&b<=this.column_fixed&&(this.list_min_pos+=this.cols[b])}this.col_draglayer.show();this.col_drag_active=!0;this.triggerEvent("column_dragstart")}if(this.col_drag_active&&this.col_draglayer){var c=0,d=rcube_event.get_mouse_pos(a);for(b=
+0;b<this.cols.length;b++)if(d.x>=this.cols[b]/2+this.list_pos+c)c+=this.cols[b];else break;b==0&&this.list_min_pos>d.x?c=this.list_min_pos-this.list_pos:!this.list.rowcount&&b==this.cols.length&&(c-=2);$("#rcmcolumnindicator").css({width:c+"px"});this.triggerEvent("column_dragmove",a?a:window.event)}return this.drag_start=!1},column_drag_mouse_up:function(a){document.onmousemove=null;if(this.col_draglayer)this.col_draglayer.remove(),this.col_draglayer=null;this.col_drag_active&&this.focus();this.col_drag_active=
+!1;rcube_event.remove_listener({event:"mousemove",object:this,method:"column_drag_mouse_move"});rcube_event.remove_listener({event:"mouseup",object:this,method:"column_drag_mouse_up"});this.del_dragfix();if(this.selected_column!==null&&this.cols&&this.cols.length){var b,c=0,d=rcube_event.get_mouse_pos(a);for(b=0;b<this.cols.length;b++)if(d.x>=this.cols[b]/2+this.list_pos+c)c+=this.cols[b];else break;b!=this.selected_column&&b!=this.selected_column+1&&this.column_replace(this.selected_column,b)}this.triggerEvent("column_dragend");
+return rcube_event.cancel(a)},add_dragfix:function(){$("iframe").each(function(){$('<div class="iframe-dragdrop-fix"></div>').css({background:"#fff",width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css($(this).offset()).appendTo(document.body)})},del_dragfix:function(){$("div.iframe-dragdrop-fix").each(function(){this.parentNode.removeChild(this)})},column_replace:function(a,b){var c;c=this.list.tHead.rows[0].cells;var d=c[a],e=c[b],f=document.createElement("td");
+e?c[0].parentNode.insertBefore(f,e):c[0].parentNode.appendChild(f);c[0].parentNode.replaceChild(d,f);r=0;for(c=this.list.tBodies[0].rows.length;r<c;r++)row=this.list.tBodies[0].rows[r],d=row.cells[a],e=row.cells[b],f=document.createElement("td"),e?row.insertBefore(f,e):row.appendChild(f),row.replaceChild(d,f);this.subject_col==a?this.subject_col=b>a?b-1:b:this.subject_col<a&&b<=this.subject_col?this.subject_col++:this.subject_col>a&&b>=this.subject_col&&this.subject_col--;this.triggerEvent("column_replace")}};
+rcube_list_widget.prototype.addEventListener=rcube_event_engine.prototype.addEventListener;rcube_list_widget.prototype.removeEventListener=rcube_event_engine.prototype.removeEventListener;rcube_list_widget.prototype.triggerEvent=rcube_event_engine.prototype.triggerEvent;
index b0288758beff64b7195078af4e5f6463dbbdafa6..78cf994a8c5c4dc45686aa6c43dd4f47e55ad48b 100644 (file)
@@ -13,7 +13,7 @@
  | Requires: common.js                                                   |
  +-----------------------------------------------------------------------+
 
-  $Id: list.js 4343 2010-12-16 09:26:30Z alec $
+  $Id: list.js 4666 2011-04-17 09:34:02Z alec $
 */
 
 
@@ -102,8 +102,8 @@ init_row: function(row)
 {
   // make references in internal array and set event handlers
   if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)) {
-    var self = this;
-    var uid = RegExp.$1;
+    var self = this,
+      uid = RegExp.$1;
     row.uid = uid;
     this.rows[uid] = {uid:uid, id:row.id, obj:row};
 
@@ -170,6 +170,10 @@ clear: function(sel)
 
   if (sel)
     this.clear_selection();
+
+  // reset scroll position (in Opera)
+  if (this.frame)
+    this.frame.scrollTop = 0;
 },
 
 
@@ -212,10 +216,10 @@ insert_row: function(row, attop)
  */
 focus: function(e)
 {
-  var id;
+  var n, id;
   this.focused = true;
 
-  for (var n in this.selection) {
+  for (n in this.selection) {
     id = this.selection[n];
     if (this.rows[id] && this.rows[id].obj) {
       $(this.rows[id].obj).addClass('selected').removeClass('unfocused');
@@ -236,9 +240,9 @@ focus: function(e)
  */
 blur: function()
 {
-  var id;
+  var n, id;
   this.focused = false;
-  for (var n in this.selection) {
+  for (n in this.selection) {
     id = this.selection[n];
     if (this.rows[id] && this.rows[id].obj) {
       $(this.rows[id].obj).removeClass('selected').addClass('unfocused');
@@ -430,8 +434,7 @@ collapse: function(row)
 
 expand: function(row)
 {
-  var depth, new_row;
-  var last_expanded_parent_depth;
+  var r, p, depth, new_row, last_expanded_parent_depth;
 
   if (row) {
     row.expanded = true;
@@ -449,13 +452,13 @@ expand: function(row)
 
   while (new_row) {
     if (new_row.nodeType == 1) {
-      var r = this.rows[new_row.uid];
+      r = this.rows[new_row.uid];
       if (r) {
         if (row && (!r.depth || r.depth <= depth))
           break;
 
         if (r.parent_uid) {
-          var p = this.rows[r.parent_uid];
+          p = this.rows[r.parent_uid];
           if (p && p.expanded) {
             if ((row && p == row) || last_expanded_parent_depth >= p.depth - 1) {
               last_expanded_parent_depth = p.depth;
@@ -696,9 +699,10 @@ select: function(id)
  */
 select_next: function()
 {
-  var next_row = this.get_next_row();
-  var prev_row = this.get_prev_row();
-  var new_row = (next_row) ? next_row : prev_row;
+  var next_row = this.get_next_row(),
+    prev_row = this.get_prev_row(),
+    new_row = (next_row) ? next_row : prev_row;
+
   if (new_row)
     this.select_row(new_row.uid, false, false);
 },
@@ -710,13 +714,16 @@ select_next: function()
 select_first: function(mod_key)
 {
   var row = this.get_first_row();
-  if (row && mod_key) {
-    this.shift_select(row, mod_key);
-    this.triggerEvent('select');
-    this.scrollto(row);
+  if (row) {
+    if (mod_key) {
+      this.shift_select(row, mod_key);
+      this.triggerEvent('select');
+      this.scrollto(row);
+    }
+    else {
+      this.select(row);
+    }
   }
-  else if (row)
-    this.select(row);
 },
 
 
@@ -726,13 +733,16 @@ select_first: function(mod_key)
 select_last: function(mod_key)
 {
   var row = this.get_last_row();
-  if (row && mod_key) {
-    this.shift_select(row, mod_key);
-    this.triggerEvent('select');
-    this.scrollto(row);
+  if (row) {
+    if (mod_key) {
+      this.shift_select(row, mod_key);
+      this.triggerEvent('select');
+      this.scrollto(row);
+    }
+    else {
+      this.select(row);
+    }
   }
-  else if (row)
-    this.select(row);
 },
 
 
@@ -744,8 +754,9 @@ select_childs: function(uid)
   if (!this.rows[uid] || !this.rows[uid].has_children)
     return;
 
-  var depth = this.rows[uid].depth;
-  var row = this.rows[uid].obj.nextSibling;
+  var depth = this.rows[uid].depth,
+    row = this.rows[uid].obj.nextSibling;
+
   while (row) {
     if (row.nodeType == 1) {
       if ((r = this.rows[row.uid])) {
@@ -768,20 +779,20 @@ shift_select: function(id, control)
   if (!this.rows[this.shift_start] || !this.selection.length)
     this.shift_start = id;
 
-  var from_rowIndex = this.rows[this.shift_start].obj.rowIndex,
+  var n, from_rowIndex = this.rows[this.shift_start].obj.rowIndex,
     to_rowIndex = this.rows[id].obj.rowIndex,
     i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex),
     j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex);
 
   // iterate through the entire message list
-  for (var n in this.rows) {
+  for (n in this.rows) {
     if (this.rows[n].obj.rowIndex >= i && this.rows[n].obj.rowIndex <= j) {
       if (!this.in_selection(n)) {
         this.highlight_row(n, true);
       }
     }
     else {
-      if  (this.in_selection(n) && !control) {
+      if (this.in_selection(n) && !control) {
         this.highlight_row(n, true);
       }
     }
@@ -794,7 +805,7 @@ shift_select: function(id, control)
  */
 in_selection: function(id)
 {
-  for(var n in this.selection)
+  for (var n in this.selection)
     if (this.selection[n]==id)
       return true;
 
@@ -811,10 +822,10 @@ select_all: function(filter)
     return false;
 
   // reset but remember selection first
-  var select_before = this.selection.join(',');
+  var n, select_before = this.selection.join(',');
   this.selection = [];
 
-  for (var n in this.rows) {
+  for (n in this.rows) {
     if (!filter || this.rows[n][filter] == true) {
       this.last_selected = n;
       this.highlight_row(n, true);
@@ -843,9 +854,9 @@ invert_selection: function()
     return false;
 
   // remember old selection
-  var select_before = this.selection.join(',');
+  var n, select_before = this.selection.join(',');
 
-  for (var n in this.rows)
+  for (n in this.rows)
     this.highlight_row(n, true);
 
   // trigger event if selection changed
@@ -863,11 +874,11 @@ invert_selection: function()
  */
 clear_selection: function(id)
 {
-  var num_select = this.selection.length;
+  var n, num_select = this.selection.length;
 
   // one row
   if (id) {
-    for (var n in this.selection)
+    for (n in this.selection)
       if (this.selection[n] == id) {
         this.selection.splice(n,1);
         break;
@@ -875,7 +886,7 @@ clear_selection: function(id)
   }
   // all rows
   else {
-    for (var n in this.selection)
+    for (n in this.selection)
       if (this.rows[this.selection[n]]) {
         $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused');
       }
@@ -927,9 +938,10 @@ highlight_row: function(id, multiple)
       $(this.rows[id].obj).addClass('selected');
     }
     else { // unselect row
-      var p = $.inArray(id, this.selection);
-      var a_pre = this.selection.slice(0, p);
-      var a_post = this.selection.slice(p+1, this.selection.length);
+      var p = $.inArray(id, this.selection),
+        a_pre = this.selection.slice(0, p),
+        a_post = this.selection.slice(p+1, this.selection.length);
+
       this.selection = a_pre.concat(a_post);
       $(this.rows[id].obj).removeClass('selected').removeClass('unfocused');
     }
@@ -945,8 +957,8 @@ key_press: function(e)
   if (this.focused != true)
     return true;
 
-  var keyCode = rcube_event.get_keycode(e);
-  var mod_key = rcube_event.get_modifier(e);
+  var keyCode = rcube_event.get_keycode(e),
+    mod_key = rcube_event.get_modifier(e);
 
   switch (keyCode) {
     case 40:
@@ -1371,7 +1383,7 @@ del_dragfix: function()
  */
 column_replace: function(from, to)
 {
-  var cells = this.list.tHead.rows[0].cells,
+  var len, cells = this.list.tHead.rows[0].cells,
     elem = cells[from],
     before = cells[to],
     td = document.createElement('td');
@@ -1384,7 +1396,7 @@ column_replace: function(from, to)
   cells[0].parentNode.replaceChild(elem, td);
 
   // replace list cells
-  for (r=0; r<this.list.tBodies[0].rows.length; r++) {
+  for (r=0, len=this.list.tBodies[0].rows.length; r<len; r++) {
     row = this.list.tBodies[0].rows[r];
 
     elem = row.cells[from];
index ea4a1b0e1426134d417c66db72fa180635c79ef4..8a80d46b1ae369c481c8c6fea4b4c1cc86f891b1 100644 (file)
@@ -12,9 +12,54 @@ not_set:"-- Not set --",
 clipboard_msg:"Copy/Cut/Paste is not available in Mozilla and Firefox.\nDo you want more information about this issue?",\r
 clipboard_no_support:"Currently not supported by your browser, use keyboard shortcuts instead.",\r
 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.",\r
-invalid_data:"Error: Invalid values entered, these are marked in red.",\r
+invalid_data:"{#field} is invalid",\r
+invalid_data_number:"{#field} must be a number",\r
+invalid_data_min:"{#field} must be a number greater than {#min}",\r
+invalid_data_size:"{#field} must be a number or percentage",\r
 more_colors:"More colors"\r
 },\r
+colors:{\r
+'000000':'Black',\r
+'993300':'Burnt orange',\r
+'333300':'Dark olive',\r
+'003300':'Dark green',\r
+'003366':'Dark azure',\r
+'000080':'Navy Blue',\r
+'333399':'Indigo',\r
+'333333':'Very dark gray',\r
+'800000':'Maroon',\r
+'FF6600':'Orange',\r
+'808000':'Olive',\r
+'008000':'Green',\r
+'008080':'Teal',\r
+'0000FF':'Blue',\r
+'666699':'Grayish blue',\r
+'808080':'Gray',\r
+'FF0000':'Red',\r
+'FF9900':'Amber',\r
+'99CC00':'Yellow green',\r
+'339966':'Sea green',\r
+'33CCCC':'Turquoise',\r
+'3366FF':'Royal blue',\r
+'800080':'Purple',\r
+'999999':'Medium gray',\r
+'FF00FF':'Magenta',\r
+'FFCC00':'Gold',\r
+'FFFF00':'Yellow',\r
+'00FF00':'Lime',\r
+'00FFFF':'Aqua',\r
+'00CCFF':'Sky blue',\r
+'993366':'Brown',\r
+'C0C0C0':'Silver',\r
+'FF99CC':'Pink',\r
+'FFCC99':'Peach',\r
+'FFFF99':'Light yellow',\r
+'CCFFCC':'Pale green',\r
+'CCFFFF':'Pale cyan',\r
+'99CCFF':'Light sky blue',\r
+'CC99FF':'Plum',\r
+'FFFFFF':'White'\r
+},\r
 contextmenu:{\r
 align:"Alignment",\r
 left:"Left",\r
@@ -151,7 +196,8 @@ langs:"Languages",
 wait:"Please wait...",\r
 sug:"Suggestions",\r
 no_sug:"No suggestions",\r
-no_mpell:"No misspellings found."\r
+no_mpell:"No misspellings found.",\r
+learn_word:"Learn word" \r
 },\r
 pagebreak:{\r
 desc:"Insert page break."\r
@@ -167,4 +213,11 @@ upper_roman:"Upper roman",
 circle:"Circle",\r
 disc:"Disc",\r
 square:"Square"\r
-}}});
\ No newline at end of file
+},\r
+aria:{\r
+rich_text_area:"Rich Text Area"\r
+},\r
+wordcount:{\r
+words: 'Words: '\r
+}\r
+}});
\ No newline at end of file
index 9749e5164cf1ac14bf24d2360dcc00e5f5033fb5..8e041ea597cf7139c5d9bc38c4d16c56500a1569 100644 (file)
@@ -1 +1 @@
-(function(){var a=tinymce.dom.Event,c=tinymce.each,b=tinymce.DOM;tinymce.create("tinymce.plugins.ContextMenu",{init:function(d){var f=this,g;f.editor=d;f.onContextMenu=new tinymce.util.Dispatcher(this);d.onContextMenu.add(function(h,i){if(!i.ctrlKey){if(g){h.selection.setRng(g)}f._getMenu(h).showMenu(i.clientX,i.clientY);a.add(h.getDoc(),"click",function(j){e(h,j)});a.cancel(i)}});d.onRemove.add(function(){if(f._menu){f._menu.removeAll()}});function e(h,i){g=null;if(i&&i.button==2){g=h.selection.getRng();return}if(f._menu){f._menu.removeAll();f._menu.destroy();a.remove(h.getDoc(),"click",e)}}d.onMouseDown.add(e);d.onKeyDown.add(e)},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(h){var l=this,f=l._menu,i=h.selection,e=i.isCollapsed(),d=i.getNode()||h.getBody(),g,k,j;if(f){f.removeAll();f.destroy()}k=b.getPos(h.getContentAreaContainer());j=b.getPos(h.getContainer());f=h.controlManager.createDropMenu("contextmenu",{offset_x:k.x+h.getParam("contextmenu_offset_x",0),offset_y:k.y+h.getParam("contextmenu_offset_y",0),constrain:1});l._menu=f;f.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(e);f.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(e);f.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((d.nodeName=="A"&&!h.dom.getAttrib(d,"name"))||!e){f.addSeparator();f.add({title:"advanced.link_desc",icon:"link",cmd:h.plugins.advlink?"mceAdvLink":"mceLink",ui:true});f.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}f.addSeparator();f.add({title:"advanced.image_desc",icon:"image",cmd:h.plugins.advimage?"mceAdvImage":"mceImage",ui:true});f.addSeparator();g=f.addMenu({title:"contextmenu.align"});g.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});g.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});g.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});g.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});l.onContextMenu.dispatch(l,f,d,e);return f}});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(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.pageX);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)}}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(h){var l=this,f=l._menu,i=h.selection,e=i.isCollapsed(),d=i.getNode()||h.getBody(),g,k,j;if(f){f.removeAll();f.destroy()}k=b.getPos(h.getContentAreaContainer());j=b.getPos(h.getContainer());f=h.controlManager.createDropMenu("contextmenu",{offset_x:k.x+h.getParam("contextmenu_offset_x",0),offset_y:k.y+h.getParam("contextmenu_offset_y",0),constrain:1,keyboard_focus:true});l._menu=f;f.add({title:"advanced.cut_desc",icon:"cut",cmd:"Cut"}).setDisabled(e);f.add({title:"advanced.copy_desc",icon:"copy",cmd:"Copy"}).setDisabled(e);f.add({title:"advanced.paste_desc",icon:"paste",cmd:"Paste"});if((d.nodeName=="A"&&!h.dom.getAttrib(d,"name"))||!e){f.addSeparator();f.add({title:"advanced.link_desc",icon:"link",cmd:h.plugins.advlink?"mceAdvLink":"mceLink",ui:true});f.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"})}f.addSeparator();f.add({title:"advanced.image_desc",icon:"image",cmd:h.plugins.advimage?"mceAdvImage":"mceImage",ui:true});f.addSeparator();g=f.addMenu({title:"contextmenu.align"});g.add({title:"contextmenu.left",icon:"justifyleft",cmd:"JustifyLeft"});g.add({title:"contextmenu.center",icon:"justifycenter",cmd:"JustifyCenter"});g.add({title:"contextmenu.right",icon:"justifyright",cmd:"JustifyRight"});g.add({title:"contextmenu.full",icon:"justifyfull",cmd:"JustifyFull"});l.onContextMenu.dispatch(l,f,d,e);return f}});tinymce.PluginManager.add("contextmenu",tinymce.plugins.ContextMenu)})();
\ No newline at end of file
index 13813a64e4630df01ed620a1d04554c00c4ad939..4328f4b117614956c979f5694279973fcfc24eaf 100644 (file)
                 * @param {string} url Absolute URL to where the plugin is located.\r
                 */\r
                init : function(ed) {\r
-                       var t = this, lastRng;\r
+                       var t = this, showMenu, contextmenuNeverUseNative, realCtrlKey;\r
 \r
                        t.editor = ed;\r
 \r
+                       contextmenuNeverUseNative = ed.settings.contextmenu_never_use_native;\r
+\r
                        /**\r
                         * This event gets fired when the context menu is shown.\r
                         *\r
                         */\r
                        t.onContextMenu = new tinymce.util.Dispatcher(this);\r
 \r
-                       ed.onContextMenu.add(function(ed, e) {\r
-                               if (!e.ctrlKey) {\r
-                                       // Restore the last selection since it was removed\r
-                                       if (lastRng)\r
-                                               ed.selection.setRng(lastRng);\r
+                       showMenu = ed.onContextMenu.add(function(ed, e) {\r
+                               // Block TinyMCE menu on ctrlKey and work around Safari issue\r
+                               if ((realCtrlKey !== 0 ? realCtrlKey : e.ctrlKey) && !contextmenuNeverUseNative)\r
+                                       return;\r
 \r
-                                       t._getMenu(ed).showMenu(e.clientX, e.clientY);\r
-                                       Event.add(ed.getDoc(), 'click', function(e) {\r
-                                               hide(ed, e);\r
-                                       });\r
-                                       Event.cancel(e);\r
-                               }\r
+                               Event.cancel(e);\r
+\r
+                               // Select the image if it's clicked. WebKit would other wise expand the selection\r
+                               if (e.target.nodeName == 'IMG')\r
+                                       ed.selection.select(e.target);\r
+\r
+                               t._getMenu(ed).showMenu(e.clientX || e.pageX, e.clientY || e.pageX);\r
+                               Event.add(ed.getDoc(), 'click', function(e) {\r
+                                       hide(ed, e);\r
+                               });\r
+\r
+                               ed.nodeChanged();\r
                        });\r
 \r
                        ed.onRemove.add(function() {\r
                        });\r
 \r
                        function hide(ed, e) {\r
-                               lastRng = null;\r
+                               realCtrlKey = 0;\r
 \r
                                // Since the contextmenu event moves\r
                                // the selection we need to store it away\r
                                if (e && e.button == 2) {\r
-                                       lastRng = ed.selection.getRng();\r
+                                       realCtrlKey = e.ctrlKey;\r
                                        return;\r
                                }\r
 \r
 \r
                        ed.onMouseDown.add(hide);\r
                        ed.onKeyDown.add(hide);\r
+                       ed.onKeyDown.add(function(ed, e) {\r
+                               if (e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode === 121) {\r
+                                       Event.cancel(e);\r
+                                       showMenu(ed, e);\r
+                               }\r
+                       });\r
                },\r
 \r
                /**\r
                        m = ed.controlManager.createDropMenu('contextmenu', {\r
                                offset_x : p1.x + ed.getParam('contextmenu_offset_x', 0),\r
                                offset_y : p1.y + ed.getParam('contextmenu_offset_y', 0),\r
-                               constrain : 1\r
+                               constrain : 1,\r
+                               keyboard_focus: true\r
                        });\r
 \r
                        t._menu = m;\r
 \r
        // Register plugin\r
        tinymce.PluginManager.add('contextmenu', tinymce.plugins.ContextMenu);\r
-})();
\ No newline at end of file
+})();\r
index 55a1d72fa7f87cf051eaf6e45e4a00af8578a609..2c91002e4e0d3c40bd74e7e4e0e8625aecbff6a1 100644 (file)
@@ -5,36 +5,37 @@
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/emotions.js"></script>\r
 </head>\r
-<body style="display: none">\r
-       <div align="center">\r
-               <div class="title">{#emotions_dlg.title}:<br /><br /></div>\r
+<body style="display: none" role="application" aria-labelledby="app_title">\r
+<span style="display:none;" id="app_title">{#emotions_dlg.title}</span>\r
+<div align="center">\r
+       <div class="title">{#emotions_dlg.title}:<br /><br /></div>\r
 \r
-               <table border="0" cellspacing="0" cellpadding="4">\r
-                 <tr>\r
+       <table role="presentation" border="0" cellspacing="0" cellpadding="4">\r
+               <tr>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-cool.gif','emotions_dlg.cool');"><img src="img/smiley-cool.gif" width="18" height="18" border="0" alt="{#emotions_dlg.cool}" title="{#emotions_dlg.cool}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-cry.gif','emotions_dlg.cry');"><img src="img/smiley-cry.gif" width="18" height="18" border="0" alt="{#emotions_dlg.cry}" title="{#emotions_dlg.cry}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-embarassed.gif','emotions_dlg.embarassed');"><img src="img/smiley-embarassed.gif" width="18" height="18" border="0" alt="{#emotions_dlg.embarassed}" title="{#emotions_dlg.embarassed}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-foot-in-mouth.gif','emotions_dlg.foot_in_mouth');"><img src="img/smiley-foot-in-mouth.gif" width="18" height="18" border="0" alt="{#emotions_dlg.foot_in_mouth}" title="{#emotions_dlg.foot_in_mouth}" /></a></td>\r
-                 </tr>\r
-                 <tr>\r
+               </tr>\r
+               <tr>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-frown.gif','emotions_dlg.frown');"><img src="img/smiley-frown.gif" width="18" height="18" border="0" alt="{#emotions_dlg.frown}" title="{#emotions_dlg.frown}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-innocent.gif','emotions_dlg.innocent');"><img src="img/smiley-innocent.gif" width="18" height="18" border="0" alt="{#emotions_dlg.innocent}" title="{#emotions_dlg.innocent}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-kiss.gif','emotions_dlg.kiss');"><img src="img/smiley-kiss.gif" width="18" height="18" border="0" alt="{#emotions_dlg.kiss}" title="{#emotions_dlg.kiss}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-laughing.gif','emotions_dlg.laughing');"><img src="img/smiley-laughing.gif" width="18" height="18" border="0" alt="{#emotions_dlg.laughing}" title="{#emotions_dlg.laughing}" /></a></td>\r
-                 </tr>\r
-                 <tr>\r
+               </tr>\r
+               <tr>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-money-mouth.gif','emotions_dlg.money_mouth');"><img src="img/smiley-money-mouth.gif" width="18" height="18" border="0" alt="{#emotions_dlg.money_mouth}" title="{#emotions_dlg.money_mouth}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-sealed.gif','emotions_dlg.sealed');"><img src="img/smiley-sealed.gif" width="18" height="18" border="0" alt="{#emotions_dlg.sealed}" title="{#emotions_dlg.sealed}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-smile.gif','emotions_dlg.smile');"><img src="img/smiley-smile.gif" width="18" height="18" border="0" alt="{#emotions_dlg.smile}" title="{#emotions_dlg.smile}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-surprised.gif','emotions_dlg.surprised');"><img src="img/smiley-surprised.gif" width="18" height="18" border="0" alt="{#emotions_dlg.surprised}" title="{#emotions_dlg.surprised}" /></a></td>\r
-                 </tr>\r
-                 <tr>\r
+               </tr>\r
+               <tr>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-tongue-out.gif','emotions_dlg.tongue_out');"><img src="img/smiley-tongue-out.gif" width="18" height="18" border="0" alt="{#emotions_dlg.tongue-out}" title="{#emotions_dlg.tongue_out}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-undecided.gif','emotions_dlg.undecided');"><img src="img/smiley-undecided.gif" width="18" height="18" border="0" alt="{#emotions_dlg.undecided}" title="{#emotions_dlg.undecided}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-wink.gif','emotions_dlg.wink');"><img src="img/smiley-wink.gif" width="18" height="18" border="0" alt="{#emotions_dlg.wink}" title="{#emotions_dlg.wink}" /></a></td>\r
                        <td><a href="javascript:EmotionsDialog.insert('smiley-yell.gif','emotions_dlg.yell');"><img src="img/smiley-yell.gif" width="18" height="18" border="0" alt="{#emotions_dlg.yell}" title="{#emotions_dlg.yell}" /></a></td>\r
-                 </tr>\r
-               </table>\r
-       </div>\r
+               </tr>\r
+       </table>\r
+</div>\r
 </body>\r
 </html>\r
index 2d087944dece9120429389d57ca27d894de5ee1f..0c45c7ff6de9e0ab4ffc4d09bc03616e750b4da3 100644 (file)
@@ -1,12 +1,12 @@
-#id, #name, #hspace, #vspace, #class_name, #align {    width: 100px }\r
+#id, #name, #hspace, #vspace, #class_name, #align { width: 100px }\r
 #hspace, #vspace { width: 50px }\r
 #flash_quality, #flash_align, #flash_scale, #flash_salign, #flash_wmode { width: 100px }\r
-#flash_base, #flash_flashvars { width: 240px }\r
+#flash_base, #flash_flashvars, #html5_altsource1, #html5_altsource2, #html5_poster { width: 240px }\r
 #width, #height { width: 40px }\r
 #src, #media_type { width: 250px }\r
 #class { width: 120px }\r
-#prev { margin: 0; border: 1px solid black; width: 380px; height: 230px; overflow: auto }\r
-.panel_wrapper div.current { height: 390px; overflow: auto }\r
+#prev { margin: 0; border: 1px solid black; width: 380px; height: 260px; overflow: auto }\r
+.panel_wrapper div.current { height: 420px; overflow: auto }\r
 #flash_options, #shockwave_options, #qt_options, #wmp_options, #rmp_options { display: none }\r
 .mceAddSelectValue { background-color: #DDDDDD }\r
 #qt_starttime, #qt_endtime, #qt_fov, #qt_href, #qt_moveid, #qt_moviename, #qt_node, #qt_pan, #qt_qtsrc, #qt_qtsrcchokespeed, #qt_target, #qt_tilt, #qt_urlsubstituten, #qt_volume { width: 70px }\r
@@ -14,3 +14,4 @@
 #rmp_console, #rmp_numloop, #rmp_controls, #rmp_scriptcallbacks { width: 70px }\r
 #shockwave_swvolume, #shockwave_swframe, #shockwave_swurl, #shockwave_swstretchvalign, #shockwave_swstretchhalign, #shockwave_swstretchstyle { width: 90px }\r
 #qt_qtsrc { width: 200px }\r
+iframe {border: 1px solid gray}\r
index 4bbe367e36c3a9548a7f7a7e30d7cf8cf6535573..66219078cbece453c204623a0679c12d9918e8f7 100644 (file)
@@ -1 +1 @@
-(function(){var a=tinymce.each;tinymce.create("tinymce.plugins.MediaPlugin",{init:function(b,c){var e=this;e.editor=b;e.url=c;function f(g){return/^(mceItemFlash|mceItemShockWave|mceItemWindowsMedia|mceItemQuickTime|mceItemRealMedia)$/.test(g.className)}b.onPreInit.add(function(){b.serializer.addRules("param[name|value|_mce_value]")});b.addCommand("mceMedia",function(){b.windowManager.open({file:c+"/media.htm",width:430+parseInt(b.getLang("media.delta_width",0)),height:470+parseInt(b.getLang("media.delta_height",0)),inline:1},{plugin_url:c})});b.addButton("media",{title:"media.desc",cmd:"mceMedia"});b.onNodeChange.add(function(h,g,i){g.setActive("media",i.nodeName=="IMG"&&f(i))});b.onInit.add(function(){var g={mceItemFlash:"flash",mceItemShockWave:"shockwave",mceItemWindowsMedia:"windowsmedia",mceItemQuickTime:"quicktime",mceItemRealMedia:"realmedia"};b.selection.onSetContent.add(function(){e._spansToImgs(b.getBody())});b.selection.onBeforeSetContent.add(e._objectsToSpans,e);if(b.settings.content_css!==false){b.dom.loadCSS(c+"/css/content.css")}if(b.theme&&b.theme.onResolveName){b.theme.onResolveName.add(function(h,i){if(i.name=="img"){a(g,function(l,j){if(b.dom.hasClass(i.node,j)){i.name=l;i.title=b.dom.getAttrib(i.node,"title");return false}})}})}if(b&&b.plugins.contextmenu){b.plugins.contextmenu.onContextMenu.add(function(i,h,j){if(j.nodeName=="IMG"&&/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(j.className)){h.add({title:"media.edit",icon:"media",cmd:"mceMedia"})}})}});b.onBeforeSetContent.add(e._objectsToSpans,e);b.onSetContent.add(function(){e._spansToImgs(b.getBody())});b.onPreProcess.add(function(g,i){var h=g.dom;if(i.set){e._spansToImgs(i.node);a(h.select("IMG",i.node),function(k){var j;if(f(k)){j=e._parse(k.title);h.setAttrib(k,"width",h.getAttrib(k,"width",j.width||100));h.setAttrib(k,"height",h.getAttrib(k,"height",j.height||100))}})}if(i.get){a(h.select("IMG",i.node),function(m){var l,j,k;if(g.getParam("media_use_script")){if(f(m)){m.className=m.className.replace(/mceItem/g,"mceTemp")}return}switch(m.className){case"mceItemFlash":l="d27cdb6e-ae6d-11cf-96b8-444553540000";j="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0";k="application/x-shockwave-flash";break;case"mceItemShockWave":l="166b1bca-3f9c-11cf-8075-444553540000";j="http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0";k="application/x-director";break;case"mceItemWindowsMedia":l=g.getParam("media_wmp6_compatible")?"05589fa1-c356-11ce-bf01-00aa0055595a":"6bf52a52-394a-11d3-b153-00c04f79faa6";j="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701";k="application/x-mplayer2";break;case"mceItemQuickTime":l="02bf25d5-8c17-4b23-bc80-d3488abddc6b";j="http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0";k="video/quicktime";break;case"mceItemRealMedia":l="cfcdaa03-8be4-11cf-b84b-0020afbbccfa";j="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0";k="audio/x-pn-realaudio-plugin";break}if(l){h.replace(e._buildObj({classid:l,codebase:j,type:k},m),m)}})}});b.onPostProcess.add(function(g,h){h.content=h.content.replace(/_mce_value=/g,"value=")});function d(g,h){h=new RegExp(h+'="([^"]+)"',"g").exec(g);return h?b.dom.decode(h[1]):""}b.onPostProcess.add(function(g,h){if(g.getParam("media_use_script")){h.content=h.content.replace(/<img[^>]+>/g,function(j){var i=d(j,"class");if(/^(mceTempFlash|mceTempShockWave|mceTempWindowsMedia|mceTempQuickTime|mceTempRealMedia)$/.test(i)){at=e._parse(d(j,"title"));at.width=d(j,"width");at.height=d(j,"height");j='<script type="text/javascript">write'+i.substring(7)+"({"+e._serialize(at)+"});<\/script>"}return j})}})},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}},_objectsToSpans:function(b,e){var c=this,d=e.content;d=d.replace(/<script[^>]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi,function(g,f,i){var h=c._parse(i);return'<img class="mceItem'+f+'" title="'+b.dom.encode(i)+'" src="'+c.url+'/img/trans.gif" width="'+h.width+'" height="'+h.height+'" />'});d=d.replace(/<object([^>]*)>/gi,'<span class="mceItemObject" $1>');d=d.replace(/<embed([^>]*)\/?>/gi,'<span class="mceItemEmbed" $1></span>');d=d.replace(/<embed([^>]*)>/gi,'<span class="mceItemEmbed" $1>');d=d.replace(/<\/(object)([^>]*)>/gi,"</span>");d=d.replace(/<\/embed>/gi,"");d=d.replace(/<param([^>]*)>/gi,function(g,f){return"<span "+f.replace(/value=/gi,"_mce_value=")+' class="mceItemParam"></span>'});d=d.replace(/\/ class=\"mceItemParam\"><\/span>/gi,'class="mceItemParam"></span>');e.content=d},_buildObj:function(g,h){var d,c=this.editor,f=c.dom,e=this._parse(h.title),b;b=c.getParam("media_strict",true)&&g.type=="application/x-shockwave-flash";e.width=g.width=f.getAttrib(h,"width")||100;e.height=g.height=f.getAttrib(h,"height")||100;if(e.src){e.src=c.convertURL(e.src,"src",h)}if(b){d=f.create("span",{id:e.id,_mce_name:"object",type:"application/x-shockwave-flash",data:e.src,style:f.getAttrib(h,"style"),width:g.width,height:g.height})}else{d=f.create("span",{id:e.id,_mce_name:"object",classid:"clsid:"+g.classid,style:f.getAttrib(h,"style"),codebase:g.codebase,width:g.width,height:g.height})}a(e,function(j,i){if(!/^(width|height|codebase|classid|id|_cx|_cy)$/.test(i)){if(g.type=="application/x-mplayer2"&&i=="src"&&!e.url){i="url"}if(j){f.add(d,"span",{_mce_name:"param",name:i,_mce_value:j})}}});if(!b){f.add(d,"span",tinymce.extend({_mce_name:"embed",type:g.type,style:f.getAttrib(h,"style")},e))}return d},_spansToImgs:function(e){var d=this,f=d.editor.dom,b,c;a(f.select("span",e),function(g){if(f.getAttrib(g,"class")=="mceItemObject"){c=f.getAttrib(g,"classid").toLowerCase().replace(/\s+/g,"");switch(c){case"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000":f.replace(d._createImg("mceItemFlash",g),g);break;case"clsid:166b1bca-3f9c-11cf-8075-444553540000":f.replace(d._createImg("mceItemShockWave",g),g);break;case"clsid:6bf52a52-394a-11d3-b153-00c04f79faa6":case"clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95":case"clsid:05589fa1-c356-11ce-bf01-00aa0055595a":f.replace(d._createImg("mceItemWindowsMedia",g),g);break;case"clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b":f.replace(d._createImg("mceItemQuickTime",g),g);break;case"clsid:cfcdaa03-8be4-11cf-b84b-0020afbbccfa":f.replace(d._createImg("mceItemRealMedia",g),g);break;default:f.replace(d._createImg("mceItemFlash",g),g)}return}if(f.getAttrib(g,"class")=="mceItemEmbed"){switch(f.getAttrib(g,"type")){case"application/x-shockwave-flash":f.replace(d._createImg("mceItemFlash",g),g);break;case"application/x-director":f.replace(d._createImg("mceItemShockWave",g),g);break;case"application/x-mplayer2":f.replace(d._createImg("mceItemWindowsMedia",g),g);break;case"video/quicktime":f.replace(d._createImg("mceItemQuickTime",g),g);break;case"audio/x-pn-realaudio-plugin":f.replace(d._createImg("mceItemRealMedia",g),g);break;default:f.replace(d._createImg("mceItemFlash",g),g)}}})},_createImg:function(c,h){var b,g=this.editor.dom,f={},e="",d;d=["id","name","width","height","bgcolor","align","flashvars","src","wmode","allowfullscreen","quality","data"];b=g.create("img",{src:this.url+"/img/trans.gif",width:g.getAttrib(h,"width")||100,height:g.getAttrib(h,"height")||100,style:g.getAttrib(h,"style"),"class":c});a(d,function(i){var j=g.getAttrib(h,i);if(j){f[i]=j}});a(g.select("span",h),function(i){if(g.hasClass(i,"mceItemParam")){f[g.getAttrib(i,"name")]=g.getAttrib(i,"_mce_value")}});if(f.movie){f.src=f.movie;delete f.movie}if(!f.src){f.src=f.data;delete f.data}h=g.select(".mceItemEmbed",h)[0];if(h){a(d,function(i){var j=g.getAttrib(h,i);if(j&&!f[i]){f[i]=j}})}delete f.width;delete f.height;b.title=this._serialize(f);return b},_parse:function(b){return tinymce.util.JSON.parse("{"+b+"}")},_serialize:function(b){return tinymce.util.JSON.serialize(b).replace(/[{}]/g,"")}});tinymce.PluginManager.add("media",tinymce.plugins.MediaPlugin)})();
\ No newline at end of file
+(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"]];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,mp3,mpeg;shockwave=dcr;windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;realmedia=rm,ra,ram;java=jar").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=g.parse(n.dom.getAttrib(i,"data-mce-json"));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,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||"320";n.height=m.height||"240";return n},dataToHtml:function(i,j){return this.editor.serializer.serialize(this.dataToImg(i,j),{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(x,n){var t=this,o=t.editor,A,E,j,s,F,w,D,u,k,C,r,p,y,B,m,v,l,z;function q(i,G){var K,J,L,I,H;H=o.getParam("flash_video_player_url",t.convertUrl(t.url+"/moxieplayer.swf"));if(H){K=o.documentBaseURI;D.params.src=H;if(o.getParam("flash_video_player_absvideourl",true)){i=K.toAbsolute(i||"",true);G=K.toAbsolute(G||"",true)}L="";J=o.getParam("flash_video_player_flashvars",{url:"$url",poster:"$poster"});tinymce.each(J,function(N,M){N=N.replace(/\$url/,i||"");N=N.replace(/\$poster/,G||"");if(N.length>0){L+=(L?"&":"")+M+"="+escape(N)}});if(L.length){D.params.flashvars=L}I=o.getParam("flash_video_player_params",{allowfullscreen:true,allowscriptaccess:true});tinymce.each(I,function(N,M){D.params[M]=""+N})}}D=g.parse(x.attr("data-mce-json"));p=this.getType(x.attr("class"));z=x.attr("data-mce-style");if(!z){z=x.attr("style");if(z){z=o.dom.serializeStyle(o.dom.parseStyle(z,"img"))}}if(p.name==="Iframe"){v=new b("iframe",1);tinymce.each(d,function(i){var G=x.attr(i);if(i=="class"&&G){G=G.replace(/mceItem.+ ?/g,"")}if(G&&G.length>0){v.attr(i,G)}});for(F in D.params){v.attr(F,D.params[F])}v.attr({style:z,src:D.params.src});x.replace(v);return}if(this.editor.settings.media_use_script){v=new b("script",1).attr("type","text/javascript");w=new b("#text",3);w.value="write"+p.name+"("+g.serialize(tinymce.extend(D.params,{width:x.attr("width"),height:x.attr("height")}))+");";v.append(w);x.replace(v);return}if(p.name==="Video"&&D.video.sources[0]){A=new b("video",1).attr(tinymce.extend({id:x.attr("id"),width:x.attr("width"),height:x.attr("height"),style:z},D.video.attrs));if(D.video.attrs){l=D.video.attrs.poster}k=D.video.sources=c(D.video.sources);for(y=0;y<k.length;y++){if(/\.mp4$/.test(k[y].src)){m=k[y].src}}if(!k[0].type){A.attr("src",k[0].src);k.splice(0,1)}for(y=0;y<k.length;y++){u=new b("source",1).attr(k[y]);u.shortEnded=true;A.append(u)}if(m){q(m,l);p=t.getType("flash")}else{D.params.src=""}}if(D.params.src){if(/\.flv$/i.test(D.params.src)){q(D.params.src,"")}if(n&&n.force_absolute){D.params.src=o.documentBaseURI.toAbsolute(D.params.src)}E=new b("object",1).attr({id:x.attr("id"),width:x.attr("width"),height:x.attr("height"),style:z});tinymce.each(d,function(i){if(D[i]&&i!="type"){E.attr(i,D[i])}});for(F in D.params){r=new b("param",1);r.shortEnded=true;w=D.params[F];if(F==="src"&&p.name==="WindowsMedia"){F="url"}r.attr({name:F,value:w});E.append(r)}if(this.editor.getParam("media_strict",true)){E.attr({data:D.params.src,type:p.mimes[0]})}else{E.attr({classid:"clsid:"+p.clsids[0],codebase:p.codebase});j=new b("embed",1);j.shortEnded=true;j.attr({id:x.attr("id"),width:x.attr("width"),height:x.attr("height"),style:z,type:p.mimes[0]});for(F in D.params){j.attr(F,D.params[F])}tinymce.each(d,function(i){if(D[i]&&i!="type"){j.attr(i,D[i])}});E.append(j)}if(D.object_html){w=new b("#text",3);w.raw=true;w.value=D.object_html;E.append(w)}if(A){A.append(E)}}if(A){if(D.video_html){w=new b("#text",3);w.raw=true;w.value=D.video_html;A.append(w)}}if(A||E){x.replace(A||E)}else{x.remove()}},objectToImg:function(y){var F,j,A,p,G,H,u,w,t,B,z,q,o,D,x,k,E,n,C=this.lookup,l,v,s=this.editor.settings.url_converter,m=this.editor.settings.url_converter_scope;function r(i){return new tinymce.html.Serializer({inner:true,validate:false}).serialize(i)}if(!y.parent){return}if(y.name==="script"){if(y.firstChild){l=a.exec(y.firstChild.value)}if(!l){return}n=l[1];E={video:{},params:g.parse(l[2])};w=E.params.width;t=E.params.height}E=E||{video:{},params:{}};G=new b("img",1);G.attr({src:this.editor.theme.url+"/img/trans.gif"});H=y.name;if(H==="video"){A=y;F=y.getAll("object")[0];j=y.getAll("embed")[0];w=A.attr("width");t=A.attr("height");u=A.attr("id");E.video={attrs:{},sources:[]};v=E.video.attrs;for(H in A.attributes.map){v[H]=A.attributes.map[H]}x=y.attr("src");if(x){E.video.sources.push({src:s.call(m,x,"src","video")})}k=A.getAll("source");for(z=0;z<k.length;z++){x=k[z].remove();E.video.sources.push({src:s.call(m,x.attr("src"),"src","source"),type:x.attr("type"),media:x.attr("media")})}if(v.poster){v.poster=s.call(m,v.poster,"poster","video")}}if(y.name==="object"){F=y;j=y.getAll("embed")[0]}if(y.name==="embed"){j=y}if(y.name==="iframe"){p=y;n="Iframe"}if(F){w=w||F.attr("width");t=t||F.attr("height");B=B||F.attr("style");u=u||F.attr("id");D=F.getAll("param");for(z=0;z<D.length;z++){o=D[z];H=o.remove().attr("name");if(!h[H]){E.params[H]=o.attr("value")}}E.params.src=E.params.src||F.attr("data")}if(j){w=w||j.attr("width");t=t||j.attr("height");B=B||j.attr("style");u=u||j.attr("id");for(H in j.attributes.map){if(!h[H]&&!E.params[H]){E.params[H]=j.attributes.map[H]}}}if(p){w=p.attr("width");t=p.attr("height");B=B||p.attr("style");u=p.attr("id");tinymce.each(d,function(i){G.attr(i,p.attr(i))});for(H in p.attributes.map){if(!h[H]&&!E.params[H]){E.params[H]=p.attributes.map[H]}}}if(E.params.movie){E.params.src=E.params.src||E.params.movie;delete E.params.movie}if(E.params.src){E.params.src=s.call(m,E.params.src,"src","object")}if(A){n=C.video.name}if(F&&!n){n=(C[(F.attr("clsid")||"").toLowerCase()]||C[(F.attr("type")||"").toLowerCase()]||{}).name}if(j&&!n){n=(C[(j.attr("type")||"").toLowerCase()]||{}).name}y.replace(G);if(j){j.remove()}if(F){q=r(F.remove());if(q){E.object_html=q}}if(A){q=r(A.remove());if(q){E.video_html=q}}G.attr({id:u,"class":"mceItemMedia mceItem"+(n||"Flash"),style:B,width:w||"320",height:t||"240","data-mce-json":g.serialize(E,"'")})}});tinymce.PluginManager.add("media",tinymce.plugins.MediaPlugin)})();
\ No newline at end of file
index fc84e5b6c5bfcd31ab44a21f3e541b4836b000a5..e640bd366321de79e05597ff3f7c1bc87e4a2270 100644 (file)
  */\r
 \r
 (function() {\r
-       var each = tinymce.each;\r
+       var rootAttributes = tinymce.explode('id,name,width,height,style,align,class,hspace,vspace,bgcolor,type'), excludedAttrs = tinymce.makeMap(rootAttributes.join(',')), Node = tinymce.html.Node,\r
+               mediaTypes, scriptRegExp, JSON = tinymce.util.JSON, mimeTypes;\r
+\r
+       // Media types supported by this plugin\r
+       mediaTypes = [\r
+               // Type, clsid:s, mime types, codebase\r
+               ["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"],\r
+               ["ShockWave", "166b1bca-3f9c-11cf-8075-444553540000", "application/x-director", "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0"],\r
+               ["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"],\r
+               ["QuickTime", "02bf25d5-8c17-4b23-bc80-d3488abddc6b", "video/quicktime", "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0"],\r
+               ["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"],\r
+               ["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"],\r
+               ["Silverlight", "dfeaf541-f3e1-4c24-acac-99c30715084a", "application/x-silverlight-2"],\r
+               ["Iframe"],\r
+               ["Video"]\r
+       ];\r
+\r
+       function toArray(obj) {\r
+               var undef, out, i;\r
+\r
+               if (obj && !obj.splice) {\r
+                       out = [];\r
+\r
+                       for (i = 0; true; i++) {\r
+                               if (obj[i])\r
+                                       out[i] = obj[i];\r
+                               else\r
+                                       break;\r
+                       }\r
+\r
+                       return out;\r
+               }\r
+\r
+               return obj;\r
+       };\r
 \r
        tinymce.create('tinymce.plugins.MediaPlugin', {\r
                init : function(ed, url) {\r
-                       var t = this;\r
-                       \r
-                       t.editor = ed;\r
-                       t.url = url;\r
+                       var self = this, lookup = {}, i, y, item, name;\r
 \r
-                       function isMediaElm(n) {\r
-                               return /^(mceItemFlash|mceItemShockWave|mceItemWindowsMedia|mceItemQuickTime|mceItemRealMedia)$/.test(n.className);\r
+                       function isMediaImg(node) {\r
+                               return node && node.nodeName === 'IMG' && ed.dom.hasClass(node, 'mceItemMedia');\r
                        };\r
 \r
-                       ed.onPreInit.add(function() {\r
-                               // Force in _value parameter this extra parameter is required for older Opera versions\r
-                               ed.serializer.addRules('param[name|value|_mce_value]');\r
-                       });\r
+                       self.editor = ed;\r
+                       self.url = url;\r
 \r
-                       // Register commands\r
-                       ed.addCommand('mceMedia', function() {\r
-                               ed.windowManager.open({\r
-                                       file : url + '/media.htm',\r
-                                       width : 430 + parseInt(ed.getLang('media.delta_width', 0)),\r
-                                       height : 470 + parseInt(ed.getLang('media.delta_height', 0)),\r
-                                       inline : 1\r
-                               }, {\r
-                                       plugin_url : url\r
-                               });\r
-                       });\r
+                       // Parse media types into a lookup table\r
+                       scriptRegExp = '';\r
+                       for (i = 0; i < mediaTypes.length; i++) {\r
+                               name = mediaTypes[i][0];\r
 \r
-                       // Register buttons\r
-                       ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'});\r
+                               item = {\r
+                                       name : name,\r
+                                       clsids : tinymce.explode(mediaTypes[i][1] || ''),\r
+                                       mimes : tinymce.explode(mediaTypes[i][2] || ''),\r
+                                       codebase : mediaTypes[i][3]\r
+                               };\r
+\r
+                               for (y = 0; y < item.clsids.length; y++)\r
+                                       lookup['clsid:' + item.clsids[y]] = item;\r
+\r
+                               for (y = 0; y < item.mimes.length; y++)\r
+                                       lookup[item.mimes[y]] = item;\r
+\r
+                               lookup['mceItem' + name] = item;\r
+                               lookup[name.toLowerCase()] = item;\r
 \r
-                       ed.onNodeChange.add(function(ed, cm, n) {\r
-                               cm.setActive('media', n.nodeName == 'IMG' && isMediaElm(n));\r
+                               scriptRegExp += (scriptRegExp ? '|' : '') + name;\r
+                       }\r
+\r
+                       // Handle the media_types setting\r
+                       tinymce.each(ed.getParam("media_types",\r
+                               "video=mp4,m4v,ogv,webm;" +\r
+                               "silverlight=xap;" +\r
+                               "flash=swf,flv;" +\r
+                               "shockwave=dcr;" +\r
+                               "quicktime=mov,qt,mpg,mp3,mpeg;" +\r
+                               "shockwave=dcr;" +\r
+                               "windowsmedia=avi,wmv,wm,asf,asx,wmx,wvx;" +\r
+                               "realmedia=rm,ra,ram;" +\r
+                               "java=jar"\r
+                       ).split(';'), function(item) {\r
+                               var i, extensions, type;\r
+\r
+                               item = item.split(/=/);\r
+                               extensions = tinymce.explode(item[1].toLowerCase());\r
+                               for (i = 0; i < extensions.length; i++) {\r
+                                       type = lookup[item[0].toLowerCase()];\r
+\r
+                                       if (type)\r
+                                               lookup[extensions[i]] = type;\r
+                               }\r
                        });\r
 \r
-                       ed.onInit.add(function() {\r
-                               var lo = {\r
-                                       mceItemFlash : 'flash',\r
-                                       mceItemShockWave : 'shockwave',\r
-                                       mceItemWindowsMedia : 'windowsmedia',\r
-                                       mceItemQuickTime : 'quicktime',\r
-                                       mceItemRealMedia : 'realmedia'\r
-                               };\r
+                       scriptRegExp = new RegExp('write(' + scriptRegExp + ')\\(([^)]+)\\)');\r
+                       self.lookup = lookup;\r
 \r
-                               ed.selection.onSetContent.add(function() {\r
-                                       t._spansToImgs(ed.getBody());\r
+                       ed.onPreInit.add(function() {\r
+                               // Allow video elements\r
+                               ed.schema.addValidElements('object[id|style|width|height|classid|codebase|*],param[name|value],embed[id|style|width|height|type|src|*],video[*],audio[*],source[*]');\r
+\r
+                               // Convert video elements to image placeholder\r
+                               ed.parser.addNodeFilter('object,embed,video,audio,script,iframe', function(nodes) {\r
+                                       var i = nodes.length;\r
+\r
+                                       while (i--)\r
+                                               self.objectToImg(nodes[i]);\r
                                });\r
 \r
-                               ed.selection.onBeforeSetContent.add(t._objectsToSpans, t);\r
+                               // Convert image placeholders to video elements\r
+                               ed.serializer.addNodeFilter('img', function(nodes, name, args) {\r
+                                       var i = nodes.length, node;\r
 \r
-                               if (ed.settings.content_css !== false)\r
-                                       ed.dom.loadCSS(url + "/css/content.css");\r
+                                       while (i--) {\r
+                                               node = nodes[i];\r
+                                               if ((node.attr('class') || '').indexOf('mceItemMedia') !== -1)\r
+                                                       self.imgToObject(node, args);\r
+                                       }\r
+                               });\r
+                       });\r
 \r
+                       ed.onInit.add(function() {\r
+                               // Display "media" instead of "img" in element path\r
                                if (ed.theme && ed.theme.onResolveName) {\r
-                                       ed.theme.onResolveName.add(function(th, o) {\r
-                                               if (o.name == 'img') {\r
-                                                       each(lo, function(v, k) {\r
-                                                               if (ed.dom.hasClass(o.node, k)) {\r
-                                                                       o.name = v;\r
-                                                                       o.title = ed.dom.getAttrib(o.node, 'title');\r
-                                                                       return false;\r
-                                                               }\r
-                                                       });\r
-                                               }\r
+                                       ed.theme.onResolveName.add(function(theme, path_object) {\r
+                                               if (path_object.name === 'img' && ed.dom.hasClass(path_object.node, 'mceItemMedia'))\r
+                                                       path_object.name = 'media';\r
                                        });\r
                                }\r
 \r
+                               // Add contect menu if it's loaded\r
                                if (ed && ed.plugins.contextmenu) {\r
-                                       ed.plugins.contextmenu.onContextMenu.add(function(th, m, e) {\r
-                                               if (e.nodeName == 'IMG' && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(e.className)) {\r
-                                                       m.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'});\r
-                                               }\r
+                                       ed.plugins.contextmenu.onContextMenu.add(function(plugin, menu, element) {\r
+                                               if (element.nodeName === 'IMG' && element.className.indexOf('mceItemMedia') !== -1)\r
+                                                       menu.add({title : 'media.edit', icon : 'media', cmd : 'mceMedia'});\r
                                        });\r
                                }\r
                        });\r
 \r
-                       ed.onBeforeSetContent.add(t._objectsToSpans, t);\r
-\r
-                       ed.onSetContent.add(function() {\r
-                               t._spansToImgs(ed.getBody());\r
-                       });\r
-\r
-                       ed.onPreProcess.add(function(ed, o) {\r
-                               var dom = ed.dom;\r
+                       // Register commands\r
+                       ed.addCommand('mceMedia', function() {\r
+                               var data, img;\r
 \r
-                               if (o.set) {\r
-                                       t._spansToImgs(o.node);\r
+                               img = ed.selection.getNode();\r
+                               if (isMediaImg(img)) {\r
+                                       data = JSON.parse(ed.dom.getAttrib(img, 'data-mce-json'));\r
 \r
-                                       each(dom.select('IMG', o.node), function(n) {\r
-                                               var p;\r
+                                       // Add some extra properties to the data object\r
+                                       tinymce.each(rootAttributes, function(name) {\r
+                                               var value = ed.dom.getAttrib(img, name);\r
 \r
-                                               if (isMediaElm(n)) {\r
-                                                       p = t._parse(n.title);\r
-                                                       dom.setAttrib(n, 'width', dom.getAttrib(n, 'width', p.width || 100));\r
-                                                       dom.setAttrib(n, 'height', dom.getAttrib(n, 'height', p.height || 100));\r
-                                               }\r
+                                               if (value)\r
+                                                       data[name] = value;\r
                                        });\r
+\r
+                                       data.type = self.getType(img.className).name.toLowerCase();\r
                                }\r
 \r
-                               if (o.get) {\r
-                                       each(dom.select('IMG', o.node), function(n) {\r
-                                               var ci, cb, mt;\r
-\r
-                                               if (ed.getParam('media_use_script')) {\r
-                                                       if (isMediaElm(n))\r
-                                                               n.className = n.className.replace(/mceItem/g, 'mceTemp');\r
-\r
-                                                       return;\r
-                                               }\r
-\r
-                                               switch (n.className) {\r
-                                                       case 'mceItemFlash':\r
-                                                               ci = 'd27cdb6e-ae6d-11cf-96b8-444553540000';\r
-                                                               cb = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0';\r
-                                                               mt = 'application/x-shockwave-flash';\r
-                                                               break;\r
-\r
-                                                       case 'mceItemShockWave':\r
-                                                               ci = '166b1bca-3f9c-11cf-8075-444553540000';\r
-                                                               cb = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0';\r
-                                                               mt = 'application/x-director';\r
-                                                               break;\r
-\r
-                                                       case 'mceItemWindowsMedia':\r
-                                                               ci = ed.getParam('media_wmp6_compatible') ? '05589fa1-c356-11ce-bf01-00aa0055595a' : '6bf52a52-394a-11d3-b153-00c04f79faa6';\r
-                                                               cb = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';\r
-                                                               mt = 'application/x-mplayer2';\r
-                                                               break;\r
-\r
-                                                       case 'mceItemQuickTime':\r
-                                                               ci = '02bf25d5-8c17-4b23-bc80-d3488abddc6b';\r
-                                                               cb = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0';\r
-                                                               mt = 'video/quicktime';\r
-                                                               break;\r
-\r
-                                                       case 'mceItemRealMedia':\r
-                                                               ci = 'cfcdaa03-8be4-11cf-b84b-0020afbbccfa';\r
-                                                               cb = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0';\r
-                                                               mt = 'audio/x-pn-realaudio-plugin';\r
-                                                               break;\r
-                                               }\r
-\r
-                                               if (ci) {\r
-                                                       dom.replace(t._buildObj({\r
-                                                               classid : ci,\r
-                                                               codebase : cb,\r
-                                                               type : mt\r
-                                                       }, n), n);\r
-                                               }\r
-                                       });\r
+                               if (!data) {\r
+                                       data = {\r
+                                               type : 'flash',\r
+                                               video: {sources:[]},\r
+                                               params: {}\r
+                                       };\r
                                }\r
-                       });\r
 \r
-                       ed.onPostProcess.add(function(ed, o) {\r
-                               o.content = o.content.replace(/_mce_value=/g, 'value=');\r
+                               ed.windowManager.open({\r
+                                       file : url + '/media.htm',\r
+                                       width : 430 + parseInt(ed.getLang('media.delta_width', 0)),\r
+                                       height : 500 + parseInt(ed.getLang('media.delta_height', 0)),\r
+                                       inline : 1\r
+                               }, {\r
+                                       plugin_url : url,\r
+                                       data : data\r
+                               });\r
                        });\r
 \r
-                       function getAttr(s, n) {\r
-                               n = new RegExp(n + '=\"([^\"]+)\"', 'g').exec(s);\r
+                       // Register buttons\r
+                       ed.addButton('media', {title : 'media.desc', cmd : 'mceMedia'});\r
 \r
-                               return n ? ed.dom.decode(n[1]) : '';\r
-                       };\r
+                       // Update media selection status\r
+                       ed.onNodeChange.add(function(ed, cm, node) {\r
+                               cm.setActive('media', isMediaImg(node));\r
+                       });\r
+               },\r
 \r
-                       ed.onPostProcess.add(function(ed, o) {\r
-                               if (ed.getParam('media_use_script')) {\r
-                                       o.content = o.content.replace(/<img[^>]+>/g, function(im) {\r
-                                               var cl = getAttr(im, 'class');\r
+               convertUrl : function(url, force_absolute) {\r
+                       var self = this, editor = self.editor, settings = editor.settings,\r
+                               urlConverter = settings.url_converter,\r
+                               urlConverterScope = settings.url_converter_scope || self;\r
 \r
-                                               if (/^(mceTempFlash|mceTempShockWave|mceTempWindowsMedia|mceTempQuickTime|mceTempRealMedia)$/.test(cl)) {\r
-                                                       at = t._parse(getAttr(im, 'title'));\r
-                                                       at.width = getAttr(im, 'width');\r
-                                                       at.height = getAttr(im, 'height');\r
-                                                       im = '<script type="text/javascript">write' + cl.substring(7) + '({' + t._serialize(at) + '});</script>';\r
-                                               }\r
+                       if (!url)\r
+                               return url;\r
 \r
-                                               return im;\r
-                                       });\r
-                               }\r
-                       });\r
+                       if (force_absolute)\r
+                               return editor.documentBaseURI.toAbsolute(url);\r
+\r
+                       return urlConverter.call(urlConverterScope, url, 'src', 'object');\r
                },\r
 \r
                getInfo : function() {\r
                        };\r
                },\r
 \r
-               // Private methods\r
-               _objectsToSpans : function(ed, o) {\r
-                       var t = this, h = o.content;\r
+               /**\r
+                * Converts the JSON data object to an img node.\r
+                */\r
+               dataToImg : function(data, force_absolute) {\r
+                       var self = this, editor = self.editor, baseUri = editor.documentBaseURI, sources, attrs, img, i;\r
+\r
+                       data.params.src = self.convertUrl(data.params.src, force_absolute);\r
 \r
-                       h = h.replace(/<script[^>]*>\s*write(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)\(\{([^\)]*)\}\);\s*<\/script>/gi, function(a, b, c) {\r
-                               var o = t._parse(c);\r
+                       attrs = data.video.attrs;\r
+                       if (attrs)\r
+                               attrs.src = self.convertUrl(attrs.src, force_absolute);\r
 \r
-                               return '<img class="mceItem' + b + '" title="' + ed.dom.encode(c) + '" src="' + t.url + '/img/trans.gif" width="' + o.width + '" height="' + o.height + '" />'\r
+                       if (attrs)\r
+                               attrs.poster = self.convertUrl(attrs.poster, force_absolute);\r
+\r
+                       sources = toArray(data.video.sources);\r
+                       if (sources) {\r
+                               for (i = 0; i < sources.length; i++)\r
+                                       sources[i].src = self.convertUrl(sources[i].src, force_absolute);\r
+                       }\r
+\r
+                       img = self.editor.dom.create('img', {\r
+                               id : data.id,\r
+                               style : data.style,\r
+                               align : data.align,\r
+                               src : self.editor.theme.url + '/img/trans.gif',\r
+                               'class' : 'mceItemMedia mceItem' + self.getType(data.type).name,\r
+                               'data-mce-json' : JSON.serialize(data, "'")\r
                        });\r
 \r
-                       h = h.replace(/<object([^>]*)>/gi, '<span class="mceItemObject" $1>');\r
-                       h = h.replace(/<embed([^>]*)\/?>/gi, '<span class="mceItemEmbed" $1></span>');\r
-                       h = h.replace(/<embed([^>]*)>/gi, '<span class="mceItemEmbed" $1>');\r
-                       h = h.replace(/<\/(object)([^>]*)>/gi, '</span>');\r
-                       h = h.replace(/<\/embed>/gi, '');\r
-                       h = h.replace(/<param([^>]*)>/gi, function(a, b) {return '<span ' + b.replace(/value=/gi, '_mce_value=') + ' class="mceItemParam"></span>'});\r
-                       h = h.replace(/\/ class=\"mceItemParam\"><\/span>/gi, 'class="mceItemParam"></span>');\r
+                       img.width = data.width || "320";\r
+                       img.height = data.height || "240";\r
 \r
-                       o.content = h;\r
+                       return img;\r
                },\r
 \r
-               _buildObj : function(o, n) {\r
-                       var ob, ed = this.editor, dom = ed.dom, p = this._parse(n.title), stc;\r
-                       \r
-                       stc = ed.getParam('media_strict', true) && o.type == 'application/x-shockwave-flash';\r
-\r
-                       p.width = o.width = dom.getAttrib(n, 'width') || 100;\r
-                       p.height = o.height = dom.getAttrib(n, 'height') || 100;\r
-\r
-                       if (p.src)\r
-                               p.src = ed.convertURL(p.src, 'src', n);\r
-\r
-                       if (stc) {\r
-                               ob = dom.create('span', {\r
-                                       id : p.id,\r
-                                       _mce_name : 'object',\r
-                                       type : 'application/x-shockwave-flash',\r
-                                       data : p.src,\r
-                                       style : dom.getAttrib(n, 'style'),\r
-                                       width : o.width,\r
-                                       height : o.height\r
-                               });\r
-                       } else {\r
-                               ob = dom.create('span', {\r
-                                       id : p.id,\r
-                                       _mce_name : 'object',\r
-                                       classid : "clsid:" + o.classid,\r
-                                       style : dom.getAttrib(n, 'style'),\r
-                                       codebase : o.codebase,\r
-                                       width : o.width,\r
-                                       height : o.height\r
+               /**\r
+                * Converts the JSON data object to a HTML string.\r
+                */\r
+               dataToHtml : function(data, force_absolute) {\r
+                       return this.editor.serializer.serialize(this.dataToImg(data, force_absolute), {force_absolute : force_absolute});\r
+               },\r
+\r
+               /**\r
+                * Converts the JSON data object to a HTML string.\r
+                */\r
+               htmlToData : function(html) {\r
+                       var fragment, img, data;\r
+\r
+                       data = {\r
+                               type : 'flash',\r
+                               video: {sources:[]},\r
+                               params: {}\r
+                       };\r
+\r
+                       fragment = this.editor.parser.parse(html);\r
+                       img = fragment.getAll('img')[0];\r
+\r
+                       if (img) {\r
+                               data = JSON.parse(img.attr('data-mce-json'));\r
+                               data.type = this.getType(img.attr('class')).name.toLowerCase();\r
+\r
+                               // Add some extra properties to the data object\r
+                               tinymce.each(rootAttributes, function(name) {\r
+                                       var value = img.attr(name);\r
+\r
+                                       if (value)\r
+                                               data[name] = value;\r
                                });\r
                        }\r
 \r
-                       each (p, function(v, k) {\r
-                               if (!/^(width|height|codebase|classid|id|_cx|_cy)$/.test(k)) {\r
-                                       // Use url instead of src in IE for Windows media\r
-                                       if (o.type == 'application/x-mplayer2' && k == 'src' && !p.url)\r
-                                               k = 'url';\r
+                       return data;\r
+               },\r
+\r
+               /**\r
+                * Get type item by extension, class, clsid or mime type.\r
+                *\r
+                * @method getType\r
+                * @param {String} value Value to get type item by.\r
+                * @return {Object} Type item object or undefined.\r
+                */\r
+               getType : function(value) {\r
+                       var i, values, typeItem;\r
+\r
+                       // Find type by checking the classes\r
+                       values = tinymce.explode(value, ' ');\r
+                       for (i = 0; i < values.length; i++) {\r
+                               typeItem = this.lookup[values[i]];\r
+\r
+                               if (typeItem)\r
+                                       return typeItem;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Converts a tinymce.html.Node image element to video/object/embed.\r
+                */\r
+               imgToObject : function(node, args) {\r
+                       var self = this, editor = self.editor, video, object, embed, iframe, name, value, data,\r
+                               source, sources, params, param, typeItem, i, item, mp4Source, replacement,\r
+                               posterSrc, style;\r
+\r
+                       // Adds the flash player\r
+                       function addPlayer(video_src, poster_src) {\r
+                               var baseUri, flashVars, flashVarsOutput, params, flashPlayer;\r
+\r
+                               flashPlayer = editor.getParam('flash_video_player_url', self.convertUrl(self.url + '/moxieplayer.swf'));\r
+                               if (flashPlayer) {\r
+                                       baseUri = editor.documentBaseURI;\r
+                                       data.params.src = flashPlayer;\r
+\r
+                                       // Convert the movie url to absolute urls\r
+                                       if (editor.getParam('flash_video_player_absvideourl', true)) {\r
+                                               video_src = baseUri.toAbsolute(video_src || '', true);\r
+                                               poster_src = baseUri.toAbsolute(poster_src || '', true);\r
+                                       }\r
+\r
+                                       // Generate flash vars\r
+                                       flashVarsOutput = '';\r
+                                       flashVars = editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'});\r
+                                       tinymce.each(flashVars, function(value, name) {\r
+                                               // Replace $url and $poster variables in flashvars value\r
+                                               value = value.replace(/\$url/, video_src || '');\r
+                                               value = value.replace(/\$poster/, poster_src || '');\r
+\r
+                                               if (value.length > 0)\r
+                                                       flashVarsOutput += (flashVarsOutput ? '&' : '') + name + '=' + escape(value);\r
+                                       });\r
+\r
+                                       if (flashVarsOutput.length)\r
+                                               data.params.flashvars = flashVarsOutput;\r
 \r
-                                       if (v)\r
-                                               dom.add(ob, 'span', {_mce_name : 'param', name : k, '_mce_value' : v});\r
+                                       params = editor.getParam('flash_video_player_params', {\r
+                                               allowfullscreen: true,\r
+                                               allowscriptaccess: true\r
+                                       });\r
+\r
+                                       tinymce.each(params, function(value, name) {\r
+                                               data.params[name] = "" + value;\r
+                                       });\r
                                }\r
-                       });\r
+                       };\r
 \r
-                       if (!stc)\r
-                               dom.add(ob, 'span', tinymce.extend({_mce_name : 'embed', type : o.type, style : dom.getAttrib(n, 'style')}, p));\r
+                       data = JSON.parse(node.attr('data-mce-json'));\r
+                       typeItem = this.getType(node.attr('class'));\r
 \r
-                       return ob;\r
-               },\r
+                       style = node.attr('data-mce-style')\r
+                       if (!style) {\r
+                               style = node.attr('style');\r
 \r
-               _spansToImgs : function(p) {\r
-                       var t = this, dom = t.editor.dom, im, ci;\r
+                               if (style)\r
+                                       style = editor.dom.serializeStyle(editor.dom.parseStyle(style, 'img'));\r
+                       }\r
 \r
-                       each(dom.select('span', p), function(n) {\r
-                               // Convert object into image\r
-                               if (dom.getAttrib(n, 'class') == 'mceItemObject') {\r
-                                       ci = dom.getAttrib(n, "classid").toLowerCase().replace(/\s+/g, '');\r
+                       // Handle iframe\r
+                       if (typeItem.name === 'Iframe') {\r
+                               replacement = new Node('iframe', 1);\r
 \r
-                                       switch (ci) {\r
-                                               case 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000':\r
-                                                       dom.replace(t._createImg('mceItemFlash', n), n);\r
-                                                       break;\r
+                               tinymce.each(rootAttributes, function(name) {\r
+                                       var value = node.attr(name);\r
 \r
-                                               case 'clsid:166b1bca-3f9c-11cf-8075-444553540000':\r
-                                                       dom.replace(t._createImg('mceItemShockWave', n), n);\r
-                                                       break;\r
+                                       if (name == 'class' && value)\r
+                                               value = value.replace(/mceItem.+ ?/g, '');\r
 \r
-                                               case 'clsid:6bf52a52-394a-11d3-b153-00c04f79faa6':\r
-                                               case 'clsid:22d6f312-b0f6-11d0-94ab-0080c74c7e95':\r
-                                               case 'clsid:05589fa1-c356-11ce-bf01-00aa0055595a':\r
-                                                       dom.replace(t._createImg('mceItemWindowsMedia', n), n);\r
-                                                       break;\r
+                                       if (value && value.length > 0)\r
+                                               replacement.attr(name, value);\r
+                               });\r
 \r
-                                               case 'clsid:02bf25d5-8c17-4b23-bc80-d3488abddc6b':\r
-                                                       dom.replace(t._createImg('mceItemQuickTime', n), n);\r
-                                                       break;\r
+                               for (name in data.params)\r
+                                       replacement.attr(name, data.params[name]);\r
 \r
-                                               case 'clsid:cfcdaa03-8be4-11cf-b84b-0020afbbccfa':\r
-                                                       dom.replace(t._createImg('mceItemRealMedia', n), n);\r
-                                                       break;\r
+                               replacement.attr({\r
+                                       style: style,\r
+                                       src: data.params.src\r
+                               });\r
 \r
-                                               default:\r
-                                                       dom.replace(t._createImg('mceItemFlash', n), n);\r
-                                       }\r
-                                       \r
-                                       return;\r
+                               node.replace(replacement);\r
+\r
+                               return;\r
+                       }\r
+\r
+                       // Handle scripts\r
+                       if (this.editor.settings.media_use_script) {\r
+                               replacement = new Node('script', 1).attr('type', 'text/javascript');\r
+\r
+                               value = new Node('#text', 3);\r
+                               value.value = 'write' + typeItem.name + '(' + JSON.serialize(tinymce.extend(data.params, {\r
+                                       width: node.attr('width'),\r
+                                       height: node.attr('height')\r
+                               })) + ');';\r
+\r
+                               replacement.append(value);\r
+                               node.replace(replacement);\r
+\r
+                               return;\r
+                       }\r
+\r
+                       // Add HTML5 video element\r
+                       if (typeItem.name === 'Video' && data.video.sources[0]) {\r
+                               // Create new object element\r
+                               video = new Node('video', 1).attr(tinymce.extend({\r
+                                       id : node.attr('id'),\r
+                                       width: node.attr('width'),\r
+                                       height: node.attr('height'),\r
+                                       style : style\r
+                               }, data.video.attrs));\r
+\r
+                               // Get poster source and use that for flash fallback\r
+                               if (data.video.attrs)\r
+                                       posterSrc = data.video.attrs.poster;\r
+\r
+                               sources = data.video.sources = toArray(data.video.sources);\r
+                               for (i = 0; i < sources.length; i++) {\r
+                                       if (/\.mp4$/.test(sources[i].src))\r
+                                               mp4Source = sources[i].src;\r
                                }\r
 \r
-                               // Convert embed into image\r
-                               if (dom.getAttrib(n, 'class') == 'mceItemEmbed') {\r
-                                       switch (dom.getAttrib(n, 'type')) {\r
-                                               case 'application/x-shockwave-flash':\r
-                                                       dom.replace(t._createImg('mceItemFlash', n), n);\r
-                                                       break;\r
+                               if (!sources[0].type) {\r
+                                       video.attr('src', sources[0].src);\r
+                                       sources.splice(0, 1);\r
+                               }\r
 \r
-                                               case 'application/x-director':\r
-                                                       dom.replace(t._createImg('mceItemShockWave', n), n);\r
-                                                       break;\r
+                               for (i = 0; i < sources.length; i++) {\r
+                                       source = new Node('source', 1).attr(sources[i]);\r
+                                       source.shortEnded = true;\r
+                                       video.append(source);\r
+                               }\r
 \r
-                                               case 'application/x-mplayer2':\r
-                                                       dom.replace(t._createImg('mceItemWindowsMedia', n), n);\r
-                                                       break;\r
+                               // Create flash fallback for video if we have a mp4 source\r
+                               if (mp4Source) {\r
+                                       addPlayer(mp4Source, posterSrc);\r
+                                       typeItem = self.getType('flash');\r
+                               } else\r
+                                       data.params.src = '';\r
+                       }\r
 \r
-                                               case 'video/quicktime':\r
-                                                       dom.replace(t._createImg('mceItemQuickTime', n), n);\r
-                                                       break;\r
+                       // Do we have a params src then we can generate object\r
+                       if (data.params.src) {\r
+                               // Is flv movie add player for it\r
+                               if (/\.flv$/i.test(data.params.src))\r
+                                       addPlayer(data.params.src, '');\r
+\r
+                               if (args && args.force_absolute)\r
+                                       data.params.src = editor.documentBaseURI.toAbsolute(data.params.src);\r
+\r
+                               // Create new object element\r
+                               object = new Node('object', 1).attr({\r
+                                       id : node.attr('id'),\r
+                                       width: node.attr('width'),\r
+                                       height: node.attr('height'),\r
+                                       style : style\r
+                               });\r
 \r
-                                               case 'audio/x-pn-realaudio-plugin':\r
-                                                       dom.replace(t._createImg('mceItemRealMedia', n), n);\r
-                                                       break;\r
+                               tinymce.each(rootAttributes, function(name) {\r
+                                       if (data[name] && name != 'type')\r
+                                               object.attr(name, data[name]);\r
+                               });\r
 \r
-                                               default:\r
-                                                       dom.replace(t._createImg('mceItemFlash', n), n);\r
-                                       }\r
-                               }                       \r
-                       });\r
+                               // Add params\r
+                               for (name in data.params) {\r
+                                       param = new Node('param', 1);\r
+                                       param.shortEnded = true;\r
+                                       value = data.params[name];\r
+\r
+                                       // Windows media needs to use url instead of src for the media URL\r
+                                       if (name === 'src' && typeItem.name === 'WindowsMedia')\r
+                                               name = 'url';\r
+\r
+                                       param.attr({name: name, value: value});\r
+                                       object.append(param);\r
+                               }\r
+\r
+                               // Setup add type and classid if strict is disabled\r
+                               if (this.editor.getParam('media_strict', true)) {\r
+                                       object.attr({\r
+                                               data: data.params.src,\r
+                                               type: typeItem.mimes[0]\r
+                                       });\r
+                               } else {\r
+                                       object.attr({\r
+                                               classid: "clsid:" + typeItem.clsids[0],\r
+                                               codebase: typeItem.codebase\r
+                                       });\r
+\r
+                                       embed = new Node('embed', 1);\r
+                                       embed.shortEnded = true;\r
+                                       embed.attr({\r
+                                               id: node.attr('id'),\r
+                                               width: node.attr('width'),\r
+                                               height: node.attr('height'),\r
+                                               style : style,\r
+                                               type: typeItem.mimes[0]\r
+                                       });\r
+\r
+                                       for (name in data.params)\r
+                                               embed.attr(name, data.params[name]);\r
+\r
+                                       tinymce.each(rootAttributes, function(name) {\r
+                                               if (data[name] && name != 'type')\r
+                                                       embed.attr(name, data[name]);\r
+                                       });\r
+\r
+                                       object.append(embed);\r
+                               }\r
+\r
+                               // Insert raw HTML\r
+                               if (data.object_html) {\r
+                                       value = new Node('#text', 3);\r
+                                       value.raw = true;\r
+                                       value.value = data.object_html;\r
+                                       object.append(value);\r
+                               }\r
+\r
+                               // Append object to video element if it exists\r
+                               if (video)\r
+                                       video.append(object);\r
+                       }\r
+\r
+                       if (video) {\r
+                               // Insert raw HTML\r
+                               if (data.video_html) {\r
+                                       value = new Node('#text', 3);\r
+                                       value.raw = true;\r
+                                       value.value = data.video_html;\r
+                                       video.append(value);\r
+                               }\r
+                       }\r
+\r
+                       if (video || object)\r
+                               node.replace(video || object);\r
+                       else\r
+                               node.remove();\r
                },\r
 \r
-               _createImg : function(cl, n) {\r
-                       var im, dom = this.editor.dom, pa = {}, ti = '', args;\r
+               /**\r
+                * Converts a tinymce.html.Node video/object/embed to an img element.\r
+                *\r
+                * The video/object/embed will be converted into an image placeholder with a JSON data attribute like this:\r
+                * <img class="mceItemMedia mceItemFlash" width="100" height="100" data-mce-json="{..}" />\r
+                *\r
+                * The JSON structure will be like this:\r
+                * {'params':{'flashvars':'something','quality':'high','src':'someurl'}, 'video':{'sources':[{src: 'someurl', type: 'video/mp4'}]}}\r
+                */\r
+               objectToImg : function(node) {\r
+                       var object, embed, video, iframe, img, name, id, width, height, style, i, html,\r
+                               param, params, source, sources, data, type, lookup = this.lookup,\r
+                               matches, attrs, urlConverter = this.editor.settings.url_converter,\r
+                               urlConverterScope = this.editor.settings.url_converter_scope;\r
+\r
+                       function getInnerHTML(node) {\r
+                               return new tinymce.html.Serializer({\r
+                                       inner: true,\r
+                                       validate: false\r
+                               }).serialize(node);\r
+                       };\r
 \r
-                       args = ['id', 'name', 'width', 'height', 'bgcolor', 'align', 'flashvars', 'src', 'wmode', 'allowfullscreen', 'quality', 'data'];        \r
+                       // If node isn't in document\r
+                       if (!node.parent)\r
+                               return;\r
 \r
-                       // Create image\r
-                       im = dom.create('img', {\r
-                               src : this.url + '/img/trans.gif',\r
-                               width : dom.getAttrib(n, 'width') || 100,\r
-                               height : dom.getAttrib(n, 'height') || 100,\r
-                               style : dom.getAttrib(n, 'style'),\r
-                               'class' : cl\r
-                       });\r
+                       // Handle media scripts\r
+                       if (node.name === 'script') {\r
+                               if (node.firstChild)\r
+                                       matches = scriptRegExp.exec(node.firstChild.value);\r
 \r
-                       // Setup base parameters\r
-                       each(args, function(na) {\r
-                               var v = dom.getAttrib(n, na);\r
+                               if (!matches)\r
+                                       return;\r
 \r
-                               if (v)\r
-                                       pa[na] = v;\r
-                       });\r
+                               type = matches[1];\r
+                               data = {video : {}, params : JSON.parse(matches[2])};\r
+                               width = data.params.width;\r
+                               height = data.params.height;\r
+                       }\r
+\r
+                       // Setup data objects\r
+                       data = data || {\r
+                               video : {},\r
+                               params : {}\r
+                       };\r
 \r
-                       // Add optional parameters\r
-                       each(dom.select('span', n), function(n) {\r
-                               if (dom.hasClass(n, 'mceItemParam'))\r
-                                       pa[dom.getAttrib(n, 'name')] = dom.getAttrib(n, '_mce_value');\r
+                       // Setup new image object\r
+                       img = new Node('img', 1);\r
+                       img.attr({\r
+                               src : this.editor.theme.url + '/img/trans.gif'\r
                        });\r
 \r
-                       // Use src not movie\r
-                       if (pa.movie) {\r
-                               pa.src = pa.movie;\r
-                               delete pa.movie;\r
+                       // Video element\r
+                       name = node.name;\r
+                       if (name === 'video') {\r
+                               video = node;\r
+                               object = node.getAll('object')[0];\r
+                               embed = node.getAll('embed')[0];\r
+                               width = video.attr('width');\r
+                               height = video.attr('height');\r
+                               id = video.attr('id');\r
+                               data.video = {attrs : {}, sources : []};\r
+\r
+                               // Get all video attributes\r
+                               attrs = data.video.attrs;\r
+                               for (name in video.attributes.map)\r
+                                       attrs[name] = video.attributes.map[name];\r
+\r
+                               source = node.attr('src');\r
+                               if (source)\r
+                                       data.video.sources.push({src : urlConverter.call(urlConverterScope, source, 'src', 'video')});\r
+\r
+                               // Get all sources\r
+                               sources = video.getAll("source");\r
+                               for (i = 0; i < sources.length; i++) {\r
+                                       source = sources[i].remove();\r
+\r
+                                       data.video.sources.push({\r
+                                               src: urlConverter.call(urlConverterScope, source.attr('src'), 'src', 'source'),\r
+                                               type: source.attr('type'),\r
+                                               media: source.attr('media')\r
+                                       });\r
+                               }\r
+\r
+                               // Convert the poster URL\r
+                               if (attrs.poster)\r
+                                       attrs.poster = urlConverter.call(urlConverterScope, attrs.poster, 'poster', 'video');\r
+                       }\r
+\r
+                       // Object element\r
+                       if (node.name === 'object') {\r
+                               object = node;\r
+                               embed = node.getAll('embed')[0];\r
+                       }\r
+\r
+                       // Embed element\r
+                       if (node.name === 'embed')\r
+                               embed = node;\r
+\r
+                       // Iframe element\r
+                       if (node.name === 'iframe') {\r
+                               iframe = node;\r
+                               type = 'Iframe';\r
+                       }\r
+\r
+                       if (object) {\r
+                               // Get width/height\r
+                               width = width || object.attr('width');\r
+                               height = height || object.attr('height');\r
+                               style = style || object.attr('style');\r
+                               id = id || object.attr('id');\r
+\r
+                               // Get all object params\r
+                               params = object.getAll("param");\r
+                               for (i = 0; i < params.length; i++) {\r
+                                       param = params[i];\r
+                                       name = param.remove().attr('name');\r
+\r
+                                       if (!excludedAttrs[name])\r
+                                               data.params[name] = param.attr('value');\r
+                               }\r
+\r
+                               data.params.src = data.params.src || object.attr('data');\r
                        }\r
 \r
-                       // No src try data\r
-                       if (!pa.src) {\r
-                               pa.src = pa.data;\r
-                               delete pa.data;\r
+                       if (embed) {\r
+                               // Get width/height\r
+                               width = width || embed.attr('width');\r
+                               height = height || embed.attr('height');\r
+                               style = style || embed.attr('style');\r
+                               id = id || embed.attr('id');\r
+\r
+                               // Get all embed attributes\r
+                               for (name in embed.attributes.map) {\r
+                                       if (!excludedAttrs[name] && !data.params[name])\r
+                                               data.params[name] = embed.attributes.map[name];\r
+                               }\r
                        }\r
 \r
-                       // Merge with embed args\r
-                       n = dom.select('.mceItemEmbed', n)[0];\r
-                       if (n) {\r
-                               each(args, function(na) {\r
-                                       var v = dom.getAttrib(n, na);\r
+                       if (iframe) {\r
+                               // Get width/height\r
+                               width = iframe.attr('width');\r
+                               height = iframe.attr('height');\r
+                               style = style || iframe.attr('style');\r
+                               id = iframe.attr('id');\r
 \r
-                                       if (v && !pa[na])\r
-                                               pa[na] = v;\r
+                               tinymce.each(rootAttributes, function(name) {\r
+                                       img.attr(name, iframe.attr(name));\r
                                });\r
+\r
+                               // Get all iframe attributes\r
+                               for (name in iframe.attributes.map) {\r
+                                       if (!excludedAttrs[name] && !data.params[name])\r
+                                               data.params[name] = iframe.attributes.map[name];\r
+                               }\r
                        }\r
 \r
-                       delete pa.width;\r
-                       delete pa.height;\r
+                       // Use src not movie\r
+                       if (data.params.movie) {\r
+                               data.params.src = data.params.src || data.params.movie;\r
+                               delete data.params.movie;\r
+                       }\r
 \r
-                       im.title = this._serialize(pa);\r
+                       // Convert the URL to relative/absolute depending on configuration\r
+                       if (data.params.src)\r
+                               data.params.src = urlConverter.call(urlConverterScope, data.params.src, 'src', 'object');\r
 \r
-                       return im;\r
-               },\r
+                       if (video)\r
+                               type = lookup.video.name;\r
 \r
-               _parse : function(s) {\r
-                       return tinymce.util.JSON.parse('{' + s + '}');\r
-               },\r
+                       if (object && !type)\r
+                               type = (lookup[(object.attr('clsid') || '').toLowerCase()] || lookup[(object.attr('type') || '').toLowerCase()] || {}).name;\r
 \r
-               _serialize : function(o) {\r
-                       return tinymce.util.JSON.serialize(o).replace(/[{}]/g, '');\r
+                       if (embed && !type)\r
+                               type = (lookup[(embed.attr('type') || '').toLowerCase()] || {}).name;\r
+\r
+                       // Replace the video/object/embed element with a placeholder image containing the data\r
+                       node.replace(img);\r
+\r
+                       // Remove embed\r
+                       if (embed)\r
+                               embed.remove();\r
+\r
+                       // Serialize the inner HTML of the object element\r
+                       if (object) {\r
+                               html = getInnerHTML(object.remove());\r
+\r
+                               if (html)\r
+                                       data.object_html = html;\r
+                       }\r
+\r
+                       // Serialize the inner HTML of the video element\r
+                       if (video) {\r
+                               html = getInnerHTML(video.remove());\r
+\r
+                               if (html)\r
+                                       data.video_html = html;\r
+                       }\r
+\r
+                       // Set width/height of placeholder\r
+                       img.attr({\r
+                               id : id,\r
+                               'class' : 'mceItemMedia mceItem' + (type || 'Flash'),\r
+                               style : style,\r
+                               width : width || "320",\r
+                               height : height || "240",\r
+                               "data-mce-json" : JSON.serialize(data, "'")\r
+                       });\r
                }\r
        });\r
 \r
index 86cfa98563d829fed029f6bc164bc4bc6493b0ef..30ad656175e1395bcd150a7bc575bcc5ad2170b6 100644 (file)
-tinyMCEPopup.requireLangPack();\r
+(function() {\r
+       var url;\r
 \r
-var oldWidth, oldHeight, ed, url;\r
+       if (url = tinyMCEPopup.getParam("media_external_list_url"))\r
+               document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');\r
 \r
-if (url = tinyMCEPopup.getParam("media_external_list_url"))\r
-       document.write('<script language="javascript" type="text/javascript" src="' + tinyMCEPopup.editor.documentBaseURI.toAbsolute(url) + '"></script>');\r
-\r
-function init() {\r
-       var pl = "", f, val;\r
-       var type = "flash", fe, i;\r
-\r
-       ed = tinyMCEPopup.editor;\r
-\r
-       tinyMCEPopup.resizeToInnerSize();\r
-       f = document.forms[0]\r
-\r
-       fe = ed.selection.getNode();\r
-       if (/mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(ed.dom.getAttrib(fe, 'class'))) {\r
-               pl = fe.title;\r
-\r
-               switch (ed.dom.getAttrib(fe, 'class')) {\r
-                       case 'mceItemFlash':\r
-                               type = 'flash';\r
-                               break;\r
-\r
-                       case 'mceItemFlashVideo':\r
-                               type = 'flv';\r
-                               break;\r
-\r
-                       case 'mceItemShockWave':\r
-                               type = 'shockwave';\r
-                               break;\r
-\r
-                       case 'mceItemWindowsMedia':\r
-                               type = 'wmp';\r
-                               break;\r
-\r
-                       case 'mceItemQuickTime':\r
-                               type = 'qt';\r
-                               break;\r
-\r
-                       case 'mceItemRealMedia':\r
-                               type = 'rmp';\r
-                               break;\r
-               }\r
-\r
-               document.forms[0].insert.value = ed.getLang('update', 'Insert', true); \r
+       function get(id) {\r
+               return document.getElementById(id);\r
        }\r
 \r
-       document.getElementById('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media');\r
-       document.getElementById('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','qt_qtsrc','media','media');\r
-       document.getElementById('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');\r
-\r
-       var html = getMediaListHTML('medialist','src','media','media');\r
-       if (html == "")\r
-               document.getElementById("linklistrow").style.display = 'none';\r
-       else\r
-               document.getElementById("linklistcontainer").innerHTML = html;\r
-\r
-       // Resize some elements\r
-       if (isVisible('filebrowser'))\r
-               document.getElementById('src').style.width = '230px';\r
-\r
-       // Setup form\r
-       if (pl != "") {\r
-               pl = tinyMCEPopup.editor.plugins.media._parse(pl);\r
-\r
-               switch (type) {\r
-                       case "flash":\r
-                               setBool(pl, 'flash', 'play');\r
-                               setBool(pl, 'flash', 'loop');\r
-                               setBool(pl, 'flash', 'menu');\r
-                               setBool(pl, 'flash', 'swliveconnect');\r
-                               setStr(pl, 'flash', 'quality');\r
-                               setStr(pl, 'flash', 'scale');\r
-                               setStr(pl, 'flash', 'salign');\r
-                               setStr(pl, 'flash', 'wmode');\r
-                               setStr(pl, 'flash', 'base');\r
-                               setStr(pl, 'flash', 'flashvars');\r
-                       break;\r
-\r
-                       case "qt":\r
-                               setBool(pl, 'qt', 'loop');\r
-                               setBool(pl, 'qt', 'autoplay');\r
-                               setBool(pl, 'qt', 'cache');\r
-                               setBool(pl, 'qt', 'controller');\r
-                               setBool(pl, 'qt', 'correction');\r
-                               setBool(pl, 'qt', 'enablejavascript');\r
-                               setBool(pl, 'qt', 'kioskmode');\r
-                               setBool(pl, 'qt', 'autohref');\r
-                               setBool(pl, 'qt', 'playeveryframe');\r
-                               setBool(pl, 'qt', 'tarsetcache');\r
-                               setStr(pl, 'qt', 'scale');\r
-                               setStr(pl, 'qt', 'starttime');\r
-                               setStr(pl, 'qt', 'endtime');\r
-                               setStr(pl, 'qt', 'tarset');\r
-                               setStr(pl, 'qt', 'qtsrcchokespeed');\r
-                               setStr(pl, 'qt', 'volume');\r
-                               setStr(pl, 'qt', 'qtsrc');\r
-                       break;\r
-\r
-                       case "shockwave":\r
-                               setBool(pl, 'shockwave', 'sound');\r
-                               setBool(pl, 'shockwave', 'progress');\r
-                               setBool(pl, 'shockwave', 'autostart');\r
-                               setBool(pl, 'shockwave', 'swliveconnect');\r
-                               setStr(pl, 'shockwave', 'swvolume');\r
-                               setStr(pl, 'shockwave', 'swstretchstyle');\r
-                               setStr(pl, 'shockwave', 'swstretchhalign');\r
-                               setStr(pl, 'shockwave', 'swstretchvalign');\r
-                       break;\r
-\r
-                       case "wmp":\r
-                               setBool(pl, 'wmp', 'autostart');\r
-                               setBool(pl, 'wmp', 'enabled');\r
-                               setBool(pl, 'wmp', 'enablecontextmenu');\r
-                               setBool(pl, 'wmp', 'fullscreen');\r
-                               setBool(pl, 'wmp', 'invokeurls');\r
-                               setBool(pl, 'wmp', 'mute');\r
-                               setBool(pl, 'wmp', 'stretchtofit');\r
-                               setBool(pl, 'wmp', 'windowlessvideo');\r
-                               setStr(pl, 'wmp', 'balance');\r
-                               setStr(pl, 'wmp', 'baseurl');\r
-                               setStr(pl, 'wmp', 'captioningid');\r
-                               setStr(pl, 'wmp', 'currentmarker');\r
-                               setStr(pl, 'wmp', 'currentposition');\r
-                               setStr(pl, 'wmp', 'defaultframe');\r
-                               setStr(pl, 'wmp', 'playcount');\r
-                               setStr(pl, 'wmp', 'rate');\r
-                               setStr(pl, 'wmp', 'uimode');\r
-                               setStr(pl, 'wmp', 'volume');\r
-                       break;\r
-\r
-                       case "rmp":\r
-                               setBool(pl, 'rmp', 'autostart');\r
-                               setBool(pl, 'rmp', 'loop');\r
-                               setBool(pl, 'rmp', 'autogotourl');\r
-                               setBool(pl, 'rmp', 'center');\r
-                               setBool(pl, 'rmp', 'imagestatus');\r
-                               setBool(pl, 'rmp', 'maintainaspect');\r
-                               setBool(pl, 'rmp', 'nojava');\r
-                               setBool(pl, 'rmp', 'prefetch');\r
-                               setBool(pl, 'rmp', 'shuffle');\r
-                               setStr(pl, 'rmp', 'console');\r
-                               setStr(pl, 'rmp', 'controls');\r
-                               setStr(pl, 'rmp', 'numloop');\r
-                               setStr(pl, 'rmp', 'scriptcallbacks');\r
-                       break;\r
-               }\r
-\r
-               setStr(pl, null, 'src');\r
-               setStr(pl, null, 'id');\r
-               setStr(pl, null, 'name');\r
-               setStr(pl, null, 'vspace');\r
-               setStr(pl, null, 'hspace');\r
-               setStr(pl, null, 'bgcolor');\r
-               setStr(pl, null, 'align');\r
-               setStr(pl, null, 'width');\r
-               setStr(pl, null, 'height');\r
-\r
-               if ((val = ed.dom.getAttrib(fe, "width")) != "")\r
-                       pl.width = f.width.value = val;\r
-\r
-               if ((val = ed.dom.getAttrib(fe, "height")) != "")\r
-                       pl.height = f.height.value = val;\r
-\r
-               oldWidth = pl.width ? parseInt(pl.width) : 0;\r
-               oldHeight = pl.height ? parseInt(pl.height) : 0;\r
-       } else\r
-               oldWidth = oldHeight = 0;\r
-\r
-       selectByValue(f, 'media_type', type);\r
-       changedType(type);\r
-       updateColor('bgcolor_pick', 'bgcolor');\r
+       function getVal(id) {\r
+               var elm = get(id);\r
 \r
-       TinyMCE_EditableSelects.init();\r
-       generatePreview();\r
-}\r
+               if (elm.nodeName == "SELECT")\r
+                       return elm.options[elm.selectedIndex].value;\r
 \r
-function insertMedia() {\r
-       var fe, f = document.forms[0], h;\r
+               if (elm.type == "checkbox")\r
+                       return elm.checked;\r
 \r
-       tinyMCEPopup.restoreSelection();\r
-\r
-       if (!AutoValidator.validate(f)) {\r
-               tinyMCEPopup.alert(ed.getLang('invalid_data'));\r
-               return false;\r
+               return elm.value;\r
        }\r
 \r
-       f.width.value = f.width.value == "" ? 100 : f.width.value;\r
-       f.height.value = f.height.value == "" ? 100 : f.height.value;\r
-\r
-       fe = ed.selection.getNode();\r
-       if (fe != null && /mceItem(Flash|ShockWave|WindowsMedia|QuickTime|RealMedia)/.test(ed.dom.getAttrib(fe, 'class'))) {\r
-               switch (f.media_type.options[f.media_type.selectedIndex].value) {\r
-                       case "flash":\r
-                               fe.className = "mceItemFlash";\r
-                               break;\r
-\r
-                       case "flv":\r
-                               fe.className = "mceItemFlashVideo";\r
-                               break;\r
-\r
-                       case "shockwave":\r
-                               fe.className = "mceItemShockWave";\r
-                               break;\r
-\r
-                       case "qt":\r
-                               fe.className = "mceItemQuickTime";\r
-                               break;\r
-\r
-                       case "wmp":\r
-                               fe.className = "mceItemWindowsMedia";\r
-                               break;\r
-\r
-                       case "rmp":\r
-                               fe.className = "mceItemRealMedia";\r
-                               break;\r
-               }\r
-\r
-               if (fe.width != f.width.value || fe.height != f.height.value)\r
-                       ed.execCommand('mceRepaint');\r
-\r
-               fe.title = serializeParameters();\r
-               fe.width = f.width.value;\r
-               fe.height = f.height.value;\r
-               fe.style.width = f.width.value + (f.width.value.indexOf('%') == -1 ? 'px' : '');\r
-               fe.style.height = f.height.value + (f.height.value.indexOf('%') == -1 ? 'px' : '');\r
-               fe.align = f.align.options[f.align.selectedIndex].value;\r
-       } else {\r
-               h = '<img src="' + tinyMCEPopup.getWindowArg("plugin_url") + '/img/trans.gif"' ;\r
-\r
-               switch (f.media_type.options[f.media_type.selectedIndex].value) {\r
-                       case "flash":\r
-                               h += ' class="mceItemFlash"';\r
-                               break;\r
-\r
-                       case "flv":\r
-                               h += ' class="mceItemFlashVideo"';\r
-                               break;\r
-\r
-                       case "shockwave":\r
-                               h += ' class="mceItemShockWave"';\r
-                               break;\r
-\r
-                       case "qt":\r
-                               h += ' class="mceItemQuickTime"';\r
-                               break;\r
-\r
-                       case "wmp":\r
-                               h += ' class="mceItemWindowsMedia"';\r
-                               break;\r
-\r
-                       case "rmp":\r
-                               h += ' class="mceItemRealMedia"';\r
-                               break;\r
+       function setVal(id, value) {\r
+               if (typeof(value) != 'undefined') {\r
+                       var elm = get(id);\r
+\r
+                       if (elm.nodeName == "SELECT")\r
+                               selectByValue(document.forms[0], id, value);\r
+                       else if (elm.type == "checkbox") {\r
+                               if (typeof(value) == 'string')\r
+                                       elm.checked = value.toLowerCase() === 'true' ? true : false;\r
+                               else\r
+                                       elm.checked = !!value;\r
+                       } else\r
+                               elm.value = value;\r
                }\r
-\r
-               h += ' title="' + serializeParameters() + '"';\r
-               h += ' width="' + f.width.value + '"';\r
-               h += ' height="' + f.height.value + '"';\r
-               h += ' align="' + f.align.options[f.align.selectedIndex].value + '"';\r
-\r
-               h += ' />';\r
-\r
-               ed.execCommand('mceInsertContent', false, h);\r
        }\r
 \r
-       tinyMCEPopup.close();\r
-}\r
-\r
-function updatePreview() {\r
-       var f = document.forms[0], type;\r
-\r
-       f.width.value = f.width.value || '320';\r
-       f.height.value = f.height.value || '240';\r
-\r
-       type = getType(f.src.value);\r
-       selectByValue(f, 'media_type', type);\r
-       changedType(type);\r
-       generatePreview();\r
-}\r
-\r
-function getMediaListHTML() {\r
-       if (typeof(tinyMCEMediaList) != "undefined" && tinyMCEMediaList.length > 0) {\r
-               var html = "";\r
-\r
-               html += '<select id="linklist" name="linklist" style="width: 250px" onchange="this.form.src.value=this.options[this.selectedIndex].value;updatePreview();">';\r
-               html += '<option value="">---</option>';\r
-\r
-               for (var i=0; i<tinyMCEMediaList.length; i++)\r
-                       html += '<option value="' + tinyMCEMediaList[i][1] + '">' + tinyMCEMediaList[i][0] + '</option>';\r
-\r
-               html += '</select>';\r
-\r
-               return html;\r
-       }\r
-\r
-       return "";\r
-}\r
-\r
-function getType(v) {\r
-       var fo, i, c, el, x, f = document.forms[0];\r
-\r
-       fo = ed.getParam("media_types", "flash=swf;flv=flv;shockwave=dcr;qt=mov,qt,mpg,mp3,mp4,mpeg;shockwave=dcr;wmp=avi,wmv,wm,asf,asx,wmx,wvx;rmp=rm,ra,ram").split(';');\r
-\r
-       // YouTube\r
-       if (v.match(/watch\?v=(.+)(.*)/)) {\r
-               f.width.value = '425';\r
-               f.height.value = '350';\r
-               f.src.value = 'http://www.youtube.com/v/' + v.match(/v=(.*)(.*)/)[0].split('=')[1];\r
-               return 'flash';\r
-       }\r
-\r
-       // Google video\r
-       if (v.indexOf('http://video.google.com/videoplay?docid=') == 0) {\r
-               f.width.value = '425';\r
-               f.height.value = '326';\r
-               f.src.value = 'http://video.google.com/googleplayer.swf?docId=' + v.substring('http://video.google.com/videoplay?docid='.length) + '&hl=en';\r
-               return 'flash';\r
-       }\r
-\r
-       for (i=0; i<fo.length; i++) {\r
-               c = fo[i].split('=');\r
-\r
-               el = c[1].split(',');\r
-               for (x=0; x<el.length; x++)\r
-               if (v.indexOf('.' + el[x]) != -1)\r
-                       return c[0];\r
-       }\r
-\r
-       return null;\r
-}\r
-\r
-function switchType(v) {\r
-       var t = getType(v), d = document, f = d.forms[0];\r
-\r
-       if (!t)\r
-               return;\r
-\r
-       selectByValue(d.forms[0], 'media_type', t);\r
-       changedType(t);\r
-\r
-       // Update qtsrc also\r
-       if (t == 'qt' && f.src.value.toLowerCase().indexOf('rtsp://') != -1) {\r
-               alert(ed.getLang("media_qt_stream_warn"));\r
-\r
-               if (f.qt_qtsrc.value == '')\r
-                       f.qt_qtsrc.value = f.src.value;\r
-       }\r
-}\r
-\r
-function changedType(t) {\r
-       var d = document;\r
-\r
-       d.getElementById('flash_options').style.display = 'none';\r
-       d.getElementById('flv_options').style.display = 'none';\r
-       d.getElementById('qt_options').style.display = 'none';\r
-       d.getElementById('shockwave_options').style.display = 'none';\r
-       d.getElementById('wmp_options').style.display = 'none';\r
-       d.getElementById('rmp_options').style.display = 'none';\r
-\r
-       if (t)\r
-               d.getElementById(t + '_options').style.display = 'block';\r
-}\r
-\r
-function serializeParameters() {\r
-       var d = document, f = d.forms[0], s = '';\r
-\r
-       switch (f.media_type.options[f.media_type.selectedIndex].value) {\r
-               case "flash":\r
-                       s += getBool('flash', 'play', true);\r
-                       s += getBool('flash', 'loop', true);\r
-                       s += getBool('flash', 'menu', true);\r
-                       s += getBool('flash', 'swliveconnect', false);\r
-                       s += getStr('flash', 'quality');\r
-                       s += getStr('flash', 'scale');\r
-                       s += getStr('flash', 'salign');\r
-                       s += getStr('flash', 'wmode');\r
-                       s += getStr('flash', 'base');\r
-                       s += getStr('flash', 'flashvars');\r
-               break;\r
-\r
-               case "qt":\r
-                       s += getBool('qt', 'loop', false);\r
-                       s += getBool('qt', 'autoplay', true);\r
-                       s += getBool('qt', 'cache', false);\r
-                       s += getBool('qt', 'controller', true);\r
-                       s += getBool('qt', 'correction', false, 'none', 'full');\r
-                       s += getBool('qt', 'enablejavascript', false);\r
-                       s += getBool('qt', 'kioskmode', false);\r
-                       s += getBool('qt', 'autohref', false);\r
-                       s += getBool('qt', 'playeveryframe', false);\r
-                       s += getBool('qt', 'targetcache', false);\r
-                       s += getStr('qt', 'scale');\r
-                       s += getStr('qt', 'starttime');\r
-                       s += getStr('qt', 'endtime');\r
-                       s += getStr('qt', 'target');\r
-                       s += getStr('qt', 'qtsrcchokespeed');\r
-                       s += getStr('qt', 'volume');\r
-                       s += getStr('qt', 'qtsrc');\r
-               break;\r
-\r
-               case "shockwave":\r
-                       s += getBool('shockwave', 'sound');\r
-                       s += getBool('shockwave', 'progress');\r
-                       s += getBool('shockwave', 'autostart');\r
-                       s += getBool('shockwave', 'swliveconnect');\r
-                       s += getStr('shockwave', 'swvolume');\r
-                       s += getStr('shockwave', 'swstretchstyle');\r
-                       s += getStr('shockwave', 'swstretchhalign');\r
-                       s += getStr('shockwave', 'swstretchvalign');\r
-               break;\r
-\r
-               case "wmp":\r
-                       s += getBool('wmp', 'autostart', true);\r
-                       s += getBool('wmp', 'enabled', false);\r
-                       s += getBool('wmp', 'enablecontextmenu', true);\r
-                       s += getBool('wmp', 'fullscreen', false);\r
-                       s += getBool('wmp', 'invokeurls', true);\r
-                       s += getBool('wmp', 'mute', false);\r
-                       s += getBool('wmp', 'stretchtofit', false);\r
-                       s += getBool('wmp', 'windowlessvideo', false);\r
-                       s += getStr('wmp', 'balance');\r
-                       s += getStr('wmp', 'baseurl');\r
-                       s += getStr('wmp', 'captioningid');\r
-                       s += getStr('wmp', 'currentmarker');\r
-                       s += getStr('wmp', 'currentposition');\r
-                       s += getStr('wmp', 'defaultframe');\r
-                       s += getStr('wmp', 'playcount');\r
-                       s += getStr('wmp', 'rate');\r
-                       s += getStr('wmp', 'uimode');\r
-                       s += getStr('wmp', 'volume');\r
-               break;\r
-\r
-               case "rmp":\r
-                       s += getBool('rmp', 'autostart', false);\r
-                       s += getBool('rmp', 'loop', false);\r
-                       s += getBool('rmp', 'autogotourl', true);\r
-                       s += getBool('rmp', 'center', false);\r
-                       s += getBool('rmp', 'imagestatus', true);\r
-                       s += getBool('rmp', 'maintainaspect', false);\r
-                       s += getBool('rmp', 'nojava', false);\r
-                       s += getBool('rmp', 'prefetch', false);\r
-                       s += getBool('rmp', 'shuffle', false);\r
-                       s += getStr('rmp', 'console');\r
-                       s += getStr('rmp', 'controls');\r
-                       s += getStr('rmp', 'numloop');\r
-                       s += getStr('rmp', 'scriptcallbacks');\r
-               break;\r
-       }\r
-\r
-       s += getStr(null, 'id');\r
-       s += getStr(null, 'name');\r
-       s += getStr(null, 'src');\r
-       s += getStr(null, 'align');\r
-       s += getStr(null, 'bgcolor');\r
-       s += getInt(null, 'vspace');\r
-       s += getInt(null, 'hspace');\r
-       s += getStr(null, 'width');\r
-       s += getStr(null, 'height');\r
-\r
-       s = s.length > 0 ? s.substring(0, s.length - 1) : s;\r
-\r
-       return s;\r
-}\r
-\r
-function setBool(pl, p, n) {\r
-       if (typeof(pl[n]) == "undefined")\r
-               return;\r
-\r
-       document.forms[0].elements[p + "_" + n].checked = pl[n] != 'false';\r
-}\r
-\r
-function setStr(pl, p, n) {\r
-       var f = document.forms[0], e = f.elements[(p != null ? p + "_" : '') + n];\r
-\r
-       if (typeof(pl[n]) == "undefined")\r
-               return;\r
-\r
-       if (e.type == "text")\r
-               e.value = pl[n];\r
-       else\r
-               selectByValue(f, (p != null ? p + "_" : '') + n, pl[n]);\r
-}\r
-\r
-function getBool(p, n, d, tv, fv) {\r
-       var v = document.forms[0].elements[p + "_" + n].checked;\r
-\r
-       tv = typeof(tv) == 'undefined' ? 'true' : "'" + jsEncode(tv) + "'";\r
-       fv = typeof(fv) == 'undefined' ? 'false' : "'" + jsEncode(fv) + "'";\r
-\r
-       return (v == d) ? '' : n + (v ? ':' + tv + ',' : ":\'" + fv + "\',");\r
-}\r
-\r
-function getStr(p, n, d) {\r
-       var e = document.forms[0].elements[(p != null ? p + "_" : "") + n];\r
-       var v = e.type == "text" ? e.value : e.options[e.selectedIndex].value;\r
-\r
-       if (n == 'src')\r
-               v = tinyMCEPopup.editor.convertURL(v, 'src', null);\r
-\r
-       return ((n == d || v == '') ? '' : n + ":'" + jsEncode(v) + "',");\r
-}\r
-\r
-function getInt(p, n, d) {\r
-       var e = document.forms[0].elements[(p != null ? p + "_" : "") + n];\r
-       var v = e.type == "text" ? e.value : e.options[e.selectedIndex].value;\r
-\r
-       return ((n == d || v == '') ? '' : n + ":" + v.replace(/[^0-9]+/g, '') + ",");\r
-}\r
-\r
-function jsEncode(s) {\r
-       s = s.replace(new RegExp('\\\\', 'g'), '\\\\');\r
-       s = s.replace(new RegExp('"', 'g'), '\\"');\r
-       s = s.replace(new RegExp("'", 'g'), "\\'");\r
+       window.Media = {\r
+               init : function() {\r
+                       var html, editor;\r
+\r
+                       this.editor = editor = tinyMCEPopup.editor;\r
+\r
+                       // Setup file browsers and color pickers\r
+                       get('filebrowsercontainer').innerHTML = getBrowserHTML('filebrowser','src','media','media');\r
+                       get('qtsrcfilebrowsercontainer').innerHTML = getBrowserHTML('qtsrcfilebrowser','quicktime_qtsrc','media','media');\r
+                       get('bgcolor_pickcontainer').innerHTML = getColorPickerHTML('bgcolor_pick','bgcolor');\r
+                       get('video_altsource1_filebrowser').innerHTML = getBrowserHTML('filebrowser_altsource1','video_altsource1','media','media');\r
+                       get('video_altsource2_filebrowser').innerHTML = getBrowserHTML('filebrowser_altsource2','video_altsource2','media','media');\r
+                       get('video_poster_filebrowser').innerHTML = getBrowserHTML('filebrowser_poster','video_poster','media','image');\r
+\r
+                       html = this.getMediaListHTML('medialist', 'src', 'media', 'media');\r
+                       if (html == "")\r
+                               get("linklistrow").style.display = 'none';\r
+                       else\r
+                               get("linklistcontainer").innerHTML = html;\r
+\r
+                       if (isVisible('filebrowser'))\r
+                               get('src').style.width = '230px';\r
+\r
+                       if (isVisible('filebrowser_altsource1'))\r
+                               get('video_altsource1').style.width = '220px';\r
+\r
+                       if (isVisible('filebrowser_altsource2'))\r
+                               get('video_altsource2').style.width = '220px';\r
+\r
+                       if (isVisible('filebrowser_poster'))\r
+                               get('video_poster').style.width = '220px';\r
+\r
+                       this.data = tinyMCEPopup.getWindowArg('data');\r
+                       this.dataToForm();\r
+                       this.preview();\r
+               },\r
+\r
+               insert : function() {\r
+                       var editor = tinyMCEPopup.editor;\r
+\r
+                       this.formToData();\r
+                       editor.execCommand('mceRepaint');\r
+                       tinyMCEPopup.restoreSelection();\r
+                       editor.selection.setNode(editor.plugins.media.dataToImg(this.data));\r
+                       tinyMCEPopup.close();\r
+               },\r
+\r
+               preview : function() {\r
+                       get('prev').innerHTML = this.editor.plugins.media.dataToHtml(this.data, true);\r
+               },\r
+\r
+               moveStates : function(to_form, field) {\r
+                       var data = this.data, editor = this.editor, data = this.data,\r
+                               mediaPlugin = editor.plugins.media, ext, src, typeInfo, defaultStates, src;\r
+\r
+                       defaultStates = {\r
+                               // QuickTime\r
+                               quicktime_autoplay : true,\r
+                               quicktime_controller : true,\r
+\r
+                               // Flash\r
+                               flash_play : true,\r
+                               flash_loop : true,\r
+                               flash_menu : true,\r
+\r
+                               // WindowsMedia\r
+                               windowsmedia_autostart : true,\r
+                               windowsmedia_enablecontextmenu : true,\r
+                               windowsmedia_invokeurls : true,\r
+\r
+                               // RealMedia\r
+                               realmedia_autogotourl : true,\r
+                               realmedia_imagestatus : true\r
+                       };\r
+\r
+                       function parseQueryParams(str) {\r
+                               var out = {};\r
+\r
+                               if (str) {\r
+                                       tinymce.each(str.split('&'), function(item) {\r
+                                               var parts = item.split('=');\r
+\r
+                                               out[unescape(parts[0])] = unescape(parts[1]);\r
+                                       });\r
+                               }\r
+\r
+                               return out;\r
+                       };\r
+\r
+                       function setOptions(type, names) {\r
+                               var i, name, formItemName, value, list;\r
+\r
+                               if (type == data.type || type == 'global') {\r
+                                       names = tinymce.explode(names);\r
+                                       for (i = 0; i < names.length; i++) {\r
+                                               name = names[i];\r
+                                               formItemName = type == 'global' ? name : type + '_' + name;\r
+\r
+                                               if (type == 'global')\r
+                                                       list = data;\r
+                                               else if (type == 'video') {\r
+                                                       list = data.video.attrs;\r
+\r
+                                                       if (!list && !to_form)\r
+                                                               data.video.attrs = list = {};\r
+                                               } else\r
+                                                       list = data.params;\r
+\r
+                                               if (list) {\r
+                                                       if (to_form) {\r
+                                                               setVal(formItemName, list[name]);\r
+                                                       } else {\r
+                                                               delete list[name];\r
+\r
+                                                               value = getVal(formItemName);\r
+                                                               if (type == 'video' && value === true)\r
+                                                                       value = name;\r
+\r
+                                                               if (defaultStates[formItemName]) {\r
+                                                                       if (value !== defaultStates[formItemName]) {\r
+                                                                               value = "" + value;\r
+                                                                               list[name] = value;\r
+                                                                       }\r
+                                                               } else if (value) {\r
+                                                                       value = "" + value;\r
+                                                                       list[name] = value;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
 \r
-       return s;\r
-}\r
+                       if (!to_form) {\r
+                               data.type = get('media_type').options[get('media_type').selectedIndex].value;\r
+                               data.width = getVal('width');\r
+                               data.height = getVal('height');\r
 \r
-function generatePreview(c) {\r
-       var f = document.forms[0], p = document.getElementById('prev'), h = '', cls, pl, n, type, codebase, wp, hp, nw, nh;\r
+                               // Switch type based on extension\r
+                               src = getVal('src');\r
+                               if (field == 'src') {\r
+                                       ext = src.replace(/^.*\.([^.]+)$/, '$1');\r
+                                       if (typeInfo = mediaPlugin.getType(ext))\r
+                                               data.type = typeInfo.name.toLowerCase();\r
 \r
-       p.innerHTML = '<!-- x --->';\r
+                                       setVal('media_type', data.type);\r
+                               }\r
 \r
-       nw = parseInt(f.width.value);\r
-       nh = parseInt(f.height.value);\r
+                               if (data.type == "video") {\r
+                                       if (!data.video.sources)\r
+                                               data.video.sources = [];\r
 \r
-       if (f.width.value != "" && f.height.value != "") {\r
-               if (f.constrain.checked) {\r
-                       if (c == 'width' && oldWidth != 0) {\r
-                               wp = nw / oldWidth;\r
-                               nh = Math.round(wp * nh);\r
-                               f.height.value = nh;\r
-                       } else if (c == 'height' && oldHeight != 0) {\r
-                               hp = nh / oldHeight;\r
-                               nw = Math.round(hp * nw);\r
-                               f.width.value = nw;\r
+                                       data.video.sources[0] = {src: getVal('src')};\r
+                               }\r
                        }\r
-               }\r
-       }\r
 \r
-       if (f.width.value != "")\r
-               oldWidth = nw;\r
-\r
-       if (f.height.value != "")\r
-               oldHeight = nh;\r
-\r
-       // After constrain\r
-       pl = serializeParameters();\r
-\r
-       switch (f.media_type.options[f.media_type.selectedIndex].value) {\r
-               case "flash":\r
-                       cls = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';\r
-                       codebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0';\r
-                       type = 'application/x-shockwave-flash';\r
-                       break;\r
-\r
-               case "shockwave":\r
-                       cls = 'clsid:166B1BCA-3F9C-11CF-8075-444553540000';\r
-                       codebase = 'http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0';\r
-                       type = 'application/x-director';\r
-                       break;\r
-\r
-               case "qt":\r
-                       cls = 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B';\r
-                       codebase = 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0';\r
-                       type = 'video/quicktime';\r
-                       break;\r
-\r
-               case "wmp":\r
-                       cls = ed.getParam('media_wmp6_compatible') ? 'clsid:05589FA1-C356-11CE-BF01-00AA0055595A' : 'clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6';\r
-                       codebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';\r
-                       type = 'application/x-mplayer2';\r
-                       break;\r
-\r
-               case "rmp":\r
-                       cls = 'clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA';\r
-                       codebase = 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701';\r
-                       type = 'audio/x-pn-realaudio-plugin';\r
-                       break;\r
-       }\r
-\r
-       if (pl == '') {\r
-               p.innerHTML = '';\r
-               return;\r
-       }\r
+                       // Hide all fieldsets and show the one active\r
+                       get('video_options').style.display = 'none';\r
+                       get('flash_options').style.display = 'none';\r
+                       get('quicktime_options').style.display = 'none';\r
+                       get('shockwave_options').style.display = 'none';\r
+                       get('windowsmedia_options').style.display = 'none';\r
+                       get('realmedia_options').style.display = 'none';\r
+\r
+                       if (get(data.type + '_options'))\r
+                               get(data.type + '_options').style.display = 'block';\r
+\r
+                       setVal('media_type', data.type);\r
+\r
+                       setOptions('flash', 'play,loop,menu,swliveconnect,quality,scale,salign,wmode,base,flashvars');\r
+                       setOptions('quicktime', 'loop,autoplay,cache,controller,correction,enablejavascript,kioskmode,autohref,playeveryframe,targetcache,scale,starttime,endtime,target,qtsrcchokespeed,volume,qtsrc');\r
+                       setOptions('shockwave', 'sound,progress,autostart,swliveconnect,swvolume,swstretchstyle,swstretchhalign,swstretchvalign');\r
+                       setOptions('windowsmedia', 'autostart,enabled,enablecontextmenu,fullscreen,invokeurls,mute,stretchtofit,windowlessvideo,balance,baseurl,captioningid,currentmarker,currentposition,defaultframe,playcount,rate,uimode,volume');\r
+                       setOptions('realmedia', 'autostart,loop,autogotourl,center,imagestatus,maintainaspect,nojava,prefetch,shuffle,console,controls,numloop,scriptcallbacks');\r
+                       setOptions('video', 'poster,autoplay,loop,preload,controls');\r
+                       setOptions('global', 'id,name,vspace,hspace,bgcolor,align,width,height');\r
+\r
+                       if (to_form) {\r
+                               if (data.type == 'video') {\r
+                                       if (data.video.sources[0])\r
+                                               setVal('src', data.video.sources[0].src);\r
+\r
+                                       src = data.video.sources[1];\r
+                                       if (src)\r
+                                               setVal('video_altsource1', src.src);\r
+\r
+                                       src = data.video.sources[2];\r
+                                       if (src)\r
+                                               setVal('video_altsource2', src.src);\r
+                               } else {\r
+                                       // Check flash vars\r
+                                       if (data.type == 'flash') {\r
+                                               tinymce.each(editor.getParam('flash_video_player_flashvars', {url : '$url', poster : '$poster'}), function(value, name) {\r
+                                                       if (value == '$url')\r
+                                                               data.params.src = parseQueryParams(data.params.flashvars)[name] || data.params.src;\r
+                                               });\r
+                                       }\r
+\r
+                                       setVal('src', data.params.src);\r
+                               }\r
+                       } else {\r
+                               src = getVal("src");\r
+       \r
+                               // YouTube\r
+                               if (src.match(/youtube.com(.+)v=([^&]+)/)) {\r
+                                       data.width = 425;\r
+                                       data.height = 350;\r
+                                       data.params.frameborder = '0';\r
+                                       data.type = 'iframe';\r
+                                       src = 'http://www.youtube.com/embed/' + src.match(/v=([^&]+)/)[1];\r
+                                       setVal('src', src);\r
+                                       setVal('media_type', data.type);\r
+                               }\r
+\r
+                               // Google video\r
+                               if (src.match(/video.google.com(.+)docid=([^&]+)/)) {\r
+                                       data.width = 425;\r
+                                       data.height = 326;\r
+                                       data.type = 'flash';\r
+                                       src = 'http://video.google.com/googleplayer.swf?docId=' + src.match(/docid=([^&]+)/)[1] + '&hl=en';\r
+                                       setVal('src', src);\r
+                                       setVal('media_type', data.type);\r
+                               }\r
+\r
+                               if (data.type == 'video') {\r
+                                       if (!data.video.sources)\r
+                                               data.video.sources = [];\r
+\r
+                                       data.video.sources[0] = {src : src};\r
+\r
+                                       src = getVal("video_altsource1");\r
+                                       if (src)\r
+                                               data.video.sources[1] = {src : src};\r
+\r
+                                       src = getVal("video_altsource2");\r
+                                       if (src)\r
+                                               data.video.sources[2] = {src : src};\r
+                               } else\r
+                                       data.params.src = src;\r
+\r
+                               // Set default size\r
+                               setVal('width', data.width || 320);\r
+                               setVal('height', data.height || 240);\r
+                       }\r
+               },\r
+\r
+               dataToForm : function() {\r
+                       this.moveStates(true);\r
+               },\r
+\r
+               formToData : function(field) {\r
+                       if (field == "width" || field == "height")\r
+                               this.changeSize(field);\r
+\r
+                       if (field == 'source') {\r
+                               this.moveStates(false, field);\r
+                               setVal('source', this.editor.plugins.media.dataToHtml(this.data));\r
+                               this.panel = 'source';\r
+                       } else {\r
+                               if (this.panel == 'source') {\r
+                                       this.data = this.editor.plugins.media.htmlToData(getVal('source'));\r
+                                       this.dataToForm();\r
+                                       this.panel = '';\r
+                               }\r
+\r
+                               this.moveStates(false, field);\r
+                               this.preview();\r
+                       }\r
+               },\r
+\r
+               beforeResize : function() {\r
+                       this.width = parseInt(getVal('width') || "320", 10);\r
+                       this.height = parseInt(getVal('height') || "240", 10);\r
+               },\r
+\r
+               changeSize : function(type) {\r
+                       var width, height, scale, size;\r
+\r
+                       if (get('constrain').checked) {\r
+                               width = parseInt(getVal('width') || "320", 10);\r
+                               height = parseInt(getVal('height') || "240", 10);\r
+\r
+                               if (type == 'width') {\r
+                                       this.height = Math.round((width / this.width) * height);\r
+                                       setVal('height', this.height);\r
+                               } else {\r
+                                       this.width = Math.round((height / this.height) * width);\r
+                                       setVal('width', this.width);\r
+                               }\r
+                       }\r
+               },\r
 \r
-       pl = tinyMCEPopup.editor.plugins.media._parse(pl);\r
+               getMediaListHTML : function() {\r
+                       if (typeof(tinyMCEMediaList) != "undefined" && tinyMCEMediaList.length > 0) {\r
+                               var html = "";\r
 \r
-       if (!pl.src) {\r
-               p.innerHTML = '';\r
-               return;\r
-       }\r
+                               html += '<select id="linklist" name="linklist" style="width: 250px" onchange="this.form.src.value=this.options[this.selectedIndex].value;Media.formToData(\'src\');">';\r
+                               html += '<option value="">---</option>';\r
 \r
-       pl.src = tinyMCEPopup.editor.documentBaseURI.toAbsolute(pl.src);\r
-       pl.width = !pl.width ? 100 : pl.width;\r
-       pl.height = !pl.height ? 100 : pl.height;\r
-       pl.id = !pl.id ? 'obj' : pl.id;\r
-       pl.name = !pl.name ? 'eobj' : pl.name;\r
-       pl.align = !pl.align ? '' : pl.align;\r
+                               for (var i=0; i<tinyMCEMediaList.length; i++)\r
+                                       html += '<option value="' + tinyMCEMediaList[i][1] + '">' + tinyMCEMediaList[i][0] + '</option>';\r
 \r
-       // Avoid annoying warning about insecure items\r
-       if (!tinymce.isIE || document.location.protocol != 'https:') {\r
-               h += '<object classid="' + cls + '" codebase="' + codebase + '" width="' + pl.width + '" height="' + pl.height + '" id="' + pl.id + '" name="' + pl.name + '" align="' + pl.align + '">';\r
+                               html += '</select>';\r
 \r
-               for (n in pl) {\r
-                       h += '<param name="' + n + '" value="' + pl[n] + '">';\r
+                               return html;\r
+                       }\r
 \r
-                       // Add extra url parameter if it's an absolute URL\r
-                       if (n == 'src' && pl[n].indexOf('://') != -1)\r
-                               h += '<param name="url" value="' + pl[n] + '" />';\r
+                       return "";\r
                }\r
-       }\r
-\r
-       h += '<embed type="' + type + '" ';\r
-\r
-       for (n in pl)\r
-               h += n + '="' + pl[n] + '" ';\r
-\r
-       h += '></embed>';\r
-\r
-       // Avoid annoying warning about insecure items\r
-       if (!tinymce.isIE || document.location.protocol != 'https:')\r
-               h += '</object>';\r
-\r
-       p.innerHTML = "<!-- x --->" + h;\r
-}\r
+       };\r
 \r
-tinyMCEPopup.onInit.add(init);\r
+       tinyMCEPopup.requireLangPack();\r
+       tinyMCEPopup.onInit.add(function() {\r
+               Media.init();\r
+       });\r
+})();
\ No newline at end of file
index 6d0a996f7d923076e2068f7f751d79b295e5bce4..29d26a0d41673a4771cc39821caf619eccdad7e4 100644 (file)
@@ -91,7 +91,6 @@ align_bottom_right:"Bottom right",
 flv_options:"Flash video options",\r
 flv_scalemode:"Scale mode",\r
 flv_buffer:"Buffer",\r
-flv_startimage:"Start image",\r
 flv_starttime:"Start time",\r
 flv_defaultvolume:"Default volumne",\r
 flv_hiddengui:"Hidden GUI",\r
@@ -99,5 +98,12 @@ flv_autostart:"Auto start",
 flv_loop:"Loop",\r
 flv_showscalemodes:"Show scale modes",\r
 flv_smoothvideo:"Smooth video",\r
-flv_jscallback:"JS Callback"\r
+flv_jscallback:"JS Callback",\r
+html5_video_options:"HTML5 Video Options",\r
+altsource1:"Alternative source 1",\r
+altsource2:"Alternative source 2",\r
+preload:"Preload",\r
+poster:"Poster",\r
+\r
+source:"Source"\r
 });
\ No newline at end of file
index 73a903f7c3afb6d66fe12ef4bec9d8d2cc59c627..807a537dc4c02027838f60817ee5f9216d6a44e5 100644 (file)
        <script type="text/javascript" src="../../utils/editable_selects.js"></script>\r
        <link href="css/media.css" rel="stylesheet" type="text/css" />\r
 </head>\r
-<body style="display: none">\r
-    <form onsubmit="insertMedia();return false;" action="#">\r
-               <div class="tabs">\r
+<body style="display: none" role="application">\r
+<form onsubmit="Media.insert();return false;" action="#">\r
+               <div class="tabs" role="presentation">\r
                        <ul>\r
-                               <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');generatePreview();" onmousedown="return false;">{#media_dlg.general}</a></span></li>\r
-                               <li id="advanced_tab"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#media_dlg.advanced}</a></span></li>\r
+                               <li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');Media.formToData();" onmousedown="return false;">{#media_dlg.general}</a></span></li>\r
+                               <li id="advanced_tab" aria-controls="advanced_panel"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');Media.formToData();" onmousedown="return false;">{#media_dlg.advanced}</a></span></li>\r
+                               <li id="source_tab" aria-controls="source_panel"><span><a href="javascript:mcTabs.displayTab('source_tab','source_panel');Media.formToData('source');" onmousedown="return false;">{#media_dlg.source}</a></span></li>\r
                        </ul>\r
                </div>\r
 \r
                                <fieldset>\r
                                        <legend>{#media_dlg.general}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                        <tr>\r
                                                                <td><label for="media_type">{#media_dlg.type}</label></td>\r
                                                                <td>\r
-                                                                       <select id="media_type" name="media_type" onchange="changedType(this.value);generatePreview();">\r
+                                                                       <select id="media_type" name="media_type" onchange="Media.formToData('type');">\r
+                                                                               <option value="video">HTML5 Video</option>\r
                                                                                <option value="flash">Flash</option>\r
-                                                                               <!-- <option value="flv">Flash video (FLV)</option> -->\r
-                                                                               <option value="qt">Quicktime</option>\r
+                                                                               <option value="quicktime">QuickTime</option>\r
                                                                                <option value="shockwave">Shockwave</option>\r
-                                                                               <option value="wmp">Windows Media</option>\r
-                                                                               <option value="rmp">Real Media</option>\r
+                                                                               <option value="windowsmedia">Windows Media</option>\r
+                                                                               <option value="realmedia">Real Media</option>\r
+                                                                               <option value="iframe">Iframe</option>\r
                                                                        </select>\r
                                                                </td>\r
                                                        </tr>\r
                                                        <tr>\r
                                                        <td><label for="src">{#media_dlg.file}</label></td>\r
-                                                         <td>\r
-                                                                       <table border="0" cellspacing="0" cellpadding="0">\r
-                                                                         <tr>\r
-                                                                               <td><input id="src" name="src" type="text" value="" class="mceFocus" onchange="switchType(this.value);generatePreview();" /></td>\r
+                                                               <td>\r
+                                                                       <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
+                                                                       <tr>\r
+                                                                               <td><input id="src" name="src" type="text" value="" class="mceFocus" onchange="Media.formToData();" /></td>\r
                                                                                <td id="filebrowsercontainer">&nbsp;</td>\r
-                                                                         </tr>\r
+                                                                       </tr>\r
                                                                        </table>\r
                                                                </td>\r
                                                        </tr>\r
                                                        <tr>\r
                                                                <td><label for="width">{#media_dlg.size}</label></td>\r
                                                                <td>\r
-                                                                       <table border="0" cellpadding="0" cellspacing="0">\r
+                                                                       <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                                <tr>\r
-                                                                                       <td><input type="text" id="width" name="width" value="" class="size" onchange="generatePreview('width');" /> x <input type="text" id="height" name="height" value="" class="size"  onchange="generatePreview('height');" /></td>\r
-                                                                                       <td>&nbsp;&nbsp;<input id="constrain" type="checkbox" name="constrain" class="checkbox" /></td>\r
+                                                                                       <td><input type="text" id="width" name="width" value="" class="size" onchange="Media.formToData('width');" onfocus="Media.beforeResize();" /> x <input type="text" id="height" name="height" value="" class="size" onfocus="Media.beforeResize();" onchange="Media.formToData('height');" /></td>\r
+                                                                                       <td>&nbsp;&nbsp;<input id="constrain" type="checkbox" name="constrain" class="checkbox" checked="checked" /></td>\r
                                                                                        <td><label id="constrainlabel" for="constrain">{#media_dlg.constrain_proportions}</label></td>\r
                                                                                </tr>\r
                                                                        </table>\r
                                <fieldset>\r
                                        <legend>{#media_dlg.advanced}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0" width="100%">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0" width="100%">\r
                                                <tr>\r
                                                        <td><label for="id">{#media_dlg.id}</label></td>\r
-                                                       <td><input type="text" id="id" name="id" onchange="generatePreview();" /></td>\r
+                                                       <td><input type="text" id="id" name="id" onchange="Media.formToData();" /></td>\r
                                                        <td><label for="name">{#media_dlg.name}</label></td>\r
-                                                       <td><input type="text" id="name" name="name" onchange="generatePreview();" /></td>\r
+                                                       <td><input type="text" id="name" name="name" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
                                                        <td><label for="align">{#media_dlg.align}</label></td>\r
                                                        <td>\r
-                                                               <select id="align" name="align" onchange="generatePreview();">\r
+                                                               <select id="align" name="align" onchange="Media.formToData();">\r
                                                                        <option value="">{#not_set}</option> \r
                                                                        <option value="top">{#media_dlg.align_top}</option>\r
                                                                        <option value="right">{#media_dlg.align_right}</option>\r
 \r
                                                        <td><label for="bgcolor">{#media_dlg.bgcolor}</label></td>\r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');generatePreview();" /></td>\r
+                                                                               <td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');Media.formToData();" /></td>\r
                                                                                <td id="bgcolor_pickcontainer">&nbsp;</td>\r
                                                                        </tr>\r
                                                                </table>\r
 \r
                                                <tr>\r
                                                        <td><label for="vspace">{#media_dlg.vspace}</label></td>\r
-                                                       <td><input type="text" id="vspace" name="vspace" class="number" onchange="generatePreview();" /></td>\r
+                                                       <td><input type="text" id="vspace" name="vspace" class="number" onchange="Media.formToData();" /></td>\r
                                                        <td><label for="hspace">{#media_dlg.hspace}</label></td>\r
-                                                       <td><input type="text" id="hspace" name="hspace" class="number" onchange="generatePreview();" /></td>\r
+                                                       <td><input type="text" id="hspace" name="hspace" class="number" onchange="Media.formToData();" /></td>\r
+                                               </tr>\r
+                                       </table>\r
+                               </fieldset>\r
+\r
+                               <fieldset id="video_options">\r
+                                       <legend>{#media_dlg.html5_video_options}</legend>\r
+\r
+                                       <table role="presentation">\r
+                                               <tr>\r
+                                                       <td><label for="video_altsource1">{#media_dlg.altsource1}</label></td>\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="text" id="video_altsource1" name="video_altsource1" onchange="Media.formToData();" style="width: 240px" /></td>\r
+                                                                               <td id="video_altsource1_filebrowser">&nbsp;</td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
+                                               </tr>\r
+\r
+                                               <tr>\r
+                                                       <td><label for="video_altsource2">{#media_dlg.altsource2}</label></td>\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="text" id="video_altsource2" name="video_altsource2" onchange="Media.formToData();" style="width: 240px" /></td>\r
+                                                                               <td id="video_altsource2_filebrowser">&nbsp;</td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
+                                               </tr>\r
+\r
+                                               <tr>\r
+                                                       <td><label for="video_poster">{#media_dlg.poster}</label></td>\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="text" id="video_poster" name="video_poster" onchange="Media.formToData();" style="width: 240px" /></td>\r
+                                                                               <td id="video_poster_filebrowser">&nbsp;</td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
+                                               </tr>\r
+                                       </table>\r
+\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
+                                               <tr>\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="video_autoplay" name="video_autoplay" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="video_autoplay">{#media_dlg.play}</label></td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
+\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="video_loop" name="video_loop" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="video_loop">{#media_dlg.loop}</label></td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
+\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="video_preload" name="video_preload" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="video_preload">{#media_dlg.preload}</label></td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
+\r
+                                                       <td>\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="video_controls" name="video_controls" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="video_controls">{#media_dlg.controls}</label></td>\r
+                                                                       </tr>\r
+                                                               </table>\r
+                                                       </td>\r
                                                </tr>\r
                                        </table>\r
                                </fieldset>\r
                                <fieldset id="flash_options">\r
                                        <legend>{#media_dlg.flash_options}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td><label for="flash_quality">{#media_dlg.quality}</label></td>\r
                                                        <td>\r
-                                                               <select id="flash_quality" name="flash_quality" onchange="generatePreview();">\r
+                                                               <select id="flash_quality" name="flash_quality" onchange="Media.formToData();">\r
                                                                        <option value="">{#not_set}</option> \r
                                                                        <option value="high">high</option>\r
                                                                        <option value="low">low</option>\r
 \r
                                                        <td><label for="flash_scale">{#media_dlg.scale}</label></td>\r
                                                        <td>\r
-                                                               <select id="flash_scale" name="flash_scale" onchange="generatePreview();">\r
+                                                               <select id="flash_scale" name="flash_scale" onchange="Media.formToData();">\r
                                                                        <option value="">{#not_set}</option> \r
                                                                        <option value="showall">showall</option>\r
                                                                        <option value="noborder">noborder</option>\r
                                                <tr>\r
                                                        <td><label for="flash_wmode">{#media_dlg.wmode}</label></td>\r
                                                        <td>\r
-                                                               <select id="flash_wmode" name="flash_wmode" onchange="generatePreview();">\r
+                                                               <select id="flash_wmode" name="flash_wmode" onchange="Media.formToData();">\r
                                                                        <option value="">{#not_set}</option> \r
                                                                        <option value="window">window</option>\r
                                                                        <option value="opaque">opaque</option>\r
 \r
                                                        <td><label for="flash_salign">{#media_dlg.salign}</label></td>\r
                                                        <td>\r
-                                                               <select id="flash_salign" name="flash_salign" onchange="generatePreview();">\r
+                                                               <select id="flash_salign" name="flash_salign" onchange="Media.formToData();">\r
                                                                        <option value="">{#not_set}</option> \r
                                                                        <option value="l">{#media_dlg.align_left}</option>\r
                                                                        <option value="t">{#media_dlg.align_top}</option>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flash_play" name="flash_play" checked="checked" onchange="generatePreview();" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="flash_play" name="flash_play" checked="checked" onchange="Media.formToData();" /></td>\r
                                                                                <td><label for="flash_play">{#media_dlg.play}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flash_loop" name="flash_loop" checked="checked" onchange="generatePreview();" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="flash_loop" name="flash_loop" checked="checked" onchange="Media.formToData();" /></td>\r
                                                                                <td><label for="flash_loop">{#media_dlg.loop}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flash_menu" name="flash_menu" checked="checked" onchange="generatePreview();" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="flash_menu" name="flash_menu" checked="checked" onchange="Media.formToData();" /></td>\r
                                                                                <td><label for="flash_menu">{#media_dlg.menu}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flash_swliveconnect" name="flash_swliveconnect" onchange="generatePreview();" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="flash_swliveconnect" name="flash_swliveconnect" onchange="Media.formToData();" /></td>\r
                                                                                <td><label for="flash_swliveconnect">{#media_dlg.liveconnect}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                </tr>\r
                                        </table>\r
 \r
-                                       <table>\r
+                                       <table role="presentation">\r
                                                <tr>\r
                                                        <td><label for="flash_base">{#media_dlg.base}</label></td>\r
-                                                       <td><input type="text" id="flash_base" name="flash_base" onchange="generatePreview();" /></td>\r
+                                                       <td><input type="text" id="flash_base" name="flash_base" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
                                                        <td><label for="flash_flashvars">{#media_dlg.flashvars}</label></td>\r
-                                                       <td><input type="text" id="flash_flashvars" name="flash_flashvars" onchange="generatePreview();" /></td>\r
-                                               </tr>\r
-                                       </table>\r
-                               </fieldset>\r
-\r
-                               <fieldset id="flv_options">\r
-                                       <legend>{#media_dlg.flv_options}</legend>\r
-\r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
-                                               <tr>\r
-                                                       <td><label for="flv_scalemode">{#media_dlg.flv_scalemode}</label></td>\r
-                                                       <td>\r
-                                                               <select id="flv_scalemode" name="flv_scalemode" onchange="generatePreview();">\r
-                                                                       <option value="">{#not_set}</option> \r
-                                                                       <option value="none">none</option>\r
-                                                                       <option value="double">double</option>\r
-                                                                       <option value="full">full</option>\r
-                                                               </select>\r
-                                                       </td>\r
-\r
-                                                       <td><label for="flv_buffer">{#media_dlg.flv_buffer}</label></td>\r
-                                                       <td><input type="text" id="flv_buffer" name="flv_buffer" onchange="generatePreview();" /></td>\r
-                                               </tr>\r
-\r
-                                               <tr>\r
-                                                       <td><label for="flv_startimage">{#media_dlg.flv_startimage}</label></td>\r
-                                                       <td><input type="text" id="flv_startimage" name="flv_startimage" onchange="generatePreview();" /></td>\r
-\r
-                                                       <td><label for="flv_starttime">{#media_dlg.flv_starttime}</label></td>\r
-                                                       <td><input type="text" id="flv_starttime" name="flv_starttime" onchange="generatePreview();" /></td>\r
-                                               </tr>\r
-\r
-                                               <tr>\r
-                                                       <td><label for="flv_defaultvolume">{#media_dlg.flv_defaultvolume}</label></td>\r
-                                                       <td><input type="text" id="flv_defaultvolume" name="flv_defaultvolume" onchange="generatePreview();" /></td>\r
-\r
-\r
-                                               </tr>\r
-\r
-                                               <tr>\r
-                                                       <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
-                                                                       <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flv_hiddengui" name="flv_hiddengui" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="flv_hiddengui">{#media_dlg.flv_hiddengui}</label></td>\r
-                                                                       </tr>\r
-                                                               </table>\r
-                                                       </td>\r
-\r
-                                                       <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
-                                                                       <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flv_autostart" name="flv_autostart" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="flv_autostart">{#media_dlg.flv_autostart}</label></td>\r
-                                                                       </tr>\r
-                                                               </table>\r
-                                                       </td>\r
-                                               </tr>\r
-\r
-                                               <tr>\r
-                                                       <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
-                                                                       <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flv_loop" name="flv_loop" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="flv_loop">{#media_dlg.flv_loop}</label></td>\r
-                                                                       </tr>\r
-                                                               </table>\r
-                                                       </td>\r
-\r
-                                                       <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
-                                                                       <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flv_showscalemodes" name="flv_showscalemodes" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="flv_showscalemodes">{#media_dlg.flv_showscalemodes}</label></td>\r
-                                                                       </tr>\r
-                                                               </table>\r
-                                                       </td>\r
-                                               </tr>\r
-\r
-                                               <tr>\r
-                                                       <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
-                                                                       <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flv_smoothvideo" name="flash_flv_flv_smoothvideosmoothvideo" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="flv_smoothvideo">{#media_dlg.flv_smoothvideo}</label></td>\r
-                                                                       </tr>\r
-                                                               </table>\r
-                                                       </td>\r
-\r
-                                                       <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
-                                                                       <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="flv_jscallback" name="flv_jscallback" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="flv_jscallback">{#media_dlg.flv_jscallback}</label></td>\r
-                                                                       </tr>\r
-                                                               </table>\r
-                                                       </td>\r
+                                                       <td><input type="text" id="flash_flashvars" name="flash_flashvars" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
                                        </table>\r
                                </fieldset>\r
 \r
-                               <fieldset id="qt_options">\r
+                               <fieldset id="quicktime_options">\r
                                        <legend>{#media_dlg.qt_options}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_loop" name="qt_loop" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_loop">{#media_dlg.loop}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_loop" name="quicktime_loop" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_loop">{#media_dlg.loop}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_autoplay" name="qt_autoplay" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_autoplay">{#media_dlg.play}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_autoplay" name="quicktime_autoplay" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_autoplay">{#media_dlg.play}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_cache" name="qt_cache" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_cache">{#media_dlg.cache}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_cache" name="quicktime_cache" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_cache">{#media_dlg.cache}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_controller" name="qt_controller" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_controller">{#media_dlg.controller}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_controller" name="quicktime_controller" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_controller">{#media_dlg.controller}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_correction" name="qt_correction" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_correction">{#media_dlg.correction}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_correction" name="quicktime_correction" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_correction">{#media_dlg.correction}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_enablejavascript" name="qt_enablejavascript" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_enablejavascript">{#media_dlg.enablejavascript}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_enablejavascript" name="quicktime_enablejavascript" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_enablejavascript">{#media_dlg.enablejavascript}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_kioskmode" name="qt_kioskmode" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_kioskmode">{#media_dlg.kioskmode}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_kioskmode" name="quicktime_kioskmode" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_kioskmode">{#media_dlg.kioskmode}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_autohref" name="qt_autohref" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_autohref">{#media_dlg.autohref}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_autohref" name="quicktime_autohref" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_autohref">{#media_dlg.autohref}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_playeveryframe" name="qt_playeveryframe" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_playeveryframe">{#media_dlg.playeveryframe}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_playeveryframe" name="quicktime_playeveryframe" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_playeveryframe">{#media_dlg.playeveryframe}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="qt_targetcache" name="qt_targetcache" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="qt_targetcache">{#media_dlg.targetcache}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="quicktime_targetcache" name="quicktime_targetcache" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="quicktime_targetcache">{#media_dlg.targetcache}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="qt_scale">{#media_dlg.scale}</label></td>\r
-                                                       <td><select id="qt_scale" name="qt_scale" class="mceEditableSelect" onchange="generatePreview();">\r
+                                                       <td><label for="quicktime_scale">{#media_dlg.scale}</label></td>\r
+                                                       <td><select id="quicktime_scale" name="quicktime_scale" class="mceEditableSelect" onchange="Media.formToData();">\r
                                                                        <option value="">{#not_set}</option> \r
                                                                        <option value="tofit">tofit</option>\r
                                                                        <option value="aspect">aspect</option>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="qt_starttime">{#media_dlg.starttime}</label></td>\r
-                                                       <td><input type="text" id="qt_starttime" name="qt_starttime" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="quicktime_starttime">{#media_dlg.starttime}</label></td>\r
+                                                       <td><input type="text" id="quicktime_starttime" name="quicktime_starttime" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="qt_endtime">{#media_dlg.endtime}</label></td>\r
-                                                       <td><input type="text" id="qt_endtime" name="qt_endtime" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="quicktime_endtime">{#media_dlg.endtime}</label></td>\r
+                                                       <td><input type="text" id="quicktime_endtime" name="quicktime_endtime" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="qt_target">{#media_dlg.target}</label></td>\r
-                                                       <td><input type="text" id="qt_target" name="qt_target" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="quicktime_target">{#media_dlg.target}</label></td>\r
+                                                       <td><input type="text" id="quicktime_target" name="quicktime_target" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="qt_href">{#media_dlg.href}</label></td>\r
-                                                       <td><input type="text" id="qt_href" name="qt_href" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="quicktime_href">{#media_dlg.href}</label></td>\r
+                                                       <td><input type="text" id="quicktime_href" name="quicktime_href" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="qt_qtsrcchokespeed">{#media_dlg.qtsrcchokespeed}</label></td>\r
-                                                       <td><input type="text" id="qt_qtsrcchokespeed" name="qt_qtsrcchokespeed" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="quicktime_qtsrcchokespeed">{#media_dlg.qtsrcchokespeed}</label></td>\r
+                                                       <td><input type="text" id="quicktime_qtsrcchokespeed" name="quicktime_qtsrcchokespeed" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="qt_volume">{#media_dlg.volume}</label></td>\r
-                                                       <td><input type="text" id="qt_volume" name="qt_volume" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="quicktime_volume">{#media_dlg.volume}</label></td>\r
+                                                       <td><input type="text" id="quicktime_volume" name="quicktime_volume" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="qt_qtsrc">{#media_dlg.qtsrc}</label></td>\r
+                                                       <td><label for="quicktime_qtsrc">{#media_dlg.qtsrc}</label></td>\r
                                                        <td colspan="4">\r
-                                                       <table border="0" cellspacing="0" cellpadding="0">\r
-                                                                 <tr>\r
-                                                                       <td><input type="text" id="qt_qtsrc" name="qt_qtsrc" onchange="generatePreview();" /></td>\r
-                                                                       <td id="qtsrcfilebrowsercontainer">&nbsp;</td>\r
-                                                                 </tr>\r
-                                                       </table>\r
+                                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
+                                                                       <tr>\r
+                                                                               <td><input type="text" id="quicktime_qtsrc" name="quicktime_qtsrc" onchange="Media.formToData();" /></td>\r
+                                                                               <td id="qtsrcfilebrowsercontainer">&nbsp;</td>\r
+                                                                       </tr>\r
+                                                               </table>\r
                                                        </td>\r
                                                </tr>\r
                                        </table>\r
                                </fieldset>\r
 \r
-                               <fieldset id="wmp_options">\r
+                               <fieldset id="windowsmedia_options">\r
                                        <legend>{#media_dlg.wmp_options}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_autostart" name="wmp_autostart" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_autostart">{#media_dlg.autostart}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_autostart" name="windowsmedia_autostart" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_autostart">{#media_dlg.autostart}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_enabled" name="wmp_enabled" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_enabled">{#media_dlg.enabled}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_enabled" name="windowsmedia_enabled" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_enabled">{#media_dlg.enabled}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_enablecontextmenu" name="wmp_enablecontextmenu" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_enablecontextmenu">{#media_dlg.menu}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_enablecontextmenu" name="windowsmedia_enablecontextmenu" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_enablecontextmenu">{#media_dlg.menu}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_fullscreen" name="wmp_fullscreen" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_fullscreen">{#media_dlg.fullscreen}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_fullscreen" name="windowsmedia_fullscreen" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_fullscreen">{#media_dlg.fullscreen}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_invokeurls" name="wmp_invokeurls" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_invokeurls">{#media_dlg.invokeurls}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_invokeurls" name="windowsmedia_invokeurls" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_invokeurls">{#media_dlg.invokeurls}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_mute" name="wmp_mute" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_mute">{#media_dlg.mute}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_mute" name="windowsmedia_mute" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_mute">{#media_dlg.mute}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_stretchtofit" name="wmp_stretchtofit" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_stretchtofit">{#media_dlg.stretchtofit}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_stretchtofit" name="windowsmedia_stretchtofit" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_stretchtofit">{#media_dlg.stretchtofit}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="wmp_windowlessvideo" name="wmp_windowlessvideo" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="wmp_windowlessvideo">{#media_dlg.windowlessvideo}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="windowsmedia_windowlessvideo" name="windowsmedia_windowlessvideo" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="windowsmedia_windowlessvideo">{#media_dlg.windowlessvideo}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="wmp_balance">{#media_dlg.balance}</label></td>\r
-                                                       <td><input type="text" id="wmp_balance" name="wmp_balance" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_balance">{#media_dlg.balance}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_balance" name="windowsmedia_balance" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="wmp_baseurl">{#media_dlg.baseurl}</label></td>\r
-                                                       <td><input type="text" id="wmp_baseurl" name="wmp_baseurl" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_baseurl">{#media_dlg.baseurl}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_baseurl" name="windowsmedia_baseurl" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="wmp_captioningid">{#media_dlg.captioningid}</label></td>\r
-                                                       <td><input type="text" id="wmp_captioningid" name="wmp_captioningid" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_captioningid">{#media_dlg.captioningid}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_captioningid" name="windowsmedia_captioningid" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="wmp_currentmarker">{#media_dlg.currentmarker}</label></td>\r
-                                                       <td><input type="text" id="wmp_currentmarker" name="wmp_currentmarker" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_currentmarker">{#media_dlg.currentmarker}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_currentmarker" name="windowsmedia_currentmarker" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="wmp_currentposition">{#media_dlg.currentposition}</label></td>\r
-                                                       <td><input type="text" id="wmp_currentposition" name="wmp_currentposition" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_currentposition">{#media_dlg.currentposition}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_currentposition" name="windowsmedia_currentposition" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="wmp_defaultframe">{#media_dlg.defaultframe}</label></td>\r
-                                                       <td><input type="text" id="wmp_defaultframe" name="wmp_defaultframe" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_defaultframe">{#media_dlg.defaultframe}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_defaultframe" name="windowsmedia_defaultframe" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="wmp_playcount">{#media_dlg.playcount}</label></td>\r
-                                                       <td><input type="text" id="wmp_playcount" name="wmp_playcount" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_playcount">{#media_dlg.playcount}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_playcount" name="windowsmedia_playcount" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="wmp_rate">{#media_dlg.rate}</label></td>\r
-                                                       <td><input type="text" id="wmp_rate" name="wmp_rate" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_rate">{#media_dlg.rate}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_rate" name="windowsmedia_rate" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="wmp_uimode">{#media_dlg.uimode}</label></td>\r
-                                                       <td><input type="text" id="wmp_uimode" name="wmp_uimode" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_uimode">{#media_dlg.uimode}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_uimode" name="windowsmedia_uimode" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="wmp_volume">{#media_dlg.volume}</label></td>\r
-                                                       <td><input type="text" id="wmp_volume" name="wmp_volume" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="windowsmedia_volume">{#media_dlg.volume}</label></td>\r
+                                                       <td><input type="text" id="windowsmedia_volume" name="windowsmedia_volume" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                        </table>\r
                                </fieldset>\r
 \r
-                               <fieldset id="rmp_options">\r
+                               <fieldset id="realmedia_options">\r
                                        <legend>{#media_dlg.rmp_options}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_autostart" name="rmp_autostart" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_autostart">{#media_dlg.autostart}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_autostart" name="realmedia_autostart" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_autostart">{#media_dlg.autostart}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_loop" name="rmp_loop" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_loop">{#media_dlg.loop}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_loop" name="realmedia_loop" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_loop">{#media_dlg.loop}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_autogotourl" name="rmp_autogotourl" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_autogotourl">{#media_dlg.autogotourl}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_autogotourl" name="realmedia_autogotourl" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_autogotourl">{#media_dlg.autogotourl}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_center" name="rmp_center" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_center">{#media_dlg.center}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_center" name="realmedia_center" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_center">{#media_dlg.center}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_imagestatus" name="rmp_imagestatus" checked="checked" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_imagestatus">{#media_dlg.imagestatus}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_imagestatus" name="realmedia_imagestatus" checked="checked" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_imagestatus">{#media_dlg.imagestatus}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_maintainaspect" name="rmp_maintainaspect" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_maintainaspect">{#media_dlg.maintainaspect}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_maintainaspect" name="realmedia_maintainaspect" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_maintainaspect">{#media_dlg.maintainaspect}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_nojava" name="rmp_nojava" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_nojava">{#media_dlg.nojava}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_nojava" name="realmedia_nojava" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_nojava">{#media_dlg.nojava}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_prefetch" name="rmp_prefetch" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_prefetch">{#media_dlg.prefetch}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_prefetch" name="realmedia_prefetch" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_prefetch">{#media_dlg.prefetch}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="rmp_shuffle" name="rmp_shuffle" onchange="generatePreview();" /></td>\r
-                                                                               <td><label for="rmp_shuffle">{#media_dlg.shuffle}</label></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="realmedia_shuffle" name="realmedia_shuffle" onchange="Media.formToData();" /></td>\r
+                                                                               <td><label for="realmedia_shuffle">{#media_dlg.shuffle}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="rmp_console">{#media_dlg.console}</label></td>\r
-                                                       <td><input type="text" id="rmp_console" name="rmp_console" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="realmedia_console">{#media_dlg.console}</label></td>\r
+                                                       <td><input type="text" id="realmedia_console" name="realmedia_console" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="rmp_controls">{#media_dlg.controls}</label></td>\r
-                                                       <td><input type="text" id="rmp_controls" name="rmp_controls" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="realmedia_controls">{#media_dlg.controls}</label></td>\r
+                                                       <td><input type="text" id="realmedia_controls" name="realmedia_controls" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td><label for="rmp_numloop">{#media_dlg.numloop}</label></td>\r
-                                                       <td><input type="text" id="rmp_numloop" name="rmp_numloop" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="realmedia_numloop">{#media_dlg.numloop}</label></td>\r
+                                                       <td><input type="text" id="realmedia_numloop" name="realmedia_numloop" onchange="Media.formToData();" /></td>\r
 \r
-                                                       <td><label for="rmp_scriptcallbacks">{#media_dlg.scriptcallbacks}</label></td>\r
-                                                       <td><input type="text" id="rmp_scriptcallbacks" name="rmp_scriptcallbacks" onchange="generatePreview();" /></td>\r
+                                                       <td><label for="realmedia_scriptcallbacks">{#media_dlg.scriptcallbacks}</label></td>\r
+                                                       <td><input type="text" id="realmedia_scriptcallbacks" name="realmedia_scriptcallbacks" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
                                        </table>\r
                                </fieldset>\r
                                <fieldset id="shockwave_options">\r
                                        <legend>{#media_dlg.shockwave_options}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td><label for="shockwave_swstretchstyle">{#media_dlg.swstretchstyle}</label></td>\r
                                                        <td>\r
-                                                               <select id="shockwave_swstretchstyle" name="shockwave_swstretchstyle" onchange="generatePreview();">\r
+                                                               <select id="shockwave_swstretchstyle" name="shockwave_swstretchstyle" onchange="Media.formToData();">\r
                                                                        <option value="none">{#not_set}</option>\r
                                                                        <option value="meet">Meet</option>\r
                                                                        <option value="fill">Fill</option>\r
                                                        </td>\r
 \r
                                                        <td><label for="shockwave_swvolume">{#media_dlg.volume}</label></td>\r
-                                                       <td><input type="text" id="shockwave_swvolume" name="shockwave_swvolume" onchange="generatePreview();" /></td>\r
+                                                       <td><input type="text" id="shockwave_swvolume" name="shockwave_swvolume" onchange="Media.formToData();" /></td>\r
                                                </tr>\r
 \r
                                                <tr>\r
                                                        <td><label for="shockwave_swstretchhalign">{#media_dlg.swstretchhalign}</label></td>\r
                                                        <td>\r
-                                                               <select id="shockwave_swstretchhalign" name="shockwave_swstretchhalign" onchange="generatePreview();">\r
+                                                               <select id="shockwave_swstretchhalign" name="shockwave_swstretchhalign" onchange="Media.formToData();">\r
                                                                        <option value="none">{#not_set}</option>\r
                                                                        <option value="left">{#media_dlg.align_left}</option>\r
                                                                        <option value="center">{#media_dlg.align_center}</option>\r
 \r
                                                        <td><label for="shockwave_swstretchvalign">{#media_dlg.swstretchvalign}</label></td>\r
                                                        <td>\r
-                                                               <select id="shockwave_swstretchvalign" name="shockwave_swstretchvalign" onchange="generatePreview();">\r
+                                                               <select id="shockwave_swstretchvalign" name="shockwave_swstretchvalign" onchange="Media.formToData();">\r
                                                                        <option value="none">{#not_set}</option>\r
                                                                        <option value="meet">Meet</option>\r
                                                                        <option value="fill">Fill</option>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_autostart" name="shockwave_autostart" onchange="generatePreview();" checked="checked" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_autostart" name="shockwave_autostart" onchange="Media.formToData();" checked="checked" /></td>\r
                                                                                <td><label for="shockwave_autostart">{#media_dlg.autostart}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_sound" name="shockwave_sound" onchange="generatePreview();" checked="checked" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_sound" name="shockwave_sound" onchange="Media.formToData();" checked="checked" /></td>\r
                                                                                <td><label for="shockwave_sound">{#media_dlg.sound}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
 \r
                                                <tr>\r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_swliveconnect" name="shockwave_swliveconnect" onchange="generatePreview();" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_swliveconnect" name="shockwave_swliveconnect" onchange="Media.formToData();" /></td>\r
                                                                                <td><label for="shockwave_swliveconnect">{#media_dlg.liveconnect}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                                        </td>\r
 \r
                                                        <td colspan="2">\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
-                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_progress" name="shockwave_progress" onchange="generatePreview();" checked="checked" /></td>\r
+                                                                               <td><input type="checkbox" class="checkbox" id="shockwave_progress" name="shockwave_progress" onchange="Media.formToData();" checked="checked" /></td>\r
                                                                                <td><label for="shockwave_progress">{#media_dlg.progress}</label></td>\r
                                                                        </tr>\r
                                                                </table>\r
                                        </table>\r
                                </fieldset>\r
                        </div>\r
+\r
+                       <div id="source_panel" class="panel">\r
+                               <fieldset>\r
+                                       <legend>{#media_dlg.source}</legend>\r
+                                       <textarea id="source" style="width: 100%; height: 390px"></textarea>\r
+                               </fieldset>\r
+                       </div>\r
                </div>\r
 \r
                <div class="mceActionPanel">\r
index f2dbbff2bba374860fde9c94744857adb35c1b45..73947355f014523794f540cb294f88b3390b4219 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create("tinymce.plugins.Nonbreaking",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceNonBreaking",function(){a.execCommand("mceInsertContent",false,(a.plugins.visualchars&&a.plugins.visualchars.state)?'<span class="mceItemHidden mceVisualNbsp">&middot;</span>':"&nbsp;")});a.addButton("nonbreaking",{title:"nonbreaking.nonbreaking_desc",cmd:"mceNonBreaking"});if(a.getParam("nonbreaking_force_tab")){a.onKeyDown.add(function(d,f){if(tinymce.isIE&&f.keyCode==9){d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");tinymce.dom.Event.cancel(f)}})}},getInfo:function(){return{longname:"Nonbreaking space",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/nonbreaking",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("nonbreaking",tinymce.plugins.Nonbreaking)})();
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.Nonbreaking",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceNonBreaking",function(){a.execCommand("mceInsertContent",false,(a.plugins.visualchars&&a.plugins.visualchars.state)?'<span data-mce-bogus="1" class="mceItemHidden mceItemNbsp">&nbsp;</span>':"&nbsp;")});a.addButton("nonbreaking",{title:"nonbreaking.nonbreaking_desc",cmd:"mceNonBreaking"});if(a.getParam("nonbreaking_force_tab")){a.onKeyDown.add(function(d,f){if(tinymce.isIE&&f.keyCode==9){d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");d.execCommand("mceNonBreaking");tinymce.dom.Event.cancel(f)}})}},getInfo:function(){return{longname:"Nonbreaking space",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/nonbreaking",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("nonbreaking",tinymce.plugins.Nonbreaking)})();
\ No newline at end of file
index e3b078bfae7f9a4372792151d8c7eb2432df2592..b3ea82ee03737a0ac3a6b922b76d3cf445ee29cb 100644 (file)
@@ -17,7 +17,7 @@
 \r
                        // Register commands\r
                        ed.addCommand('mceNonBreaking', function() {\r
-                               ed.execCommand('mceInsertContent', false, (ed.plugins.visualchars && ed.plugins.visualchars.state) ? '<span class="mceItemHidden mceVisualNbsp">&middot;</span>' : '&nbsp;');\r
+                               ed.execCommand('mceInsertContent', false, (ed.plugins.visualchars && ed.plugins.visualchars.state) ? '<span data-mce-bogus="1" class="mceItemHidden mceItemNbsp">&nbsp;</span>' : '&nbsp;');\r
                        });\r
 \r
                        // Register buttons\r
index 3e7b2504f19213aa8ab25af22a5843132027927f..6c65069f3ee22e761aae344abaf536a46bbe95c3 100644 (file)
@@ -1 +1 @@
-(function(){var c=tinymce.each,d=null,a={paste_auto_cleanup_on_paste: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_notifyalways:false,paste_text_linebreaktype:"p",paste_text_replacements:[[/\u2026/g,"..."],[/[\x93\x94\u201c\u201d]/g,'"'],[/[\x60\x91\x92\u2018\u2019]/g,"'"]]};function b(e,f){return e.getParam(f,a[f])}tinymce.create("tinymce.plugins.PastePlugin",{init:function(e,f){var g=this;g.editor=e;g.url=f;g.onPreProcess=new tinymce.util.Dispatcher(g);g.onPostProcess=new tinymce.util.Dispatcher(g);g.onPreProcess.add(g._preProcess);g.onPostProcess.add(g._postProcess);g.onPreProcess.add(function(j,k){e.execCallback("paste_preprocess",j,k)});g.onPostProcess.add(function(j,k){e.execCallback("paste_postprocess",j,k)});e.pasteAsPlainText=false;function i(l,j){var k=e.dom;g.onPreProcess.dispatch(g,l);l.node=k.create("div",0,l.content);g.onPostProcess.dispatch(g,l);l.content=e.serializer.serialize(l.node,{getInner:1});if((!j)&&(e.pasteAsPlainText)){g._insertPlainText(e,k,l.content);if(!b(e,"paste_text_sticky")){e.pasteAsPlainText=false;e.controlManager.setActive("pastetext",false)}}else{if(/<(p|h[1-6]|ul|ol)/.test(l.content)){g._insertBlockContent(e,k,l.content)}else{g._insert(l.content)}}}e.addCommand("mceInsertClipboardContent",function(j,k){i(k,true)});if(!b(e,"paste_text_use_dialog")){e.addCommand("mcePasteText",function(k,j){var l=tinymce.util.Cookie;e.pasteAsPlainText=!e.pasteAsPlainText;e.controlManager.setActive("pastetext",e.pasteAsPlainText);if((e.pasteAsPlainText)&&(!l.get("tinymcePasteText"))){if(b(e,"paste_text_sticky")){e.windowManager.alert(e.translate("paste.plaintext_mode_sticky"))}else{e.windowManager.alert(e.translate("paste.plaintext_mode_sticky"))}if(!b(e,"paste_text_notifyalways")){l.set("tinymcePasteText","1",new Date(new Date().getFullYear()+1,12,31))}}})}e.addButton("pastetext",{title:"paste.paste_text_desc",cmd:"mcePasteText"});e.addButton("selectall",{title:"paste.selectall_desc",cmd:"selectall"});function h(s){var m,q,k,l=e.selection,p=e.dom,r=e.getBody(),j;if(e.pasteAsPlainText&&(s.clipboardData||p.doc.dataTransfer)){s.preventDefault();i({content:(s.clipboardData||p.doc.dataTransfer).getData("Text")},true);return}if(p.get("_mcePaste")){return}m=p.add(r,"div",{id:"_mcePaste","class":"mcePaste"},"\uFEFF");if(r!=e.getDoc().body){j=p.getPos(e.selection.getStart(),r).y}else{j=r.scrollTop}p.setStyles(m,{position:"absolute",left:-10000,top:j,width:1,height:1,overflow:"hidden"});if(tinymce.isIE){k=p.doc.body.createTextRange();k.moveToElementText(m);k.execCommand("Paste");p.remove(m);if(m.innerHTML==="\uFEFF"){e.execCommand("mcePasteWord");s.preventDefault();return}i({content:m.innerHTML});return tinymce.dom.Event.cancel(s)}else{function o(n){n.preventDefault()}p.bind(e.getDoc(),"mousedown",o);p.bind(e.getDoc(),"keydown",o);q=e.selection.getRng();m=m.firstChild;k=e.getDoc().createRange();k.setStart(m,0);k.setEnd(m,1);l.setRng(k);window.setTimeout(function(){var t="",n=p.select("div.mcePaste");c(n,function(u){c(p.select("div.mcePaste",u),function(v){p.remove(v,1)});c(p.select("span.Apple-style-span",u),function(v){p.remove(v,1)});t+=u.innerHTML});c(n,function(u){p.remove(u)});if(q){l.setRng(q)}i({content:t});p.unbind(e.getDoc(),"mousedown",o);p.unbind(e.getDoc(),"keydown",o)},0)}}if(b(e,"paste_auto_cleanup_on_paste")){if(tinymce.isOpera||/Firefox\/2/.test(navigator.userAgent)){e.onKeyDown.add(function(j,k){if(((tinymce.isMac?k.metaKey:k.ctrlKey)&&k.keyCode==86)||(k.shiftKey&&k.keyCode==45)){h(k)}})}else{e.onPaste.addToTop(function(j,k){return h(k)})}}if(b(e,"paste_block_drop")){e.onInit.add(function(){e.dom.bind(e.getBody(),["dragend","dragover","draggesture","dragdrop","drop","drag"],function(j){j.preventDefault();j.stopPropagation();return false})})}g._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(i,f){var l=this.editor,k=f.content,q=tinymce.grep,p=tinymce.explode,g=tinymce.trim,m,j;function e(h){c(h,function(o){if(o.constructor==RegExp){k=k.replace(o,"")}else{k=k.replace(o[0],o[1])}})}if(/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(k)||f.wordContent){f.wordContent=true;e([/^\s*(&nbsp;)+/gi,/(&nbsp;|<br[^>]*>)+\s*$/gi]);if(b(l,"paste_convert_headers_to_strong")){k=k.replace(/<p [^>]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"<p><strong>$1</strong></p>")}if(b(l,"paste_convert_middot_lists")){e([[/<!--\[if !supportLists\]-->/gi,"$&__MCE_ITEM__"],[/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi,"$1__MCE_ITEM__"]])}e([/<!--[\s\S]+?-->/gi,/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|img|meta|link|style|\w:\w+)(?=[\s\/>]))[^>]*>/gi,[/<(\/?)s>/gi,"<$1strike>"],[/&nbsp;/gi,"\u00a0"]]);do{m=k.length;k=k.replace(/(<[a-z][^>]*\s)(?:id|name|language|type|on\w+|\w+:\w+)=(?:"[^"]*"|\w+)\s?/gi,"$1")}while(m!=k.length);if(b(l,"paste_retain_style_properties").replace(/^none$/i,"").length==0){k=k.replace(/<\/?span[^>]*>/gi,"")}else{e([[/<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(u,h,t){var v=[],o=0,r=p(g(t).replace(/&quot;/gi,"'"),";");c(r,function(s){var w,y,z=p(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":v[o++]=w.replace(/^mso-|-alt$/g,"")+":"+x(y);return;case"horiz-align":v[o++]="text-align:"+y;return;case"vert-align":v[o++]="vertical-align:"+y;return;case"font-color":case"mso-foreground":v[o++]="color:"+y;return;case"mso-background":case"mso-highlight":v[o++]="background:"+y;return;case"mso-default-height":v[o++]="min-height:"+x(y);return;case"mso-default-width":v[o++]="min-width:"+x(y);return;case"mso-padding-between-alt":v[o++]="border-collapse:separate;border-spacing:"+x(y);return;case"text-line-through":if((y=="single")||(y=="double")){v[o++]="text-decoration:line-through"}return;case"mso-zero-height":if(y=="yes"){v[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}v[o++]=w+":"+z[1]}});if(o>0){return h+' style="'+v.join(";")+'"'}else{return h}}]])}}if(b(l,"paste_convert_headers_to_strong")){e([[/<h[1-6][^>]*>/gi,"<p><strong>"],[/<\/h[1-6][^>]*>/gi,"</strong></p>"]])}j=b(l,"paste_strip_class_attributes");if(j!=="none"){function n(r,o){if(j==="all"){return""}var h=q(p(o.replace(/^(["'])(.*)\1$/,"$2")," "),function(s){return(/^(?!mso)/i.test(s))});return h.length?' class="'+h.join(" ")+'"':""}k=k.replace(/ class="([^"]+)"/gi,n);k=k.replace(/ class=(\w+)/gi,n)}if(b(l,"paste_remove_spans")){k=k.replace(/<\/?span[^>]*>/gi,"")}f.content=k},_postProcess:function(h,j){var g=this,f=g.editor,i=f.dom,e;if(j.wordContent){c(i.select("a",j.node),function(k){if(!k.href||k.href.indexOf("#_Toc")!=-1){i.remove(k,1)}});if(b(f,"paste_convert_middot_lists")){g._convertLists(h,j)}e=b(f,"paste_retain_style_properties");if((tinymce.is(e,"string"))&&(e!=="all")&&(e!=="*")){e=tinymce.explode(e.replace(/^none$/i,""));c(i.select("*",j.node),function(n){var o={},l=0,m,p,k;if(e){for(m=0;m<e.length;m++){p=e[m];k=i.getStyle(n,p);if(k){o[p]=k;l++}}}i.setAttrib(n,"style","");if(e&&l>0){i.setStyles(n,o)}else{if(n.nodeName=="SPAN"&&!n.className){i.remove(n,true)}}})}}if(b(f,"paste_remove_styles")||(b(f,"paste_remove_styles_if_webkit")&&tinymce.isWebKit)){c(i.select("*[style]",j.node),function(k){k.removeAttribute("style");k.removeAttribute("_mce_style")})}else{if(tinymce.isWebKit){c(i.select("*",j.node),function(k){k.removeAttribute("_mce_style")})}}},_convertLists:function(h,f){var j=h.editor.dom,i,m,e=-1,g,n=[],l,k;c(j.select("p",f.node),function(u){var r,v="",t,s,o,q;for(r=u.firstChild;r&&r.nodeType==3;r=r.nextSibling){v+=r.nodeValue}v=u.innerHTML.replace(/<\/?\w+[^>]*>/gi,"").replace(/&nbsp;/g,"\u00a0");if(/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(v)){t="ul"}if(/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(v)){t="ol"}if(t){g=parseFloat(u.style.marginLeft||0);if(g>e){n.push(g)}if(!i||t!=l){i=j.create(t);j.insertAfter(i,u)}else{if(g>e){i=m.appendChild(j.create(t))}else{if(g<e){o=tinymce.inArray(n,g);q=j.getParents(i.parentNode,t);i=q[q.length-1-o]||i}}}c(j.select("span",u),function(w){var p=w.innerHTML.replace(/<\/?\w+[^>]*>/gi,"");if(t=="ul"&&/^[\u2022\u00b7\u00a7\u00d8o]/.test(p)){j.remove(w)}else{if(/^[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(p)){j.remove(w)}}});s=u.innerHTML;if(t=="ul"){s=u.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/,"")}else{s=u.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/,"")}m=i.appendChild(j.create("li",0,s));j.remove(u);e=g;l=t}else{i=e=0}});k=f.node.innerHTML;if(k.indexOf("__MCE_ITEM__")!=-1){f.node.innerHTML=k.replace(/__MCE_ITEM__/g,"")}},_insertBlockContent:function(l,h,m){var f,j,g=l.selection,q,n,e,o,i,k="mce_marker";function p(t){var s;if(tinymce.isIE){s=l.getDoc().body.createTextRange();s.moveToElementText(t);s.collapse(false);s.select()}else{g.select(t,1);g.collapse(false)}}this._insert('<span id="'+k+'">&nbsp;</span>',1);j=h.get(k);f=h.getParent(j,"p,h1,h2,h3,h4,h5,h6,ul,ol,th,td");if(f&&!/TD|TH/.test(f.nodeName)){j=h.split(f,j);c(h.create("div",0,m).childNodes,function(r){q=j.parentNode.insertBefore(r.cloneNode(true),j)});p(q)}else{h.setOuterHTML(j,m);g.select(l.getBody(),1);g.collapse(0)}while(n=h.get(k)){h.remove(n)}n=g.getStart();e=h.getViewPort(l.getWin());o=l.dom.getPos(n).y;i=n.clientHeight;if(o<e.y||o+i>e.y+e.h){l.getDoc().body.scrollTop=o<e.y?o:o-e.h+25}},_insert:function(g,e){var f=this.editor,i=f.selection.getRng();if(!f.selection.isCollapsed()&&i.startContainer!=i.endContainer){f.getDoc().execCommand("Delete",false,null)}f.execCommand(tinymce.isGecko?"insertHTML":"mceInsertContent",false,g,{skip_undo:e})},_insertPlainText:function(j,x,v){var t,u,l,k,r,e,p,f,n=j.getWin(),z=j.getDoc(),s=j.selection,m=tinymce.is,y=tinymce.inArray,g=b(j,"paste_text_linebreaktype"),o=b(j,"paste_text_replacements");function q(h){c(h,function(i){if(i.constructor==RegExp){v=v.replace(i,"")}else{v=v.replace(i[0],i[1])}})}if((typeof(v)==="string")&&(v.length>0)){if(!d){d=("34,quot,38,amp,39,apos,60,lt,62,gt,"+j.serializer.settings.entities).split(",")}if(/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(v)){q([/[\n\r]+/g])}else{q([/\r+/g])}q([[/<\/(?: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,[/&nbsp;/gi," "],[/&(#\d+|[a-z0-9]{1,10});/gi,function(i,h){if(h.charAt(0)==="#"){return String.fromCharCode(h.slice(1))}else{return((i=y(d,h))>0)?String.fromCharCode(d[i-1]):" "}}],[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi,"$1"],[/\n{3,}/g,"\n\n"],/^\s+|\s+$/g]);v=x.encode(v);if(!s.isCollapsed()){z.execCommand("Delete",false,null)}if(m(o,"array")||(m(o,"array"))){q(o)}else{if(m(o,"string")){q(new RegExp(o,"gi"))}}if(g=="none"){q([[/\n+/g," "]])}else{if(g=="br"){q([[/\n/g,"<br />"]])}else{q([/^\s+|\s+$/g,[/\n\n/g,"</p><p>"],[/\n/g,"<br />"]])}}if((l=v.indexOf("</p><p>"))!=-1){k=v.lastIndexOf("</p><p>");r=s.getNode();e=[];do{if(r.nodeType==1){if(r.nodeName=="TD"||r.nodeName=="BODY"){break}e[e.length]=r}}while(r=r.parentNode);if(e.length>0){p=v.substring(0,l);f="";for(t=0,u=e.length;t<u;t++){p+="</"+e[t].nodeName.toLowerCase()+">";f+="<"+e[e.length-t-1].nodeName.toLowerCase()+">"}if(l==k){v=p+f+v.substring(l+7)}else{v=p+v.substring(l+4,k+4)+f+v.substring(k+7)}}}j.execCommand("mceInsertRawHTML",false,v+'<span id="_plain_text_marker">&nbsp;</span>');window.setTimeout(function(){var h=x.get("_plain_text_marker"),B,i,A,w;s.select(h,false);z.execCommand("Delete",false,null);h=null;B=s.getStart();i=x.getViewPort(n);A=x.getPos(B).y;w=B.clientHeight;if((A<i.y)||(A+w>i.y+i.h)){z.body.scrollTop=A<i.y?A:A-i.h+25}},0)}},_legacySupport:function(){var f=this,e=f.editor;e.addCommand("mcePasteWord",function(){e.windowManager.open({file:f.url+"/pasteword.htm",width:parseInt(b(e,"paste_dialog_width")),height:parseInt(b(e,"paste_dialog_height")),inline:1})});if(b(e,"paste_text_use_dialog")){e.addCommand("mcePasteText",function(){e.windowManager.open({file:f.url+"/pastetext.htm",width:parseInt(b(e,"paste_dialog_width")),height:parseInt(b(e,"paste_dialog_height")),inline:1})})}e.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_text_use_dialog:false,paste_text_sticky:false,paste_text_sticky_default:false,paste_text_notifyalways:false,paste_text_linebreaktype:"p",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(m,k){var l=d.dom,i,j;f.onPreProcess.dispatch(f,m);m.node=l.create("div",0,m.content);if(tinymce.isGecko){i=d.selection.getRng(true);if(i.startContainer==i.endContainer&&i.startContainer.nodeType==3){j=l.select("p,h1,h2,h3,h4,h5,h6,pre",m.node);if(j.length==1&&m.content.indexOf("__MCE_ITEM__")===-1){l.remove(j.reverse(),true)}}}f.onPostProcess.dispatch(f,m);m.content=d.serializer.serialize(m.node,{getInner:1});if((!k)&&(d.pasteAsPlainText)){f._insertPlainText(d,l,m.content);if(!b(d,"paste_text_sticky")){d.pasteAsPlainText=false;d.controlManager.setActive("pastetext",false)}}else{f._insert(m.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_sticky"))}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: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().y}o.setStyles(l,{position:"absolute",left:-10000,top:i,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="<pre>"+o.encode(r).replace(/\r?\n/g,"<br />")+"</pre>"}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>&nbsp;[\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>&nbsp;[\s\r\n]+|<br>)*/g,"$1"]])}if(/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(j)||e.wordContent){e.wordContent=true;d([/^\s*(&nbsp;)+/gi,/(&nbsp;|<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>"],[/&nbsp;/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(/&quot;/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(/&nbsp;/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+\.(&nbsp;|\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*(&nbsp;|\u00a0)+\s*/,"")}else{r=t.innerHTML.replace(/__MCE_ITEM__/g,"").replace(/^\s*\w+\.(&nbsp;|\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,x,v){var t,u,l,k,r,e,p,f,n=j.getWin(),z=j.getDoc(),s=j.selection,m=tinymce.is,y=tinymce.inArray,g=b(j,"paste_text_linebreaktype"),o=b(j,"paste_text_replacements");function q(d){c(d,function(h){if(h.constructor==RegExp){v=v.replace(h,"")}else{v=v.replace(h[0],h[1])}})}if((typeof(v)==="string")&&(v.length>0)){if(/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(v)){q([/[\n\r]+/g])}else{q([/\r+/g])}q([[/<\/(?: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,[/&nbsp;/gi," "],[/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi,"$1"],[/\n{3,}/g,"\n\n"],/^\s+|\s+$/g]);v=x.decode(tinymce.html.Entities.encodeRaw(v));if(!s.isCollapsed()){z.execCommand("Delete",false,null)}if(m(o,"array")||(m(o,"array"))){q(o)}else{if(m(o,"string")){q(new RegExp(o,"gi"))}}if(g=="none"){q([[/\n+/g," "]])}else{if(g=="br"){q([[/\n/g,"<br />"]])}else{q([/^\s+|\s+$/g,[/\n\n/g,"</p><p>"],[/\n/g,"<br />"]])}}if((l=v.indexOf("</p><p>"))!=-1){k=v.lastIndexOf("</p><p>");r=s.getNode();e=[];do{if(r.nodeType==1){if(r.nodeName=="TD"||r.nodeName=="BODY"){break}e[e.length]=r}}while(r=r.parentNode);if(e.length>0){p=v.substring(0,l);f="";for(t=0,u=e.length;t<u;t++){p+="</"+e[t].nodeName.toLowerCase()+">";f+="<"+e[e.length-t-1].nodeName.toLowerCase()+">"}if(l==k){v=p+f+v.substring(l+7)}else{v=p+v.substring(l+4,k+4)+f+v.substring(k+7)}}}j.execCommand("mceInsertRawHTML",false,v+'<span id="_plain_text_marker">&nbsp;</span>');window.setTimeout(function(){var d=x.get("_plain_text_marker"),A,h,w,i;s.select(d,false);z.execCommand("Delete",false,null);d=null;A=s.getStart();h=x.getViewPort(n);w=x.getPos(A).y;i=A.clientHeight;if((w<h.y)||(w+i>h.y+h.h)){z.body.scrollTop=w<h.y?w:w-h.h+25}},0)}},_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
index 4c3bf6542ec8643737e90c0da910f7f447c94873..ef5fe3a7cf5787e260c3f6d6ce2c90c51a7e89a3 100644 (file)
@@ -10,9 +10,9 @@
 \r
 (function() {\r
        var each = tinymce.each,\r
-               entities = null,\r
                defs = {\r
                        paste_auto_cleanup_on_paste : true,\r
+                       paste_enable_default_filters : true,\r
                        paste_block_drop : false,\r
                        paste_retain_style_properties : "none",\r
                        paste_strip_class_attributes : "mso",\r
@@ -25,6 +25,7 @@
                        paste_dialog_height : "400",\r
                        paste_text_use_dialog : false,\r
                        paste_text_sticky : false,\r
+                       paste_text_sticky_default : false,\r
                        paste_text_notifyalways : false,\r
                        paste_text_linebreaktype : "p",\r
                        paste_text_replacements : [\r
                                ed.execCallback('paste_postprocess', pl, o);\r
                        });\r
 \r
+                       ed.onKeyDown.addToTop(function(ed, e) {\r
+                               // Block ctrl+v from adding an undo level since the default logic in tinymce.Editor will add that\r
+                               if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45))\r
+                                       return false; // Stop other listeners\r
+                       });\r
+\r
                        // Initialize plain text flag\r
-                       ed.pasteAsPlainText = false;\r
+                       ed.pasteAsPlainText = getParam(ed, 'paste_text_sticky_default');\r
 \r
                        // This function executes the process handlers and inserts the contents\r
                        // force_rich overrides plain text mode set by user, important for pasting with execCommand\r
                        function process(o, force_rich) {\r
-                               var dom = ed.dom;\r
+                               var dom = ed.dom, rng, nodes;\r
 \r
                                // Execute pre process handlers\r
                                t.onPreProcess.dispatch(t, o);\r
                                // Create DOM structure\r
                                o.node = dom.create('div', 0, o.content);\r
 \r
+                               // If pasting inside the same element and the contents is only one block\r
+                               // remove the block and keep the text since Firefox will copy parts of pre and h1-h6 as a pre element\r
+                               if (tinymce.isGecko) {\r
+                                       rng = ed.selection.getRng(true);\r
+                                       if (rng.startContainer == rng.endContainer && rng.startContainer.nodeType == 3) {\r
+                                               nodes = dom.select('p,h1,h2,h3,h4,h5,h6,pre', o.node);\r
+\r
+                                               // Is only one block node and it doesn't contain word stuff\r
+                                               if (nodes.length == 1 && o.content.indexOf('__MCE_ITEM__') === -1)\r
+                                                       dom.remove(nodes.reverse(), true);\r
+                                       }\r
+                               }\r
+\r
                                // Execute post process handlers\r
                                t.onPostProcess.dispatch(t, o);\r
 \r
                                                ed.pasteAsPlainText = false;\r
                                                ed.controlManager.setActive("pastetext", false);\r
                                        }\r
-                               } else if (/<(p|h[1-6]|ul|ol)/.test(o.content)) {\r
-                                       // Handle insertion of contents containing block elements separately\r
-                                       t._insertBlockContent(ed, dom, o.content);\r
                                } else {\r
                                        t._insert(o.content);\r
                                }\r
                        // hidden div and placing the caret inside it and after the browser paste\r
                        // is done it grabs that contents and processes that\r
                        function grabContent(e) {\r
-                               var n, or, rng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY;\r
+                               var n, or, rng, oldRng, sel = ed.selection, dom = ed.dom, body = ed.getBody(), posY, textContent;\r
 \r
                                // Check if browser supports direct plaintext access\r
-                               if (ed.pasteAsPlainText && (e.clipboardData || dom.doc.dataTransfer)) {\r
-                                       e.preventDefault();\r
-                                       process({content : (e.clipboardData || dom.doc.dataTransfer).getData('Text')}, true);\r
-                                       return;\r
+                               if (e.clipboardData || dom.doc.dataTransfer) {\r
+                                       textContent = (e.clipboardData || dom.doc.dataTransfer).getData('Text');\r
+\r
+                                       if (ed.pasteAsPlainText) {\r
+                                               e.preventDefault();\r
+                                               process({content : textContent.replace(/\r?\n/g, '<br />')});\r
+                                               return;\r
+                                       }\r
                                }\r
 \r
                                if (dom.get('_mcePaste'))\r
                                        return;\r
 \r
                                // Create container to paste into\r
-                               n = dom.add(body, 'div', {id : '_mcePaste', 'class' : 'mcePaste'}, '\uFEFF');\r
+                               n = dom.add(body, 'div', {id : '_mcePaste', 'class' : 'mcePaste', 'data-mce-bogus' : '1'}, '\uFEFF\uFEFF');\r
 \r
                                // If contentEditable mode we need to find out the position of the closest element\r
                                if (body != ed.getDoc().body)\r
                                        posY = dom.getPos(ed.selection.getStart(), body).y;\r
                                else\r
-                                       posY = body.scrollTop;\r
+                                       posY = body.scrollTop + dom.getViewPort().y;\r
 \r
                                // Styles needs to be applied after the element is added to the document since WebKit will otherwise remove all styles\r
                                dom.setStyles(n, {\r
                                });\r
 \r
                                if (tinymce.isIE) {\r
+                                       // Store away the old range\r
+                                       oldRng = sel.getRng();\r
+\r
                                        // Select the container\r
                                        rng = dom.doc.body.createTextRange();\r
                                        rng.moveToElementText(n);\r
 \r
                                        // Check if the contents was changed, if it wasn't then clipboard extraction failed probably due\r
                                        // to IE security settings so we pass the junk though better than nothing right\r
-                                       if (n.innerHTML === '\uFEFF') {\r
+                                       if (n.innerHTML === '\uFEFF\uFEFF') {\r
                                                ed.execCommand('mcePasteWord');\r
                                                e.preventDefault();\r
                                                return;\r
                                        }\r
 \r
-                                       // Process contents\r
-                                       process({content : n.innerHTML});\r
+                                       // Restore the old range and clear the contents before pasting\r
+                                       sel.setRng(oldRng);\r
+                                       sel.setContent('');\r
+\r
+                                       // For some odd reason we need to detach the the mceInsertContent call from the paste event\r
+                                       // It's like IE has a reference to the parent element that you paste in and the selection gets messed up\r
+                                       // when it tries to restore the selection\r
+                                       setTimeout(function() {\r
+                                               // Process contents\r
+                                               process({content : n.innerHTML});\r
+                                       }, 0);\r
 \r
                                        // Block the real paste event\r
                                        return tinymce.dom.Event.cancel(e);\r
 \r
                                        or = ed.selection.getRng();\r
 \r
-                                       // Move caret into hidden div\r
+                                       // Move select contents inside DIV\r
                                        n = n.firstChild;\r
                                        rng = ed.getDoc().createRange();\r
                                        rng.setStart(n, 0);\r
-                                       rng.setEnd(n, 1);\r
+                                       rng.setEnd(n, 2);\r
                                        sel.setRng(rng);\r
 \r
                                        // Wait a while and grab the pasted contents\r
                                        window.setTimeout(function() {\r
-                                               var h = '', nl = dom.select('div.mcePaste');\r
+                                               var h = '', nl;\r
 \r
-                                               // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string\r
-                                               each(nl, function(n) {\r
-                                                       // WebKit duplicates the divs so we need to remove them\r
-                                                       each(dom.select('div.mcePaste', n), function(n) {\r
-                                                               dom.remove(n, 1);\r
-                                                       });\r
+                                               // Paste divs duplicated in paste divs seems to happen when you paste plain text so lets first look for that broken behavior in WebKit\r
+                                               if (!dom.select('div.mcePaste > div.mcePaste').length) {\r
+                                                       nl = dom.select('div.mcePaste');\r
 \r
-                                                       // Remove apply style spans\r
-                                                       each(dom.select('span.Apple-style-span', n), function(n) {\r
-                                                               dom.remove(n, 1);\r
-                                                       });\r
+                                                       // WebKit will split the div into multiple ones so this will loop through then all and join them to get the whole HTML string\r
+                                                       each(nl, function(n) {\r
+                                                               var child = n.firstChild;\r
 \r
-                                                       h += n.innerHTML;\r
-                                               });\r
+                                                               // WebKit inserts a DIV container with lots of odd styles\r
+                                                               if (child && child.nodeName == 'DIV' && child.style.marginTop && child.style.backgroundColor) {\r
+                                                                       dom.remove(child, 1);\r
+                                                               }\r
+\r
+                                                               // Remove apply style spans\r
+                                                               each(dom.select('span.Apple-style-span', n), function(n) {\r
+                                                                       dom.remove(n, 1);\r
+                                                               });\r
+\r
+                                                               // Remove bogus br elements\r
+                                                               each(dom.select('br[data-mce-bogus]', n), function(n) {\r
+                                                                       dom.remove(n);\r
+                                                               });\r
+\r
+                                                               // WebKit will make a copy of the DIV for each line of plain text pasted and insert them into the DIV\r
+                                                               if (n.parentNode.className != 'mcePaste')\r
+                                                                       h += n.innerHTML;\r
+                                                       });\r
+                                               } else {\r
+                                                       // Found WebKit weirdness so force the content into plain text mode\r
+                                                       h = '<pre>' + dom.encode(textContent).replace(/\r?\n/g, '<br />') + '</pre>';\r
+                                               }\r
 \r
                                                // Remove the nodes\r
-                                               each(nl, function(n) {\r
+                                               each(dom.select('div.mcePaste'), function(n) {\r
                                                        dom.remove(n);\r
                                                });\r
 \r
                        if (getParam(ed, "paste_auto_cleanup_on_paste")) {\r
                                // Is it's Opera or older FF use key handler\r
                                if (tinymce.isOpera || /Firefox\/2/.test(navigator.userAgent)) {\r
-                                       ed.onKeyDown.add(function(ed, e) {\r
+                                       ed.onKeyDown.addToTop(function(ed, e) {\r
                                                if (((tinymce.isMac ? e.metaKey : e.ctrlKey) && e.keyCode == 86) || (e.shiftKey && e.keyCode == 45))\r
                                                        grabContent(e);\r
                                        });\r
                                }\r
                        }\r
 \r
-                       // Block all drag/drop events\r
-                       if (getParam(ed, "paste_block_drop")) {\r
-                               ed.onInit.add(function() {\r
+                       ed.onInit.add(function() {\r
+                               ed.controlManager.setActive("pastetext", ed.pasteAsPlainText);\r
+\r
+                               // Block all drag/drop events\r
+                               if (getParam(ed, "paste_block_drop")) {\r
                                        ed.dom.bind(ed.getBody(), ['dragend', 'dragover', 'draggesture', 'dragdrop', 'drop', 'drag'], function(e) {\r
                                                e.preventDefault();\r
                                                e.stopPropagation();\r
 \r
                                                return false;\r
                                        });\r
-                               });\r
-                       }\r
+                               }\r
+                       });\r
 \r
                        // Add legacy support\r
                        t._legacySupport();\r
                },\r
 \r
                _preProcess : function(pl, o) {\r
-                       //console.log('Before preprocess:' + o.content);\r
-\r
                        var ed = this.editor,\r
                                h = o.content,\r
                                grep = tinymce.grep,\r
                                trim = tinymce.trim,\r
                                len, stripClass;\r
 \r
+                       //console.log('Before preprocess:' + o.content);\r
+\r
                        function process(items) {\r
                                each(items, function(v) {\r
                                        // Remove or replace\r
                                                h = h.replace(v[0], v[1]);\r
                                });\r
                        }\r
+                       \r
+                       if (ed.settings.paste_enable_default_filters == false) {\r
+                               return;\r
+                       }\r
+\r
+                       // IE9 adds BRs before/after block elements when contents is pasted from word or for example another browser\r
+                       if (tinymce.isIE && document.documentMode >= 9)\r
+                               process([[/(?:<br>&nbsp;[\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>&nbsp;[\s\r\n]+|<br>)*/g, '$1']]);\r
 \r
                        // Detect Word content and process it more aggressive\r
                        if (/class="?Mso|style="[^"]*\bmso-|w:WordDocument/i.test(h) || o.wordContent) {\r
                                if (getParam(ed, "paste_convert_middot_lists")) {\r
                                        process([\r
                                                [/<!--\[if !supportLists\]-->/gi, '$&__MCE_ITEM__'],                                    // Convert supportLists to a list item marker\r
-                                               [/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi, '$1__MCE_ITEM__']              // Convert mso-list and symbol spans to item markers\r
+                                               [/(<span[^>]+(?:mso-list:|:\s*symbol)[^>]+>)/gi, '$1__MCE_ITEM__'],             // Convert mso-list and symbol spans to item markers\r
+                                               [/(<p[^>]+(?:MsoListParagraph)[^>]+>)/gi, '$1__MCE_ITEM__']                             // Convert mso-list and symbol paragraphs to item markers (FF)\r
                                        ]);\r
                                }\r
 \r
                                ]);\r
                        }\r
 \r
+                       process([\r
+                               // Copy paste from Java like Open Office will produce this junk on FF\r
+                               [/Version:[\d.]+\nStartHTML:\d+\nEndHTML:\d+\nStartFragment:\d+\nEndFragment:\d+/gi, '']\r
+                       ]);\r
+\r
                        // Class attribute options are: leave all as-is ("none"), remove all ("all"), or remove only those starting with mso ("mso").\r
                        // Note:-  paste_strip_class_attributes: "none", verify_css_classes: true is also a good variation.\r
                        stripClass = getParam(ed, "paste_strip_class_attributes");\r
                                };\r
 \r
                                h = h.replace(/ class="([^"]+)"/gi, removeClasses);\r
-                               h = h.replace(/ class=(\w+)/gi, removeClasses);\r
+                               h = h.replace(/ class=([\-\w]+)/gi, removeClasses);\r
                        }\r
 \r
                        // Remove spans option\r
                _postProcess : function(pl, o) {\r
                        var t = this, ed = t.editor, dom = ed.dom, styleProps;\r
 \r
+                       if (ed.settings.paste_enable_default_filters == false) {\r
+                               return;\r
+                       }\r
+                       \r
                        if (o.wordContent) {\r
                                // Remove named anchors or TOC links\r
                                each(dom.select('a', o.node), function(a) {\r
                        if (getParam(ed, "paste_remove_styles") || (getParam(ed, "paste_remove_styles_if_webkit") && tinymce.isWebKit)) {\r
                                each(dom.select('*[style]', o.node), function(el) {\r
                                        el.removeAttribute('style');\r
-                                       el.removeAttribute('_mce_style');\r
+                                       el.removeAttribute('data-mce-style');\r
                                });\r
                        } else {\r
                                if (tinymce.isWebKit) {\r
                                        // We need to compress the styles on WebKit since if you paste <img border="0" /> it will become <img border="0" style="... lots of junk ..." />\r
                                        // Removing the mce_style that contains the real value will force the Serializer engine to compress the styles\r
                                        each(dom.select('*', o.node), function(el) {\r
-                                               el.removeAttribute('_mce_style');\r
+                                               el.removeAttribute('data-mce-style');\r
                                        });\r
                                }\r
                        }\r
                                val = p.innerHTML.replace(/<\/?\w+[^>]*>/gi, '').replace(/&nbsp;/g, '\u00a0');\r
 \r
                                // Detect unordered lists look for bullets\r
-                               if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o]\s*\u00a0*/.test(val))\r
+                               if (/^(__MCE_ITEM__)+[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*\u00a0*/.test(val))\r
                                        type = 'ul';\r
 \r
                                // Detect ordered lists 1., a. or ixv.\r
-                               if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0{2,}/.test(val))\r
+                               if (/^__MCE_ITEM__\s*\w+\.\s*\u00a0+/.test(val))\r
                                        type = 'ol';\r
 \r
                                // Check if node value matches the list pattern: o&nbsp;&nbsp;\r
                                                var html = span.innerHTML.replace(/<\/?\w+[^>]*>/gi, '');\r
 \r
                                                // Remove span with the middot or the number\r
-                                               if (type == 'ul' && /^[\u2022\u00b7\u00a7\u00d8o]/.test(html))\r
+                                               if (type == 'ul' && /^__MCE_ITEM__[\u2022\u00b7\u00a7\u00d8o\u25CF]/.test(html))\r
                                                        dom.remove(span);\r
-                                               else if (/^[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(html))\r
+                                               else if (/^__MCE_ITEM__[\s\S]*\w+\.(&nbsp;|\u00a0)*\s*/.test(html))\r
                                                        dom.remove(span);\r
                                        });\r
 \r
 \r
                                        // Remove middot/list items\r
                                        if (type == 'ul')\r
-                                               html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o]\s*(&nbsp;|\u00a0)+\s*/, '');\r
+                                               html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^[\u2022\u00b7\u00a7\u00d8o\u25CF]\s*(&nbsp;|\u00a0)+\s*/, '');\r
                                        else\r
                                                html = p.innerHTML.replace(/__MCE_ITEM__/g, '').replace(/^\s*\w+\.(&nbsp;|\u00a0)+\s*/, '');\r
 \r
                                o.node.innerHTML = html.replace(/__MCE_ITEM__/g, '');\r
                },\r
 \r
-               /**\r
-                * This method will split the current block parent and insert the contents inside the split position.\r
-                * This logic can be improved so text nodes at the start/end remain in the start/end block elements\r
-                */\r
-               _insertBlockContent : function(ed, dom, content) {\r
-                       var parentBlock, marker, sel = ed.selection, last, elm, vp, y, elmHeight, markerId = 'mce_marker';\r
-\r
-                       function select(n) {\r
-                               var r;\r
-\r
-                               if (tinymce.isIE) {\r
-                                       r = ed.getDoc().body.createTextRange();\r
-                                       r.moveToElementText(n);\r
-                                       r.collapse(false);\r
-                                       r.select();\r
-                               } else {\r
-                                       sel.select(n, 1);\r
-                                       sel.collapse(false);\r
-                               }\r
-                       }\r
-\r
-                       // Insert a marker for the caret position\r
-                       this._insert('<span id="' + markerId + '">&nbsp;</span>', 1);\r
-                       marker = dom.get(markerId);\r
-                       parentBlock = dom.getParent(marker, 'p,h1,h2,h3,h4,h5,h6,ul,ol,th,td');\r
-\r
-                       // If it's a parent block but not a table cell\r
-                       if (parentBlock && !/TD|TH/.test(parentBlock.nodeName)) {\r
-                               // Split parent block\r
-                               marker = dom.split(parentBlock, marker);\r
-\r
-                               // Insert nodes before the marker\r
-                               each(dom.create('div', 0, content).childNodes, function(n) {\r
-                                       last = marker.parentNode.insertBefore(n.cloneNode(true), marker);\r
-                               });\r
-\r
-                               // Move caret after marker\r
-                               select(last);\r
-                       } else {\r
-                               dom.setOuterHTML(marker, content);\r
-                               sel.select(ed.getBody(), 1);\r
-                               sel.collapse(0);\r
-                       }\r
-\r
-                       // Remove marker if it's left\r
-                       while (elm = dom.get(markerId))\r
-                               dom.remove(elm);\r
-\r
-                       // Get element, position and height\r
-                       elm = sel.getStart();\r
-                       vp = dom.getViewPort(ed.getWin());\r
-                       y = ed.dom.getPos(elm).y;\r
-                       elmHeight = elm.clientHeight;\r
-\r
-                       // Is element within viewport if not then scroll it into view\r
-                       if (y < vp.y || y + elmHeight > vp.y + vp.h)\r
-                               ed.getDoc().body.scrollTop = y < vp.y ? y : y - vp.h + 25;\r
-               },\r
-\r
                /**\r
                 * Inserts the specified contents at the caret position.\r
                 */\r
                        if (!ed.selection.isCollapsed() && r.startContainer != r.endContainer)\r
                                ed.getDoc().execCommand('Delete', false, null);\r
 \r
-                       // It's better to use the insertHTML method on Gecko since it will combine paragraphs correctly before inserting the contents\r
-                       ed.execCommand(tinymce.isGecko ? 'insertHTML' : 'mceInsertContent', false, h, {skip_undo : skip_undo});\r
+                       ed.execCommand('mceInsertContent', false, h, {skip_undo : skip_undo});\r
                },\r
 \r
                /**\r
                        };\r
 \r
                        if ((typeof(h) === "string") && (h.length > 0)) {\r
-                               if (!entities)\r
-                                       entities = ("34,quot,38,amp,39,apos,60,lt,62,gt," + ed.serializer.settings.entities).split(",");\r
-\r
                                // If HTML content with line-breaking tags, then remove all cr/lf chars because only tags will break a line\r
                                if (/<(?:p|br|h[1-6]|ul|ol|dl|table|t[rdh]|div|blockquote|fieldset|pre|address|center)[^>]*>/i.test(h)) {\r
                                        process([\r
                                        [/<\/t[dh]>\s*<t[dh][^>]*>/gi, "\t"],           // Table cells get tabs betweem them\r
                                        /<[a-z!\/?][^>]*>/gi,                                           // Delete all remaining tags\r
                                        [/&nbsp;/gi, " "],                                                      // Convert non-break spaces to regular spaces (remember, *plain text*)\r
-                                       [\r
-                                               // HTML entity\r
-                                               /&(#\d+|[a-z0-9]{1,10});/gi,\r
-\r
-                                               // Replace with actual character\r
-                                               function(e, s) {\r
-                                                       if (s.charAt(0) === "#") {\r
-                                                               return String.fromCharCode(s.slice(1));\r
-                                                       }\r
-                                                       else {\r
-                                                               return ((e = inArray(entities, s)) > 0)? String.fromCharCode(entities[e-1]) : " ";\r
-                                                       }\r
-                                               }\r
-                                       ],\r
                                        [/(?:(?!\n)\s)*(\n+)(?:(?!\n)\s)*/gi, "$1"],    // Cool little RegExp deletes whitespace around linebreak chars.\r
                                        [/\n{3,}/g, "\n\n"],                                                    // Max. 2 consecutive linebreaks\r
                                        /^\s+|\s+$/g                                                                    // Trim the front & back\r
                                ]);\r
 \r
-                               h = dom.encode(h);\r
+                               h = dom.decode(tinymce.html.Entities.encodeRaw(h));\r
 \r
                                // Delete any highlighted text before pasting\r
                                if (!sel.isCollapsed()) {\r
index cd9c985b7a414df3215d7d7a3c1e9d2fc393bafe..165bc12df59988ec355c95be4931ab2b3d2df673 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create("tinymce.plugins.SearchReplacePlugin",{init:function(a,c){function b(d){a.windowManager.open({file:c+"/searchreplace.htm",width:420+parseInt(a.getLang("searchreplace.delta_width",0)),height:170+parseInt(a.getLang("searchreplace.delta_height",0)),inline:1,auto_focus:0},{mode:d,search_string:a.selection.getContent({format:"text"}),plugin_url:c})}a.addCommand("mceSearch",function(){b("search")});a.addCommand("mceReplace",function(){b("replace")});a.addButton("search",{title:"searchreplace.search_desc",cmd:"mceSearch"});a.addButton("replace",{title:"searchreplace.replace_desc",cmd:"mceReplace"});a.addShortcut("ctrl+f","searchreplace.search_desc","mceSearch")},getInfo:function(){return{longname:"Search/Replace",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/searchreplace",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("searchreplace",tinymce.plugins.SearchReplacePlugin)})();
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.SearchReplacePlugin",{init:function(a,c){function b(d){window.focus();a.windowManager.open({file:c+"/searchreplace.htm",width:420+parseInt(a.getLang("searchreplace.delta_width",0)),height:170+parseInt(a.getLang("searchreplace.delta_height",0)),inline:1,auto_focus:0},{mode:d,search_string:a.selection.getContent({format:"text"}),plugin_url:c})}a.addCommand("mceSearch",function(){b("search")});a.addCommand("mceReplace",function(){b("replace")});a.addButton("search",{title:"searchreplace.search_desc",cmd:"mceSearch"});a.addButton("replace",{title:"searchreplace.replace_desc",cmd:"mceReplace"});a.addShortcut("ctrl+f","searchreplace.search_desc","mceSearch")},getInfo:function(){return{longname:"Search/Replace",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/searchreplace",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.PluginManager.add("searchreplace",tinymce.plugins.SearchReplacePlugin)})();
\ No newline at end of file
index 1433a06a4aef1b25ce965360a9cc3e102b61685e..4c87e8fa79d0fdd12b5f577094f74c549db70266 100644 (file)
        tinymce.create('tinymce.plugins.SearchReplacePlugin', {\r
                init : function(ed, url) {\r
                        function open(m) {\r
+                               // Keep IE from writing out the f/r character to the editor\r
+                               // instance while initializing a new dialog. See: #3131190\r
+                               window.focus();\r
+\r
                                ed.windowManager.open({\r
                                        file : url + '/searchreplace.htm',\r
                                        width : 420 + parseInt(ed.getLang('searchreplace.delta_width', 0)),\r
index c0a62432978dd4cda1343ce7a2d376692a44a886..80284b9f3ff0b33d7348de16cbdf0a162bb89419 100644 (file)
@@ -2,14 +2,18 @@ tinyMCEPopup.requireLangPack();
 \r
 var SearchReplaceDialog = {\r
        init : function(ed) {\r
-               var f = document.forms[0], m = tinyMCEPopup.getWindowArg("mode");\r
+               var t = this, f = document.forms[0], m = tinyMCEPopup.getWindowArg("mode");\r
 \r
-               this.switchMode(m);\r
+               t.switchMode(m);\r
 \r
                f[m + '_panel_searchstring'].value = tinyMCEPopup.getWindowArg("search_string");\r
 \r
                // Focus input field\r
                f[m + '_panel_searchstring'].focus();\r
+               \r
+               mcTabs.onChange.add(function(tab_id, panel_id) {\r
+                       t.switchMode(tab_id.substring(0, tab_id.indexOf('_')));\r
+               });\r
        },\r
 \r
        switchMode : function(m) {\r
@@ -42,21 +46,23 @@ var SearchReplaceDialog = {
                ca = f[m + '_panel_casesensitivebox'].checked;\r
                rs = f['replace_panel_replacestring'].value;\r
 \r
+               if (tinymce.isIE) {\r
+                       r = ed.getDoc().selection.createRange();\r
+               }\r
+\r
                if (s == '')\r
                        return;\r
 \r
                function fix() {\r
                        // Correct Firefox graphics glitches\r
+                       // TODO: Verify if this is actually needed any more, maybe it was for very old FF versions? \r
                        r = se.getRng().cloneRange();\r
                        ed.getDoc().execCommand('SelectAll', false, null);\r
                        se.setRng(r);\r
                };\r
 \r
                function replace() {\r
-                       if (tinymce.isIE)\r
-                               ed.selection.getRng().duplicate().pasteHTML(rs); // Needs to be duplicated due to selection bug in IE\r
-                       else\r
-                               ed.getDoc().execCommand('InsertHTML', false, rs);\r
+                       ed.selection.setContent(rs); // Needs to be duplicated due to selection bug in IE\r
                };\r
 \r
                // IE flags\r
@@ -70,6 +76,9 @@ var SearchReplaceDialog = {
                                ed.selection.collapse(true);\r
 \r
                                if (tinymce.isIE) {\r
+                                       ed.focus();\r
+                                       r = ed.getDoc().selection.createRange();\r
+\r
                                        while (r.findText(s, b ? -1 : 1, fl)) {\r
                                                r.scrollIntoView();\r
                                                r.select();\r
@@ -111,6 +120,9 @@ var SearchReplaceDialog = {
                        return;\r
 \r
                if (tinymce.isIE) {\r
+                       ed.focus();\r
+                       r = ed.getDoc().selection.createRange();\r
+\r
                        if (r.findText(s, b ? -1 : 1, fl)) {\r
                                r.scrollIntoView();\r
                                r.select();\r
index d0424cfc9bcc1b857f5a1cabb2ed33b2f1dd7204..5a22d8aa4dcc977e547e07a93f20df0ea84524a0 100644 (file)
@@ -8,27 +8,28 @@
        <script type="text/javascript" src="js/searchreplace.js"></script>\r
        <link rel="stylesheet" type="text/css" href="css/searchreplace.css" />\r
 </head>\r
-<body style="display:none;">\r
+<body style="display:none;" role="application" aria-labelledby="app_title">\r
+<span id="app_title" style="display:none">{#searchreplace_dlg.replace_title}</span>\r
 <form onsubmit="SearchReplaceDialog.searchNext('none');return false;" action="#">\r
        <div class="tabs">\r
                <ul>\r
-                       <li id="search_tab"><span><a href="javascript:SearchReplaceDialog.switchMode('search');" onmousedown="return false;">{#searchreplace.search_desc}</a></span></li>\r
-                       <li id="replace_tab"><span><a href="javascript:SearchReplaceDialog.switchMode('replace');" onmousedown="return false;">{#searchreplace_dlg.replace}</a></span></li>\r
+                       <li id="search_tab" aria-controls="search_panel"><span><a href="javascript:SearchReplaceDialog.switchMode('search');" onmousedown="return false;">{#searchreplace.search_desc}</a></span></li>\r
+                       <li id="replace_tab" aria-controls="replace_panel"><span><a href="javascript:SearchReplaceDialog.switchMode('replace');" onmousedown="return false;">{#searchreplace_dlg.replace}</a></span></li>\r
                </ul>\r
        </div>\r
 \r
        <div class="panel_wrapper">\r
                <div id="search_panel" class="panel">\r
-                       <table border="0" cellspacing="0" cellpadding="2">\r
+                       <table role="presentation" border="0" cellspacing="0" cellpadding="2">\r
                                <tr>\r
                                        <td><label for="search_panel_searchstring">{#searchreplace_dlg.findwhat}</label></td>\r
-                                       <td><input type="text" id="search_panel_searchstring" name="search_panel_searchstring" style="width: 200px" /></td>\r
+                                       <td><input type="text" id="search_panel_searchstring" name="search_panel_searchstring" style="width: 200px" aria-required="true" /></td>\r
                                </tr>\r
                                <tr>\r
                                        <td colspan="2">\r
-                                               <table border="0" cellspacing="0" cellpadding="0" class="direction">\r
-                                                       <tr>\r
-                                                               <td><label>{#searchreplace_dlg.direction}</label></td>\r
+                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0" class="direction">\r
+                                                       <tr role="group" aria-labelledby="search_panel_backwards_label">\r
+                                                               <td><label id="search_panel_backwards_label">{#searchreplace_dlg.direction}</label></td>\r
                                                                <td><input id="search_panel_backwardsu" name="search_panel_backwards" class="radio" type="radio" /></td>\r
                                                                <td><label for="search_panel_backwardsu">{#searchreplace_dlg.up}</label></td>\r
                                                                <td><input id="search_panel_backwardsd" name="search_panel_backwards" class="radio" type="radio" checked="checked" /></td>\r
@@ -39,7 +40,7 @@
                                </tr>\r
                                <tr>\r
                                        <td colspan="2">\r
-                                               <table border="0" cellspacing="0" cellpadding="0">\r
+                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
                                                        <tr>\r
                                                                <td><input id="search_panel_casesensitivebox" name="search_panel_casesensitivebox" class="checkbox" type="checkbox" /></td>\r
                                                                <td><label for="search_panel_casesensitivebox">{#searchreplace_dlg.mcase}</label></td>\r
                </div>\r
 \r
                <div id="replace_panel" class="panel">\r
-                       <table border="0" cellspacing="0" cellpadding="2">\r
+                       <table role="presentation" border="0" cellspacing="0" cellpadding="2">\r
                                <tr>\r
                                        <td><label for="replace_panel_searchstring">{#searchreplace_dlg.findwhat}</label></td>\r
-                                       <td><input type="text" id="replace_panel_searchstring" name="replace_panel_searchstring" style="width: 200px" /></td>\r
+                                       <td><input type="text" id="replace_panel_searchstring" name="replace_panel_searchstring" style="width: 200px" aria-required="true" /></td>\r
                                </tr>\r
                                <tr>\r
                                        <td><label for="replace_panel_replacestring">{#searchreplace_dlg.replacewith}</label></td>\r
-                                       <td><input type="text" id="replace_panel_replacestring" name="replace_panel_replacestring" style="width: 200px" /></td>\r
+                                       <td><input type="text" id="replace_panel_replacestring" name="replace_panel_replacestring" style="width: 200px" aria-required="true" /></td>\r
                                </tr>\r
                                <tr>\r
                                        <td colspan="2">\r
-                                               <table border="0" cellspacing="0" cellpadding="0" class="direction">\r
-                                                       <tr>\r
-                                                               <td><label>{#searchreplace_dlg.direction}</label></td>\r
+                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0" class="direction">\r
+                                                       <tr role="group" aria-labelledby="replace_panel_dir_label">\r
+                                                               <td><label id="replace_panel_dir_label">{#searchreplace_dlg.direction}</label></td>\r
                                                                <td><input id="replace_panel_backwardsu" name="replace_panel_backwards" class="radio" type="radio" /></td>\r
                                                                <td><label for="replace_panel_backwardsu">{#searchreplace_dlg.up}</label></td>\r
                                                                <td><input id="replace_panel_backwardsd" name="replace_panel_backwards" class="radio" type="radio" checked="checked" /></td>\r
@@ -75,7 +76,7 @@
                                </tr>\r
                                <tr>\r
                                        <td colspan="2">\r
-                                               <table border="0" cellspacing="0" cellpadding="0">\r
+                                               <table role="presentation" border="0" cellspacing="0" cellpadding="0">\r
                                                        <tr>\r
                                                                <td><input id="replace_panel_casesensitivebox" name="replace_panel_casesensitivebox" class="checkbox" type="checkbox" /></td>\r
                                                                <td><label for="replace_panel_casesensitivebox">{#searchreplace_dlg.mcase}</label></td>\r
index a9ec3b9cf0f777ec381ffe77cf0ec6dd98780f8e..90cde6a546c59629fafd15c61b40796915effcc2 100644 (file)
@@ -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()}});e.onInit.add(function(){if(e.settings.content_css!==false){e.dom.loadCSS(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(){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(o){var i,h,g,f,e,n="",k=this.editor,p=this._getSeparators(),j=k.dom,d=[];var l=k.selection,m=l.getBookmark();c(o,function(q){n+=(n?"|":"")+q});i=new RegExp("(["+p+"])("+n+")(["+p+"])","g");h=new RegExp("^("+n+")","g");g=new RegExp("("+n+")(["+p+"]?)$","g");f=new RegExp("^("+n+")(["+p+"]?)$","g");e=new RegExp("("+n+")(["+p+"])","g");this._walk(this.editor.getBody(),function(q){if(q.nodeType==3){d.push(q)}});c(d,function(r){var q;if(r.nodeType==3){q=r.nodeValue;if(i.test(q)||h.test(q)||g.test(q)||f.test(q)){q=j.encode(q);q=q.replace(e,'<span class="mceItemHiddenSpellWord">$1</span>$2');q=q.replace(g,'<span class="mceItemHiddenSpellWord">$1</span>$2');j.replace(j.create("span",{"class":"mceItemHidden"},q),r)}}});l.moveToBookmark(m)},_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){l=b.getPos(h.getContentAreaContainer());d=h.controlManager.createDropMenu("spellcheckermenu",{offset_x:l.x,offset_y:l.y,"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)}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()});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(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)}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=k.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
index d8680baf2cdfac60b4dc0e8624713aebdf7401f6..9757aec9c3eb7680de10da4607498196c13d6a51 100644 (file)
                                        t._done();\r
                        });\r
 \r
-                       ed.onInit.add(function() {\r
-                               if (ed.settings.content_css !== false)\r
-                                       ed.dom.loadCSS(url + '/css/content.css');\r
-                       });\r
+                       if (ed.settings.content_css !== false)\r
+                               ed.contentCSS.push(url + '/css/content.css');\r
 \r
                        ed.onClick.add(t._showMenu, t);\r
                        ed.onContextMenu.add(t._showMenu, t);\r
                                                var o = {icon : 1}, mi;\r
 \r
                                                o.onclick = function() {\r
+                                                       if (v == t.selectedLang) {\r
+                                                               return;\r
+                                                       }\r
                                                        mi.setSelected(1);\r
                                                        t.selectedItem.setSelected(0);\r
                                                        t.selectedItem = mi;\r
                },\r
 \r
                _markWords : function(wl) {\r
-                       var r1, r2, r3, r4, r5, w = '', ed = this.editor, re = this._getSeparators(), dom = ed.dom, nl = [];\r
-                       var se = ed.selection, b = se.getBookmark();\r
-\r
-                       each(wl, function(v) {\r
-                               w += (w ? '|' : '') + v;\r
-                       });\r
-\r
-                       r1 = new RegExp('([' + re + '])(' + w + ')([' + re + '])', 'g');\r
-                       r2 = new RegExp('^(' + w + ')', 'g');\r
-                       r3 = new RegExp('(' + w + ')([' + re + ']?)$', 'g');\r
-                       r4 = new RegExp('^(' + w + ')([' + re + ']?)$', 'g');\r
-                       r5 = new RegExp('(' + w + ')([' + re + '])', 'g');\r
+                       var ed = this.editor, dom = ed.dom, doc = ed.getDoc(), se = ed.selection, b = se.getBookmark(), nl = [],\r
+                               w = wl.join('|'), re = this._getSeparators(), rx = new RegExp('(^|[' + re + '])(' + w + ')(?=[' + re + ']|$)', 'g');\r
 \r
                        // Collect all text nodes\r
-                       this._walk(this.editor.getBody(), function(n) {\r
+                       this._walk(ed.getBody(), function(n) {\r
                                if (n.nodeType == 3) {\r
                                        nl.push(n);\r
                                }\r
 \r
                        // Wrap incorrect words in spans\r
                        each(nl, function(n) {\r
-                               var v;\r
-\r
-                               if (n.nodeType == 3) {\r
-                                       v = n.nodeValue;\r
-\r
-                                       if (r1.test(v) || r2.test(v) || r3.test(v) || r4.test(v)) {\r
-                                               v = dom.encode(v);\r
-                                               v = v.replace(r5, '<span class="mceItemHiddenSpellWord">$1</span>$2');\r
-                                               v = v.replace(r3, '<span class="mceItemHiddenSpellWord">$1</span>$2');\r
-\r
-                                               dom.replace(dom.create('span', {'class' : 'mceItemHidden'}, v), n);\r
+                               var node, elem, txt, pos, v = n.nodeValue;\r
+\r
+                               if (rx.test(v)) {\r
+                                       // Encode the content\r
+                                       v = dom.encode(v);\r
+                                       // Create container element\r
+                                       elem = dom.create('span', {'class' : 'mceItemHidden'});\r
+\r
+                                       // Following code fixes IE issues by creating text nodes\r
+                                       // using DOM methods instead of innerHTML.\r
+                                       // Bug #3124: <PRE> elements content is broken after spellchecking.\r
+                                       // Bug #1408: Preceding whitespace characters are removed\r
+                                       // @TODO: I'm not sure that both are still issues on IE9.\r
+                                       if (tinymce.isIE) {\r
+                                               // Enclose mispelled words with temporal tag\r
+                                               v = v.replace(rx, '$1<mcespell>$2</mcespell>');\r
+                                               // Loop over the content finding mispelled words\r
+                                               while ((pos = v.indexOf('<mcespell>')) != -1) {\r
+                                                       // Add text node for the content before the word\r
+                                                       txt = v.substring(0, pos);\r
+                                                       if (txt.length) {\r
+                                                               node = doc.createTextNode(dom.decode(txt));\r
+                                                               elem.appendChild(node);\r
+                                                       }\r
+                                                       v = v.substring(pos+10);\r
+                                                       pos = v.indexOf('</mcespell>');\r
+                                                       txt = v.substring(0, pos);\r
+                                                       v = v.substring(pos+11);\r
+                                                       // Add span element for the word\r
+                                                       elem.appendChild(dom.create('span', {'class' : 'mceItemHiddenSpellWord'}, txt));\r
+                                               }\r
+                                               // Add text node for the rest of the content\r
+                                               if (v.length) {\r
+                                                       node = doc.createTextNode(dom.decode(v));\r
+                                                       elem.appendChild(node);\r
+                                               }\r
+                                       } else {\r
+                                               // Other browsers preserve whitespace characters on innerHTML usage\r
+                                               elem.innerHTML = v.replace(rx, '$1<span class="mceItemHiddenSpellWord">$2</span>');\r
                                        }\r
+\r
+                                       // Finally, replace the node with the container\r
+                                       dom.replace(elem, n);\r
                                }\r
                        });\r
 \r
                        e = 0; // Fixes IE memory leak\r
 \r
                        if (!m) {\r
-                               p1 = DOM.getPos(ed.getContentAreaContainer());\r
-                               //p2 = DOM.getPos(ed.getContainer());\r
-\r
-                               m = ed.controlManager.createDropMenu('spellcheckermenu', {\r
-                                       offset_x : p1.x,\r
-                                       offset_y : p1.y,\r
-                                       'class' : 'mceNoIcons'\r
-                               });\r
-\r
+                               m = ed.controlManager.createDropMenu('spellcheckermenu', {'class' : 'mceNoIcons'});\r
                                t._menu = m;\r
                        }\r
 \r
                                        m.update();\r
                                });\r
 \r
+                               p1 = dom.getPos(ed.getContentAreaContainer());\r
+                               m.settings.offset_x = p1.x;\r
+                               m.settings.offset_y = p1.y;\r
+\r
                                ed.selection.select(wordSpan);\r
                                p1 = dom.getPos(wordSpan);\r
                                m.showMenu(p1.x, p1.y + wordSpan.offsetHeight - vp.y);\r
index 27d2440222d233a3c1d784aa1e94022f8caa62a6..d18689ddb9a9753d4d73d9a93bb79d8704a2e871 100644 (file)
@@ -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(i){o=c.getParent(l.id,"form");n=o.elements;if(o){d(n,function(s,r){if(s.id==l.id){j=r;return false}});if(i>0){for(m=j+1;m<n.length;m++){if(n[m].type!="hidden"){return n[m]}}}else{for(m=j-1;m>=0;m--){if(n[m].type!="hidden"){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(l=tinymce.get(n.id||n.name)){l.focus()}else{window.setTimeout(function(){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)}f.onInit.add(function(){d(c.select("a:first,a:last",f.getContainer()),function(i){a.add(i,"focus",function(){f.focus()})})})},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(r){n=c.select(":input:enabled,*[tabindex]");function i(s){return s.type!="hidden"&&s.tabIndex!="-1"&&!(n[m].style.display=="none")&&!(n[m].style.visibility=="hidden")}d(n,function(t,s){if(t.id==l.id){j=s;return false}});if(r>0){for(m=j+1;m<n.length;m++){if(i(n[m])){return n[m]}}}else{for(m=j-1;m>=0;m--){if(i(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
index c2be2f40a6b2a9aa4f3c34e80b3947349b52040b..f4545e16703546db8e08a1c1a03e94cb23eb8314 100644 (file)
                                var x, i, f, el, v;\r
 \r
                                function find(d) {\r
-                                       f = DOM.getParent(ed.id, 'form');\r
-                                       el = f.elements;\r
-\r
-                                       if (f) {\r
-                                               each(el, function(e, i) {\r
-                                                       if (e.id == ed.id) {\r
-                                                               x = i;\r
-                                                               return false;\r
-                                                       }\r
-                                               });\r
-\r
-                                               if (d > 0) {\r
-                                                       for (i = x + 1; i < el.length; i++) {\r
-                                                               if (el[i].type != 'hidden')\r
-                                                                       return el[i];\r
-                                                       }\r
-                                               } else {\r
-                                                       for (i = x - 1; i >= 0; i--) {\r
-                                                               if (el[i].type != 'hidden')\r
-                                                                       return el[i];\r
-                                                       }\r
+                                       el = DOM.select(':input:enabled,*[tabindex]');\r
+                                       function canSelect(e) {\r
+                                               return e.type != 'hidden' && \r
+                                               e.tabIndex != '-1' && \r
+                                                       !(el[i].style.display == "none") && \r
+                                                       !(el[i].style.visibility == "hidden");\r
+                                   }\r
+\r
+                                       each(el, function(e, i) {\r
+                                               if (e.id == ed.id) {\r
+                                                       x = i;\r
+                                                       return false;\r
+                                               }\r
+                                       });\r
+\r
+                                       if (d > 0) {\r
+                                               for (i = x + 1; i < el.length; i++) {\r
+                                                       if (canSelect(el[i]))\r
+                                                               return el[i];\r
+                                               }\r
+                                       } else {\r
+                                               for (i = x - 1; i >= 0; i--) {\r
+                                                       if (canSelect(el[i]))\r
+                                                               return el[i];\r
                                                }\r
                                        }\r
 \r
                                        }\r
 \r
                                        if (el) {\r
-                                               if (ed = tinymce.get(el.id || el.name))\r
+                                               if (el.id && (ed = tinymce.get(el.id || el.name)))\r
                                                        ed.focus();\r
                                                else\r
-                                                       window.setTimeout(function() {window.focus();el.focus();}, 10);\r
+                                                       window.setTimeout(function() {\r
+                                                               if (!tinymce.isWebKit)\r
+                                                                       window.focus();\r
+                                                               el.focus();\r
+                                                       }, 10);\r
 \r
                                                return Event.cancel(e);\r
                                        }\r
                        } else\r
                                ed.onKeyDown.add(tabHandler);\r
 \r
-                       ed.onInit.add(function() {\r
-                               each(DOM.select('a:first,a:last', ed.getContainer()), function(n) {\r
-                                       Event.add(n, 'focus', function() {ed.focus();});\r
-                               });\r
-                       });\r
                },\r
 \r
                getInfo : function() {\r
index d243e1d833541b6a29e2600cbcd031f68ef01a3a..4afb6afa3a7acc8d48196a3a9d5c27735961338f 100644 (file)
@@ -9,12 +9,12 @@
        <script type="text/javascript" src="js/cell.js"></script>\r
        <link href="css/cell.css" rel="stylesheet" type="text/css" />\r
 </head>\r
-<body id="tablecell" style="display: none">\r
+<body id="tablecell" style="display: none" role="application">\r
        <form onsubmit="updateAction();return false;" action="#">\r
                <div class="tabs">\r
                        <ul>\r
-                               <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#table_dlg.general_tab}</a></span></li>\r
-                               <li id="advanced_tab"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#table_dlg.advanced_tab}</a></span></li>\r
+                               <li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#table_dlg.general_tab}</a></span></li>\r
+                               <li id="advanced_tab" aria-controls="advanced_panel"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#table_dlg.advanced_tab}</a></span></li>\r
                        </ul>\r
                </div>\r
 \r
@@ -23,7 +23,7 @@
                                <fieldset>\r
                                        <legend>{#table_dlg.general_props}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td><label for="align">{#table_dlg.align}</label></td>\r
                                                        <td>\r
@@ -92,7 +92,7 @@
                                <fieldset>\r
                                        <legend>{#table_dlg.advanced_props}</legend>\r
 \r
-                                       <table border="0" cellpadding="0" cellspacing="4">\r
+                                       <table role="presentation" border="0" cellpadding="0" cellspacing="4">\r
                                                <tr>\r
                                                        <td class="column1"><label for="id">{#table_dlg.id}</label></td> \r
                                                        <td><input id="id" name="id" type="text" value="" style="width: 200px" /></td> \r
                                                <tr>\r
                                                        <td class="column1"><label for="backgroundimage">{#table_dlg.bgimage}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="backgroundimage" name="backgroundimage" type="text" value="" style="width: 200px" onchange="changedBackgroundImage();" /></td>\r
                                                                                <td id="backgroundimagebrowsercontainer">&nbsp;</td>\r
                                                        </td> \r
                                                </tr>\r
 \r
-                                               <tr>\r
-                                                       <td class="column1"><label for="bordercolor">{#table_dlg.bordercolor}</label></td> \r
+                                               <tr role="group" aria-labelledby="bordercolor_label">\r
+                                                       <td class="column1"><label id="bordercolor_label" for="bordercolor">{#table_dlg.bordercolor}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="bordercolor" name="bordercolor" type="text" value="" size="9" onchange="updateColor('bordercolor_pick','bordercolor');changedColor();" /></td>\r
                                                                                <td id="bordercolor_pickcontainer">&nbsp;</td>\r
                                                        </td> \r
                                                </tr>\r
 \r
-                                               <tr>\r
-                                                       <td class="column1"><label for="bgcolor">{#table_dlg.bgcolor}</label></td> \r
+                                               <tr role="group" aria-labelledby="bgcolor_label">\r
+                                                       <td class="column1"><label id="bgcolor_label" for="bgcolor">{#table_dlg.bgcolor}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');changedColor();" /></td>\r
                                                                                <td id="bgcolor_pickcontainer">&nbsp;</td>\r
index 266d7d5371de3b9b773b7a162c0a36eeef04a89e..727ae4e79e45c77e05e51ac44d03217daf7a1e49 100644 (file)
@@ -1 +1 @@
-(function(b){var c=b.each;function a(F,E,I){var e,J,B,n;r();n=E.getParent(I.getStart(),"th,td");if(n){J=D(n);B=G();n=v(J.x,J.y)}function w(L,K){L=L.cloneNode(K);L.removeAttribute("id");return L}function r(){var K=0;e=[];c(["thead","tbody","tfoot"],function(L){var M=E.select(L+" tr",F);c(M,function(N,O){O+=K;c(E.select("td,th",N),function(U,P){var Q,R,S,T;if(e[O]){while(e[O][P]){P++}}S=g(U,"rowspan");T=g(U,"colspan");for(R=O;R<O+S;R++){if(!e[R]){e[R]=[]}for(Q=P;Q<P+T;Q++){e[R][Q]={part:L,real:R==O&&Q==P,elm:U,rowspan:S,colspan:T}}}})});K+=M.length})}function v(K,M){var L;L=e[M];if(L){return L[K]}}function g(L,K){return parseInt(L.getAttribute(K)||1)}function h(K){return E.hasClass(K.elm,"mceSelected")||K==n}function j(){var K=[];c(F.rows,function(L){c(L.cells,function(M){if(E.hasClass(M,"mceSelected")||M==n.elm){K.push(L);return false}})});return K}function q(){var K=E.createRng();K.setStartAfter(F);K.setEndAfter(F);I.setRng(K);E.remove(F)}function d(K){var L;b.walk(K,function(N){var M;if(N.nodeType==3){c(E.getParents(N.parentNode,null,K).reverse(),function(O){O=w(O,false);if(!L){L=M=O}else{if(M){M.appendChild(O)}}M=O});if(M){M.innerHTML=b.isIE?"&nbsp;":'<br _mce_bogus="1" />'}return false}},"childNodes");K=w(K,false);K.rowSpan=K.colSpan=1;if(L){K.appendChild(L)}else{if(!b.isIE){K.innerHTML='<br _mce_bogus="1" />'}}return K}function p(){var K=E.createRng();c(E.select("tr",F),function(L){if(L.cells.length==0){E.remove(L)}});if(E.select("tr",F).length==0){K.setStartAfter(F);K.setEndAfter(F);I.setRng(K);E.remove(F);return}c(E.select("thead,tbody,tfoot",F),function(L){if(L.rows.length==0){E.remove(L)}});r();row=e[Math.min(e.length-1,J.y)];if(row){I.select(row[Math.min(row.length-1,J.x)].elm,true);I.collapse(true)}}function s(Q,O,S,P){var N,L,K,M,R;N=e[O][Q].elm.parentNode;for(K=1;K<=S;K++){N=E.getNext(N,"tr");if(N){for(L=Q;L>=0;L--){R=e[O+K][L].elm;if(R.parentNode==N){for(M=1;M<=P;M++){E.insertAfter(d(R),R)}break}}if(L==-1){for(M=1;M<=P;M++){N.insertBefore(d(N.cells[0]),N.cells[0])}}}}}function A(){c(e,function(K,L){c(K,function(N,M){var Q,P,R,O;if(h(N)){N=N.elm;Q=g(N,"colspan");P=g(N,"rowspan");if(Q>1||P>1){N.colSpan=N.rowSpan=1;for(O=0;O<Q-1;O++){E.insertAfter(d(N),N)}s(M,L,P-1,Q)}}})})}function o(S,P,V){var N,M,U,T,R,O,Q,K,S,L;if(S){pos=D(S);N=pos.x;M=pos.y;U=N+(P-1);T=M+(V-1)}else{N=J.x;M=J.y;U=B.x;T=B.y}Q=v(N,M);K=v(U,T);if(Q&&K&&Q.part==K.part){A();r();Q=v(N,M).elm;Q.colSpan=(U-N)+1;Q.rowSpan=(T-M)+1;for(O=M;O<=T;O++){for(R=N;R<=U;R++){S=e[O][R].elm;if(S!=Q){L=b.grep(S.childNodes);c(L,function(X,W){if(X.nodeName!="BR"||W!=L.length-1){Q.appendChild(X)}});E.remove(S)}}}p()}}function k(N){var K,P,M,O,Q,R,L,S;c(e,function(T,U){c(T,function(W,V){if(h(W)){W=W.elm;Q=W.parentNode;R=w(Q,false);K=U;if(N){return false}}});if(N){return !K}});for(O=0;O<e[0].length;O++){P=e[K][O].elm;if(P!=M){if(!N){rowSpan=g(P,"rowspan");if(rowSpan>1){P.rowSpan=rowSpan+1;continue}}else{if(K>0&&e[K-1][O]){S=e[K-1][O].elm;rowSpan=g(S,"rowspan");if(rowSpan>1){S.rowSpan=rowSpan+1;continue}}}L=d(P);L.colSpan=P.colSpan;R.appendChild(L);M=P}}if(R.hasChildNodes()){if(!N){E.insertAfter(R,Q)}else{Q.parentNode.insertBefore(R,Q)}}}function f(L){var M,K;c(e,function(N,O){c(N,function(Q,P){if(h(Q)){M=P;if(L){return false}}});if(L){return !M}});c(e,function(Q,R){var N=Q[M].elm,O,P;if(N!=K){P=g(N,"colspan");O=g(N,"rowspan");if(P==1){if(!L){E.insertAfter(d(N),N);s(M,R,O-1,P)}else{N.parentNode.insertBefore(d(N),N);s(M,R,O-1,P)}}else{N.colSpan++}K=N}})}function m(){var K=[];c(e,function(L,M){c(L,function(O,N){if(h(O)&&b.inArray(K,N)===-1){c(e,function(R){var P=R[N].elm,Q;Q=g(P,"colspan");if(Q>1){P.colSpan=Q-1}else{E.remove(P)}});K.push(N)}})});p()}function l(){var L;function K(O){var N,P,M;N=E.getNext(O,"tr");c(O.cells,function(Q){var R=g(Q,"rowspan");if(R>1){Q.rowSpan=R-1;P=D(Q);s(P.x,P.y,1,1)}});P=D(O.cells[0]);c(e[P.y],function(Q){var R;Q=Q.elm;if(Q!=M){R=g(Q,"rowspan");if(R<=1){E.remove(Q)}else{Q.rowSpan=R-1}M=Q}})}L=j();c(L.reverse(),function(M){K(M)});p()}function C(){var K=j();E.remove(K);p();return K}function H(){var K=j();c(K,function(M,L){K[L]=w(M,true)});return K}function z(M,L){var N=j(),K=N[L?0:N.length-1],O=K.cells.length;c(e,function(Q){var P;O=0;c(Q,function(S,R){if(S.real){O+=S.colspan}if(S.elm.parentNode==K){P=1}});if(P){return false}});if(!L){M.reverse()}c(M,function(R){var Q=R.cells.length,P;for(i=0;i<Q;i++){P=R.cells[i];P.colSpan=P.rowSpan=1}for(i=Q;i<O;i++){R.appendChild(d(R.cells[Q-1]))}for(i=O;i<Q;i++){E.remove(R.cells[i])}if(L){K.parentNode.insertBefore(R,K)}else{E.insertAfter(R,K)}})}function D(K){var L;c(e,function(M,N){c(M,function(P,O){if(P.elm==K){L={x:O,y:N};return false}});return !L});return L}function u(K){J=D(K)}function G(){var M,L,K;L=K=0;c(e,function(N,O){c(N,function(Q,P){var S,R;if(h(Q)){Q=e[O][P];if(P>L){L=P}if(O>K){K=O}if(Q.real){S=Q.colspan-1;R=Q.rowspan-1;if(S){if(P+S>L){L=P+S}}if(R){if(O+R>K){K=O+R}}}}})});return{x:L,y:K}}function t(Q){var N,M,S,R,L,K,O,P;B=D(Q);if(J&&B){N=Math.min(J.x,B.x);M=Math.min(J.y,B.y);S=Math.max(J.x,B.x);R=Math.max(J.y,B.y);L=S;K=R;for(y=M;y<=K;y++){Q=e[y][N];if(!Q.real){if(N-(Q.colspan-1)<N){N-=Q.colspan-1}}}for(x=N;x<=L;x++){Q=e[M][x];if(!Q.real){if(M-(Q.rowspan-1)<M){M-=Q.rowspan-1}}}for(y=M;y<=R;y++){for(x=N;x<=S;x++){Q=e[y][x];if(Q.real){O=Q.colspan-1;P=Q.rowspan-1;if(O){if(x+O>L){L=x+O}}if(P){if(y+P>K){K=y+P}}}}}E.removeClass(E.select("td.mceSelected,th.mceSelected"),"mceSelected");for(y=M;y<=K;y++){for(x=N;x<=L;x++){E.addClass(e[y][x].elm,"mceSelected")}}}}b.extend(this,{deleteTable:q,split:A,merge:o,insertRow:k,insertCol:f,deleteCols:m,deleteRows:l,cutRows:C,copyRows:H,pasteRows:z,getPos:D,setStartCell:u,setEndCell:t})}b.create("tinymce.plugins.TablePlugin",{init:function(e,f){var d,j;function h(m){var l=e.selection,k=e.dom.getParent(m||l.getNode(),"table");if(k){return new a(k,e.dom,l)}}function g(){e.getBody().style.webkitUserSelect="";e.dom.removeClass(e.dom.select("td.mceSelected,th.mceSelected"),"mceSelected")}c([["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(k){e.addButton(k[0],{title:k[1],cmd:k[2],ui:k[3]})});if(!b.isIE){e.onClick.add(function(k,l){l=l.target;if(l.nodeName==="TABLE"){k.selection.select(l)}})}e.onNodeChange.add(function(l,k,o){var m;o=l.selection.getStart();m=l.dom.getParent(o,"td,th,caption");k.setActive("table",o.nodeName==="TABLE"||!!m);if(m&&m.nodeName==="CAPTION"){m=0}k.setDisabled("delete_table",!m);k.setDisabled("delete_col",!m);k.setDisabled("delete_table",!m);k.setDisabled("delete_row",!m);k.setDisabled("col_after",!m);k.setDisabled("col_before",!m);k.setDisabled("row_after",!m);k.setDisabled("row_before",!m);k.setDisabled("row_props",!m);k.setDisabled("cell_props",!m);k.setDisabled("split_cells",!m);k.setDisabled("merge_cells",!m)});e.onInit.add(function(l){var k,o,p=l.dom,m;d=l.windowManager;l.onMouseDown.add(function(q,r){if(r.button!=2){g();o=p.getParent(r.target,"td,th");k=p.getParent(o,"table")}});p.bind(l.getDoc(),"mouseover",function(t){var r,q,s=t.target;if(o&&(m||s!=o)&&(s.nodeName=="TD"||s.nodeName=="TH")){q=p.getParent(s,"table");if(q==k){if(!m){m=h(q);m.setStartCell(o);l.getBody().style.webkitUserSelect="none"}m.setEndCell(s)}r=l.selection.getSel();if(r.removeAllRanges){r.removeAllRanges()}else{r.empty()}t.preventDefault()}});l.onMouseUp.add(function(z,A){var r,t=z.selection,B,C=t.getSel(),q,u,s,w;if(o){if(m){z.getBody().style.webkitUserSelect=""}function v(D,F){var E=new b.dom.TreeWalker(D,D);do{if(D.nodeType==3&&b.trim(D.nodeValue).length!=0){if(F){r.setStart(D,0)}else{r.setEnd(D,D.nodeValue.length)}return}if(D.nodeName=="BR"){if(F){r.setStartBefore(D)}else{r.setEndBefore(D)}return}}while(D=(F?E.next():E.prev()))}B=p.select("td.mceSelected,th.mceSelected");if(B.length>0){r=p.createRng();u=B[0];w=B[B.length-1];v(u,1);q=new b.dom.TreeWalker(u,p.getParent(B[0],"table"));do{if(u.nodeName=="TD"||u.nodeName=="TH"){if(!p.hasClass(u,"mceSelected")){break}s=u}}while(u=q.next());v(s);t.setRng(r)}z.nodeChanged();o=m=k=null}});l.onKeyUp.add(function(q,r){g()});if(l&&l.plugins.contextmenu){l.plugins.contextmenu.onContextMenu.add(function(s,q,u){var v,t=l.selection,r=t.getNode()||l.getBody();if(l.dom.getParent(u,"td")||l.dom.getParent(u,"th")||l.dom.select("td.mceSelected,th.mceSelected").length){q.removeAll();if(r.nodeName=="A"&&!l.dom.getAttrib(r,"name")){q.add({title:"advanced.link_desc",icon:"link",cmd:l.plugins.advlink?"mceAdvLink":"mceLink",ui:true});q.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});q.addSeparator()}if(r.nodeName=="IMG"&&r.className.indexOf("mceItem")==-1){q.add({title:"advanced.image_desc",icon:"image",cmd:l.plugins.advimage?"mceAdvImage":"mceImage",ui:true});q.addSeparator()}q.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",value:{action:"insert"}});q.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable"});q.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete"});q.addSeparator();v=q.addMenu({title:"table.cell"});v.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps"});v.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells"});v.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells"});v=q.addMenu({title:"table.row"});v.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps"});v.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});v.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});v.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});v.addSeparator();v.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});v.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});v.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"}).setDisabled(!j);v.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"}).setDisabled(!j);v=q.addMenu({title:"table.col"});v.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});v.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});v.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{q.add({title:"table.desc",icon:"table",cmd:"mceInsertTable"})}})}if(!b.isIE){function n(){var q;for(q=l.getBody().lastChild;q&&q.nodeType==3&&!q.nodeValue.length;q=q.previousSibling){}if(q&&q.nodeName=="TABLE"){l.dom.add(l.getBody(),"p",null,'<br mce_bogus="1" />')}}if(b.isGecko){l.onKeyDown.add(function(r,t){var q,s,u=r.dom;if(t.keyCode==37||t.keyCode==38){q=r.selection.getRng();s=u.getParent(q.startContainer,"table");if(s&&r.getBody().firstChild==s){if(isAtStart(q,s)){q=u.createRng();q.setStartBefore(s);q.setEndBefore(s);r.selection.setRng(q);t.preventDefault()}}}})}l.onKeyUp.add(n);l.onSetContent.add(n);l.onVisualAid.add(n);l.onPreProcess.add(function(q,s){var r=s.node.lastChild;if(r&&r.childNodes.length==1&&r.firstChild.nodeName=="BR"){q.dom.remove(r)}});n()}});c({mceTableSplitCells:function(k){k.split()},mceTableMergeCells:function(l){var m,n,k;k=e.dom.getParent(e.selection.getNode(),"th,td");if(k){m=k.rowSpan;n=k.colSpan}if(!e.dom.select("td.mceSelected,th.mceSelected").length){d.open({url:f+"/merge_cells.htm",width:240+parseInt(e.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(e.getLang("table.merge_cells_delta_height",0)),inline:1},{rows:m,cols:n,onaction:function(o){l.merge(k,o.cols,o.rows)},plugin_url:f})}else{l.merge()}},mceTableInsertRowBefore:function(k){k.insertRow(true)},mceTableInsertRowAfter:function(k){k.insertRow()},mceTableInsertColBefore:function(k){k.insertCol(true)},mceTableInsertColAfter:function(k){k.insertCol()},mceTableDeleteCol:function(k){k.deleteCols()},mceTableDeleteRow:function(k){k.deleteRows()},mceTableCutRow:function(k){j=k.cutRows()},mceTableCopyRow:function(k){j=k.copyRows()},mceTablePasteRowBefore:function(k){k.pasteRows(j,true)},mceTablePasteRowAfter:function(k){k.pasteRows(j)},mceTableDelete:function(k){k.deleteTable()}},function(l,k){e.addCommand(k,function(){var m=h();if(m){l(m);e.execCommand("mceRepaint");g()}})});c({mceInsertTable:function(k){d.open({url:f+"/table.htm",width:400+parseInt(e.getLang("table.table_delta_width",0)),height:320+parseInt(e.getLang("table.table_delta_height",0)),inline:1},{plugin_url:f,action:k?k.action:0})},mceTableRowProps:function(){d.open({url:f+"/row.htm",width:400+parseInt(e.getLang("table.rowprops_delta_width",0)),height:295+parseInt(e.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:f})},mceTableCellProps:function(){d.open({url:f+"/cell.htm",width:400+parseInt(e.getLang("table.cellprops_delta_width",0)),height:295+parseInt(e.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:f})}},function(l,k){e.addCommand(k,function(m,n){l(n)})})}});b.PluginManager.add("table",b.plugins.TablePlugin)})(tinymce);
\ No newline at end of file
+(function(c){var d=c.each;function b(f,g){var h=g.ownerDocument,e=h.createRange(),j;e.setStartBefore(g);e.setEnd(f.endContainer,f.endOffset);j=h.createElement("body");j.appendChild(e.cloneContents());return j.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi,"-").replace(/<[^>]+>/g,"").length==0}function a(H,G,K){var f,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;f=[];d(["thead","tbody","tfoot"],function(N){var O=G.select("> "+N+" tr",H);d(O,function(P,Q){Q+=M;d(G.select("> td, > th",P),function(W,R){var S,T,U,V;if(f[Q]){while(f[Q][R]){R++}}U=h(W,"rowspan");V=h(W,"colspan");for(T=Q;T<Q+U;T++){if(!f[T]){f[T]=[]}for(S=R;S<R+V;S++){f[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=f[O];if(N){return N[M]}}function h(N,M){return parseInt(N.getAttribute(M)||1)}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=[];d(H.rows,function(N){d(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 e(M){var N;c.walk(M,function(P){var O;if(P.nodeType==3){d(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=c.isIE?"&nbsp;":'<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(!c.isIE){M.innerHTML='<br data-mce-bogus="1" />'}}return M}function q(){var M=G.createRng();d(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}d(G.select("thead,tbody,tfoot",H),function(N){if(N.rows.length==0){G.remove(N)}});t();row=f[Math.min(f.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=f[Q][S].elm.parentNode;for(M=1;M<=U;M++){P=G.getNext(P,"tr");if(P){for(N=S;N>=0;N--){T=f[Q+M][N].elm;if(T.parentNode==P){for(O=1;O<=R;O++){G.insertAfter(e(T),T)}break}}if(N==-1){for(O=1;O<=R;O++){P.insertBefore(e(P.cells[0]),P.cells[0])}}}}}function C(){d(f,function(M,N){d(M,function(P,O){var S,R,T,Q;if(j(P)){P=P.elm;S=h(P,"colspan");R=h(P,"rowspan");if(S>1||R>1){s(P,"rowSpan",1);s(P,"colSpan",1);for(Q=0;Q<S-1;Q++){G.insertAfter(e(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(!f[R]||!f[R][U]){continue}V=f[R][U].elm;if(V!=T){N=c.grep(V.childNodes);d(N,function(Z){T.appendChild(Z)});if(N.length){N=c.grep(T.childNodes);Q=0;d(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;d(f,function(W,X){d(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<f[0].length;R++){if(!f[M][R]){continue}S=f[M][R].elm;if(S!=P){if(!Q){O=h(S,"rowspan");if(O>1){s(S,"rowSpan",O+1);continue}}else{if(M>0&&f[M-1][R]){V=f[M-1][R].elm;O=h(V,"rowSpan");if(O>1){s(V,"rowSpan",O+1);continue}}}N=e(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 g(N){var O,M;d(f,function(P,Q){d(P,function(S,R){if(j(S)){O=R;if(N){return false}}});if(N){return !O}});d(f,function(S,T){var P,Q,R;if(!S[O]){return}P=S[O].elm;if(P!=M){R=h(P,"colspan");Q=h(P,"rowspan");if(R==1){if(!N){G.insertAfter(e(P),P);u(O,T,Q-1,R)}else{P.parentNode.insertBefore(e(P),P);u(O,T,Q-1,R)}}else{s(P,"colSpan",P.colSpan+1)}M=P}})}function n(){var M=[];d(f,function(N,O){d(N,function(Q,P){if(j(Q)&&c.inArray(M,P)===-1){d(f,function(T){var R=T[P].elm,S;S=h(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");d(Q.cells,function(S){var T=h(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]);d(f[R.y],function(S){var T;S=S.elm;if(S!=O){T=h(S,"rowSpan");if(T<=1){G.remove(S)}else{s(S,"rowSpan",T-1)}O=S}})}N=k();d(N.reverse(),function(O){M(O)});q()}function E(){var M=k();G.remove(M);q();return M}function J(){var M=k();d(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;d(f,function(S){var R;Q=0;d(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()}d(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(e(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;d(f,function(O,P){d(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;d(f,function(P,Q){d(P,function(S,R){var U,T;if(j(S)){S=f[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=f[y][P];if(!S.real){if(P-(S.colspan-1)<P){P-=S.colspan-1}}}for(x=P;x<=N;x++){S=f[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=f[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(f[y][x]){G.addClass(f[y][x].elm,"mceSelected")}}}}}c.extend(this,{deleteTable:r,split:C,merge:p,insertRow:l,insertCol:g,deleteCols:n,deleteRows:m,cutRows:E,copyRows:J,pasteRows:B,getPos:F,setStartCell:w,setEndCell:v})}c.create("tinymce.plugins.TablePlugin",{init:function(f,g){var e,k;function j(n){var m=f.selection,l=f.dom.getParent(n||m.getNode(),"table");if(l){return new a(l,f.dom,m)}}function h(){f.getBody().style.webkitUserSelect="";f.dom.removeClass(f.dom.select("td.mceSelected,th.mceSelected"),"mceSelected")}d([["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(l){f.addButton(l[0],{title:l[1],cmd:l[2],ui:l[3]})});if(!c.isIE){f.onClick.add(function(l,m){m=m.target;if(m.nodeName==="TABLE"){l.selection.select(m);l.nodeChanged()}})}f.onPreProcess.add(function(m,n){var l,o,p,r=m.dom,q;l=r.select("table",n.node);o=l.length;while(o--){p=l[o];r.setAttrib(p,"data-mce-style","");if((q=r.getAttrib(p,"width"))){r.setStyle(p,"width",q);r.setAttrib(p,"width","")}if((q=r.getAttrib(p,"height"))){r.setStyle(p,"height",q);r.setAttrib(p,"height","")}}});f.onNodeChange.add(function(m,l,q){var o;q=m.selection.getStart();o=m.dom.getParent(q,"td,th,caption");l.setActive("table",q.nodeName==="TABLE"||!!o);if(o&&o.nodeName==="CAPTION"){o=0}l.setDisabled("delete_table",!o);l.setDisabled("delete_col",!o);l.setDisabled("delete_table",!o);l.setDisabled("delete_row",!o);l.setDisabled("col_after",!o);l.setDisabled("col_before",!o);l.setDisabled("row_after",!o);l.setDisabled("row_before",!o);l.setDisabled("row_props",!o);l.setDisabled("cell_props",!o);l.setDisabled("split_cells",!o);l.setDisabled("merge_cells",!o)});f.onInit.add(function(m){var l,p,q=m.dom,n;e=m.windowManager;m.onMouseDown.add(function(r,s){if(s.button!=2){h();p=q.getParent(s.target,"td,th");l=q.getParent(p,"table")}});q.bind(m.getDoc(),"mouseover",function(v){var t,s,u=v.target;if(p&&(n||u!=p)&&(u.nodeName=="TD"||u.nodeName=="TH")){s=q.getParent(u,"table");if(s==l){if(!n){n=j(s);n.setStartCell(p);m.getBody().style.webkitUserSelect="none"}n.setEndCell(u)}t=m.selection.getSel();try{if(t.removeAllRanges){t.removeAllRanges()}else{t.empty()}}catch(r){}v.preventDefault()}});m.onMouseUp.add(function(A,B){var s,u=A.selection,C,D=u.getSel(),r,v,t,z;if(p){if(n){A.getBody().style.webkitUserSelect=""}function w(E,G){var F=new c.dom.TreeWalker(E,E);do{if(E.nodeType==3&&c.trim(E.nodeValue).length!=0){if(G){s.setStart(E,0)}else{s.setEnd(E,E.nodeValue.length)}return}if(E.nodeName=="BR"){if(G){s.setStartBefore(E)}else{s.setEndBefore(E)}return}}while(E=(G?F.next():F.prev()))}C=q.select("td.mceSelected,th.mceSelected");if(C.length>0){s=q.createRng();v=C[0];z=C[C.length-1];w(v,1);r=new c.dom.TreeWalker(v,q.getParent(C[0],"table"));do{if(v.nodeName=="TD"||v.nodeName=="TH"){if(!q.hasClass(v,"mceSelected")){break}t=v}}while(v=r.next());w(t);u.setRng(s)}A.nodeChanged();p=n=l=null}});m.onKeyUp.add(function(r,s){h()});if(m&&m.plugins.contextmenu){m.plugins.contextmenu.onContextMenu.add(function(t,r,v){var w,u=m.selection,s=u.getNode()||m.getBody();if(m.dom.getParent(v,"td")||m.dom.getParent(v,"th")||m.dom.select("td.mceSelected,th.mceSelected").length){r.removeAll();if(s.nodeName=="A"&&!m.dom.getAttrib(s,"name")){r.add({title:"advanced.link_desc",icon:"link",cmd:m.plugins.advlink?"mceAdvLink":"mceLink",ui:true});r.add({title:"advanced.unlink_desc",icon:"unlink",cmd:"UnLink"});r.addSeparator()}if(s.nodeName=="IMG"&&s.className.indexOf("mceItem")==-1){r.add({title:"advanced.image_desc",icon:"image",cmd:m.plugins.advimage?"mceAdvImage":"mceImage",ui:true});r.addSeparator()}r.add({title:"table.desc",icon:"table",cmd:"mceInsertTable",value:{action:"insert"}});r.add({title:"table.props_desc",icon:"table_props",cmd:"mceInsertTable"});r.add({title:"table.del",icon:"delete_table",cmd:"mceTableDelete"});r.addSeparator();w=r.addMenu({title:"table.cell"});w.add({title:"table.cell_desc",icon:"cell_props",cmd:"mceTableCellProps"});w.add({title:"table.split_cells_desc",icon:"split_cells",cmd:"mceTableSplitCells"});w.add({title:"table.merge_cells_desc",icon:"merge_cells",cmd:"mceTableMergeCells"});w=r.addMenu({title:"table.row"});w.add({title:"table.row_desc",icon:"row_props",cmd:"mceTableRowProps"});w.add({title:"table.row_before_desc",icon:"row_before",cmd:"mceTableInsertRowBefore"});w.add({title:"table.row_after_desc",icon:"row_after",cmd:"mceTableInsertRowAfter"});w.add({title:"table.delete_row_desc",icon:"delete_row",cmd:"mceTableDeleteRow"});w.addSeparator();w.add({title:"table.cut_row_desc",icon:"cut",cmd:"mceTableCutRow"});w.add({title:"table.copy_row_desc",icon:"copy",cmd:"mceTableCopyRow"});w.add({title:"table.paste_row_before_desc",icon:"paste",cmd:"mceTablePasteRowBefore"}).setDisabled(!k);w.add({title:"table.paste_row_after_desc",icon:"paste",cmd:"mceTablePasteRowAfter"}).setDisabled(!k);w=r.addMenu({title:"table.col"});w.add({title:"table.col_before_desc",icon:"col_before",cmd:"mceTableInsertColBefore"});w.add({title:"table.col_after_desc",icon:"col_after",cmd:"mceTableInsertColAfter"});w.add({title:"table.delete_col_desc",icon:"delete_col",cmd:"mceTableDeleteCol"})}else{r.add({title:"table.desc",icon:"table",cmd:"mceInsertTable"})}})}if(!c.isIE){function o(){var r;for(r=m.getBody().lastChild;r&&r.nodeType==3&&!r.nodeValue.length;r=r.previousSibling){}if(r&&r.nodeName=="TABLE"){m.dom.add(m.getBody(),"p",null,'<br mce_bogus="1" />')}}if(c.isGecko){m.onKeyDown.add(function(s,u){var r,t,v=s.dom;if(u.keyCode==37||u.keyCode==38){r=s.selection.getRng();t=v.getParent(r.startContainer,"table");if(t&&s.getBody().firstChild==t){if(b(r,t)){r=v.createRng();r.setStartBefore(t);r.setEndBefore(t);s.selection.setRng(r);u.preventDefault()}}}})}m.onKeyUp.add(o);m.onSetContent.add(o);m.onVisualAid.add(o);m.onPreProcess.add(function(r,t){var s=t.node.lastChild;if(s&&s.childNodes.length==1&&s.firstChild.nodeName=="BR"){r.dom.remove(s)}});o()}});d({mceTableSplitCells:function(l){l.split()},mceTableMergeCells:function(m){var n,o,l;l=f.dom.getParent(f.selection.getNode(),"th,td");if(l){n=l.rowSpan;o=l.colSpan}if(!f.dom.select("td.mceSelected,th.mceSelected").length){e.open({url:g+"/merge_cells.htm",width:240+parseInt(f.getLang("table.merge_cells_delta_width",0)),height:110+parseInt(f.getLang("table.merge_cells_delta_height",0)),inline:1},{rows:n,cols:o,onaction:function(p){m.merge(l,p.cols,p.rows)},plugin_url:g})}else{m.merge()}},mceTableInsertRowBefore:function(l){l.insertRow(true)},mceTableInsertRowAfter:function(l){l.insertRow()},mceTableInsertColBefore:function(l){l.insertCol(true)},mceTableInsertColAfter:function(l){l.insertCol()},mceTableDeleteCol:function(l){l.deleteCols()},mceTableDeleteRow:function(l){l.deleteRows()},mceTableCutRow:function(l){k=l.cutRows()},mceTableCopyRow:function(l){k=l.copyRows()},mceTablePasteRowBefore:function(l){l.pasteRows(k,true)},mceTablePasteRowAfter:function(l){l.pasteRows(k)},mceTableDelete:function(l){l.deleteTable()}},function(m,l){f.addCommand(l,function(){var n=j();if(n){m(n);f.execCommand("mceRepaint");h()}})});d({mceInsertTable:function(l){e.open({url:g+"/table.htm",width:400+parseInt(f.getLang("table.table_delta_width",0)),height:320+parseInt(f.getLang("table.table_delta_height",0)),inline:1},{plugin_url:g,action:l?l.action:0})},mceTableRowProps:function(){e.open({url:g+"/row.htm",width:400+parseInt(f.getLang("table.rowprops_delta_width",0)),height:295+parseInt(f.getLang("table.rowprops_delta_height",0)),inline:1},{plugin_url:g})},mceTableCellProps:function(){e.open({url:g+"/cell.htm",width:400+parseInt(f.getLang("table.cellprops_delta_width",0)),height:295+parseInt(f.getLang("table.cellprops_delta_height",0)),inline:1},{plugin_url:g})}},function(m,l){f.addCommand(l,function(n,o){m(o)})})}});c.PluginManager.add("table",c.plugins.TablePlugin)})(tinymce);
\ No newline at end of file
index c2f307f045c2a4c3c5befb0176db93a3ce40c6b1..442e465c43a31db6ef418bdaa087c030489e7ecf 100644 (file)
 (function(tinymce) {\r
        var each = tinymce.each;\r
 \r
+       // Checks if the selection/caret is at the start of the specified block element\r
+       function isAtStart(rng, par) {\r
+               var doc = par.ownerDocument, rng2 = doc.createRange(), elm;\r
+\r
+               rng2.setStartBefore(par);\r
+               rng2.setEnd(rng.endContainer, rng.endOffset);\r
+\r
+               elm = doc.createElement('body');\r
+               elm.appendChild(rng2.cloneContents());\r
+\r
+               // Check for text characters of other elements that should be treated as content\r
+               return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length == 0;\r
+       };\r
+\r
        /**\r
         * Table Grid class.\r
         */\r
                        grid = [];\r
 \r
                        each(['thead', 'tbody', 'tfoot'], function(part) {\r
-                               var rows = dom.select(part + ' tr', table);\r
+                               var rows = dom.select('> ' + part + ' tr', table);\r
 \r
                                each(rows, function(tr, y) {\r
                                        y += startY;\r
 \r
-                                       each(dom.select('td,th', tr), function(td, x) {\r
+                                       each(dom.select('> td, > th', tr), function(td, x) {\r
                                                var x2, y2, rowspan, colspan;\r
 \r
                                                // Skip over existing cells produced by rowspan\r
                        return parseInt(td.getAttribute(name) || 1);\r
                };\r
 \r
+               function setSpanVal(td, name, val) {\r
+                       if (td) {\r
+                               val = parseInt(val);\r
+\r
+                               if (val === 1)\r
+                                       td.removeAttribute(name, 1);\r
+                               else\r
+                                       td.setAttribute(name, val, 1);\r
+                       }\r
+               }\r
+\r
                function isCellSelected(cell) {\r
-                       return dom.hasClass(cell.elm, 'mceSelected') || cell == selectedCell;\r
+                       return cell && (dom.hasClass(cell.elm, 'mceSelected') || cell == selectedCell);\r
                };\r
 \r
                function getSelectedRows() {\r
 \r
                                        // Add something to the inner node\r
                                        if (curNode)\r
-                                               curNode.innerHTML = tinymce.isIE ? '&nbsp;' : '<br _mce_bogus="1" />';\r
+                                               curNode.innerHTML = tinymce.isIE ? '&nbsp;' : '<br data-mce-bogus="1" />';\r
 \r
                                        return false;\r
                                }\r
                        }, 'childNodes');\r
 \r
                        cell = cloneNode(cell, false);\r
-                       cell.rowSpan = cell.colSpan = 1;\r
+                       setSpanVal(cell, 'rowSpan', 1);\r
+                       setSpanVal(cell, 'colSpan', 1);\r
 \r
                        if (formatNode) {\r
                                cell.appendChild(formatNode);\r
                        } else {\r
                                if (!tinymce.isIE)\r
-                                       cell.innerHTML = '<br _mce_bogus="1" />';\r
+                                       cell.innerHTML = '<br data-mce-bogus="1" />';\r
                        }\r
 \r
                        return cell;\r
                                                rowSpan = getSpanVal(cell, 'rowspan');\r
 \r
                                                if (colSpan > 1 || rowSpan > 1) {\r
-                                                       cell.colSpan = cell.rowSpan = 1;\r
+                                                       setSpanVal(cell, 'rowSpan', 1);\r
+                                                       setSpanVal(cell, 'colSpan', 1);\r
 \r
                                                        // Insert cells right\r
                                                        for (i = 0; i < colSpan - 1; i++)\r
                };\r
 \r
                function merge(cell, cols, rows) {\r
-                       var startX, startY, endX, endY, x, y, startCell, endCell, cell, children;\r
+                       var startX, startY, endX, endY, x, y, startCell, endCell, cell, children, count;\r
 \r
                        // Use specified cell and cols/rows\r
                        if (cell) {\r
 \r
                                // Set row/col span to start cell\r
                                startCell = getCell(startX, startY).elm;\r
-                               startCell.colSpan = (endX - startX) + 1;\r
-                               startCell.rowSpan = (endY - startY) + 1;\r
+                               setSpanVal(startCell, 'colSpan', (endX - startX) + 1);\r
+                               setSpanVal(startCell, 'rowSpan', (endY - startY) + 1);\r
 \r
                                // Remove other cells and add it's contents to the start cell\r
                                for (y = startY; y <= endY; y++) {\r
                                        for (x = startX; x <= endX; x++) {\r
+                                               if (!grid[y] || !grid[y][x])\r
+                                                       continue;\r
+\r
                                                cell = grid[y][x].elm;\r
 \r
                                                if (cell != startCell) {\r
                                                        // Move children to startCell\r
                                                        children = tinymce.grep(cell.childNodes);\r
-                                                       each(children, function(node, i) {\r
-                                                               // Jump over last BR element\r
-                                                               if (node.nodeName != 'BR' || i != children.length - 1)\r
-                                                                       startCell.appendChild(node);\r
+                                                       each(children, function(node) {\r
+                                                               startCell.appendChild(node);\r
                                                        });\r
 \r
+                                                       // Remove bogus nodes if there is children in the target cell\r
+                                                       if (children.length) {\r
+                                                               children = tinymce.grep(startCell.childNodes);\r
+                                                               count = 0;\r
+                                                               each(children, function(node) {\r
+                                                                       if (node.nodeName == 'BR' && dom.getAttrib(node, 'data-mce-bogus') && count++ < children.length - 1)\r
+                                                                               startCell.removeChild(node);\r
+                                                               });\r
+                                                       }\r
+                                                       \r
                                                        // Remove cell\r
                                                        dom.remove(cell);\r
                                                }\r
                };\r
 \r
                function insertRow(before) {\r
-                       var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell;\r
+                       var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell, rowSpan;\r
 \r
                        // Find first/last row\r
                        each(grid, function(row, y) {\r
                        });\r
 \r
                        for (x = 0; x < grid[0].length; x++) {\r
+                               // Cell not found could be because of an invalid table structure\r
+                               if (!grid[posY][x])\r
+                                       continue;\r
+\r
                                cell = grid[posY][x].elm;\r
 \r
                                if (cell != lastCell) {\r
                                        if (!before) {\r
                                                rowSpan = getSpanVal(cell, 'rowspan');\r
                                                if (rowSpan > 1) {\r
-                                                       cell.rowSpan = rowSpan + 1;\r
+                                                       setSpanVal(cell, 'rowSpan', rowSpan + 1);\r
                                                        continue;\r
                                                }\r
                                        } else {\r
                                                // Check if cell above can be expanded\r
                                                if (posY > 0 && grid[posY - 1][x]) {\r
                                                        otherCell = grid[posY - 1][x].elm;\r
-                                                       rowSpan = getSpanVal(otherCell, 'rowspan');\r
+                                                       rowSpan = getSpanVal(otherCell, 'rowSpan');\r
                                                        if (rowSpan > 1) {\r
-                                                               otherCell.rowSpan = rowSpan + 1;\r
+                                                               setSpanVal(otherCell, 'rowSpan', rowSpan + 1);\r
                                                                continue;\r
                                                        }\r
                                                }\r
                                        }\r
 \r
                                        // Insert new cell into new row\r
-                                       newCell = cloneCell(cell)\r
-                                       newCell.colSpan = cell.colSpan;\r
+                                       newCell = cloneCell(cell);\r
+                                       setSpanVal(newCell, 'colSpan', cell.colSpan);\r
+\r
                                        newRow.appendChild(newCell);\r
 \r
                                        lastCell = cell;\r
                        });\r
 \r
                        each(grid, function(row, y) {\r
-                               var cell = row[posX].elm, rowSpan, colSpan;\r
+                               var cell, rowSpan, colSpan;\r
+\r
+                               if (!row[posX])\r
+                                       return;\r
 \r
+                               cell = row[posX].elm;\r
                                if (cell != lastCell) {\r
                                        colSpan = getSpanVal(cell, 'colspan');\r
                                        rowSpan = getSpanVal(cell, 'rowspan');\r
                                                        fillLeftDown(posX, y, rowSpan - 1, colSpan);\r
                                                }\r
                                        } else\r
-                                               cell.colSpan++;\r
+                                               setSpanVal(cell, 'colSpan', cell.colSpan + 1);\r
 \r
                                        lastCell = cell;\r
                                }\r
                                                each(grid, function(row) {\r
                                                        var cell = row[x].elm, colSpan;\r
 \r
-                                                       colSpan = getSpanVal(cell, 'colspan');\r
+                                                       colSpan = getSpanVal(cell, 'colSpan');\r
 \r
                                                        if (colSpan > 1)\r
-                                                               cell.colSpan = colSpan - 1;\r
+                                                               setSpanVal(cell, 'colSpan', colSpan - 1);\r
                                                        else\r
                                                                dom.remove(cell);\r
                                                });\r
 \r
                                // Move down row spanned cells\r
                                each(tr.cells, function(cell) {\r
-                                       var rowSpan = getSpanVal(cell, 'rowspan');\r
+                                       var rowSpan = getSpanVal(cell, 'rowSpan');\r
 \r
                                        if (rowSpan > 1) {\r
-                                               cell.rowSpan = rowSpan - 1;\r
+                                               setSpanVal(cell, 'rowSpan', rowSpan - 1);\r
                                                pos = getPos(cell);\r
                                                fillLeftDown(pos.x, pos.y, 1, 1);\r
                                        }\r
                                        cell = cell.elm;\r
 \r
                                        if (cell != lastCell) {\r
-                                               rowSpan = getSpanVal(cell, 'rowspan');\r
+                                               rowSpan = getSpanVal(cell, 'rowSpan');\r
 \r
                                                if (rowSpan <= 1)\r
                                                        dom.remove(cell);\r
                                                else\r
-                                                       cell.rowSpan = rowSpan - 1;\r
+                                                       setSpanVal(cell, 'rowSpan', rowSpan - 1);\r
 \r
                                                lastCell = cell;\r
                                        }\r
                                // Remove col/rowspans\r
                                for (i = 0; i < cellCount; i++) {\r
                                        cell = row.cells[i];\r
-                                       cell.colSpan = cell.rowSpan = 1;\r
+                                       setSpanVal(cell, 'colSpan', 1);\r
+                                       setSpanVal(cell, 'rowSpan', 1);\r
                                }\r
 \r
                                // Needs more cells\r
 \r
                                // Add new selection\r
                                for (y = startY; y <= maxY; y++) {\r
-                                       for (x = startX; x <= maxX; x++)\r
-                                               dom.addClass(grid[y][x].elm, 'mceSelected');\r
+                                       for (x = startX; x <= maxX; x++) {\r
+                                               if (grid[y][x])\r
+                                                       dom.addClass(grid[y][x].elm, 'mceSelected');\r
+                                       }\r
                                }\r
                        }\r
                };\r
                                ed.onClick.add(function(ed, e) {\r
                                        e = e.target;\r
 \r
-                                       if (e.nodeName === 'TABLE')\r
+                                       if (e.nodeName === 'TABLE') {\r
                                                ed.selection.select(e);\r
+                                               ed.nodeChanged();\r
+                                       }\r
                                });\r
                        }\r
 \r
+                       ed.onPreProcess.add(function(ed, args) {\r
+                               var nodes, i, node, dom = ed.dom, value;\r
+\r
+                               nodes = dom.select('table', args.node);\r
+                               i = nodes.length;\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       dom.setAttrib(node, 'data-mce-style', '');\r
+\r
+                                       if ((value = dom.getAttrib(node, 'width'))) {\r
+                                               dom.setStyle(node, 'width', value);\r
+                                               dom.setAttrib(node, 'width', '');\r
+                                       }\r
+\r
+                                       if ((value = dom.getAttrib(node, 'height'))) {\r
+                                               dom.setStyle(node, 'height', value);\r
+                                               dom.setAttrib(node, 'height', '');\r
+                                       }\r
+                               }\r
+                       });\r
+\r
                        // Handle node change updates\r
                        ed.onNodeChange.add(function(ed, cm, n) {\r
                                var p;\r
                                                // Remove current selection\r
                                                sel = ed.selection.getSel();\r
 \r
-                                               if (sel.removeAllRanges)\r
-                                                       sel.removeAllRanges();\r
-                                               else\r
-                                                       sel.empty();\r
+                                               try {\r
+                                                       if (sel.removeAllRanges)\r
+                                                               sel.removeAllRanges();\r
+                                                       else\r
+                                                               sel.empty();\r
+                                               } catch (ex) {\r
+                                                       // IE9 might throw errors here\r
+                                               }\r
 \r
                                                e.preventDefault();\r
                                        }\r
index b5fc1fda3d701ab6399793ec530e1379c73db445..45e6061fd081a5f18894ff301afc54c69a36ffd0 100644 (file)
@@ -83,8 +83,6 @@ function updateAction() {
                return;\r
        }\r
 \r
-       ed.execCommand('mceBeginUndoLevel');\r
-\r
        switch (getSelectValue(formObj, 'action')) {\r
                case "cell":\r
                        var celltype = getSelectValue(formObj, 'celltype');\r
@@ -166,15 +164,15 @@ function updateCell(td, skip_id) {
        var dom = ed.dom;\r
 \r
        if (!skip_id)\r
-               td.setAttribute('id', formObj.id.value);\r
-\r
-       td.setAttribute('align', formObj.align.value);\r
-       td.setAttribute('vAlign', formObj.valign.value);\r
-       td.setAttribute('lang', formObj.lang.value);\r
-       td.setAttribute('dir', getSelectValue(formObj, 'dir'));\r
-       td.setAttribute('style', ed.dom.serializeStyle(ed.dom.parseStyle(formObj.style.value)));\r
-       td.setAttribute('scope', formObj.scope.value);\r
-       ed.dom.setAttrib(td, 'class', getSelectValue(formObj, 'class'));\r
+               dom.setAttrib(td, 'id', formObj.id.value);\r
+\r
+       dom.setAttrib(td, 'align', formObj.align.value);\r
+       dom.setAttrib(td, 'vAlign', formObj.valign.value);\r
+       dom.setAttrib(td, 'lang', formObj.lang.value);\r
+       dom.setAttrib(td, 'dir', getSelectValue(formObj, 'dir'));\r
+       dom.setAttrib(td, 'style', ed.dom.serializeStyle(ed.dom.parseStyle(formObj.style.value)));\r
+       dom.setAttrib(td, 'scope', formObj.scope.value);\r
+       dom.setAttrib(td, 'class', getSelectValue(formObj, 'class'));\r
 \r
        // Clear deprecated attributes\r
        ed.dom.setAttrib(td, 'width', '');\r
index 70d95b6729d78b16c9934f8fac9462e9bddb6aec..b275e6ea98c08301aabb6600d3a3d95c72b899a1 100644 (file)
@@ -80,8 +80,6 @@ function updateAction() {
                return;\r
        }\r
 \r
-       inst.execCommand('mceBeginUndoLevel');\r
-\r
        switch (action) {\r
                case "row":\r
                        updateRow(trElm);\r
@@ -123,19 +121,19 @@ function updateRow(tr_elm, skip_id, skip_parent) {
 \r
        // Update row element\r
        if (!skip_id)\r
-               tr_elm.setAttribute('id', formObj.id.value);\r
+               dom.setAttrib(tr_elm, 'id', formObj.id.value);\r
 \r
-       tr_elm.setAttribute('align', getSelectValue(formObj, 'align'));\r
-       tr_elm.setAttribute('vAlign', getSelectValue(formObj, 'valign'));\r
-       tr_elm.setAttribute('lang', formObj.lang.value);\r
-       tr_elm.setAttribute('dir', getSelectValue(formObj, 'dir'));\r
-       tr_elm.setAttribute('style', dom.serializeStyle(dom.parseStyle(formObj.style.value)));\r
+       dom.setAttrib(tr_elm, 'align', getSelectValue(formObj, 'align'));\r
+       dom.setAttrib(tr_elm, 'vAlign', getSelectValue(formObj, 'valign'));\r
+       dom.setAttrib(tr_elm, 'lang', formObj.lang.value);\r
+       dom.setAttrib(tr_elm, 'dir', getSelectValue(formObj, 'dir'));\r
+       dom.setAttrib(tr_elm, 'style', dom.serializeStyle(dom.parseStyle(formObj.style.value)));\r
        dom.setAttrib(tr_elm, 'class', getSelectValue(formObj, 'class'));\r
 \r
        // Clear deprecated attributes\r
-       tr_elm.setAttribute('background', '');\r
-       tr_elm.setAttribute('bgColor', '');\r
-       tr_elm.setAttribute('height', '');\r
+       dom.setAttrib(tr_elm, 'background', '');\r
+       dom.setAttrib(tr_elm, 'bgColor', '');\r
+       dom.setAttrib(tr_elm, 'height', '');\r
 \r
        // Set styles\r
        tr_elm.style.height = getCSSSize(formObj.height.value);\r
@@ -163,13 +161,10 @@ function updateRow(tr_elm, skip_id, skip_parent) {
                if (newParent == null) {\r
                        newParent = doc.createElement(dest);\r
 \r
-                       if (dest == "thead") {\r
-                               if (theTable.firstChild.nodeName == 'CAPTION')\r
-                                       inst.dom.insertAfter(newParent, theTable.firstChild);\r
-                               else\r
-                                       theTable.insertBefore(newParent, theTable.firstChild);\r
-                       } else\r
-                               theTable.appendChild(newParent);\r
+                       if (theTable.firstChild.nodeName == 'CAPTION')\r
+                               inst.dom.insertAfter(newParent, theTable.firstChild);\r
+                       else\r
+                               theTable.insertBefore(newParent, theTable.firstChild);\r
                }\r
 \r
                // append the row to the new parent\r
index d1b42c2af0dc43596c3576f0499253337d3ede14..520d857fcee05a41563523e7b2836f7708070ede 100644 (file)
@@ -12,7 +12,7 @@ function insertTable() {
        tinyMCEPopup.restoreSelection();\r
 \r
        if (!AutoValidator.validate(formObj)) {\r
-               tinyMCEPopup.alert(inst.getLang('invalid_data'));\r
+               tinyMCEPopup.alert(AutoValidator.getErrorMessages(formObj).join('. ') + '.');\r
                return false;\r
        }\r
 \r
@@ -21,7 +21,7 @@ function insertTable() {
        // Get form data\r
        cols = formObj.elements['cols'].value;\r
        rows = formObj.elements['rows'].value;\r
-       border = formObj.elements['border'].value != "" ? formObj.elements['border'].value  : 0;\r
+       border = formObj.elements['border'].value != "" ? formObj.elements['border'].value : 0;\r
        cellpadding = formObj.elements['cellpadding'].value != "" ? formObj.elements['cellpadding'].value : "";\r
        cellspacing = formObj.elements['cellspacing'].value != "" ? formObj.elements['cellspacing'].value : "";\r
        align = getSelectValue(formObj, "align");\r
@@ -58,8 +58,6 @@ function insertTable() {
 \r
        // Update table\r
        if (action == "update") {\r
-               inst.execCommand('mceBeginUndoLevel');\r
-\r
                dom.setAttrib(elm, 'cellPadding', cellpadding, true);\r
                dom.setAttrib(elm, 'cellSpacing', cellspacing, true);\r
                dom.setAttrib(elm, 'border', border);\r
@@ -82,7 +80,7 @@ function insertTable() {
                        capEl = elm.ownerDocument.createElement('caption');\r
 \r
                        if (!tinymce.isIE)\r
-                               capEl.innerHTML = '<br _mce_bogus="1"/>';\r
+                               capEl.innerHTML = '<br data-mce-bogus="1"/>';\r
 \r
                        elm.insertBefore(capEl, elm.firstChild);\r
                }\r
@@ -151,7 +149,7 @@ function insertTable() {
        html += makeAttrib('border', border);\r
        html += makeAttrib('cellpadding', cellpadding);\r
        html += makeAttrib('cellspacing', cellspacing);\r
-       html += makeAttrib('_mce_new', '1');\r
+       html += makeAttrib('data-mce-new', '1');\r
 \r
        if (width && inst.settings.inline_styles) {\r
                if (style)\r
@@ -187,7 +185,7 @@ function insertTable() {
 \r
        if (caption) {\r
                if (!tinymce.isIE)\r
-                       html += '<caption><br _mce_bogus="1"/></caption>';\r
+                       html += '<caption><br data-mce-bogus="1"/></caption>';\r
                else\r
                        html += '<caption></caption>';\r
        }\r
@@ -197,7 +195,7 @@ function insertTable() {
 \r
                for (var x=0; x<cols; x++) {\r
                        if (!tinymce.isIE)\r
-                               html += '<td><br _mce_bogus="1"/></td>';\r
+                               html += '<td><br data-mce-bogus="1"/></td>';\r
                        else\r
                                html += '<td></td>';\r
                }\r
@@ -207,8 +205,6 @@ function insertTable() {
 \r
        html += "</table>";\r
 \r
-       inst.execCommand('mceBeginUndoLevel');\r
-\r
        // Move table\r
        if (inst.settings.fix_table_elements) {\r
                var patt = '';\r
@@ -231,13 +227,18 @@ function insertTable() {
        } else\r
                inst.execCommand('mceInsertContent', false, html);\r
 \r
-       tinymce.each(dom.select('table[_mce_new]'), function(node) {\r
+       tinymce.each(dom.select('table[data-mce-new]'), function(node) {\r
                var td = dom.select('td', node);\r
 \r
-               inst.selection.select(td[0], true);\r
-               inst.selection.collapse();\r
+               try {\r
+                       // IE9 might fail to do this selection\r
+                       inst.selection.select(td[0], true);\r
+                       inst.selection.collapse();\r
+               } catch (ex) {\r
+                       // Ignore\r
+               }\r
 \r
-               dom.setAttrib(node, '_mce_new', '');\r
+               dom.setAttrib(node, 'data-mce-new', '');\r
        });\r
 \r
        inst.addVisual();\r
@@ -279,7 +280,7 @@ function init() {
 \r
        var cols = 2, rows = 2, border = tinyMCEPopup.getParam('table_default_border', '0'), cellpadding = tinyMCEPopup.getParam('table_default_cellpadding', ''), cellspacing = tinyMCEPopup.getParam('table_default_cellspacing', '');\r
        var align = "", width = "", height = "", bordercolor = "", bgcolor = "", className = "";\r
-       var id = "", summary = "", style = "", dir = "", lang = "", background = "", bgcolor = "", bordercolor = "", rules, frame;\r
+       var id = "", summary = "", style = "", dir = "", lang = "", background = "", bgcolor = "", bordercolor = "", rules = "", frame = "";\r
        var inst = tinyMCEPopup.editor, dom = inst.dom;\r
        var formObj = document.forms[0];\r
        var elm = dom.getParent(inst.selection.getNode(), "table");\r
index 000332a35da4924d5764b00991d93fb1eb4269a1..8352d9ffa19b88e391508c5113413802cd9a8b00 100644 (file)
@@ -7,7 +7,7 @@ rowtype:"Row in table part",
 title:"Insert/Modify table",\r
 width:"Width",\r
 height:"Height",\r
-cols:"Cols",\r
+cols:"Columns",\r
 rows:"Rows",\r
 cellspacing:"Cellspacing",\r
 cellpadding:"Cellpadding",\r
index 9736ed8c03f09248ed515235d963d0fb05d57567..d231090e7988149d0bd087828c4fdbdd4c3f3b51 100644 (file)
@@ -7,20 +7,20 @@
        <script type="text/javascript" src="../../utils/validate.js"></script>\r
        <script type="text/javascript" src="js/merge_cells.js"></script>\r
 </head>\r
-<body style="margin: 8px">\r
+<body style="margin: 8px" role="application">\r
 <form onsubmit="MergeCellsDialog.merge();return false;" action="#">\r
        <fieldset>\r
                <legend>{#table_dlg.merge_cells_title}</legend>\r
-                 <table border="0" cellpadding="0" cellspacing="3" width="100%">\r
-                         <tr>\r
-                               <td>{#table_dlg.cols}:</td>\r
-                               <td align="right"><input type="text" name="numcols" value="" class="number min1 mceFocus" style="width: 30px" /></td>\r
-                         </tr>\r
-                         <tr>\r
-                               <td>{#table_dlg.rows}:</td>\r
-                               <td align="right"><input type="text" name="numrows" value="" class="number min1" style="width: 30px" /></td>\r
-                         </tr>\r
-                 </table>\r
+               <table role="presentation" border="0" cellpadding="0" cellspacing="3" width="100%">\r
+                       <tr>\r
+                               <td><label for="numcols">{#table_dlg.cols}</label>:</td>\r
+                               <td align="right"><input type="text" id="numcols" name="numcols" value="" class="number min1 mceFocus" style="width: 30px" aria-required="true" /></td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td><label for="numrows">{#table_dlg.rows}</label>:</td>\r
+                               <td align="right"><input type="text" id="numrows" name="numrows" value="" class="number min1" style="width: 30px" aria-required="true" /></td>\r
+                       </tr>\r
+               </table>\r
        </fieldset>\r
 \r
        <div class="mceActionPanel">\r
index 092e6c8270e23825ce47634d98ca6847e83d37dd..c197ff6c7099373d9377b30583eaf96a80f25b1b 100644 (file)
@@ -9,12 +9,12 @@
        <script type="text/javascript" src="js/row.js"></script>\r
        <link href="css/row.css" rel="stylesheet" type="text/css" />\r
 </head>\r
-<body id="tablerow" style="display: none">\r
+<body id="tablerow" style="display: none" role="application">\r
        <form onsubmit="updateAction();return false;" action="#">\r
                <div class="tabs">\r
                        <ul>\r
-                               <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#table_dlg.general_tab}</a></span></li>\r
-                               <li id="advanced_tab"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#table_dlg.advanced_tab}</a></span></li>\r
+                               <li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#table_dlg.general_tab}</a></span></li>\r
+                               <li id="advanced_tab" aria-controls="advanced_panel"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#table_dlg.advanced_tab}</a></span></li>\r
                        </ul>\r
                </div>\r
 \r
@@ -23,7 +23,7 @@
                                <fieldset>\r
                                        <legend>{#table_dlg.general_props}</legend>\r
 \r
-                                       <table border="0" cellpadding="4" cellspacing="0">\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0">\r
                                                <tr>\r
                                                        <td><label for="rowtype">{#table_dlg.rowtype}</label></td>\r
                                                        <td class="col2">\r
@@ -80,7 +80,7 @@
                                <fieldset>\r
                                        <legend>{#table_dlg.advanced_props}</legend>\r
 \r
-                                       <table border="0" cellpadding="0" cellspacing="4">\r
+                                       <table role="presentation" border="0" cellpadding="0" cellspacing="4">\r
                                                <tr>\r
                                                        <td class="column1"><label for="id">{#table_dlg.id}</label></td> \r
                                                        <td><input id="id" name="id" type="text" value="" style="width: 200px" /></td> \r
                                                <tr>\r
                                                        <td class="column1"><label for="backgroundimage">{#table_dlg.bgimage}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="backgroundimage" name="backgroundimage" type="text" value="" style="width: 200px" onchange="changedBackgroundImage();" /></td>\r
                                                                                <td id="backgroundimagebrowsercontainer">&nbsp;</td>\r
                                                </tr>\r
 \r
                                                <tr>\r
-                                                       <td class="column1"><label for="bgcolor">{#table_dlg.bgcolor}</label></td> \r
+                                                       <td class="column1"><label for="bgcolor" id="bgcolor_label">{#table_dlg.bgcolor}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <span role="group" aria-labelledby="bgcolor_label">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');changedColor();" /></td>\r
                                                                                <td id="bgcolor_pickcontainer">&nbsp;</td>\r
                                                                        </tr>\r
                                                                </table>\r
+                                                               </span>\r
                                                        </td> \r
                                                </tr>\r
                                        </table>\r
index f269039228dbe343035e21544b92378aa230fe11..4a873b0a6f9c3902de7d662cad86834fc2e3a6dd 100644 (file)
        <script type="text/javascript" src="js/table.js"></script>\r
        <link href="css/table.css" rel="stylesheet" type="text/css" />\r
 </head>\r
-<body id="table" style="display: none">\r
+<body id="table" style="display: none" role="application" aria-labelledby="app_title">\r
+       <span style="display:none;" id="app_title">{#table_dlg.title}</span>\r
        <form onsubmit="insertTable();return false;" action="#">\r
                <div class="tabs">\r
                        <ul>\r
-                               <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#table_dlg.general_tab}</a></span></li>\r
-                               <li id="advanced_tab"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#table_dlg.advanced_tab}</a></span></li>\r
+                               <li id="general_tab" aria-controls="general_panel" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#table_dlg.general_tab}</a></span></li>\r
+                               <li id="advanced_tab" aria-controls="advanced_panel"><span><a href="javascript:mcTabs.displayTab('advanced_tab','advanced_panel');" onmousedown="return false;">{#table_dlg.advanced_tab}</a></span></li>\r
                        </ul>\r
                </div>\r
 \r
                        <div id="general_panel" class="panel current">\r
                                <fieldset>\r
                                        <legend>{#table_dlg.general_props}</legend>\r
-                                         <table border="0" cellpadding="4" cellspacing="0" width="100%">\r
-                                                         <tr>\r
-                                                               <td><label id="colslabel" for="cols">{#table_dlg.cols}</label></td>\r
-                                                               <td><input id="cols" name="cols" type="text" value="" size="3" maxlength="3" class="required number min1 mceFocus" /></td>\r
-                                                               <td><label id="rowslabel" for="rows">{#table_dlg.rows}</label></td>\r
-                                                               <td><input id="rows" name="rows" type="text" value="" size="3" maxlength="3" class="required number min1" /></td>\r
-                                                         </tr>\r
-                                                         <tr>\r
-                                                               <td><label id="cellpaddinglabel" for="cellpadding">{#table_dlg.cellpadding}</label></td>\r
-                                                               <td><input id="cellpadding" name="cellpadding" type="text" value="" size="3" maxlength="3" class="number" /></td>\r
-                                                               <td><label id="cellspacinglabel" for="cellspacing">{#table_dlg.cellspacing}</label></td>\r
-                                                               <td><input id="cellspacing" name="cellspacing" type="text" value="" size="3" maxlength="3" class="number" /></td>\r
-                                                         </tr>\r
-                                                         <tr>\r
-                                                               <td><label id="alignlabel" for="align">{#table_dlg.align}</label></td>\r
-                                                               <td><select id="align" name="align">\r
-                                                                       <option value="">{#not_set}</option>\r
-                                                                       <option value="center">{#table_dlg.align_middle}</option>\r
-                                                                       <option value="left">{#table_dlg.align_left}</option>\r
-                                                                       <option value="right">{#table_dlg.align_right}</option>\r
-                                                                 </select></td>\r
-                                                               <td><label id="borderlabel" for="border">{#table_dlg.border}</label></td>\r
-                                                               <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" onchange="changedBorder();" class="number" /></td>\r
-                                                         </tr>\r
-                                                         <tr id="width_row">\r
-                                                               <td><label id="widthlabel" for="width">{#table_dlg.width}</label></td>\r
-                                                               <td><input name="width" type="text" id="width" value="" size="4" maxlength="4" onchange="changedSize();" class="size" /></td>\r
-                                                               <td><label id="heightlabel" for="height">{#table_dlg.height}</label></td>\r
-                                                               <td><input name="height" type="text" id="height" value="" size="4" maxlength="4" onchange="changedSize();" class="size" /></td>\r
-                                                         </tr>\r
-                                                         <tr id="styleSelectRow">\r
-                                                               <td><label id="classlabel" for="class">{#class_name}</label></td>\r
-                                                               <td colspan="3">\r
-                                                                <select id="class" name="class" class="mceEditableSelect">\r
-                                                                       <option value="" selected="selected">{#not_set}</option>\r
-                                                                </select></td>\r
-                                                         </tr>\r
-                                                         <tr>\r
-                                                               <td class="column1"><label for="caption">{#table_dlg.caption}</label></td> \r
-                                                               <td><input id="caption" name="caption" type="checkbox" class="checkbox" value="true" /></td> \r
-                                                         </tr>\r
-                                                       </table>\r
+                                       <table role="presentation" border="0" cellpadding="4" cellspacing="0" width="100%">\r
+                                               <tr>\r
+                                                       <td><label id="colslabel" for="cols">{#table_dlg.cols}</label></td>\r
+                                                       <td><input id="cols" name="cols" type="text" value="" size="3" maxlength="3" class="required number min1 mceFocus" aria-required="true" /></td>\r
+                                                       <td><label id="rowslabel" for="rows">{#table_dlg.rows}</label></td>\r
+                                                       <td><input id="rows" name="rows" type="text" value="" size="3" maxlength="3" class="required number min1" aria-required="true" /></td>\r
+                                               </tr>\r
+                                               <tr>\r
+                                                       <td><label id="cellpaddinglabel" for="cellpadding">{#table_dlg.cellpadding}</label></td>\r
+                                                       <td><input id="cellpadding" name="cellpadding" type="text" value="" size="3" maxlength="3" class="number" /></td>\r
+                                                       <td><label id="cellspacinglabel" for="cellspacing">{#table_dlg.cellspacing}</label></td>\r
+                                                       <td><input id="cellspacing" name="cellspacing" type="text" value="" size="3" maxlength="3" class="number" /></td>\r
+                                               </tr>\r
+                                               <tr>\r
+                                                       <td><label id="alignlabel" for="align">{#table_dlg.align}</label></td>\r
+                                                       <td><select id="align" name="align">\r
+                                                               <option value="">{#not_set}</option>\r
+                                                               <option value="center">{#table_dlg.align_middle}</option>\r
+                                                               <option value="left">{#table_dlg.align_left}</option>\r
+                                                               <option value="right">{#table_dlg.align_right}</option>\r
+                                                       </select></td>\r
+                                                       <td><label id="borderlabel" for="border">{#table_dlg.border}</label></td>\r
+                                                       <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" onchange="changedBorder();" class="number" /></td>\r
+                                               </tr>\r
+                                               <tr id="width_row">\r
+                                                       <td><label id="widthlabel" for="width">{#table_dlg.width}</label></td>\r
+                                                       <td><input name="width" type="text" id="width" value="" size="4" maxlength="4" onchange="changedSize();" class="size" /></td>\r
+                                                       <td><label id="heightlabel" for="height">{#table_dlg.height}</label></td>\r
+                                                       <td><input name="height" type="text" id="height" value="" size="4" maxlength="4" onchange="changedSize();" class="size" /></td>\r
+                                               </tr>\r
+                                               <tr id="styleSelectRow" >\r
+                                                       <td><label id="classlabel" for="class">{#class_name}</label></td>\r
+                                                       <td colspan="3" >\r
+                                                        <select id="class" name="class" class="mceEditableSelect">\r
+                                                               <option value="" selected="selected">{#not_set}</option>\r
+                                                        </select></td>\r
+                                               </tr>\r
+                                               <tr>\r
+                                                       <td class="column1" ><label for="caption">{#table_dlg.caption}</label></td> \r
+                                                       <td><input id="caption" name="caption" type="checkbox" class="checkbox" value="true" /></td> \r
+                                               </tr>\r
+                                       </table>\r
                                </fieldset>\r
                        </div>\r
 \r
@@ -72,7 +73,7 @@
                                <fieldset>\r
                                        <legend>{#table_dlg.advanced_props}</legend>\r
 \r
-                                       <table border="0" cellpadding="0" cellspacing="4">\r
+                                       <table role="presentation" border="0" cellpadding="0" cellspacing="4">\r
                                                <tr>\r
                                                        <td class="column1"><label for="id">{#table_dlg.id}</label></td> \r
                                                        <td><input id="id" name="id" type="text" value="" class="advfield" /></td> \r
@@ -98,7 +99,7 @@
                                                <tr>\r
                                                        <td class="column1"><label for="backgroundimage">{#table_dlg.bgimage}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" aria-labelledby="backgroundimage_label" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="backgroundimage" name="backgroundimage" type="text" value="" class="advfield" onchange="changedBackgroundImage();" /></td>\r
                                                                                <td id="backgroundimagebrowsercontainer">&nbsp;</td>\r
                                                        </td> \r
                                                </tr>\r
 \r
-                                               <tr>\r
-                                                       <td class="column1"><label for="bordercolor">{#table_dlg.bordercolor}</label></td> \r
+                                               <tr role="group" aria-labelledby="bordercolor_label">\r
+                                                       <td class="column1"><label id="bordercolor_label" for="bordercolor">{#table_dlg.bordercolor}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="bordercolor" name="bordercolor" type="text" value="" size="9" onchange="updateColor('bordercolor_pick','bordercolor');changedColor();" /></td>\r
                                                                                <td id="bordercolor_pickcontainer">&nbsp;</td>\r
                                                        </td> \r
                                                </tr>\r
 \r
-                                               <tr>\r
-                                                       <td class="column1"><label for="bgcolor">{#table_dlg.bgcolor}</label></td> \r
+                                               <tr role="group" aria-labelledby="bgcolor_label">\r
+                                                       <td class="column1"><label id="bgcolor_label" for="bgcolor">{#table_dlg.bgcolor}</label></td> \r
                                                        <td>\r
-                                                               <table border="0" cellpadding="0" cellspacing="0">\r
+                                                               <table role="presentation" border="0" cellpadding="0" cellspacing="0">\r
                                                                        <tr>\r
                                                                                <td><input id="bgcolor" name="bgcolor" type="text" value="" size="9" onchange="updateColor('bgcolor_pick','bgcolor');changedColor();" /></td>\r
                                                                                <td id="bgcolor_pickcontainer">&nbsp;</td>\r
index 53d31c44faf0c13ab35f56815525e1a4c9b24b53..1a148e8b4fc57cf41baf0f72bb4c0744ef4780ff 100644 (file)
@@ -1 +1 @@
-(function(){tinymce.create("tinymce.plugins.VisualChars",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceVisualChars",c._toggleVisualChars,c);a.addButton("visualchars",{title:"visualchars.desc",cmd:"mceVisualChars"});a.onBeforeGetContent.add(function(d,e){if(c.state){c.state=true;c._toggleVisualChars()}})},getInfo:function(){return{longname:"Visual characters",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualchars",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_toggleVisualChars:function(){var m=this,g=m.editor,a,e,f,k=g.getDoc(),l=g.getBody(),j,n=g.selection,c;m.state=!m.state;g.controlManager.setActive("visualchars",m.state);if(m.state){a=[];tinymce.walk(l,function(b){if(b.nodeType==3&&b.nodeValue&&b.nodeValue.indexOf("\u00a0")!=-1){a.push(b)}},"childNodes");for(e=0;e<a.length;e++){j=a[e].nodeValue;j=j.replace(/(\u00a0+)/g,'<span class="mceItemHidden mceVisualNbsp">$1</span>');j=j.replace(/\u00a0/g,"\u00b7");g.dom.setOuterHTML(a[e],j,k)}}else{a=tinymce.grep(g.dom.select("span",l),function(b){return g.dom.hasClass(b,"mceVisualNbsp")});for(e=0;e<a.length;e++){g.dom.setOuterHTML(a[e],a[e].innerHTML.replace(/(&middot;|\u00b7)/g,"&nbsp;"),k)}}}});tinymce.PluginManager.add("visualchars",tinymce.plugins.VisualChars)})();
\ No newline at end of file
+(function(){tinymce.create("tinymce.plugins.VisualChars",{init:function(a,b){var c=this;c.editor=a;a.addCommand("mceVisualChars",c._toggleVisualChars,c);a.addButton("visualchars",{title:"visualchars.desc",cmd:"mceVisualChars"});a.onBeforeGetContent.add(function(d,e){if(c.state&&e.format!="raw"&&!e.draft){c.state=true;c._toggleVisualChars(false)}})},getInfo:function(){return{longname:"Visual characters",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",infourl:"http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/visualchars",version:tinymce.majorVersion+"."+tinymce.minorVersion}},_toggleVisualChars:function(m){var p=this,k=p.editor,a,g,j,n=k.getDoc(),o=k.getBody(),l,q=k.selection,e,c,f;p.state=!p.state;k.controlManager.setActive("visualchars",p.state);if(m){f=q.getBookmark()}if(p.state){a=[];tinymce.walk(o,function(b){if(b.nodeType==3&&b.nodeValue&&b.nodeValue.indexOf("\u00a0")!=-1){a.push(b)}},"childNodes");for(g=0;g<a.length;g++){l=a[g].nodeValue;l=l.replace(/(\u00a0)/g,'<span data-mce-bogus="1" class="mceItemHidden mceItemNbsp">$1</span>');c=k.dom.create("div",null,l);while(node=c.lastChild){k.dom.insertAfter(node,a[g])}k.dom.remove(a[g])}}else{a=k.dom.select("span.mceItemNbsp",o);for(g=a.length-1;g>=0;g--){k.dom.remove(a[g],1)}}q.moveToBookmark(f)}});tinymce.PluginManager.add("visualchars",tinymce.plugins.VisualChars)})();
\ No newline at end of file
index 0a5275fe284898be6a1c688f6b036a8125637ada..df985905b6a1b26eb775f38783b24926be73b3d9 100644 (file)
@@ -22,9 +22,9 @@
                        ed.addButton('visualchars', {title : 'visualchars.desc', cmd : 'mceVisualChars'});\r
 \r
                        ed.onBeforeGetContent.add(function(ed, o) {\r
-                               if (t.state) {\r
+                               if (t.state && o.format != 'raw' && !o.draft) {\r
                                        t.state = true;\r
-                                       t._toggleVisualChars();\r
+                                       t._toggleVisualChars(false);\r
                                }\r
                        });\r
                },\r
 \r
                // Private methods\r
 \r
-               _toggleVisualChars : function() {\r
-                       var t = this, ed = t.editor, nl, i, h, d = ed.getDoc(), b = ed.getBody(), nv, s = ed.selection, bo;\r
+               _toggleVisualChars : function(bookmark) {\r
+                       var t = this, ed = t.editor, nl, i, h, d = ed.getDoc(), b = ed.getBody(), nv, s = ed.selection, bo, div, bm;\r
 \r
                        t.state = !t.state;\r
                        ed.controlManager.setActive('visualchars', t.state);\r
 \r
+                       if (bookmark)\r
+                               bm = s.getBookmark();\r
+\r
                        if (t.state) {\r
                                nl = [];\r
                                tinymce.walk(b, function(n) {\r
                                                nl.push(n);\r
                                }, 'childNodes');\r
 \r
-                               for (i=0; i<nl.length; i++) {\r
+                               for (i = 0; i < nl.length; i++) {\r
                                        nv = nl[i].nodeValue;\r
-                                       nv = nv.replace(/(\u00a0+)/g, '<span class="mceItemHidden mceVisualNbsp">$1</span>');\r
-                                       nv = nv.replace(/\u00a0/g, '\u00b7');\r
-                                       ed.dom.setOuterHTML(nl[i], nv, d);\r
+                                       nv = nv.replace(/(\u00a0)/g, '<span data-mce-bogus="1" class="mceItemHidden mceItemNbsp">$1</span>');\r
+\r
+                                       div = ed.dom.create('div', null, nv);\r
+                                       while (node = div.lastChild)\r
+                                               ed.dom.insertAfter(node, nl[i]);\r
+\r
+                                       ed.dom.remove(nl[i]);\r
                                }\r
                        } else {\r
-                               nl = tinymce.grep(ed.dom.select('span', b), function(n) {\r
-                                       return ed.dom.hasClass(n, 'mceVisualNbsp');\r
-                               });\r
+                               nl = ed.dom.select('span.mceItemNbsp', b);\r
 \r
-                               for (i=0; i<nl.length; i++)\r
-                                       ed.dom.setOuterHTML(nl[i], nl[i].innerHTML.replace(/(&middot;|\u00b7)/g, '&nbsp;'), d);\r
+                               for (i = nl.length - 1; i >= 0; i--)\r
+                                       ed.dom.remove(nl[i], 1);\r
                        }\r
+\r
+                       s.moveToBookmark(bm);\r
                }\r
        });\r
 \r
index 267f837eb171711e11e39b06443a703ea137993e..7a97cb71543913cc020b8fc84dadee3dcf83db5c 100644 (file)
@@ -9,9 +9,9 @@
 <body id="about" style="display: none">\r
                <div class="tabs">\r
                        <ul>\r
-                               <li id="general_tab" class="current"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advanced_dlg.about_general}</a></span></li>\r
-                               <li id="help_tab" style="display:none"><span><a href="javascript:mcTabs.displayTab('help_tab','help_panel');" onmousedown="return false;">{#advanced_dlg.about_help}</a></span></li>\r
-                               <li id="plugins_tab"><span><a href="javascript:mcTabs.displayTab('plugins_tab','plugins_panel');" onmousedown="return false;">{#advanced_dlg.about_plugins}</a></span></li>\r
+                               <li id="general_tab" class="current" aria-controls="general_panel"><span><a href="javascript:mcTabs.displayTab('general_tab','general_panel');" onmousedown="return false;">{#advanced_dlg.about_general}</a></span></li>\r
+                               <li id="help_tab" style="display:none" aria-hidden="true" aria-controls="help_panel"><span><a href="javascript:mcTabs.displayTab('help_tab','help_panel');" onmousedown="return false;">{#advanced_dlg.about_help}</a></span></li>\r
+                               <li id="plugins_tab" aria-controls="plugins_panel"><span><a href="javascript:mcTabs.displayTab('plugins_tab','plugins_panel');" onmousedown="return false;">{#advanced_dlg.about_plugins}</a></span></li>\r
                        </ul>\r
                </div>\r
 \r
@@ -26,8 +26,6 @@
 \r
                                <div id="buttoncontainer">\r
                                        <a href="http://www.moxiecode.com" target="_blank"><img src="http://tinymce.moxiecode.com/images/gotmoxie.png" alt="Got Moxie?" border="0" /></a>\r
-                                       <a href="http://sourceforge.net/projects/tinymce/" target="_blank"><img src="http://sourceforge.net/sflogo.php?group_id=103281" alt="Hosted By Sourceforge" border="0" /></a>\r
-                                       <a href="http://www.freshmeat.net/projects/tinymce" target="_blank"><img src="http://tinymce.moxiecode.com/images/fm.gif" alt="Also on freshmeat" border="0" /></a>\r
                                </div>\r
                        </div>\r
 \r
index 2bc63fcfdc6a5c9e520793e723fa4da22d8bfcdf..75c93b799b87bb53b0675116e0bffb6d732b4b7f 100644 (file)
@@ -5,15 +5,15 @@
        <script type="text/javascript" src="../../tiny_mce_popup.js"></script>\r
        <script type="text/javascript" src="js/anchor.js"></script>\r
 </head>\r
-<body style="display: none">\r
+<body style="display: none" role="application" aria-labelledby="app_title">\r
 <form onsubmit="AnchorDialog.update();return false;" action="#">\r
-       <table border="0" cellpadding="4" cellspacing="0">\r
+       <table border="0" cellpadding="4" cellspacing="0" role="presentation">\r
                <tr>\r
-                       <td colspan="2" class="title">{#advanced_dlg.anchor_title}</td>\r
+                       <td colspan="2" class="title" id="app_title">{#advanced_dlg.anchor_title}</td>\r
                </tr>\r
                <tr>\r
-                       <td class="nowrap">{#advanced_dlg.anchor_name}:</td>\r
-                       <td><input name="anchorName" type="text" class="mceFocus" id="anchorName" value="" style="width: 200px" /></td>\r
+                       <td class="nowrap"><label for="anchorName">{#advanced_dlg.anchor_name}:</label></td>\r
+                       <td><input name="anchorName" type="text" class="mceFocus" id="anchorName" value="" style="width: 200px" aria-required="true" /></td>\r
                </tr>\r
        </table>\r
 \r
index 3991b8141b34a0bb3c6b5151c4134c5c445b4a69..2c3b3f27bde8c158d8ba2bc797e9afeaf4fcc392 100644 (file)
@@ -6,47 +6,46 @@
        <script type="text/javascript" src="js/charmap.js"></script>\r
 </head>\r
 <body id="charmap" style="display:none">\r
-<table align="center" border="0" cellspacing="0" cellpadding="2">\r
-    <tr>\r
-        <td colspan="2" class="title">{#advanced_dlg.charmap_title}</td>\r
-    </tr>\r
-    <tr>\r
-        <td id="charmapView" rowspan="2" align="left" valign="top">\r
+<table align="center" border="0" cellspacing="0" cellpadding="2" role="presentation">\r
+       <tr>\r
+               <td colspan="2" class="title" ><label for="charmapView" id="charmap_label">{#advanced_dlg.charmap_title}</label></td>\r
+       </tr>\r
+       <tr>\r
+               <td id="charmapView" rowspan="2" align="left" valign="top">\r
                        <!-- Chars will be rendered here -->\r
-        </td>\r
-        <td width="100" align="center" valign="top">\r
-            <table border="0" cellpadding="0" cellspacing="0" width="100" style="height:100px">\r
-                <tr>\r
-                    <td id="codeV">&nbsp;</td>\r
-                </tr>\r
-                <tr>\r
-                    <td id="codeN">&nbsp;</td>\r
-                </tr>\r
-            </table>\r
-        </td>\r
-    </tr>\r
-    <tr>\r
-        <td valign="bottom" style="padding-bottom: 3px;">\r
-            <table width="100" align="center" border="0" cellpadding="2" cellspacing="0">\r
-                <tr>\r
-                    <td align="center" style="border-left: 1px solid #666699; border-top: 1px solid #666699; border-right: 1px solid #666699;">HTML-Code</td>\r
-                </tr>\r
-                <tr>\r
-                    <td style="font-size: 16px; font-weight: bold; border-left: 1px solid #666699; border-bottom: 1px solid #666699; border-right: 1px solid #666699;" id="codeA" align="center">&nbsp;</td>\r
-                </tr>\r
-                <tr>\r
-                    <td style="font-size: 1px;">&nbsp;</td>\r
-                </tr>\r
-                <tr>\r
-                    <td align="center" style="border-left: 1px solid #666699; border-top: 1px solid #666699; border-right: 1px solid #666699;">NUM-Code</td>\r
-                </tr>\r
-                <tr>\r
-                    <td style="font-size: 16px; font-weight: bold; border-left: 1px solid #666699; border-bottom: 1px solid #666699; border-right: 1px solid #666699;" id="codeB" align="center">&nbsp;</td>\r
-                </tr>\r
-            </table>\r
-        </td>\r
-    </tr>\r
+               </td>\r
+               <td width="100" align="center" valign="top">\r
+                       <table border="0" cellpadding="0" cellspacing="0" width="100" style="height:100px" role="presentation">\r
+                               <tr>\r
+                                       <td id="codeV">&nbsp;</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td id="codeN">&nbsp;</td>\r
+                               </tr>\r
+                       </table>\r
+               </td>\r
+       </tr>\r
+       <tr>\r
+               <td valign="bottom" style="padding-bottom: 3px;">\r
+                       <table width="100" align="center" border="0" cellpadding="2" cellspacing="0" role="presentation">\r
+                               <tr>\r
+                                       <td align="center" style="border-left: 1px solid #666699; border-top: 1px solid #666699; border-right: 1px solid #666699;"><label for="codeA">HTML-Code</label></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td style="font-size: 16px; font-weight: bold; border-left: 1px solid #666699; border-bottom: 1px solid #666699; border-right: 1px solid #666699;" id="codeA" align="center">&nbsp;</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td style="font-size: 1px;">&nbsp;</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td align="center" style="border-left: 1px solid #666699; border-top: 1px solid #666699; border-right: 1px solid #666699;"><label for="codeB">NUM-Code</label></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td style="font-size: 16px; font-weight: bold; border-left: 1px solid #666699; border-bottom: 1px solid #666699; border-right: 1px solid #666699;" id="codeB" align="center">&nbsp;</td>\r
+                               </tr>\r
+                       </table>\r
+               </td>\r
+       </tr>\r
 </table>\r
-\r
 </body>\r
 </html>\r
index 096e7550c33f00fc4cc6c0216f3831674fa42b31..ad1bb0f6ccfaee3762641f44044e39d2fbae4d8a 100644 (file)
@@ -6,13 +6,14 @@
        <script type="text/javascript" src="../../utils/mctabs.js"></script>\r
        <script type="text/javascript" src="js/color_picker.js"></script>\r
 </head>\r
-<body id="colorpicker" style="display: none">\r
+<body id="colorpicker" style="display: none" role="application" aria-labelledby="app_label">\r
+       <span class="mceVoiceLabel" id="app_label" style="display:none;">{#advanced_dlg.colorpicker_title}</span>\r
 <form onsubmit="insertAction();return false" action="#">\r
        <div class="tabs">\r
                <ul>\r
-                       <li id="picker_tab" class="current"><span><a href="javascript:mcTabs.displayTab('picker_tab','picker_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_picker_tab}</a></span></li>\r
-                       <li id="rgb_tab"><span><a href="javascript:;" onclick="generateWebColors();mcTabs.displayTab('rgb_tab','rgb_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_palette_tab}</a></span></li>\r
-                       <li id="named_tab"><span><a  href="javascript:;" onclick="generateNamedColors();javascript:mcTabs.displayTab('named_tab','named_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_named_tab}</a></span></li>\r
+                       <li id="picker_tab" aria-controls="picker_panel" class="current"><span><a href="javascript:mcTabs.displayTab('picker_tab','picker_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_picker_tab}</a></span></li>\r
+                       <li id="rgb_tab" aria-controls="rgb_panel"><span><a href="javascript:;" onclick="mcTabs.displayTab('rgb_tab','rgb_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_palette_tab}</a></span></li>\r
+                       <li id="named_tab" aria-controls="named_panel"><span><a  href="javascript:;" onclick="javascript:mcTabs.displayTab('named_tab','named_panel');" onmousedown="return false;">{#advanced_dlg.colorpicker_named_tab}</a></span></li>\r
                </ul>\r
        </div>\r
 \r
@@ -34,7 +35,7 @@
 \r
                <div id="rgb_panel" class="panel">\r
                        <fieldset>\r
-                               <legend>{#advanced_dlg.colorpicker_palette_title}</legend>\r
+                               <legend id="webcolors_title">{#advanced_dlg.colorpicker_palette_title}</legend>\r
                                <div id="webcolors">\r
                                        <!-- Gets filled with web safe colors-->\r
                                </div>\r
@@ -44,9 +45,9 @@
                </div>\r
 \r
                <div id="named_panel" class="panel">\r
-                       <fieldset>\r
-                               <legend>{#advanced_dlg.colorpicker_named_title}</legend>\r
-                               <div id="namedcolors">\r
+                       <fieldset id="named_picker_label">\r
+                               <legend id="named_title">{#advanced_dlg.colorpicker_named_title}</legend>\r
+                               <div id="namedcolors" role="listbox" tabindex="0" aria-labelledby="named_picker_label">\r
                                        <!-- Gets filled with named colors-->\r
                                </div>\r
 \r
@@ -65,7 +66,7 @@
                <div id="preview"></div>\r
 \r
                <div id="previewblock">\r
-                       <label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" maxlength="8" class="text mceFocus" />\r
+                       <label for="color">{#advanced_dlg.colorpicker_color}</label> <input id="color" type="text" size="8" class="text mceFocus" aria-required="true" />\r
                </div>\r
        </div>\r
 </form>\r
index dc619774616e1d3c7646475d2dd7c0e90e5cad4a..ba8dd4c30432612fca279391bbb1cabce94f3018 100644 (file)
@@ -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);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",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}j.onInit.add(function(){if(!j.settings.readonly){j.onNodeChange.add(l._nodeChanged,l)}if(j.settings.content_css!==false){j.dom.loadCSS(j.baseURI.toAbsolute("themes/advanced/skins/"+j.settings.skin+"/content.css"))}});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")}},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(p[0]==o){i.formatter.remove(o)}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){i.execCommand("FontName",false,l);k.select(function(m){return l==m});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){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(o){return i==o});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",cmd:"FormatBlock"});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;m=j=d.create("span",{id:r.id+"_parent","class":"mceEditor "+r.settings.skin+"Skin"+(w.skin_variant?" "+r.settings.skin+"Skin"+v._ufirst(w.skin_variant):"")});if(!d.boxModel){m=d.add(m,"div",{"class":"mceOldBoxModel"})}m=u=d.add(m,"table",{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=d.stdMode?u.getElementsByTagName("tr"):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;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+"_tbl");this.resizeTo(k.clientWidth+i,k.clientHeight+j)},resizeTo:function(i,l){var j=this.editor,k=this.settings,m=d.get(j.id+"_tbl"),n=d.get(j.id+"_ifr");i=Math.max(k.theme_advanced_resizing_min_width||100,i);l=Math.max(k.theme_advanced_resizing_min_height||100,l);i=Math.min(k.theme_advanced_resizing_max_width||65535,i);l=Math.min(k.theme_advanced_resizing_max_height||65535,l);d.setStyle(m,"height","");d.setStyle(n,"height",l);if(k.theme_advanced_resize_horizontal){d.setStyle(m,"width","");d.setStyle(n,"width",i);if(i<m.clientWidth){d.setStyle(n,"width",m.clientWidth)}}},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(n.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(w,k){var z=this,p,m,r=z.editor,A=z.settings,y,j=r.controlManager,u,l,q=[],x;x=A.theme_advanced_toolbar_align.toLowerCase();x="mce"+z._ufirst(x);l=d.add(d.add(w,"tr"),"td",{"class":"mceToolbar "+x});if(!r.getParam("accessibility_focus")){q.push(d.createHTML("a",{href:"#",onfocus:"tinyMCE.get('"+r.id+"').focus();"},"<!-- IE -->"))}q.push(d.createHTML("a",{href:"#",accesskey:"q",title:r.getLang("advanced.toolbar_focus")},"<!-- IE -->"));for(p=1;(y=A["theme_advanced_buttons"+p]);p++){m=j.createToolbar("toolbar"+p,{"class":"mceToolbarRow"+p});if(A["theme_advanced_buttons"+p+"_add"]){y+=","+A["theme_advanced_buttons"+p+"_add"]}if(A["theme_advanced_buttons"+p+"_add_before"]){y=A["theme_advanced_buttons"+p+"_add_before"]+","+y}z._addControls(y,m);q.push(m.renderHTML());k.deltaHeight-=A.theme_advanced_row_height}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"},w.theme_advanced_path?p.translate("advanced.path")+": ":"&#160;");d.add(k,"a",{href:"#",accesskey:"x"});if(w.theme_advanced_resizing){d.add(l,"a",{id:p.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize"});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","mousedown",function(D){var t,r,s,o,C,z,A,F,n,E,x;function y(G){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);if(w.theme_advanced_resizing_use_cookie){a.setHash("TinyMCE_"+p.id+"_size",{cw:n,ch:E})}}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},_nodeChanged:function(r,z,l,x,j){var C=this,i,y=0,B,u,D=C.settings,A,k,w,m,q;e.each(C.stateControls,function(n){z.setActive(n,r.queryCommandState(C.controls[n][1]))});function o(p){var s,n=j.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]}}}z.setActive("visualaid",r.hasVisual);z.setDisabled("undo",!r.undoManager.hasUndo()&&!r.typing);z.setDisabled("redo",!r.undoManager.hasRedo());z.setDisabled("outdent",!r.queryCommandState("Outdent"));i=o("A");if(u=z.get("link")){if(!i||!i.name){u.setDisabled(!i&&x);u.setActive(!!i)}}if(u=z.get("unlink")){u.setDisabled(!i&&x);u.setActive(!!i&&!i.name)}if(u=z.get("anchor")){u.setActive(!!i&&i.name)}i=o("IMG");if(u=z.get("image")){u.setActive(!!i&&l.className.indexOf("mceItem")==-1)}if(u=z.get("styleselect")){C._importClasses();m=[];f(u.items,function(n){m.push(n.value)});q=r.formatter.matchAll(m);u.select(q[0])}if(u=z.get("formatselect")){i=o(d.isBlock);if(i){u.select(i.nodeName.toLowerCase())}}o(function(p){if(p.nodeName==="SPAN"){if(!A&&p.className){A=p.className}if(!k&&p.style.fontSize){k=p.style.fontSize}if(!w&&p.style.fontFamily){w=p.style.fontFamily.replace(/[\"\']+/g,"").replace(/^([^,]+).*/,"$1").toLowerCase()}}return false});if(u=z.get("fontselect")){u.select(function(n){return n.replace(/^([^,]+).*/,"$1").toLowerCase()==w})}if(u=z.get("fontsizeselect")){if(D.theme_advanced_runtime_fontsize&&!k&&!A){k=r.dom.getStyle(l,"fontSize",true)}u.select(function(n){if(n.fontSize&&n.fontSize===k){return true}if(n["class"]&&n["class"]===A){return true}})}if(D.theme_advanced_path&&D.theme_advanced_statusbar_location){i=d.get(r.id+"_path")||d.add(r.id+"_path_row","span",{id:r.id+"_path"});d.setHTML(i,"");o(function(E){var p=E.nodeName.toLowerCase(),s,v,t="";if(E.nodeType!=1||E.nodeName==="BR"||(d.hasClass(E,"mceItemHidden")||d.hasClass(E,"mceItemRemoved"))){return}if(B=d.getAttrib(E,"mce_name")){p=B}if(e.isIE&&E.scopeName!=="HTML"){p=E.scopeName+":"+p}p=p.replace(/mce\:/g,"");switch(p){case"b":p="strong";break;case"i":p="em";break;case"img":if(B=d.getAttrib(E,"src")){t+="src: "+B+" "}break;case"a":if(B=d.getAttrib(E,"name")){t+="name: "+B+" ";p+="#"+B}if(B=d.getAttrib(E,"href")){t+="href: "+B+" "}break;case"font":if(B=d.getAttrib(E,"face")){t+="font: "+B+" "}if(B=d.getAttrib(E,"size")){t+="size: "+B+" "}if(B=d.getAttrib(E,"color")){t+="color: "+B+" "}break;case"span":if(B=d.getAttrib(E,"style")){t+="style: "+B+" "}break}if(B=d.getAttrib(E,"id")){t+="id: "+B+" "}if(B=E.className){B=B.replace(/\b\s*(webkit|mce|Apple-)\w+\s*\b/g,"");if(B){t+="class: "+B+" ";if(d.isBlock(E)||p=="img"||p=="span"){p+="."+B}}}p=p.replace(/(html:)/g,"");p={name:p,node:E,title:t};C.onResolveName.dispatch(C,p);t=p.title;p=p.name;v=d.create("a",{href:"javascript:;",onmousedown:"return false;",title:t,"class":"mcePath_"+(y++)},p);if(i.hasChildNodes()){i.insertBefore(d.doc.createTextNode(" \u00bb "),i.firstChild);i.insertBefore(v,i.firstChild)}else{i.appendChild(v)}},r.getBody())}},_sel:function(i){this.editor.execCommand("mceSelectNodeDepth",false,i)},_mceInsertAnchor:function(k,j){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/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:e.baseURL+"/themes/advanced/charmap.htm",width:550+parseInt(i.getLang("advanced.charmap_delta_width",0)),height:250+parseInt(i.getLang("advanced.charmap_delta_height",0)),inline:true},{theme_url:this.url})},_mceHelp:function(){var i=this.editor;i.windowManager.open({url:e.baseURL+"/themes/advanced/about.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:e.baseURL+"/themes/advanced/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:e.baseURL+"/themes/advanced/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:e.baseURL+"/themes/advanced/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:e.baseURL+"/themes/advanced/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(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"]==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){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",{},"&#160;")}if(w.theme_advanced_resizing){d.add(l,"a",{id:p.id+"_resize",href:"javascript:;",onclick:"return false;","class":"mceResize"});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;i.setDisabled("undo",!j.undoManager.hasUndo()&&!j.typing);i.setDisabled("redo",!j.undoManager.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.getAttribute("data-mce-bogus")){return}if(H.nodeType!=1||H.nodeName==="BR"||(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:250+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
index 279ca359ce3d9f6246367d3df302ccbc94b1b12e..2bdef96d508b39b808247f09278a5b507221c95d 100644 (file)
@@ -66,6 +66,9 @@
                        t.url = url;\r
                        t.onResolveName = new tinymce.util.Dispatcher(this);\r
 \r
+                       ed.forcedHighContrastMode = ed.settings.detect_highcontrast && t._isHighContrast();\r
+                       ed.settings.skin = ed.forcedHighContrastMode ? 'highcontrast' : ed.settings.skin;\r
+\r
                        // Default settings\r
                        t.settings = s = extend({\r
                                theme_advanced_path : true,\r
@@ -81,6 +84,8 @@
                                theme_advanced_resize_horizontal : 1,\r
                                theme_advanced_resizing_use_cookie : 1,\r
                                theme_advanced_font_sizes : "1,2,3,4,5,6,7",\r
+                               theme_advanced_font_selector : "span",\r
+                               theme_advanced_show_current_color: 0,\r
                                readonly : ed.settings.readonly\r
                        }, ed.settings);\r
 \r
                        if (s.theme_advanced_statusbar_location == 'none')\r
                                s.theme_advanced_statusbar_location = 0;\r
 \r
+                       if (ed.settings.content_css !== false)\r
+                               ed.contentCSS.push(ed.baseURI.toAbsolute(url + "/skins/" + ed.settings.skin + "/content.css"));\r
+\r
                        // Init editor\r
                        ed.onInit.add(function() {\r
-                               if (!ed.settings.readonly)\r
+                               if (!ed.settings.readonly) {\r
                                        ed.onNodeChange.add(t._nodeChanged, t);\r
-\r
-                               if (ed.settings.content_css !== false)\r
-                                       ed.dom.loadCSS(ed.baseURI.toAbsolute("themes/advanced/skins/" + ed.settings.skin + "/content.css"));\r
+                                       ed.onKeyUp.add(t._updateUndoStatus, t);\r
+                                       ed.onMouseUp.add(t._updateUndoStatus, t);\r
+                                       ed.dom.bind(ed.dom.getRoot(), 'dragend', function() {\r
+                                               t._updateUndoStatus(ed);\r
+                                       });\r
+                               }\r
                        });\r
 \r
                        ed.onSetProgressState.add(function(ed, b, ti) {\r
                                DOM.loadCSS(url + "/skins/" + ed.settings.skin + "/ui_" + s.skin_variant + ".css");\r
                },\r
 \r
+               _isHighContrast : function() {\r
+                       var actualColor, div = DOM.add(DOM.getRoot(), 'div', {'style': 'background-color: rgb(171,239,86);'});\r
+\r
+                       actualColor = (DOM.getStyle(div, 'background-color', true) + '').toLowerCase().replace(/ /g, '');\r
+                       DOM.remove(div);\r
+\r
+                       return actualColor != 'rgb(171,239,86)' && actualColor != '#abef56';\r
+               },\r
+\r
                createControl : function(n, cf) {\r
                        var cd, c;\r
 \r
 \r
                                        // Toggle off the current format\r
                                        matches = ed.formatter.matchAll(formatNames);\r
-                                       if (matches[0] == name)\r
-                                               ed.formatter.remove(name);\r
-                                       else\r
+                                       if (!name || matches[0] == name) {\r
+                                               if (matches[0]) \r
+                                                       ed.formatter.remove(matches[0]);\r
+                                       } else\r
                                                ed.formatter.apply(name);\r
 \r
                                        ed.undoManager.add();\r
                        c = ed.controlManager.createListBox('fontselect', {\r
                                title : 'advanced.fontdefault',\r
                                onselect : function(v) {\r
+                                       var cur = c.items[c.selectedIndex];\r
+\r
+                                       if (!v && cur) {\r
+                                               ed.execCommand('FontName', false, cur.value);\r
+                                               return;\r
+                                       }\r
+\r
                                        ed.execCommand('FontName', false, v);\r
 \r
                                        // Fake selection, execCommand will fire a nodeChange and update the selection\r
                                                return v == sv;\r
                                        });\r
 \r
+                                       if (cur && cur.value == v) {\r
+                                               c.select(null);\r
+                                       }\r
+\r
                                        return false; // No auto select\r
                                }\r
                        });\r
                        var t = this, ed = t.editor, c, i = 0, cl = [];\r
 \r
                        c = ed.controlManager.createListBox('fontsizeselect', {title : 'advanced.font_size', onselect : function(v) {\r
+                               var cur = c.items[c.selectedIndex];\r
+\r
+                               if (!v && cur) {\r
+                                       cur = cur.value;\r
+\r
+                                       if (cur['class']) {\r
+                                               ed.formatter.toggle('fontsize_class', {value : cur['class']});\r
+                                               ed.undoManager.add();\r
+                                               ed.nodeChanged();\r
+                                       } else {\r
+                                               ed.execCommand('FontSize', false, cur.fontSize);\r
+                                       }\r
+\r
+                                       return;\r
+                               }\r
+\r
                                if (v['class']) {\r
                                        ed.focus();\r
                                        ed.undoManager.add();\r
                                        return v == sv;\r
                                });\r
 \r
+                               if (cur && (cur.value.fontSize == v.fontSize || cur.value['class'] == v['class'])) {\r
+                                       c.select(null);\r
+                               }\r
+\r
                                return false; // No auto select\r
                        }});\r
 \r
                                samp : 'advanced.samp'\r
                        }, t = this;\r
 \r
-                       c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', cmd : 'FormatBlock'});\r
+                       c = t.editor.controlManager.createListBox('formatselect', {title : 'advanced.block', onselect : function(v) {\r
+                               t.editor.execCommand('FormatBlock', false, v);\r
+                               return false;\r
+                       }});\r
+\r
                        if (c) {\r
                                each(t.editor.getParam('theme_advanced_blockformats', t.settings.theme_advanced_blockformats, 'hash'), function(v, k) {\r
                                        c.add(t.editor.translate(k != v ? k : fmts[v]), v, {'class' : 'mce_formatPreview mce_' + v});\r
                renderUI : function(o) {\r
                        var n, ic, tb, t = this, ed = t.editor, s = t.settings, sc, p, nl;\r
 \r
-                       n = p = DOM.create('span', {id : ed.id + '_parent', 'class' : 'mceEditor ' + ed.settings.skin + 'Skin' + (s.skin_variant ? ' ' + ed.settings.skin + 'Skin' + t._ufirst(s.skin_variant) : '')});\r
+                       if (ed.settings) {\r
+                               ed.settings.aria_label = s.aria_label + ed.getLang('advanced.help_shortcut');\r
+                       }\r
+\r
+                       // TODO: ACC Should have an aria-describedby attribute which is user-configurable to describe what this field is actually for.\r
+                       // Maybe actually inherit it from the original textara?\r
+                       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) : '')});\r
+                       DOM.add(n, 'span', {'class': 'mceVoiceLabel', 'style': 'display:none;', id: ed.id + '_voice'}, s.aria_label);\r
 \r
                        if (!DOM.boxModel)\r
                                n = DOM.add(n, 'div', {'class' : 'mceOldBoxModel'});\r
 \r
-                       n = sc = DOM.add(n, 'table', {id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0});\r
+                       n = sc = DOM.add(n, 'table', {role : "presentation", id : ed.id + '_tbl', 'class' : 'mceLayout', cellSpacing : 0, cellPadding : 0});\r
                        n = tb = DOM.add(n, 'tbody');\r
 \r
                        switch ((s.theme_advanced_layout_manager || '').toLowerCase()) {\r
                        n = o.targetNode;\r
 \r
                        // Add classes to first and last TRs\r
-                       nl = DOM.stdMode ? sc.getElementsByTagName('tr') : sc.rows; // Quick fix for IE 8\r
+                       nl = sc.rows;\r
                        DOM.addClass(nl[0], 'mceFirst');\r
                        DOM.addClass(nl[nl.length - 1], 'mceLast');\r
 \r
                        t.deltaHeight = o.deltaHeight;\r
                        o.targetNode = null;\r
 \r
+                       ed.onKeyDown.add(function(ed, evt) {\r
+                               var DOM_VK_F10 = 121, DOM_VK_F11 = 122;\r
+\r
+                               if (evt.altKey) {\r
+                                       if (evt.keyCode === DOM_VK_F10) {\r
+                                               t.toolbarGroup.focus();\r
+                                               return Event.cancel(evt);\r
+                                       } else if (evt.keyCode === DOM_VK_F11) {\r
+                                               DOM.get(ed.id + '_path_row').focus();\r
+                                               return Event.cancel(evt);\r
+                                       }\r
+                               }\r
+                       });\r
+\r
+                       // alt+0 is the UK recommended shortcut for accessing the list of access controls.\r
+                       ed.addShortcut('alt+0', '', 'mceShortcuts', t);\r
+\r
                        return {\r
                                iframeContainer : ic,\r
                                editorContainer : ed.id + '_parent',\r
                },\r
 \r
                resizeBy : function(dw, dh) {\r
-                       var e = DOM.get(this.editor.id + '_tbl');\r
+                       var e = DOM.get(this.editor.id + '_ifr');\r
 \r
                        this.resizeTo(e.clientWidth + dw, e.clientHeight + dh);\r
                },\r
 \r
-               resizeTo : function(w, h) {\r
+               resizeTo : function(w, h, store) {\r
                        var ed = this.editor, s = this.settings, e = DOM.get(ed.id + '_tbl'), ifr = DOM.get(ed.id + '_ifr');\r
 \r
                        // Boundery fix box\r
                                DOM.setStyle(ifr, 'width', w);\r
 \r
                                // Make sure that the size is never smaller than the over all ui\r
-                               if (w < e.clientWidth)\r
+                               if (w < e.clientWidth) {\r
+                                       w = e.clientWidth;\r
                                        DOM.setStyle(ifr, 'width', e.clientWidth);\r
+                               }\r
+                       }\r
+\r
+                       // Store away the size\r
+                       if (store && s.theme_advanced_resizing_use_cookie) {\r
+                               Cookie.setHash("TinyMCE_" + ed.id + "_size", {\r
+                                       cw : w,\r
+                                       ch : h\r
+                               });\r
                        }\r
                },\r
 \r
                        each(explode(s.theme_advanced_containers || ''), function(c, i) {\r
                                var v = s['theme_advanced_container_' + c] || '';\r
 \r
-                               switch (v.toLowerCase()) {\r
+                               switch (c.toLowerCase()) {\r
                                        case 'mceeditor':\r
                                                n = DOM.add(tb, 'tr');\r
                                                n = ic = DOM.add(n, 'td', {'class' : 'mceIframeContainer'});\r
                },\r
 \r
                _addToolbars : function(c, o) {\r
-                       var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a;\r
+                       var t = this, i, tb, ed = t.editor, s = t.settings, v, cf = ed.controlManager, di, n, h = [], a, toolbarGroup;\r
 \r
-                       a = s.theme_advanced_toolbar_align.toLowerCase();\r
-                       a = 'mce' + t._ufirst(a);\r
+                       toolbarGroup = cf.createToolbarGroup('toolbargroup', {\r
+                               'name': ed.getLang('advanced.toolbar'),\r
+                               'tab_focus_toolbar':ed.getParam('theme_advanced_tab_focus_toolbar')\r
+                       });\r
 \r
-                       n = DOM.add(DOM.add(c, 'tr'), 'td', {'class' : 'mceToolbar ' + a});\r
+                       t.toolbarGroup = toolbarGroup;\r
 \r
-                       if (!ed.getParam('accessibility_focus'))\r
-                               h.push(DOM.createHTML('a', {href : '#', onfocus : 'tinyMCE.get(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));\r
+                       a = s.theme_advanced_toolbar_align.toLowerCase();\r
+                       a = 'mce' + t._ufirst(a);\r
 \r
-                       h.push(DOM.createHTML('a', {href : '#', accesskey : 'q', title : ed.getLang("advanced.toolbar_focus")}, '<!-- IE -->'));\r
+                       n = DOM.add(DOM.add(c, 'tr', {role: 'presentation'}), 'td', {'class' : 'mceToolbar ' + a, "role":"presentation"});\r
 \r
                        // Create toolbar and add the controls\r
                        for (i=1; (v = s['theme_advanced_buttons' + i]); i++) {\r
                                        v = s['theme_advanced_buttons' + i + '_add_before'] + ',' + v;\r
 \r
                                t._addControls(v, tb);\r
-\r
-                               //n.appendChild(n = tb.render());\r
-                               h.push(tb.renderHTML());\r
+                               toolbarGroup.add(tb);\r
 \r
                                o.deltaHeight -= s.theme_advanced_row_height;\r
                        }\r
-\r
+                       h.push(toolbarGroup.renderHTML());\r
                        h.push(DOM.createHTML('a', {href : '#', accesskey : 'z', title : ed.getLang("advanced.toolbar_focus"), onfocus : 'tinyMCE.getInstanceById(\'' + ed.id + '\').focus();'}, '<!-- IE -->'));\r
                        DOM.setHTML(n, h.join(''));\r
                },\r
                        var n, t = this, ed = t.editor, s = t.settings, r, mf, me, td;\r
 \r
                        n = DOM.add(tb, 'tr');\r
-                       n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'});\r
-                       n = DOM.add(n, 'div', {id : ed.id + '_path_row'}, s.theme_advanced_path ? ed.translate('advanced.path') + ': ' : '&#160;');\r
-                       DOM.add(n, 'a', {href : '#', accesskey : 'x'});\r
+                       n = td = DOM.add(n, 'td', {'class' : 'mceStatusbar'}); \r
+                       n = DOM.add(n, 'div', {id : ed.id + '_path_row', 'role': 'group', 'aria-labelledby': ed.id + '_path_voice'});\r
+                       if (s.theme_advanced_path) {\r
+                               DOM.add(n, 'span', {id: ed.id + '_path_voice'}, ed.translate('advanced.path'));\r
+                               DOM.add(n, 'span', {}, ': ');\r
+                       } else {\r
+                               DOM.add(n, 'span', {}, '&#160;');\r
+                       }\r
+                       \r
 \r
                        if (s.theme_advanced_resizing) {\r
                                DOM.add(td, 'a', {id : ed.id + '_resize', href : 'javascript:;', onclick : "return false;", 'class' : 'mceResize'});\r
                                }\r
 \r
                                ed.onPostRender.add(function() {\r
+                                       Event.add(ed.id + '_resize', 'click', function(e) {\r
+                                               e.preventDefault();\r
+                                       });\r
+\r
                                        Event.add(ed.id + '_resize', 'mousedown', function(e) {\r
                                                var mouseMoveHandler1, mouseMoveHandler2,\r
                                                        mouseUpHandler1, mouseUpHandler2,\r
                                                        startX, startY, startWidth, startHeight, width, height, ifrElm;\r
 \r
                                                function resizeOnMove(e) {\r
+                                                       e.preventDefault();\r
+\r
                                                        width = startWidth + (e.screenX - startX);\r
                                                        height = startHeight + (e.screenY - startY);\r
 \r
                                                        Event.remove(DOM.doc, 'mouseup', mouseUpHandler1);\r
                                                        Event.remove(ed.getDoc(), 'mouseup', mouseUpHandler2);\r
 \r
-                                                       // Store away the size\r
-                                                       if (s.theme_advanced_resizing_use_cookie) {\r
-                                                               Cookie.setHash("TinyMCE_" + ed.id + "_size", {\r
-                                                                       cw : width,\r
-                                                                       ch : height\r
-                                                               });\r
-                                                       }\r
+                                                       width = startWidth + (e.screenX - startX);\r
+                                                       height = startHeight + (e.screenY - startY);\r
+                                                       t.resizeTo(width, height, true);\r
                                                };\r
 \r
                                                e.preventDefault();\r
                        n = tb = null;\r
                },\r
 \r
+               _updateUndoStatus : function(ed) {\r
+                       var cm = ed.controlManager;\r
+\r
+                       cm.setDisabled('undo', !ed.undoManager.hasUndo() && !ed.typing);\r
+                       cm.setDisabled('redo', !ed.undoManager.hasRedo());\r
+               },\r
+\r
                _nodeChanged : function(ed, cm, n, co, ob) {\r
-                       var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn, formatNames, matches;\r
+                       var t = this, p, de = 0, v, c, s = t.settings, cl, fz, fn, fc, bc, formatNames, matches;\r
 \r
                        tinymce.each(t.stateControls, function(c) {\r
                                cm.setActive(c, ed.queryCommandState(t.controls[c][1]));\r
                        };\r
 \r
                        cm.setActive('visualaid', ed.hasVisual);\r
-                       cm.setDisabled('undo', !ed.undoManager.hasUndo() && !ed.typing);\r
-                       cm.setDisabled('redo', !ed.undoManager.hasRedo());\r
+                       t._updateUndoStatus(ed);\r
                        cm.setDisabled('outdent', !ed.queryCommandState('Outdent'));\r
 \r
                        p = getParent('A');\r
                        }\r
 \r
                        if (c = cm.get('anchor')) {\r
-                               c.setActive(!!p && p.name);\r
+                               c.setActive(!co && !!p && p.name);\r
                        }\r
 \r
                        p = getParent('IMG');\r
                        if (c = cm.get('image'))\r
-                               c.setActive(!!p && n.className.indexOf('mceItem') == -1);\r
+                               c.setActive(!co && !!p && n.className.indexOf('mceItem') == -1);\r
 \r
                        if (c = cm.get('styleselect')) {\r
                                t._importClasses();\r
                                if (n.nodeName === 'SPAN') {\r
                                        if (!cl && n.className)\r
                                                cl = n.className;\r
+                               }\r
 \r
+                               if (ed.dom.is(n, s.theme_advanced_font_selector)) {\r
                                        if (!fz && n.style.fontSize)\r
                                                fz = n.style.fontSize;\r
 \r
                                        if (!fn && n.style.fontFamily)\r
                                                fn = n.style.fontFamily.replace(/[\"\']+/g, '').replace(/^([^,]+).*/, '$1').toLowerCase();\r
+                                       \r
+                                       if (!fc && n.style.color)\r
+                                               fc = n.style.color;\r
+\r
+                                       if (!bc && n.style.backgroundColor)\r
+                                               bc = n.style.backgroundColor;\r
                                }\r
 \r
                                return false;\r
                                                return true;\r
                                });\r
                        }\r
+                       \r
+                       if (s.theme_advanced_show_current_color) {\r
+                               function updateColor(controlId, color) {\r
+                                       if (c = cm.get(controlId)) {\r
+                                               if (!color)\r
+                                                       color = c.settings.default_color;\r
+                                               if (color !== c.value) {\r
+                                                       c.displayColor(color);\r
+                                               }\r
+                                       }\r
+                               }\r
+                               updateColor('forecolor', fc);\r
+                               updateColor('backcolor', bc);\r
+                       }\r
+\r
+                       if (s.theme_advanced_show_current_color) {\r
+                               function updateColor(controlId, color) {\r
+                                       if (c = cm.get(controlId)) {\r
+                                               if (!color)\r
+                                                       color = c.settings.default_color;\r
+                                               if (color !== c.value) {\r
+                                                       c.displayColor(color);\r
+                                               }\r
+                                       }\r
+                               };\r
+\r
+                               updateColor('forecolor', fc);\r
+                               updateColor('backcolor', bc);\r
+                       }\r
 \r
                        if (s.theme_advanced_path && s.theme_advanced_statusbar_location) {\r
                                p = DOM.get(ed.id + '_path') || DOM.add(ed.id + '_path_row', 'span', {id : ed.id + '_path'});\r
+\r
+                               if (t.statusKeyboardNavigation) {\r
+                                       t.statusKeyboardNavigation.destroy();\r
+                                       t.statusKeyboardNavigation = null;\r
+                               }\r
+\r
                                DOM.setHTML(p, '');\r
 \r
                                getParent(function(n) {\r
                                        var na = n.nodeName.toLowerCase(), u, pi, ti = '';\r
 \r
-                                       /*if (n.getAttribute('_mce_bogus'))\r
+                                       if (n.getAttribute('data-mce-bogus'))\r
                                                return;\r
-*/\r
+\r
                                        // Ignore non element and hidden elements\r
                                        if (n.nodeType != 1 || n.nodeName === 'BR' || (DOM.hasClass(n, 'mceItemHidden') || DOM.hasClass(n, 'mceItemRemoved')))\r
                                                return;\r
 \r
-                                       // Fake name\r
-                                       if (v = DOM.getAttrib(n, 'mce_name'))\r
-                                               na = v;\r
-\r
                                        // Handle prefix\r
                                        if (tinymce.isIE && n.scopeName !== 'HTML')\r
                                                na = n.scopeName + ':' + na;\r
                                        na = na.name;\r
 \r
                                        //u = "javascript:tinymce.EditorManager.get('" + ed.id + "').theme._sel('" + (de++) + "');";\r
-                                       pi = DOM.create('a', {'href' : "javascript:;", onmousedown : "return false;", title : ti, 'class' : 'mcePath_' + (de++)}, na);\r
+                                       pi = DOM.create('a', {'href' : "javascript:;", role: 'button', onmousedown : "return false;", title : ti, 'class' : 'mcePath_' + (de++)}, na);\r
 \r
                                        if (p.hasChildNodes()) {\r
-                                               p.insertBefore(DOM.doc.createTextNode(' \u00bb '), p.firstChild);\r
+                                               p.insertBefore(DOM.create('span', {'aria-hidden': 'true'}, '\u00a0\u00bb '), p.firstChild);\r
                                                p.insertBefore(pi, p.firstChild);\r
                                        } else\r
                                                p.appendChild(pi);\r
                                }, ed.getBody());\r
+\r
+                               if (DOM.select('a', p).length > 0) {\r
+                                       t.statusKeyboardNavigation = new tinymce.ui.KeyboardNavigation({\r
+                                               root: ed.id + "_path_row",\r
+                                               items: DOM.select('a', p),\r
+                                               excludeFromTabOrder: true,\r
+                                               onCancel: function() {\r
+                                                       ed.focus();\r
+                                               }\r
+                                       }, DOM);\r
+                               }\r
                        }\r
                },\r
 \r
                        var ed = this.editor;\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/anchor.htm',\r
+                               url : this.url + '/anchor.htm',\r
                                width : 320 + parseInt(ed.getLang('advanced.anchor_delta_width', 0)),\r
                                height : 90 + parseInt(ed.getLang('advanced.anchor_delta_height', 0)),\r
                                inline : true\r
                        var ed = this.editor;\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/charmap.htm',\r
+                               url : this.url + '/charmap.htm',\r
                                width : 550 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)),\r
                                height : 250 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)),\r
                                inline : true\r
                        var ed = this.editor;\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/about.htm',\r
+                               url : this.url + '/about.htm',\r
                                width : 480,\r
                                height : 380,\r
                                inline : true\r
                        });\r
                },\r
 \r
+               _mceShortcuts : function() {\r
+                       var ed = this.editor;\r
+                       ed.windowManager.open({\r
+                               url: this.url + '/shortcuts.htm',\r
+                               width: 480,\r
+                               height: 380,\r
+                               inline: true\r
+                       }, {\r
+                               theme_url: this.url\r
+                       });\r
+               },\r
+\r
                _mceColorPicker : function(u, v) {\r
                        var ed = this.editor;\r
 \r
                        v = v || {};\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/color_picker.htm',\r
+                               url : this.url + '/color_picker.htm',\r
                                width : 375 + parseInt(ed.getLang('advanced.colorpicker_delta_width', 0)),\r
                                height : 250 + parseInt(ed.getLang('advanced.colorpicker_delta_height', 0)),\r
                                close_previous : false,\r
                        var ed = this.editor;\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/source_editor.htm',\r
+                               url : this.url + '/source_editor.htm',\r
                                width : parseInt(ed.getParam("theme_advanced_source_editor_width", 720)),\r
                                height : parseInt(ed.getParam("theme_advanced_source_editor_height", 580)),\r
                                inline : true,\r
                                return;\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/image.htm',\r
+                               url : this.url + '/image.htm',\r
                                width : 355 + parseInt(ed.getLang('advanced.image_delta_width', 0)),\r
                                height : 275 + parseInt(ed.getLang('advanced.image_delta_height', 0)),\r
                                inline : true\r
                        var ed = this.editor;\r
 \r
                        ed.windowManager.open({\r
-                               url : tinymce.baseURL + '/themes/advanced/link.htm',\r
+                               url : this.url + '/link.htm',\r
                                width : 310 + parseInt(ed.getLang('advanced.link_delta_width', 0)),\r
                                height : 200 + parseInt(ed.getLang('advanced.link_delta_height', 0)),\r
                                inline : true\r
        });\r
 \r
        tinymce.ThemeManager.add('advanced', tinymce.themes.AdvancedTheme);\r
-}(tinymce));
\ No newline at end of file
+}(tinymce));\r
index f30d670641afcb284105b7bbc79afcbd102b2aa4..b8ba729f6f24776226b23388afa170d3d32a5308 100644 (file)
 \r
        <div class="panel_wrapper">\r
                <div id="general_panel" class="panel current">\r
-     <table border="0" cellpadding="4" cellspacing="0">\r
-          <tr>\r
-            <td class="nowrap"><label for="src">{#advanced_dlg.image_src}</label></td>\r
-            <td><table border="0" cellspacing="0" cellpadding="0">\r
-                <tr>\r
-                  <td><input id="src" name="src" type="text" class="mceFocus" value="" style="width: 200px" onchange="ImageDialog.getImageData();" /></td>\r
-                  <td id="srcbrowsercontainer">&nbsp;</td>\r
-                </tr>\r
-              </table></td>\r
-          </tr>\r
-                 <tr>\r
-                       <td><label for="image_list">{#advanced_dlg.image_list}</label></td>\r
-                       <td><select id="image_list" name="image_list" onchange="document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;"></select></td>\r
-                 </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="alt">{#advanced_dlg.image_alt}</label></td>\r
-            <td><input id="alt" name="alt" type="text" value="" style="width: 200px" /></td>\r
-          </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="align">{#advanced_dlg.image_align}</label></td>\r
-            <td><select id="align" name="align" onchange="ImageDialog.updateStyle();">\r
-                <option value="">{#not_set}</option>\r
-                <option value="baseline">{#advanced_dlg.image_align_baseline}</option>\r
-                <option value="top">{#advanced_dlg.image_align_top}</option>\r
-                <option value="middle">{#advanced_dlg.image_align_middle}</option>\r
-                <option value="bottom">{#advanced_dlg.image_align_bottom}</option>\r
-                <option value="text-top">{#advanced_dlg.image_align_texttop}</option>\r
-                <option value="text-bottom">{#advanced_dlg.image_align_textbottom}</option>\r
-                <option value="left">{#advanced_dlg.image_align_left}</option>\r
-                <option value="right">{#advanced_dlg.image_align_right}</option>\r
-              </select></td>\r
-          </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="width">{#advanced_dlg.image_dimensions}</label></td>\r
-            <td><input id="width" name="width" type="text" value="" size="3" maxlength="5" />\r
-              x\r
-              <input id="height" name="height" type="text" value="" size="3" maxlength="5" /></td>\r
-          </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="border">{#advanced_dlg.image_border}</label></td>\r
-            <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td>\r
-          </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="vspace">{#advanced_dlg.image_vspace}</label></td>\r
-            <td><input id="vspace" name="vspace" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td>\r
-          </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="hspace">{#advanced_dlg.image_hspace}</label></td>\r
-            <td><input id="hspace" name="hspace" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td>\r
-          </tr>\r
-        </table>\r
+                       <table border="0" cellpadding="4" cellspacing="0">\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="src">{#advanced_dlg.image_src}</label></td>\r
+                                       <td><table border="0" cellspacing="0" cellpadding="0">\r
+                                               <tr>\r
+                                                       <td><input id="src" name="src" type="text" class="mceFocus" value="" style="width: 200px" onchange="ImageDialog.getImageData();" /></td>\r
+                                                       <td id="srcbrowsercontainer">&nbsp;</td>\r
+                                               </tr>\r
+                                       </table></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td><label for="image_list">{#advanced_dlg.image_list}</label></td>\r
+                                       <td><select id="image_list" name="image_list" onchange="document.getElementById('src').value=this.options[this.selectedIndex].value;document.getElementById('alt').value=this.options[this.selectedIndex].text;"></select></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="alt">{#advanced_dlg.image_alt}</label></td>\r
+                                       <td><input id="alt" name="alt" type="text" value="" style="width: 200px" /></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="align">{#advanced_dlg.image_align}</label></td>\r
+                                       <td><select id="align" name="align" onchange="ImageDialog.updateStyle();">\r
+                                               <option value="">{#not_set}</option>\r
+                                               <option value="baseline">{#advanced_dlg.image_align_baseline}</option>\r
+                                               <option value="top">{#advanced_dlg.image_align_top}</option>\r
+                                               <option value="middle">{#advanced_dlg.image_align_middle}</option>\r
+                                               <option value="bottom">{#advanced_dlg.image_align_bottom}</option>\r
+                                               <option value="text-top">{#advanced_dlg.image_align_texttop}</option>\r
+                                               <option value="text-bottom">{#advanced_dlg.image_align_textbottom}</option>\r
+                                               <option value="left">{#advanced_dlg.image_align_left}</option>\r
+                                               <option value="right">{#advanced_dlg.image_align_right}</option>\r
+                                       </select></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="width">{#advanced_dlg.image_dimensions}</label></td>\r
+                                       <td><input id="width" name="width" type="text" value="" size="3" maxlength="5" />\r
+                                        x \r
+                                       <input id="height" name="height" type="text" value="" size="3" maxlength="5" /></td>\r
+                               </tr>\r
+                               <tr>\r
+                               <td class="nowrap"><label for="border">{#advanced_dlg.image_border}</label></td>\r
+                               <td><input id="border" name="border" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="vspace">{#advanced_dlg.image_vspace}</label></td>\r
+                                       <td><input id="vspace" name="vspace" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="hspace">{#advanced_dlg.image_hspace}</label></td>\r
+                                       <td><input id="hspace" name="hspace" type="text" value="" size="3" maxlength="3" onchange="ImageDialog.updateStyle();" /></td>\r
+                               </tr>\r
+                       </table>\r
                </div>\r
        </div>\r
 \r
index 5cee9ed863cdb6ffaf6cc44979375c1beb9cd920..5b358457617adaba1ebc51fbb70f77930065fcea 100644 (file)
@@ -66,6 +66,7 @@ function insertHelpIFrame() {
                html = '<iframe width="100%" height="300" src="' + tinyMCEPopup.editor.baseURI.toAbsolute(tinyMCEPopup.getParam('docs_url')) + '"></iframe>';\r
                document.getElementById('iframecontainer').innerHTML = html;\r
                document.getElementById('help_tab').style.display = 'block';\r
+               document.getElementById('help_tab').setAttribute("aria-hidden", "false");\r
        }\r
 }\r
 \r
index 7fe7810558e74edefb59a63da1c14cfc9689b139..e528e4f42f78a571657b6abe88f429a1d57400dd 100644 (file)
@@ -19,6 +19,11 @@ var AnchorDialog = {
        update : function() {\r
                var ed = this.editor, elm, name = document.forms[0].anchorName.value;\r
 \r
+               if (!name || !/^[a-z][a-z0-9\-\_:\.]*$/i.test(name)) {\r
+                       tinyMCEPopup.alert('advanced_dlg.anchor_invalid');\r
+                       return;\r
+               }\r
+\r
                tinyMCEPopup.restoreSelection();\r
 \r
                if (this.action != 'update')\r
index 8c5aea1721f56c80391a174cbc1c719ef9d124a1..1cead6dfe87c50cc7dc2d9a889131ee5e45eb2df 100644 (file)
@@ -173,7 +173,7 @@ var charmap = [
        ['&yacute;',  '&#253;',  true, 'y - acute'],\r
        ['&thorn;',   '&#254;',  true, 'thorn'],\r
        ['&yuml;',    '&#255;',  true, 'y - diaeresis'],\r
-    ['&Alpha;',   '&#913;',  true, 'Alpha'],\r
+       ['&Alpha;',   '&#913;',  true, 'Alpha'],\r
        ['&Beta;',    '&#914;',  true, 'Beta'],\r
        ['&Gamma;',   '&#915;',  true, 'Gamma'],\r
        ['&Delta;',   '&#916;',  true, 'Delta'],\r
@@ -258,8 +258,8 @@ var charmap = [
        ['&rfloor;',  '&#8971;', false,'right floor'],\r
        ['&lang;',    '&#9001;', false,'left-pointing angle bracket'],\r
        ['&rang;',    '&#9002;', false,'right-pointing angle bracket'],\r
-       ['&loz;',     '&#9674;', true,'lozenge'],\r
-       ['&spades;',  '&#9824;', false,'black spade suit'],\r
+       ['&loz;',     '&#9674;', true, 'lozenge'],\r
+       ['&spades;',  '&#9824;', true, 'black spade suit'],\r
        ['&clubs;',   '&#9827;', true, 'black club suit'],\r
        ['&hearts;',  '&#9829;', true, 'black heart suit'],\r
        ['&diams;',   '&#9830;', true, 'black diamond suit'],\r
@@ -275,19 +275,38 @@ var charmap = [
 \r
 tinyMCEPopup.onInit.add(function() {\r
        tinyMCEPopup.dom.setHTML('charmapView', renderCharMapHTML());\r
+       addKeyboardNavigation();\r
 });\r
 \r
+function addKeyboardNavigation(){\r
+       var tableElm, cells, settings;\r
+\r
+       cells = tinyMCEPopup.dom.select(".charmaplink", "charmapgroup");\r
+\r
+       settings ={\r
+               root: "charmapgroup",\r
+               items: cells\r
+       };\r
+\r
+       tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', settings, tinyMCEPopup.dom);\r
+}\r
+\r
 function renderCharMapHTML() {\r
        var charsPerRow = 20, tdWidth=20, tdHeight=20, i;\r
-       var html = '<table border="0" cellspacing="1" cellpadding="0" width="' + (tdWidth*charsPerRow) + '"><tr height="' + tdHeight + '">';\r
+       var html = '<div id="charmapgroup" aria-labelledby="charmap_label" tabindex="0" role="listbox">'+\r
+       '<table role="presentation" border="0" cellspacing="1" cellpadding="0" width="' + (tdWidth*charsPerRow) + \r
+       '"><tr height="' + tdHeight + '">';\r
        var cols=-1;\r
 \r
        for (i=0; i<charmap.length; i++) {\r
+               var previewCharFn;\r
+\r
                if (charmap[i][2]==true) {\r
                        cols++;\r
+                       previewCharFn = 'previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');';\r
                        html += ''\r
                                + '<td class="charmap">'\r
-                               + '<a onmouseover="previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');" onfocus="previewChar(\'' + charmap[i][1].substring(1,charmap[i][1].length) + '\',\'' + charmap[i][0].substring(1,charmap[i][0].length) + '\',\'' + charmap[i][3] + '\');" href="javascript:void(0)" onclick="insertChar(\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\');" onclick="return false;" onmousedown="return false;" title="' + charmap[i][3] + '">'\r
+                               + '<a class="charmaplink" role="button" onmouseover="'+previewCharFn+'" onfocus="'+previewCharFn+'" href="javascript:void(0)" onclick="insertChar(\'' + charmap[i][1].substring(2,charmap[i][1].length-1) + '\');" onclick="return false;" onmousedown="return false;" title="' + charmap[i][3] + '">'\r
                                + charmap[i][1]\r
                                + '</a></td>';\r
                        if ((cols+1) % charsPerRow == 0)\r
@@ -301,7 +320,8 @@ function renderCharMapHTML() {
                        html += '<td width="' + tdWidth + '" height="' + tdHeight + '" class="charmap">&nbsp;</td>';\r
        }\r
 \r
-       html += '</tr></table>';\r
+       html += '</tr></table></div>';\r
+       html = html.replace(/<tr height="20"><\/tr>/g, '');\r
 \r
        return html;\r
 }\r
index fd9700f2224320b9ab6a252c19e6c54fa018fee6..7decac5b43c3c431867eb07a13f70e7dbebf76f5 100644 (file)
@@ -1,6 +1,6 @@
 tinyMCEPopup.requireLangPack();\r
 \r
-var detail = 50, strhex = "0123456789abcdef", i, isMouseDown = false, isMouseOver = false;\r
+var detail = 50, strhex = "0123456789ABCDEF", i, isMouseDown = false, isMouseOver = false;\r
 \r
 var colors = [\r
        "#000000","#000033","#000066","#000099","#0000cc","#0000ff","#330000","#330033",\r
@@ -33,37 +33,41 @@ var colors = [
 ];\r
 \r
 var named = {\r
-       '#F0F8FF':'AliceBlue','#FAEBD7':'AntiqueWhite','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige',\r
-       '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'BlanchedAlmond','#0000FF':'Blue','#8A2BE2':'BlueViolet','#A52A2A':'Brown',\r
-       '#DEB887':'BurlyWood','#5F9EA0':'CadetBlue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'CornflowerBlue',\r
-       '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'DarkBlue','#008B8B':'DarkCyan','#B8860B':'DarkGoldenRod',\r
-       '#A9A9A9':'DarkGray','#A9A9A9':'DarkGrey','#006400':'DarkGreen','#BDB76B':'DarkKhaki','#8B008B':'DarkMagenta','#556B2F':'DarkOliveGreen',\r
-       '#FF8C00':'Darkorange','#9932CC':'DarkOrchid','#8B0000':'DarkRed','#E9967A':'DarkSalmon','#8FBC8F':'DarkSeaGreen','#483D8B':'DarkSlateBlue',\r
-       '#2F4F4F':'DarkSlateGray','#2F4F4F':'DarkSlateGrey','#00CED1':'DarkTurquoise','#9400D3':'DarkViolet','#FF1493':'DeepPink','#00BFFF':'DeepSkyBlue',\r
-       '#696969':'DimGray','#696969':'DimGrey','#1E90FF':'DodgerBlue','#B22222':'FireBrick','#FFFAF0':'FloralWhite','#228B22':'ForestGreen',\r
-       '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'GhostWhite','#FFD700':'Gold','#DAA520':'GoldenRod','#808080':'Gray','#808080':'Grey',\r
-       '#008000':'Green','#ADFF2F':'GreenYellow','#F0FFF0':'HoneyDew','#FF69B4':'HotPink','#CD5C5C':'IndianRed','#4B0082':'Indigo','#FFFFF0':'Ivory',\r
-       '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'LavenderBlush','#7CFC00':'LawnGreen','#FFFACD':'LemonChiffon','#ADD8E6':'LightBlue',\r
-       '#F08080':'LightCoral','#E0FFFF':'LightCyan','#FAFAD2':'LightGoldenRodYellow','#D3D3D3':'LightGray','#D3D3D3':'LightGrey','#90EE90':'LightGreen',\r
-       '#FFB6C1':'LightPink','#FFA07A':'LightSalmon','#20B2AA':'LightSeaGreen','#87CEFA':'LightSkyBlue','#778899':'LightSlateGray','#778899':'LightSlateGrey',\r
-       '#B0C4DE':'LightSteelBlue','#FFFFE0':'LightYellow','#00FF00':'Lime','#32CD32':'LimeGreen','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon',\r
-       '#66CDAA':'MediumAquaMarine','#0000CD':'MediumBlue','#BA55D3':'MediumOrchid','#9370D8':'MediumPurple','#3CB371':'MediumSeaGreen','#7B68EE':'MediumSlateBlue',\r
-       '#00FA9A':'MediumSpringGreen','#48D1CC':'MediumTurquoise','#C71585':'MediumVioletRed','#191970':'MidnightBlue','#F5FFFA':'MintCream','#FFE4E1':'MistyRose','#FFE4B5':'Moccasin',\r
-       '#FFDEAD':'NavajoWhite','#000080':'Navy','#FDF5E6':'OldLace','#808000':'Olive','#6B8E23':'OliveDrab','#FFA500':'Orange','#FF4500':'OrangeRed','#DA70D6':'Orchid',\r
-       '#EEE8AA':'PaleGoldenRod','#98FB98':'PaleGreen','#AFEEEE':'PaleTurquoise','#D87093':'PaleVioletRed','#FFEFD5':'PapayaWhip','#FFDAB9':'PeachPuff',\r
-       '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'PowderBlue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'RosyBrown','#4169E1':'RoyalBlue',\r
-       '#8B4513':'SaddleBrown','#FA8072':'Salmon','#F4A460':'SandyBrown','#2E8B57':'SeaGreen','#FFF5EE':'SeaShell','#A0522D':'Sienna','#C0C0C0':'Silver',\r
-       '#87CEEB':'SkyBlue','#6A5ACD':'SlateBlue','#708090':'SlateGray','#708090':'SlateGrey','#FFFAFA':'Snow','#00FF7F':'SpringGreen',\r
-       '#4682B4':'SteelBlue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet',\r
-       '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'WhiteSmoke','#FFFF00':'Yellow','#9ACD32':'YellowGreen'\r
+       '#F0F8FF':'Alice Blue','#FAEBD7':'Antique White','#00FFFF':'Aqua','#7FFFD4':'Aquamarine','#F0FFFF':'Azure','#F5F5DC':'Beige',\r
+       '#FFE4C4':'Bisque','#000000':'Black','#FFEBCD':'Blanched Almond','#0000FF':'Blue','#8A2BE2':'Blue Violet','#A52A2A':'Brown',\r
+       '#DEB887':'Burly Wood','#5F9EA0':'Cadet Blue','#7FFF00':'Chartreuse','#D2691E':'Chocolate','#FF7F50':'Coral','#6495ED':'Cornflower Blue',\r
+       '#FFF8DC':'Cornsilk','#DC143C':'Crimson','#00FFFF':'Cyan','#00008B':'Dark Blue','#008B8B':'Dark Cyan','#B8860B':'Dark Golden Rod',\r
+       '#A9A9A9':'Dark Gray','#A9A9A9':'Dark Grey','#006400':'Dark Green','#BDB76B':'Dark Khaki','#8B008B':'Dark Magenta','#556B2F':'Dark Olive Green',\r
+       '#FF8C00':'Darkorange','#9932CC':'Dark Orchid','#8B0000':'Dark Red','#E9967A':'Dark Salmon','#8FBC8F':'Dark Sea Green','#483D8B':'Dark Slate Blue',\r
+       '#2F4F4F':'Dark Slate Gray','#2F4F4F':'Dark Slate Grey','#00CED1':'Dark Turquoise','#9400D3':'Dark Violet','#FF1493':'Deep Pink','#00BFFF':'Deep Sky Blue',\r
+       '#696969':'Dim Gray','#696969':'Dim Grey','#1E90FF':'Dodger Blue','#B22222':'Fire Brick','#FFFAF0':'Floral White','#228B22':'Forest Green',\r
+       '#FF00FF':'Fuchsia','#DCDCDC':'Gainsboro','#F8F8FF':'Ghost White','#FFD700':'Gold','#DAA520':'Golden Rod','#808080':'Gray','#808080':'Grey',\r
+       '#008000':'Green','#ADFF2F':'Green Yellow','#F0FFF0':'Honey Dew','#FF69B4':'Hot Pink','#CD5C5C':'Indian Red','#4B0082':'Indigo','#FFFFF0':'Ivory',\r
+       '#F0E68C':'Khaki','#E6E6FA':'Lavender','#FFF0F5':'Lavender Blush','#7CFC00':'Lawn Green','#FFFACD':'Lemon Chiffon','#ADD8E6':'Light Blue',\r
+       '#F08080':'Light Coral','#E0FFFF':'Light Cyan','#FAFAD2':'Light Golden Rod Yellow','#D3D3D3':'Light Gray','#D3D3D3':'Light Grey','#90EE90':'Light Green',\r
+       '#FFB6C1':'Light Pink','#FFA07A':'Light Salmon','#20B2AA':'Light Sea Green','#87CEFA':'Light Sky Blue','#778899':'Light Slate Gray','#778899':'Light Slate Grey',\r
+       '#B0C4DE':'Light Steel Blue','#FFFFE0':'Light Yellow','#00FF00':'Lime','#32CD32':'Lime Green','#FAF0E6':'Linen','#FF00FF':'Magenta','#800000':'Maroon',\r
+       '#66CDAA':'Medium Aqua Marine','#0000CD':'Medium Blue','#BA55D3':'Medium Orchid','#9370D8':'Medium Purple','#3CB371':'Medium Sea Green','#7B68EE':'Medium Slate Blue',\r
+       '#00FA9A':'Medium Spring Green','#48D1CC':'Medium Turquoise','#C71585':'Medium Violet Red','#191970':'Midnight Blue','#F5FFFA':'Mint Cream','#FFE4E1':'Misty Rose','#FFE4B5':'Moccasin',\r
+       '#FFDEAD':'Navajo White','#000080':'Navy','#FDF5E6':'Old Lace','#808000':'Olive','#6B8E23':'Olive Drab','#FFA500':'Orange','#FF4500':'Orange Red','#DA70D6':'Orchid',\r
+       '#EEE8AA':'Pale Golden Rod','#98FB98':'Pale Green','#AFEEEE':'Pale Turquoise','#D87093':'Pale Violet Red','#FFEFD5':'Papaya Whip','#FFDAB9':'Peach Puff',\r
+       '#CD853F':'Peru','#FFC0CB':'Pink','#DDA0DD':'Plum','#B0E0E6':'Powder Blue','#800080':'Purple','#FF0000':'Red','#BC8F8F':'Rosy Brown','#4169E1':'Royal Blue',\r
+       '#8B4513':'Saddle Brown','#FA8072':'Salmon','#F4A460':'Sandy Brown','#2E8B57':'Sea Green','#FFF5EE':'Sea Shell','#A0522D':'Sienna','#C0C0C0':'Silver',\r
+       '#87CEEB':'Sky Blue','#6A5ACD':'Slate Blue','#708090':'Slate Gray','#708090':'Slate Grey','#FFFAFA':'Snow','#00FF7F':'Spring Green',\r
+       '#4682B4':'Steel Blue','#D2B48C':'Tan','#008080':'Teal','#D8BFD8':'Thistle','#FF6347':'Tomato','#40E0D0':'Turquoise','#EE82EE':'Violet',\r
+       '#F5DEB3':'Wheat','#FFFFFF':'White','#F5F5F5':'White Smoke','#FFFF00':'Yellow','#9ACD32':'Yellow Green'\r
 };\r
 \r
+var namedLookup = {};\r
+\r
 function init() {\r
-       var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color'));\r
+       var inputColor = convertRGBToHex(tinyMCEPopup.getWindowArg('input_color')), key, value;\r
 \r
        tinyMCEPopup.resizeToInnerSize();\r
 \r
        generatePicker();\r
+       generateWebColors();\r
+       generateNamedColors();\r
 \r
        if (inputColor) {\r
                changeFinalColor(inputColor);\r
@@ -73,6 +77,45 @@ function init() {
                if (col)\r
                        updateLight(col.r, col.g, col.b);\r
        }\r
+       \r
+       for (key in named) {\r
+               value = named[key];\r
+               namedLookup[value.replace(/\s+/, '').toLowerCase()] = key.replace(/#/, '').toLowerCase();\r
+       }\r
+}\r
+\r
+function toHexColor(color) {\r
+       var matches, red, green, blue, toInt = parseInt;\r
+\r
+       function hex(value) {\r
+               value = parseInt(value).toString(16);\r
+\r
+               return value.length > 1 ? value : '0' + value; // Padd with leading zero\r
+       };\r
+\r
+       color = color.replace(/[\s#]+/g, '').toLowerCase();\r
+       color = namedLookup[color] || color;\r
+       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);\r
+\r
+       if (matches) {\r
+               if (matches[1]) {\r
+                       red = toInt(matches[1]);\r
+                       green = toInt(matches[2]);\r
+                       blue = toInt(matches[3]);\r
+               } else if (matches[4]) {\r
+                       red = toInt(matches[4], 16);\r
+                       green = toInt(matches[5], 16);\r
+                       blue = toInt(matches[6], 16);\r
+               } else if (matches[7]) {\r
+                       red = toInt(matches[7] + matches[7], 16);\r
+                       green = toInt(matches[8] + matches[8], 16);\r
+                       blue = toInt(matches[9] + matches[9], 16);\r
+               }\r
+\r
+               return '#' + hex(red) + hex(green) + hex(blue);\r
+       }\r
+\r
+       return '';\r
 }\r
 \r
 function insertAction() {\r
@@ -81,7 +124,7 @@ function insertAction() {
        tinyMCEPopup.restoreSelection();\r
 \r
        if (f)\r
-               f(color);\r
+               f(toHexColor(color));\r
 \r
        tinyMCEPopup.close();\r
 }\r
@@ -91,7 +134,7 @@ function showColor(color, name) {
                document.getElementById("colorname").innerHTML = name;\r
 \r
        document.getElementById("preview").style.backgroundColor = color;\r
-       document.getElementById("color").value = color.toLowerCase();\r
+       document.getElementById("color").value = color.toUpperCase();\r
 }\r
 \r
 function convertRGBToHex(col) {\r
@@ -153,23 +196,40 @@ function generateWebColors() {
        if (el.className == 'generated')\r
                return;\r
 \r
-       h += '<table border="0" cellspacing="1" cellpadding="0">'\r
+       // TODO: VoiceOver doesn't seem to support legend as a label referenced by labelledby.\r
+       h += '<div role="listbox" aria-labelledby="webcolors_title" tabindex="0"><table role="presentation" border="0" cellspacing="1" cellpadding="0">'\r
                + '<tr>';\r
 \r
        for (i=0; i<colors.length; i++) {\r
                h += '<td bgcolor="' + colors[i] + '" width="10" height="10">'\r
-                       + '<a href="javascript:insertAction();" onfocus="showColor(\'' + colors[i] +  '\');" onmouseover="showColor(\'' + colors[i] +  '\');" style="display:block;width:10px;height:10px;overflow:hidden;">'\r
-                       + '</a></td>';\r
+                       + '<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;">';\r
+               if (tinyMCEPopup.editor.forcedHighContrastMode) {\r
+                       h += '<canvas class="mceColorSwatch" height="10" width="10" data-color="' + colors[i] + '"></canvas>';\r
+               }\r
+               h += '<span class="mceVoiceLabel" style="display:none;" id="web_colors_' + i + '">' + colors[i].toUpperCase() + '</span>';\r
+               h += '</a></td>';\r
                if ((i+1) % 18 == 0)\r
                        h += '</tr><tr>';\r
        }\r
 \r
-       h += '</table>';\r
+       h += '</table></div>';\r
 \r
        el.innerHTML = h;\r
        el.className = 'generated';\r
+\r
+       paintCanvas(el);\r
+       enableKeyboardNavigation(el.firstChild);\r
 }\r
 \r
+function paintCanvas(el) {\r
+       tinyMCEPopup.getWin().tinymce.each(tinyMCEPopup.dom.select('canvas.mceColorSwatch', el), function(canvas) {\r
+               var context;\r
+               if (canvas.getContext && (context = canvas.getContext("2d"))) {\r
+                       context.fillStyle = canvas.getAttribute('data-color');\r
+                       context.fillRect(0, 0, 10, 10);\r
+               }\r
+       });\r
+}\r
 function generateNamedColors() {\r
        var el = document.getElementById('namedcolors'), h = '', n, v, i = 0;\r
 \r
@@ -178,11 +238,27 @@ function generateNamedColors() {
 \r
        for (n in named) {\r
                v = named[n];\r
-               h += '<a href="javascript:insertAction();" onmouseover="showColor(\'' + n +  '\',\'' + v + '\');" style="background-color: ' + n + '"><!-- IE --></a>'\r
+               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 + '">';\r
+               if (tinyMCEPopup.editor.forcedHighContrastMode) {\r
+                       h += '<canvas class="mceColorSwatch" height="10" width="10" data-color="' + colors[i] + '"></canvas>';\r
+               }\r
+               h += '<span class="mceVoiceLabel" style="display:none;" id="named_colors_' + i + '">' + v + '</span>';\r
+               h += '</a>';\r
+               i++;\r
        }\r
 \r
        el.innerHTML = h;\r
        el.className = 'generated';\r
+\r
+       paintCanvas(el);\r
+       enableKeyboardNavigation(el);\r
+}\r
+\r
+function enableKeyboardNavigation(el) {\r
+       tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', {\r
+               root: el,\r
+               items: tinyMCEPopup.dom.select('a', el)\r
+       }, tinyMCEPopup.dom);\r
 }\r
 \r
 function dechex(n) {\r
index 6423d908095f0f1a221c9dcecde7ca281137b665..257477282f041c6f8d9e9b2a6106f5fd4517635a 100644 (file)
@@ -77,7 +77,7 @@ var ImageDialog = {
                        args.style = this.styleVal;\r
 \r
                tinymce.extend(args, {\r
-                       src : f.src.value,\r
+                       src : f.src.value.replace(/ /g, '%20'),\r
                        alt : f.alt.value,\r
                        width : f.width.value,\r
                        height : f.height.value\r
@@ -87,6 +87,8 @@ var ImageDialog = {
 \r
                if (el && el.nodeName == 'IMG') {\r
                        ed.dom.setAttribs(el, args);\r
+                       tinyMCEPopup.editor.execCommand('mceRepaint');\r
+                       tinyMCEPopup.editor.focus();\r
                } else {\r
                        ed.execCommand('mceInsertContent', false, '<img id="__mce_tmp" />', {skip_undo : 1});\r
                        ed.dom.setAttribs('__mce_tmp', args);\r
index f67a5bc82810d5cd57d3b6a05fdf4bee9e199b2c..53ff409e7962f0d4f2d686922e33eff2ae53714b 100644 (file)
@@ -31,7 +31,7 @@ var LinkDialog = {
        },\r
 \r
        update : function() {\r
-               var f = document.forms[0], ed = tinyMCEPopup.editor, e, b;\r
+               var f = document.forms[0], ed = tinyMCEPopup.editor, e, b, href = f.href.value.replace(/ /g, '%20');\r
 \r
                tinyMCEPopup.restoreSelection();\r
                e = ed.dom.getParent(ed.selection.getNode(), 'A');\r
@@ -39,7 +39,6 @@ var LinkDialog = {
                // Remove element if there is no href\r
                if (!f.href.value) {\r
                        if (e) {\r
-                               tinyMCEPopup.execCommand("mceBeginUndoLevel");\r
                                b = ed.selection.getBookmark();\r
                                ed.dom.remove(e, 1);\r
                                ed.selection.moveToBookmark(b);\r
@@ -49,19 +48,17 @@ var LinkDialog = {
                        }\r
                }\r
 \r
-               tinyMCEPopup.execCommand("mceBeginUndoLevel");\r
-\r
                // Create new anchor elements\r
                if (e == null) {\r
                        ed.getDoc().execCommand("unlink", false, null);\r
-                       tinyMCEPopup.execCommand("CreateLink", false, "#mce_temp_url#", {skip_undo : 1});\r
+                       tinyMCEPopup.execCommand("mceInsertLink", false, "#mce_temp_url#", {skip_undo : 1});\r
 \r
                        tinymce.each(ed.dom.select("a"), function(n) {\r
                                if (ed.dom.getAttrib(n, 'href') == '#mce_temp_url#') {\r
                                        e = n;\r
 \r
                                        ed.dom.setAttribs(e, {\r
-                                               href : f.href.value,\r
+                                               href : href,\r
                                                title : f.linktitle.value,\r
                                                target : f.target_list ? getSelectValue(f, "target_list") : null,\r
                                                'class' : f.class_list ? getSelectValue(f, "class_list") : null\r
@@ -70,7 +67,7 @@ var LinkDialog = {
                        });\r
                } else {\r
                        ed.dom.setAttribs(e, {\r
-                               href : f.href.value,\r
+                               href : href,\r
                                title : f.linktitle.value,\r
                                target : f.target_list ? getSelectValue(f, "target_list") : null,\r
                                'class' : f.class_list ? getSelectValue(f, "class_list") : null\r
index 279328614c5ee8a0077295a0ff7814a24d723922..84546ad52ebc461ccdebb02e1762e8c9ea760744 100644 (file)
@@ -44,19 +44,13 @@ function toggleWordWrap(elm) {
                setWrap('off');\r
 }\r
 \r
-var wHeight=0, wWidth=0, owHeight=0, owWidth=0;\r
-\r
 function resizeInputs() {\r
-       var el = document.getElementById('htmlSource');\r
+       var vp = tinyMCEPopup.dom.getViewPort(window), el;\r
 \r
-       if (!tinymce.isIE) {\r
-                wHeight = self.innerHeight - 65;\r
-                wWidth = self.innerWidth - 16;\r
-       } else {\r
-                wHeight = document.body.clientHeight - 70;\r
-                wWidth = document.body.clientWidth - 16;\r
-       }\r
+       el = document.getElementById('htmlSource');\r
 \r
-       el.style.height = Math.abs(wHeight) + 'px';\r
-       el.style.width  = Math.abs(wWidth) + 'px';\r
+       if (el) {\r
+               el.style.width = (vp.w - 20) + 'px';\r
+               el.style.height = (vp.h - 65) + 'px';\r
+       }\r
 }\r
index 69694b1f9f8cd4ecfe36a64b7ccb80014458a5fa..fbf29893fe02656ab99c9771769f544215ad966b 100644 (file)
@@ -58,5 +58,11 @@ clipboard_msg:"Copy/Cut/Paste is not available in Mozilla and Firefox.\r\nDo you
 path:"Path",\r
 newdocument:"Are you sure you want clear all contents?",\r
 toolbar_focus:"Jump to tool buttons - Alt+Q, Jump to editor - Alt-Z, Jump to element path - Alt-X",\r
-more_colors:"More colors"\r
-});
\ No newline at end of file
+more_colors:"More colors",\r
+\r
+// Accessibility Strings\r
+shortcuts_desc:'Accessibility Help',\r
+help_shortcut:'. Press ALT F10 for toolbar. Press ALT 0 for help.',\r
+rich_text_area:"Rich Text Area",\r
+toolbar:"Toolbar"\r
+});\r
index 9d124d7db69b022cdca56f02bc4d418e1f4b25c3..0a459beb5ca3e31ba7d1ae00dce8a0b0915ff2a6 100644 (file)
@@ -10,6 +10,7 @@ about_version:"Version",
 about_loaded:"Loaded plugins",\r
 anchor_title:"Insert/edit anchor",\r
 anchor_name:"Anchor name",\r
+anchor_invalid:"Please specify a valid anchor name.",\r
 code_title:"HTML Source Editor",\r
 code_wordwrap:"Word wrap",\r
 colorpicker_title:"Select a color",\r
@@ -45,7 +46,9 @@ link_target:"Target",
 link_target_same:"Open link in the same window",\r
 link_target_blank:"Open link in a new window",\r
 link_titlefield:"Title",\r
-link_is_email:"The URL you entered seems to be an email address, do you want to add the required mailto: prefix?",\r
-link_is_external:"The URL you entered seems to external link, do you want to add the required http:// prefix?",\r
-link_list:"Link list"\r
+link_is_email:"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?",\r
+link_is_external:"The URL you entered seems to be an external link. Do you want to add the required http:// prefix?",\r
+link_list:"Link list",\r
+accessibility_help:"Accessibility Help",\r
+accessibility_usage_title:"General Usage"\r
 });
\ No newline at end of file
index 7565b9ae8b23f0c01cd868e59a69bbaa1f0dbadc..5d9dea9b8c2a91dd1fc00a5839cf91da3ea31425 100644 (file)
 \r
        <div class="panel_wrapper">\r
                <div id="general_panel" class="panel current">\r
-\r
-               <table border="0" cellpadding="4" cellspacing="0">\r
-          <tr>\r
-            <td class="nowrap"><label for="href">{#advanced_dlg.link_url}</label></td>\r
-            <td><table border="0" cellspacing="0" cellpadding="0"> \r
-                                 <tr> \r
-                                       <td><input id="href" name="href" type="text" class="mceFocus" value="" style="width: 200px" onchange="LinkDialog.checkPrefix(this);" /></td> \r
-                                       <td id="hrefbrowsercontainer">&nbsp;</td>\r
-                                 </tr> \r
-                               </table></td>\r
-          </tr>\r
-                 <tr>\r
-                       <td><label for="link_list">{#advanced_dlg.link_list}</label></td>\r
-                       <td><select id="link_list" name="link_list" onchange="document.getElementById('href').value=this.options[this.selectedIndex].value;"></select></td>\r
-                 </tr>\r
-               <tr>\r
-                       <td><label id="targetlistlabel" for="targetlist">{#advanced_dlg.link_target}</label></td>\r
-                       <td><select id="target_list" name="target_list"></select></td>\r
-               </tr>\r
-          <tr>\r
-            <td class="nowrap"><label for="linktitle">{#advanced_dlg.link_titlefield}</label></td>\r
-            <td><input id="linktitle" name="linktitle" type="text" value="" style="width: 200px" /></td>\r
-          </tr>\r
-                       <tr>\r
-                               <td><label for="class_list">{#class_name}</label></td>\r
-                               <td><select id="class_list" name="class_list"></select></td>\r
-                       </tr>\r
-        </table>\r
+                       <table border="0" cellpadding="4" cellspacing="0">\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="href">{#advanced_dlg.link_url}</label></td>\r
+                                       <td><table border="0" cellspacing="0" cellpadding="0"> \r
+                                               <tr> \r
+                                                       <td><input id="href" name="href" type="text" class="mceFocus" value="" style="width: 200px" onchange="LinkDialog.checkPrefix(this);" /></td> \r
+                                                       <td id="hrefbrowsercontainer">&nbsp;</td>\r
+                                               </tr> \r
+                                       </table></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td><label for="link_list">{#advanced_dlg.link_list}</label></td>\r
+                                       <td><select id="link_list" name="link_list" onchange="document.getElementById('href').value=this.options[this.selectedIndex].value;"></select></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td><label id="targetlistlabel" for="targetlist">{#advanced_dlg.link_target}</label></td>\r
+                                       <td><select id="target_list" name="target_list"></select></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td class="nowrap"><label for="linktitle">{#advanced_dlg.link_titlefield}</label></td>\r
+                                       <td><input id="linktitle" name="linktitle" type="text" value="" style="width: 200px" /></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td><label for="class_list">{#class_name}</label></td>\r
+                                       <td><select id="class_list" name="class_list"></select></td>\r
+                               </tr>\r
+                       </table>\r
                </div>\r
        </div>\r
 \r
index 36f38aba296a50bf8e8321df4d4b57ddc9a01c96..03634668e72380f35fd0af48bbfecbc50f44d6f7 100644 (file)
@@ -1,6 +1,7 @@
 body, td, pre {color:#000; font-family:Verdana, Arial, Helvetica, sans-serif; font-size:10px; margin:8px;}\r
 body {background:#FFF;}\r
 body.mceForceColors {background:#FFF; color:#000;}\r
+body.mceBrowserDefaults {background:transparent; color:inherit; font-size:inherit; font-family:inherit;}\r
 h1 {font-size: 2em}\r
 h2 {font-size: 1.5em}\r
 h3 {font-size: 1.17em}\r
@@ -9,6 +10,7 @@ h5 {font-size: .83em}
 h6 {font-size: .75em}\r
 .mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;}\r
 a.mceItemAnchor {display:inline-block; width:11px !important; height:11px  !important; background:url(img/items.gif) no-repeat 0 0;}\r
+span.mceItemNbsp {background: #DDD}\r
 td.mceSelected, th.mceSelected {background-color:#3399ff !important}\r
 img {border:0;}\r
 table {cursor:default}\r
@@ -33,3 +35,13 @@ scrollbar-track-color:#F5F5F5;
 \r
 img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px}\r
 font[face=mceinline] {font-family:inherit !important}\r
+\r
+.mceItemMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc}\r
+.mceItemShockWave {background-image:url(../../img/shockwave.gif)}\r
+.mceItemFlash {background-image:url(../../img/flash.gif)}\r
+.mceItemQuickTime {background-image:url(../../img/quicktime.gif)}\r
+.mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)}\r
+.mceItemRealMedia {background-image:url(../../img/realmedia.gif)}\r
+.mceItemVideo {background-image:url(../../img/video.gif)}\r
+.mceItemIframe {background-image:url(../../img/iframe.gif)}\r
+.mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;}\r
index 0049c7b3d0f1789c800954edc95986a5886acbca..556b510714dd456331d36e5ec9f709d7cee0fb4f 100644 (file)
@@ -4,8 +4,8 @@
 .defaultSkin table td {vertical-align:middle}\r
 \r
 /* Containers */\r
-.defaultSkin table {direction:ltr; background:#F0F0EE}\r
-.defaultSkin iframe {display:block; background:#FFF}\r
+.defaultSkin table {direction:ltr;background:transparent}\r
+.defaultSkin iframe {display:block;}\r
 .defaultSkin .mceToolbar {height:26px}\r
 .defaultSkin .mceLeft {text-align:left}\r
 .defaultSkin .mceRight {text-align:right}\r
@@ -20,9 +20,9 @@
 .defaultSkin table.mceLayout tr.mceFirst td {border-top:1px solid #CCC}\r
 .defaultSkin table.mceLayout tr.mceLast td {border-bottom:1px solid #CCC}\r
 .defaultSkin table.mceToolbar, .defaultSkin tr.mceFirst .mceToolbar tr td, .defaultSkin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0;}\r
-.defaultSkin td.mceToolbar {padding-top:1px; vertical-align:top}\r
+.defaultSkin td.mceToolbar {background:#F0F0EE; padding-top:1px; vertical-align:top}\r
 .defaultSkin .mceIframeContainer {border-top:1px solid #CCC; border-bottom:1px solid #CCC}\r
-.defaultSkin .mceStatusbar {font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px}\r
+.defaultSkin .mceStatusbar {background:#F0F0EE; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; display:block; height:20px}\r
 .defaultSkin .mceStatusbar div {float:left; margin:2px}\r
 .defaultSkin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0}\r
 .defaultSkin .mceStatusbar a:hover {text-decoration:underline}\r
index 3cea5ff1ce3c296e739b37e09bbc111fc52e17bb..4ac4e4dfb3d16f4aba0b6f1c6595127dc3e27978 100644 (file)
@@ -9,6 +9,7 @@ h5 {font-size: .83em}
 h6 {font-size: .75em}\r
 .mceItemTable, .mceItemTable td, .mceItemTable th, .mceItemTable caption, .mceItemVisualAid {border: 1px dashed #BBB;}\r
 a.mceItemAnchor {display:inline-block; width:11px !important; height:11px  !important; background:url(../default/img/items.gif) no-repeat 0 0;}\r
+span.mceItemNbsp {background: #DDD}\r
 td.mceSelected, th.mceSelected {background-color:#3399ff !important}\r
 img {border:0;}\r
 table {cursor:default}\r
@@ -33,3 +34,13 @@ scrollbar-track-color:#F5F5F5;
 \r
 img:-moz-broken {-moz-force-broken-image-icon:1; width:24px; height:24px}\r
 font[face=mceinline] {font-family:inherit !important}\r
+\r
+.mceItemMedia {border:1px dotted #cc0000; background-position:center; background-repeat:no-repeat; background-color:#ffffcc}\r
+.mceItemShockWave {background-image:url(../../img/shockwave.gif)}\r
+.mceItemFlash {background-image:url(../../img/flash.gif)}\r
+.mceItemQuickTime {background-image:url(../../img/quicktime.gif)}\r
+.mceItemWindowsMedia {background-image:url(../../img/windowsmedia.gif)}\r
+.mceItemRealMedia {background-image:url(../../img/realmedia.gif)}\r
+.mceItemVideo {background-image:url(../../img/video.gif)}\r
+.mceItemIframe {background-image:url(../../img/iframe.gif)}\r
+.mcePageBreak {display:block;border:0;width:100%;height:12px;border-top:1px dotted #ccc;margin-top:15px;background:#fff url(../../img/pagebreak.gif) no-repeat center top;}\r
index e3af1396e4c29259bb12be1cb0c3dd3e82f7b2da..ec087722481db858c53b6cf7a637988e254a76b5 100644 (file)
@@ -114,3 +114,4 @@ h3 {font-size:14px;}
 #colorpicker #namedcolors {width:150px;}\r
 #colorpicker #namedcolors a {display:block; float:left; width:10px; height:10px; margin:1px 1px 0 0; overflow:hidden;}\r
 #colorpicker #colornamecontainer {margin-top:5px;}\r
+#colorpicker #picker_panel fieldset {margin:auto;width:325px;}\r
index a6253976afc3755ed06a2cbe6b40353f67a8b3f6..df596bf781ef3507227e960bd14f8fce6537f833 100644 (file)
@@ -4,8 +4,8 @@
 .o2k7Skin table td {vertical-align:middle}\r
 \r
 /* Containers */\r
-.o2k7Skin table {background:#E5EFFD}\r
-.o2k7Skin iframe {display:block; background:#FFF}\r
+.o2k7Skin table {background:transparent}\r
+.o2k7Skin iframe {display:block;}\r
 .o2k7Skin .mceToolbar {height:26px}\r
 \r
 /* External */\r
@@ -19,7 +19,8 @@
 .o2k7Skin table.mceLayout tr.mceLast td {border-bottom:1px solid #ABC6DD}\r
 .o2k7Skin table.mceToolbar, .o2k7Skin tr.mceFirst .mceToolbar tr td, .o2k7Skin tr.mceLast .mceToolbar tr td {border:0; margin:0; padding:0}\r
 .o2k7Skin .mceIframeContainer {border-top:1px solid #ABC6DD; border-bottom:1px solid #ABC6DD}\r
-.o2k7Skin .mceStatusbar {display:block; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; height:20px}\r
+.o2k7Skin td.mceToolbar{background:#E5EFFD}\r
+.o2k7Skin .mceStatusbar {background:#E5EFFD; display:block; font-family:'MS Sans Serif',sans-serif,Verdana,Arial; font-size:9pt; line-height:16px; overflow:visible; color:#000; height:20px}\r
 .o2k7Skin .mceStatusbar div {float:left; padding:2px}\r
 .o2k7Skin .mceStatusbar a.mceResize {display:block; float:right; background:url(../../img/icons.gif) -800px 0; width:20px; height:20px; cursor:se-resize; outline:0}\r
 .o2k7Skin .mceStatusbar a:hover {text-decoration:underline}\r
@@ -62,7 +63,7 @@
 .o2k7Skin select.mceListBox {font-family:Tahoma,Verdana,Arial,Helvetica; font-size:12px; border:1px solid #b3c7e1; background:#FFF;}\r
 \r
 /* SplitButton */\r
-.o2k7Skin .mceSplitButton, .o2k7Skin .mceSplitButton a, .o2k7Skin .mceSplitButton span {display:block; height:22px}\r
+.o2k7Skin .mceSplitButton, .o2k7Skin .mceSplitButton a, .o2k7Skin .mceSplitButton span {display:block; height:22px; direction:ltr}\r
 .o2k7Skin .mceSplitButton {background:url(img/button_bg.png)}\r
 .o2k7Skin .mceSplitButton a.mceAction {width:22px}\r
 .o2k7Skin .mceSplitButton span.mceAction {width:22px; background-image:url(../../img/icons.gif)}\r
index 153f0c38a6c69b897b9d7dbb5fd66a75991048bc..50c9b76a2d4da3ebdebba7cf52a027a212929555 100644 (file)
@@ -1,6 +1,6 @@
 /* Black */\r
 .o2k7SkinBlack .mceToolbar .mceToolbarStart span, .o2k7SkinBlack .mceToolbar .mceToolbarEnd span, .o2k7SkinBlack .mceButton, .o2k7SkinBlack .mceSplitButton, .o2k7SkinBlack .mceSeparator, .o2k7SkinBlack .mceSplitButton a.mceOpen, .o2k7SkinBlack .mceListBox a.mceOpen {background-image:url(img/button_bg_black.png)}\r
-.o2k7SkinBlack table, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack .mceMenuItemTitle span.mceText, .o2k7SkinBlack .mceStatusbar div, .o2k7SkinBlack .mceStatusbar span, .o2k7SkinBlack .mceStatusbar a {background:#535353; color:#FFF}\r
+.o2k7SkinBlack td.mceToolbar, .o2k7SkinBlack td.mceStatusbar, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack .mceMenuItemTitle span.mceText, .o2k7SkinBlack .mceStatusbar div, .o2k7SkinBlack .mceStatusbar span, .o2k7SkinBlack .mceStatusbar a {background:#535353; color:#FFF}\r
 .o2k7SkinBlack table.mceListBoxEnabled .mceText, o2k7SkinBlack .mceListBox .mceText {background:#FFF; border:1px solid #CBCFD4; border-bottom-color:#989FA9; border-right:0}\r
 .o2k7SkinBlack table.mceListBoxEnabled:hover .mceText, .o2k7SkinBlack .mceListBoxHover .mceText, .o2k7SkinBlack .mceListBoxSelected .mceText {background:#FFF; border:1px solid #FFBD69; border-right:0}\r
 .o2k7SkinBlack .mceExternalToolbar, .o2k7SkinBlack .mceListBox .mceText, .o2k7SkinBlack div.mceMenu, .o2k7SkinBlack table.mceLayout, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack table.mceLayout tr.mceFirst td, .o2k7SkinBlack table.mceLayout, .o2k7SkinBlack .mceMenuItemTitle a, .o2k7SkinBlack table.mceLayout tr.mceLast td, .o2k7SkinBlack .mceIframeContainer {border-color: #535353;}\r
index 7fe3b45e1264ad10f89c696ecc3b0e0801a96653..960a8e475554f8100b5419042a270984ec99103b 100644 (file)
@@ -1,5 +1,5 @@
 /* Silver */\r
 .o2k7SkinSilver .mceToolbar .mceToolbarStart span, .o2k7SkinSilver .mceButton, .o2k7SkinSilver .mceSplitButton, .o2k7SkinSilver .mceSeparator, .o2k7SkinSilver .mceSplitButton a.mceOpen, .o2k7SkinSilver .mceListBox a.mceOpen {background-image:url(img/button_bg_silver.png)}\r
-.o2k7SkinSilver table, .o2k7SkinSilver .mceMenuItemTitle a {background:#eee}\r
+.o2k7SkinSilver td.mceToolbar, .o2k7SkinSilver td.mceStatusbar, .o2k7SkinSilver .mceMenuItemTitle a {background:#eee}\r
 .o2k7SkinSilver .mceListBox .mceText {background:#FFF}\r
 .o2k7SkinSilver .mceExternalToolbar, .o2k7SkinSilver .mceListBox .mceText, .o2k7SkinSilver div.mceMenu, .o2k7SkinSilver table.mceLayout, .o2k7SkinSilver .mceMenuItemTitle a, .o2k7SkinSilver table.mceLayout tr.mceFirst td, .o2k7SkinSilver table.mceLayout, .o2k7SkinSilver .mceMenuItemTitle a, .o2k7SkinSilver table.mceLayout tr.mceLast td, .o2k7SkinSilver .mceIframeContainer {border-color: #bbb}\r
index 5957bbd1782e4a9727f0b708b05b0b2b419cea4f..3c6d65808a854b73e184ba7ec9a67a0790e501ff 100644 (file)
@@ -6,7 +6,7 @@
 </head>\r
 <body onresize="resizeInputs();" style="display:none; overflow:hidden;">\r
        <form name="source" onsubmit="saveContent();return false;" action="#">\r
-               <div style="float: left" class="title">{#advanced_dlg.code_title}</div>\r
+               <div style="float: left" class="title"><label for="htmlSource">{#advanced_dlg.code_title}</label></div>\r
 \r
                <div id="wrapline" style="float: right">\r
                        <input type="checkbox" name="wraped" id="wraped" onclick="toggleWordWrap(this);" class="wordWrapCode" /><label for="wraped">{#advanced_dlg.code_wordwrap}</label>\r
@@ -17,8 +17,8 @@
                <textarea name="htmlSource" id="htmlSource" rows="15" cols="100" style="width: 100%; height: 100%; font-family: 'Courier New',Courier,monospace; font-size: 12px;" dir="ltr" wrap="off" class="mceFocus"></textarea>\r
 \r
                <div class="mceActionPanel">\r
-                       <input type="submit" name="insert" value="{#update}" id="insert" />\r
-                       <input type="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" />\r
+                       <input type="submit" role="button" name="insert" value="{#update}" id="insert" />\r
+                       <input type="button" role="button" name="cancel" value="{#cancel}" onclick="tinyMCEPopup.close();" id="cancel" />\r
                </div>\r
        </form>\r
 </body>\r
index ed89abc067613b25c124f6e39af8b7d498ad0714..4b3209cc921bae7fd4ca101ccf55b0c617b890a1 100644 (file)
@@ -1 +1 @@
-(function(){var a=tinymce.DOM;tinymce.ThemeManager.requireLangPack("simple");tinymce.create("tinymce.themes.SimpleTheme",{init:function(c,d){var e=this,b=["Bold","Italic","Underline","Strikethrough","InsertUnorderedList","InsertOrderedList"],f=c.settings;e.editor=c;c.onInit.add(function(){c.onNodeChange.add(function(h,g){tinymce.each(b,function(i){g.get(i.toLowerCase()).setActive(h.queryCommandState(i))})});c.dom.loadCSS(d+"/skins/"+f.skin+"/content.css")});a.loadCSS((f.editor_css?c.documentBaseURI.toAbsolute(f.editor_css):"")||d+"/skins/"+f.skin+"/ui.css")},renderUI:function(h){var e=this,i=h.targetNode,b,c,d=e.editor,f=d.controlManager,g;i=a.insertAfter(a.create("span",{id:d.id+"_container","class":"mceEditor "+d.settings.skin+"SimpleSkin"}),i);i=g=a.add(i,"table",{cellPadding:0,cellSpacing:0,"class":"mceLayout"});i=c=a.add(i,"tbody");i=a.add(c,"tr");i=b=a.add(a.add(i,"td"),"div",{"class":"mceIframeContainer"});i=a.add(a.add(c,"tr",{"class":"last"}),"td",{"class":"mceToolbar mceLast",align:"center"});c=e.toolbar=f.createToolbar("tools1");c.add(f.createButton("bold",{title:"simple.bold_desc",cmd:"Bold"}));c.add(f.createButton("italic",{title:"simple.italic_desc",cmd:"Italic"}));c.add(f.createButton("underline",{title:"simple.underline_desc",cmd:"Underline"}));c.add(f.createButton("strikethrough",{title:"simple.striketrough_desc",cmd:"Strikethrough"}));c.add(f.createSeparator());c.add(f.createButton("undo",{title:"simple.undo_desc",cmd:"Undo"}));c.add(f.createButton("redo",{title:"simple.redo_desc",cmd:"Redo"}));c.add(f.createSeparator());c.add(f.createButton("cleanup",{title:"simple.cleanup_desc",cmd:"mceCleanup"}));c.add(f.createSeparator());c.add(f.createButton("insertunorderedlist",{title:"simple.bullist_desc",cmd:"InsertUnorderedList"}));c.add(f.createButton("insertorderedlist",{title:"simple.numlist_desc",cmd:"InsertOrderedList"}));c.renderTo(i);return{iframeContainer:b,editorContainer:d.id+"_container",sizeContainer:g,deltaHeight:-20}},getInfo:function(){return{longname:"Simple theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.ThemeManager.add("simple",tinymce.themes.SimpleTheme)})();
\ No newline at end of file
+(function(){var a=tinymce.DOM;tinymce.ThemeManager.requireLangPack("simple");tinymce.create("tinymce.themes.SimpleTheme",{init:function(c,d){var e=this,b=["Bold","Italic","Underline","Strikethrough","InsertUnorderedList","InsertOrderedList"],f=c.settings;e.editor=c;c.contentCSS.push(d+"/skins/"+f.skin+"/content.css");c.onInit.add(function(){c.onNodeChange.add(function(h,g){tinymce.each(b,function(i){g.get(i.toLowerCase()).setActive(h.queryCommandState(i))})})});a.loadCSS((f.editor_css?c.documentBaseURI.toAbsolute(f.editor_css):"")||d+"/skins/"+f.skin+"/ui.css")},renderUI:function(h){var e=this,i=h.targetNode,b,c,d=e.editor,f=d.controlManager,g;i=a.insertAfter(a.create("span",{id:d.id+"_container","class":"mceEditor "+d.settings.skin+"SimpleSkin"}),i);i=g=a.add(i,"table",{cellPadding:0,cellSpacing:0,"class":"mceLayout"});i=c=a.add(i,"tbody");i=a.add(c,"tr");i=b=a.add(a.add(i,"td"),"div",{"class":"mceIframeContainer"});i=a.add(a.add(c,"tr",{"class":"last"}),"td",{"class":"mceToolbar mceLast",align:"center"});c=e.toolbar=f.createToolbar("tools1");c.add(f.createButton("bold",{title:"simple.bold_desc",cmd:"Bold"}));c.add(f.createButton("italic",{title:"simple.italic_desc",cmd:"Italic"}));c.add(f.createButton("underline",{title:"simple.underline_desc",cmd:"Underline"}));c.add(f.createButton("strikethrough",{title:"simple.striketrough_desc",cmd:"Strikethrough"}));c.add(f.createSeparator());c.add(f.createButton("undo",{title:"simple.undo_desc",cmd:"Undo"}));c.add(f.createButton("redo",{title:"simple.redo_desc",cmd:"Redo"}));c.add(f.createSeparator());c.add(f.createButton("cleanup",{title:"simple.cleanup_desc",cmd:"mceCleanup"}));c.add(f.createSeparator());c.add(f.createButton("insertunorderedlist",{title:"simple.bullist_desc",cmd:"InsertUnorderedList"}));c.add(f.createButton("insertorderedlist",{title:"simple.numlist_desc",cmd:"InsertOrderedList"}));c.renderTo(i);return{iframeContainer:b,editorContainer:d.id+"_container",sizeContainer:g,deltaHeight:-20}},getInfo:function(){return{longname:"Simple theme",author:"Moxiecode Systems AB",authorurl:"http://tinymce.moxiecode.com",version:tinymce.majorVersion+"."+tinymce.minorVersion}}});tinymce.ThemeManager.add("simple",tinymce.themes.SimpleTheme)})();
\ No newline at end of file
index 4b862d49d62afec995fffba2a7ddb4fa904a5ee3..01ce87c58a9e25eb6cb8b3a0d331e8416099c5ee 100644 (file)
@@ -19,6 +19,7 @@
                        var t = this, states = ['Bold', 'Italic', 'Underline', 'Strikethrough', 'InsertUnorderedList', 'InsertOrderedList'], s = ed.settings;\r
 \r
                        t.editor = ed;\r
+                       ed.contentCSS.push(url + "/skins/" + s.skin + "/content.css");\r
 \r
                        ed.onInit.add(function() {\r
                                ed.onNodeChange.add(function(ed, cm) {\r
@@ -26,8 +27,6 @@
                                                cm.get(c.toLowerCase()).setActive(ed.queryCommandState(c));\r
                                        });\r
                                });\r
-\r
-                               ed.dom.loadCSS(url + "/skins/" + s.skin + "/content.css");\r
                        });\r
 \r
                        DOM.loadCSS((s.editor_css ? ed.documentBaseURI.toAbsolute(s.editor_css) : '') || url + "/skins/" + s.skin + "/ui.css");\r
index f49c5ab75ef9812a66bf6359410ed059c33e815a..8596abaa1bf81e7312925182b33fb89a6da8bef8 100644 (file)
-(function(l){var o=/^\s*|\s*$/g,q={majorVersion:"3",minorVersion:"3.7",releaseDate:"2010-06-10",_init:function(){function k(v){if(v.src&&/tiny_mce(|_gzip|_jquery|_prototype)(_dev|_src)?.js/.test(v.src)){if(/_(src|dev)\.js/g.test(v.src))j.suffix="_src";if((r=v.src.indexOf("?"))!=-1)j.query=v.src.substring(r+1);j.baseURL=v.src.substring(0,v.src.lastIndexOf("/"));if(n&&j.baseURL.indexOf("://")==-1&&j.baseURL.indexOf("/")!==0)j.baseURL=n+j.baseURL;return j.baseURL}return null}var j=this,b=document,g=
-navigator,d=g.userAgent,n,r,u;j.isOpera=l.opera&&opera.buildNumber;j.isWebKit=/WebKit/.test(d);j.isIE=!j.isWebKit&&!j.isOpera&&/MSIE/gi.test(d)&&/Explorer/gi.test(g.appName);j.isIE6=j.isIE&&/MSIE [56]/.test(d);j.isGecko=!j.isWebKit&&/Gecko/.test(d);j.isMac=d.indexOf("Mac")!=-1;j.isAir=/adobeair/i.test(d);j.isIDevice=/(iPad|iPhone)/.test(d);if(l.tinyMCEPreInit){j.suffix=tinyMCEPreInit.suffix;j.baseURL=tinyMCEPreInit.base;j.query=tinyMCEPreInit.query}else{j.suffix="";d=b.getElementsByTagName("base");
-for(g=0;g<d.length;g++)if(u=d[g].href){if(/^https?:\/\/[^\/]+$/.test(u))u+="/";n=u?u.match(/.*\//)[0]:""}d=b.getElementsByTagName("script");for(g=0;g<d.length;g++)if(k(d[g]))return;if(b=b.getElementsByTagName("head")[0]){d=b.getElementsByTagName("script");for(g=0;g<d.length;g++)if(k(d[g]))break}}},is:function(k,j){if(!j)return k!==void 0;if(j=="array"&&k.hasOwnProperty&&k instanceof Array)return true;return typeof k==j},each:function(k,j,b){var g,d;if(!k)return 0;b=b||k;if(k.length!==void 0){g=0;
-for(d=k.length;g<d;g++)if(j.call(b,k[g],g,k)===false)return 0}else for(g in k)if(k.hasOwnProperty(g))if(j.call(b,k[g],g,k)===false)return 0;return 1},map:function(k,j){var b=[];q.each(k,function(g){b.push(j(g))});return b},grep:function(k,j){var b=[];q.each(k,function(g){if(!j||j(g))b.push(g)});return b},inArray:function(k,j){var b,g;if(k){b=0;for(g=k.length;b<g;b++)if(k[b]===j)return b}return-1},extend:function(k,j){var b,g,d=arguments;b=1;for(g=d.length;b<g;b++){j=d[b];q.each(j,function(n,r){if(n!==
-void 0)k[r]=n})}return k},trim:function(k){return(k?""+k:"").replace(o,"")},create:function(k,j){var b,g,d,n,r,u=0;k=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(k);d=k[3].match(/(^|\.)(\w+)$/i)[2];g=this.createNS(k[3].replace(/\.\w+$/,""));if(!g[d])if(k[2]=="static"){g[d]=j;if(this.onCreate)this.onCreate(k[2],k[3],g[d])}else{if(!j[d]){j[d]=function(){};u=1}g[d]=j[d];this.extend(g[d].prototype,j);if(k[5]){b=this.resolve(k[5]).prototype;n=k[5].match(/\.(\w+)$/i)[1];r=g[d];g[d]=u?function(){return b[n].apply(this,
-arguments)}:function(){this.parent=b[n];return r.apply(this,arguments)};g[d].prototype[d]=g[d];this.each(b,function(v,f){g[d].prototype[f]=b[f]});this.each(j,function(v,f){if(b[f])g[d].prototype[f]=function(){this.parent=b[f];return v.apply(this,arguments)};else if(f!=d)g[d].prototype[f]=v})}this.each(j["static"],function(v,f){g[d][f]=v});if(this.onCreate)this.onCreate(k[2],k[3],g[d].prototype)}},walk:function(k,j,b,g){g=g||this;if(k){if(b)k=k[b];q.each(k,function(d,n){if(j.call(g,d,n,b)===false)return false;
-q.walk(d,j,b,g)})}},createNS:function(k,j){var b,g;j=j||l;k=k.split(".");for(b=0;b<k.length;b++){g=k[b];j[g]||(j[g]={});j=j[g]}return j},resolve:function(k,j){var b,g;j=j||l;k=k.split(".");b=0;for(g=k.length;b<g;b++){j=j[k[b]];if(!j)break}return j},addUnload:function(k,j){var b=this;k={func:k,scope:j||this};if(b.unloads)b.unloads.push(k);else{var g=function(){var n=b.unloads,r,u;if(n){for(u in n)(r=n[u])&&r.func&&r.func.call(r.scope,1);if(l.detachEvent){l.detachEvent("onbeforeunload",d);l.detachEvent("onunload",
-g)}else l.removeEventListener&&l.removeEventListener("unload",g,false);b.unloads=w=g=0;l.CollectGarbage&&CollectGarbage()}},d=function(){var n=document;if(n.readyState=="interactive"){var r=function(){n.detachEvent("onstop",r);g&&g();n=0};n&&n.attachEvent("onstop",r);l.setTimeout(function(){n&&n.detachEvent("onstop",r)},0)}};if(l.attachEvent){l.attachEvent("onunload",g);l.attachEvent("onbeforeunload",d)}else l.addEventListener&&l.addEventListener("unload",g,false);b.unloads=[k]}return k},removeUnload:function(k){var j=
-this.unloads,b=null;q.each(j,function(g,d){if(g&&g.func==k){j.splice(d,1);b=k;return false}});return b},explode:function(k,j){return k?q.map(k.split(j||","),q.trim):k},_addVer:function(k){var j;if(!this.query)return k;j=(k.indexOf("?")==-1?"?":"&")+this.query;if(k.indexOf("#")==-1)return k+j;return k.replace("#",j+"#")}};q._init();l.tinymce=l.tinyMCE=q})(window);
-tinymce.create("tinymce.util.Dispatcher",{scope:null,listeners:null,Dispatcher:function(l){this.scope=l||this;this.listeners=[]},add:function(l,o){this.listeners.push({cb:l,scope:o||this.scope});return l},addToTop:function(l,o){this.listeners.unshift({cb:l,scope:o||this.scope});return l},remove:function(l){var o=this.listeners,q=null;tinymce.each(o,function(k,j){if(l==k.cb){q=l;o.splice(j,1);return false}});return q},dispatch:function(){var l,o=arguments,q,k=this.listeners;for(q=0;q<k.length;q++){l=
-k[q];l=l.cb.apply(l.scope,o);if(l===false)break}return l}});
-(function(){var l=tinymce.each;tinymce.create("tinymce.util.URI",{URI:function(o,q){var k=this,j;o=tinymce.trim(o);q=k.settings=q||{};if(/^(mailto|tel|news|javascript|about|data):/i.test(o)||/^\s*#/.test(o))k.source=o;else{if(o.indexOf("/")===0&&o.indexOf("//")!==0)o=(q.base_uri?q.base_uri.protocol||"http":"http")+"://mce_host"+o;/^\w*:?\/\//.test(o)||(o=(q.base_uri.protocol||"http")+"://mce_host"+k.toAbsPath(q.base_uri.path,o));o=o.replace(/@@/g,"(mce_at)");o=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(o);
-l(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(b,g){var d=o[g];if(d)d=d.replace(/\(mce_at\)/g,"@@");k[b]=d});if(j=q.base_uri){if(!k.protocol)k.protocol=j.protocol;if(!k.userInfo)k.userInfo=j.userInfo;if(!k.port&&k.host=="mce_host")k.port=j.port;if(!k.host||k.host=="mce_host")k.host=j.host;k.source=""}}},setPath:function(o){o=/^(.*?)\/?(\w+)?$/.exec(o);this.path=o[0];this.directory=o[1];this.file=o[2];this.source=
-"";this.getURI()},toRelative:function(o){var q;if(o==="./")return o;o=new tinymce.util.URI(o,{base_uri:this});if(o.host!="mce_host"&&this.host!=o.host&&o.host||this.port!=o.port||this.protocol!=o.protocol)return o.getURI();q=this.toRelPath(this.path,o.path);if(o.query)q+="?"+o.query;if(o.anchor)q+="#"+o.anchor;return q},toAbsolute:function(o,q){o=new tinymce.util.URI(o,{base_uri:this});return o.getURI(this.host==o.host&&this.protocol==o.protocol?q:0)},toRelPath:function(o,q){var k,j=0,b="",g,d;o=
-o.substring(0,o.lastIndexOf("/"));o=o.split("/");k=q.split("/");if(o.length>=k.length){g=0;for(d=o.length;g<d;g++)if(g>=k.length||o[g]!=k[g]){j=g+1;break}}if(o.length<k.length){g=0;for(d=k.length;g<d;g++)if(g>=o.length||o[g]!=k[g]){j=g+1;break}}if(j==1)return q;g=0;for(d=o.length-(j-1);g<d;g++)b+="../";g=j-1;for(d=k.length;g<d;g++)b+=g!=j-1?"/"+k[g]:k[g];return b},toAbsPath:function(o,q){var k,j=0,b=[],g;g=/\/$/.test(q)?"/":"";o=o.split("/");q=q.split("/");l(o,function(d){d&&b.push(d)});o=b;k=q.length-
-1;for(b=[];k>=0;k--)if(!(q[k].length==0||q[k]=="."))if(q[k]=="..")j++;else if(j>0)j--;else b.push(q[k]);k=o.length-j;k=k<=0?b.reverse().join("/"):o.slice(0,k).join("/")+"/"+b.reverse().join("/");if(k.indexOf("/")!==0)k="/"+k;if(g&&k.lastIndexOf("/")!==k.length-1)k+=g;return k},getURI:function(o){var q;if(!this.source||o){q="";if(!o){if(this.protocol)q+=this.protocol+"://";if(this.userInfo)q+=this.userInfo+"@";if(this.host)q+=this.host;if(this.port)q+=":"+this.port}if(this.path)q+=this.path;if(this.query)q+=
-"?"+this.query;if(this.anchor)q+="#"+this.anchor;this.source=q}return this.source}})})();
-(function(){var l=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(o){o=this.get(o);var q;o&&l(o.split("&"),function(k){k=k.split("=");q=q||{};q[unescape(k[0])]=unescape(k[1])});return q},setHash:function(o,q,k,j,b,g){var d="";l(q,function(n,r){d+=(!d?"":"&")+escape(r)+"="+escape(n)});this.set(o,d,k,j,b,g)},get:function(o){var q=document.cookie,k=o+"=",j;if(q){j=q.indexOf("; "+k);if(j==-1){j=q.indexOf(k);if(j!=0)return null}else j+=2;o=q.indexOf(";",j);if(o==-1)o=q.length;
-return unescape(q.substring(j+k.length,o))}},set:function(o,q,k,j,b,g){document.cookie=o+"="+escape(q)+(k?"; expires="+k.toGMTString():"")+(j?"; path="+escape(j):"")+(b?"; domain="+b:"")+(g?"; secure":"")},remove:function(o,q){var k=new Date;k.setTime(k.getTime()-1E3);this.set(o,"",k,q,k)}})})();
-tinymce.create("static tinymce.util.JSON",{serialize:function(l){var o,q,k=tinymce.util.JSON.serialize,j;if(l==null)return"null";j=typeof l;if(j=="string"){q="\u0008b\tt\nn\u000cf\rr\"\"''\\\\";return'"'+l.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g,function(b,g){o=q.indexOf(g);if(o+1)return"\\"+q.charAt(o+1);b=g.charCodeAt().toString(16);return"\\u"+"0000".substring(b.length)+b})+'"'}if(j=="object"){if(l.hasOwnProperty&&l instanceof Array){o=0;for(q="[";o<l.length;o++)q+=(o>0?",":"")+k(l[o]);return q+
-"]"}q="{";for(o in l)q+=typeof l[o]!="function"?(q.length>1?',"':'"')+o+'":'+k(l[o]):"";return q+"}"}return""+l},parse:function(l){try{return eval("("+l+")")}catch(o){}}});
-tinymce.create("static tinymce.util.XHR",{send:function(l){function o(g){q=0;try{q=new ActiveXObject(g)}catch(d){}return q}var q,k=window,j=0;l.scope=l.scope||this;l.success_scope=l.success_scope||l.scope;l.error_scope=l.error_scope||l.scope;l.async=l.async===false?false:true;l.data=l.data||"";if(q=k.XMLHttpRequest?new XMLHttpRequest:o("Microsoft.XMLHTTP")||o("Msxml2.XMLHTTP")){q.overrideMimeType&&q.overrideMimeType(l.content_type);q.open(l.type||(l.data?"POST":"GET"),l.url,l.async);l.content_type&&
-q.setRequestHeader("Content-Type",l.content_type);q.setRequestHeader("X-Requested-With","XMLHttpRequest");q.send(l.data);var b=function(){if(!l.async||q.readyState==4||j++>1E4){if(l.success&&j<1E4&&q.status==200)l.success.call(l.success_scope,""+q.responseText,q,l);else if(l.error)l.error.call(l.error_scope,j>1E4?"TIMED_OUT":"GENERAL",q,l);q=null}else k.setTimeout(b,10)};if(!l.async)return b();k.setTimeout(b,10)}}});
-(function(){var l=tinymce.extend,o=tinymce.util.JSON,q=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(k){this.settings=l({},k);this.count=0},send:function(k){var j=k.error,b=k.success;k=l(this.settings,k);k.success=function(g,d){g=o.parse(g);if(typeof g=="undefined")g={error:"JSON Parse error."};g.error?j.call(k.error_scope||k.scope,g.error,d):b.call(k.success_scope||k.scope,g.result)};k.error=function(g,d){j.call(k.error_scope||k.scope,g,d)};k.data=o.serialize({id:k.id||
-"c"+this.count++,method:k.method,params:k.params});k.content_type="application/json";q.send(k)},"static":{sendRPC:function(k){return(new tinymce.util.JSONRequest).send(k)}}})})();
-(function(l){function o(c){var i={},a;c=c.split(",");for(a=c.length;a>=0;a--)i[c[a]]=1;return i}var q=l.each,k=l.is,j=l.isWebKit,b=l.isIE,g=/^(H[1-6R]|P|DIV|ADDRESS|PRE|FORM|T(ABLE|BODY|HEAD|FOOT|H|R|D)|LI|OL|UL|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|MENU|ISINDEX|SAMP)$/,d=o("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"),n=o("src,href,style,coords,shape"),r={"&":"&amp;",'"':"&quot;","<":"&lt;",">":"&gt;"},u=/[<>&\"]/g,v=
-/^([a-z0-9],?)+$/i,f=/<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)(\s*\/?)>/g,e=/(\w+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;l.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(c,i){var a=this;a.doc=c;a.win=window;a.files={};a.cssFlicker=false;a.counter=0;a.boxModel=!l.isIE||c.compatMode=="CSS1Compat";a.stdMode=c.documentMode===8;a.settings=i=l.extend({keep_values:false,hex_colors:1,process_html:1},i);if(l.isIE6)try{c.execCommand("BackgroundImageCache",false,true)}catch(h){a.cssFlicker=true}if(i.valid_styles){a._styles={};q(i.valid_styles,function(m,p){a._styles[p]=l.explode(m)})}l.addUnload(a.destroy,a)},getRoot:function(){var c=this.settings;
-return c&&this.get(c.root_element)||this.doc.body},getViewPort:function(c){var i;c=!c?this.win:c;i=c.document;i=this.boxModel?i.documentElement:i.body;return{x:c.pageXOffset||i.scrollLeft,y:c.pageYOffset||i.scrollTop,w:c.innerWidth||i.clientWidth,h:c.innerHeight||i.clientHeight}},getRect:function(c){var i;c=this.get(c);i=this.getPos(c);c=this.getSize(c);return{x:i.x,y:i.y,w:c.w,h:c.h}},getSize:function(c){var i,a;c=this.get(c);i=this.getStyle(c,"width");a=this.getStyle(c,"height");if(i.indexOf("px")===
--1)i=0;if(a.indexOf("px")===-1)a=0;return{w:parseInt(i)||c.offsetWidth||c.clientWidth,h:parseInt(a)||c.offsetHeight||c.clientHeight}},getParent:function(c,i,a){return this.getParents(c,i,a,false)},getParents:function(c,i,a,h){var m=this,p,t=m.settings,s=[];c=m.get(c);h=h===undefined;if(t.strict_root)a=a||m.getRoot();if(k(i,"string")){p=i;i=i==="*"?function(x){return x.nodeType==1}:function(x){return m.is(x,p)}}for(;c;){if(c==a||!c.nodeType||c.nodeType===9)break;if(!i||i(c))if(h)s.push(c);else return c;
-c=c.parentNode}return h?s:null},get:function(c){var i;if(c&&this.doc&&typeof c=="string"){i=c;if((c=this.doc.getElementById(c))&&c.id!==i)return this.doc.getElementsByName(i)[1]}return c},getNext:function(c,i){return this._findSib(c,i,"nextSibling")},getPrev:function(c,i){return this._findSib(c,i,"previousSibling")},select:function(c,i){return l.dom.Sizzle(c,this.get(i)||this.get(this.settings.root_element)||this.doc,[])},is:function(c,i){var a;if(c.length===undefined){if(i==="*")return c.nodeType==
-1;if(v.test(i)){i=i.toLowerCase().split(/,/);c=c.nodeName.toLowerCase();for(a=i.length-1;a>=0;a--)if(i[a]==c)return true;return false}}return l.dom.Sizzle.matches(i,c.nodeType?[c]:c).length>0},add:function(c,i,a,h,m){var p=this;return this.run(c,function(t){var s;s=k(i,"string")?p.doc.createElement(i):i;p.setAttribs(s,a);if(h)h.nodeType?s.appendChild(h):p.setHTML(s,h);return!m?t.appendChild(s):s})},create:function(c,i,a){return this.add(this.doc.createElement(c),c,i,a,1)},createHTML:function(c,i,
-a){var h="",m;h+="<"+c;for(m in i)if(i.hasOwnProperty(m))h+=" "+m+'="'+this.encode(i[m])+'"';if(l.is(a))return h+">"+a+"</"+c+">";return h+" />"},remove:function(c,i){return this.run(c,function(a){var h,m;h=a.parentNode;if(!h)return null;if(i)for(;m=a.firstChild;)!l.isIE||m.nodeType!==3||m.nodeValue?h.insertBefore(m,a):a.removeChild(m);return h.removeChild(a)})},setStyle:function(c,i,a){var h=this;return h.run(c,function(m){var p;p=m.style;i=i.replace(/-(\D)/g,function(t,s){return s.toUpperCase()});
-if(h.pixelStyles.test(i)&&(l.is(a,"number")||/^[\-0-9\.]+$/.test(a)))a+="px";switch(i){case "opacity":if(b){p.filter=a===""?"":"alpha(opacity="+a*100+")";if(!c.currentStyle||!c.currentStyle.hasLayout)p.display="inline-block"}p[i]=p["-moz-opacity"]=p["-khtml-opacity"]=a||"";break;case "float":b?p.styleFloat=a:p.cssFloat=a;break;default:p[i]=a||""}h.settings.update_styles&&h.setAttrib(m,"_mce_style")})},getStyle:function(c,i,a){c=this.get(c);if(!c)return false;if(this.doc.defaultView&&a){i=i.replace(/[A-Z]/g,
-function(m){return"-"+m});try{return this.doc.defaultView.getComputedStyle(c,null).getPropertyValue(i)}catch(h){return null}}i=i.replace(/-(\D)/g,function(m,p){return p.toUpperCase()});if(i=="float")i=b?"styleFloat":"cssFloat";if(c.currentStyle&&a)return c.currentStyle[i];return c.style[i]},setStyles:function(c,i){var a=this,h=a.settings,m;m=h.update_styles;h.update_styles=0;q(i,function(p,t){a.setStyle(c,t,p)});h.update_styles=m;h.update_styles&&a.setAttrib(c,h.cssText)},setAttrib:function(c,i,a){var h=
-this;if(c&&i){if(h.settings.strict)i=i.toLowerCase();return this.run(c,function(m){var p=h.settings;switch(i){case "style":if(!k(a,"string")){q(a,function(t,s){h.setStyle(m,s,t)});return}if(p.keep_values)a&&!h._isRes(a)?m.setAttribute("_mce_style",a,2):m.removeAttribute("_mce_style",2);m.style.cssText=a;break;case "class":m.className=a||"";break;case "src":case "href":if(p.keep_values){if(p.url_converter)a=p.url_converter.call(p.url_converter_scope||h,a,i,m);h.setAttrib(m,"_mce_"+i,a,2)}break;case "shape":m.setAttribute("_mce_style",
-a)}k(a)&&a!==null&&a.length!==0?m.setAttribute(i,""+a,2):m.removeAttribute(i,2)})}},setAttribs:function(c,i){var a=this;return this.run(c,function(h){q(i,function(m,p){a.setAttrib(h,p,m)})})},getAttrib:function(c,i,a){var h;c=this.get(c);if(!c||c.nodeType!==1)return false;k(a)||(a="");if(/^(src|href|style|coords|shape)$/.test(i))if(h=c.getAttribute("_mce_"+i))return h;if(b&&this.props[i])h=(h=c[this.props[i]])&&h.nodeValue?h.nodeValue:h;h||(h=c.getAttribute(i,2));if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(i)){if(c[this.props[i]]===
-true&&h==="")return i;return h?i:""}if(c.nodeName==="FORM"&&c.getAttributeNode(i))return c.getAttributeNode(i).nodeValue;if(i==="style")if(h=h||c.style.cssText){h=this.serializeStyle(this.parseStyle(h),c.nodeName);this.settings.keep_values&&!this._isRes(h)&&c.setAttribute("_mce_style",h)}if(j&&i==="class"&&h)h=h.replace(/(apple|webkit)\-[a-z\-]+/gi,"");if(b)switch(i){case "rowspan":case "colspan":if(h===1)h="";break;case "size":if(h==="+0"||h===20||h===0)h="";break;case "width":case "height":case "vspace":case "checked":case "disabled":case "readonly":if(h===
-0)h="";break;case "hspace":if(h===-1)h="";break;case "maxlength":case "tabindex":if(h===32768||h===2147483647||h==="32768")h="";break;case "multiple":case "compact":case "noshade":case "nowrap":if(h===65535)return i;return a;case "shape":h=h.toLowerCase();break;default:if(i.indexOf("on")===0&&h)h=(""+h).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1")}return h!==undefined&&h!==null&&h!==""?""+h:a},getPos:function(c,i){var a=0,h=0,m=this.doc;c=this.get(c);i=i||m.body;if(c){if(b&&!this.stdMode){c=
-c.getBoundingClientRect();h=this.boxModel?m.documentElement:m.body;a=this.getStyle(this.select("html")[0],"borderWidth");a=(a=="medium"||this.boxModel&&!this.isIE6)&&2||a;c.top+=this.win.self!=this.win.top?2:0;return{x:c.left+h.scrollLeft-a,y:c.top+h.scrollTop-a}}for(m=c;m&&m!=i&&m.nodeType;){a+=m.offsetLeft||0;h+=m.offsetTop||0;m=m.offsetParent}for(m=c.parentNode;m&&m!=i&&m.nodeType;){a-=m.scrollLeft||0;h-=m.scrollTop||0;m=m.parentNode}}return{x:a,y:h}},parseStyle:function(c){function i(p,t,s){var x,
-y;if(x=m[p+"-top"+t]){y=m[p+"-right"+t];if(x==y){x=m[p+"-bottom"+t];if(y==x){y=m[p+"-left"+t];if(x==y){m[s]=y;delete m[p+"-top"+t];delete m[p+"-right"+t];delete m[p+"-bottom"+t];delete m[p+"-left"+t]}}}}}var a=this,h=a.settings,m={};if(!c)return m;c=c.replace(/&(#?[a-z0-9]+);/g,"&$1_MCE_SEMI_");q(c.split(";"),function(p){var t,s=[];if(p){p=p.replace(/_MCE_SEMI_/g,";");p=p.replace(/url\([^\)]+\)/g,function(x){s.push(x);return"url("+s.length+")"});p=p.split(":");t=l.trim(p[1]);t=t.replace(/url\(([^\)]+)\)/g,
-function(x,y){return s[parseInt(y)-1]});t=t.replace(/rgb\([^\)]+\)/g,function(x){return a.toHex(x)});if(h.url_converter)t=t.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g,function(x,y){return"url("+h.url_converter.call(h.url_converter_scope||a,a.decode(y),"style",null)+")"});m[l.trim(p[0]).toLowerCase()]=t}});i("border","","border");i("border","-width","border-width");i("border","-color","border-color");i("border","-style","border-style");i("padding","","padding");i("margin","","margin");(function(p,
-t,s,x){var y;if(y=m[t])if(y=m[s])if(y=m[x]){m[p]=m[t]+" "+m[s]+" "+m[x];delete m[t];delete m[s];delete m[x]}})("border","border-width","border-style","border-color");if(b)if(m.border=="medium none")m.border="";return m},serializeStyle:function(c,i){function a(m,p){if(p&&m)if(p.indexOf("-")!==0){switch(p){case "font-weight":if(m==700)m="bold";break;case "color":case "background-color":m=m.toLowerCase()}h+=(h?" ":"")+p+": "+m+";"}}var h="";if(i&&this._styles){q(this._styles["*"],function(m){a(c[m],
-m)});q(this._styles[i.toLowerCase()],function(m){a(c[m],m)})}else q(c,a);return h},loadCSS:function(c){var i=this,a=i.doc,h;c||(c="");h=i.select("head")[0];q(c.split(","),function(m){var p;if(!i.files[m]){i.files[m]=true;p=i.create("link",{rel:"stylesheet",href:l._addVer(m)});if(b&&a.documentMode)p.onload=function(){a.recalc();p.onload=null};h.appendChild(p)}})},addClass:function(c,i){return this.run(c,function(a){var h;if(!i)return 0;if(this.hasClass(a,i))return a.className;h=this.removeClass(a,
-i);return a.className=(h!=""?h+" ":"")+i})},removeClass:function(c,i){var a=this,h;return a.run(c,function(m){var p;if(a.hasClass(m,i)){h||(h=RegExp("(^|\\s+)"+i+"(\\s+|$)","g"));p=m.className.replace(h," ");p=l.trim(p!=" "?p:"");m.className=p;if(!p){m.removeAttribute("class");m.removeAttribute("className")}return p}return m.className})},hasClass:function(c,i){c=this.get(c);if(!c||!i)return false;return(" "+c.className+" ").indexOf(" "+i+" ")!==-1},show:function(c){return this.setStyle(c,"display",
-"block")},hide:function(c){return this.setStyle(c,"display","none")},isHidden:function(c){c=this.get(c);return!c||c.style.display=="none"||this.getStyle(c,"display")=="none"},uniqueId:function(c){return(!c?"mce_":c)+this.counter++},setHTML:function(c,i){var a=this;return this.run(c,function(h){var m,p,t,s,x;i=a.processHTML(i);if(b){var y=function(){for(;h.firstChild;)h.firstChild.removeNode();try{h.innerHTML="<br />"+i;h.removeChild(h.firstChild)}catch(C){m=a.create("div");m.innerHTML="<br />"+i;
-q(m.childNodes,function(A,M){M&&h.appendChild(A)})}};if(a.settings.fix_ie_paragraphs)i=i.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi,'<p$1 _mce_keep="true">&nbsp;</p>');y();if(a.settings.fix_ie_paragraphs){t=h.getElementsByTagName("p");p=t.length-1;for(m=0;p>=0;p--){s=t[p];if(!s.hasChildNodes()){if(!s._mce_keep){m=1;break}s.removeAttribute("_mce_keep")}}}if(m){i=i.replace(/<p ([^>]+)>|<p>/ig,'<div $1 _mce_tmp="1">');i=i.replace(/<\/p>/gi,"</div>");y();if(a.settings.fix_ie_paragraphs){t=h.getElementsByTagName("DIV");
-for(p=t.length-1;p>=0;p--){s=t[p];if(s._mce_tmp){x=a.doc.createElement("p");s.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi,function(C,A){var M;if(A!=="_mce_tmp"){M=s.getAttribute(A);if(!M&&A==="class")M=s.className;x.setAttribute(A,M)}});for(m=0;m<s.childNodes.length;m++)x.appendChild(s.childNodes[m].cloneNode(true));s.swapNode(x)}}}}}else h.innerHTML=i;return i})},processHTML:function(c){var i=this,a=i.settings,h=[];if(!a.process_html)return c;if(b){c=c.replace(/&apos;/g,"&#39;");c=c.replace(/\s+(disabled|checked|readonly|selected)\s*=\s*[\"\']?(false|0)[\"\']?/gi,
-"")}c=c.replace(/<a( )([^>]+)\/>|<a\/>/gi,"<a$1$2></a>");if(a.keep_values){if(/<script|noscript|style/i.test(c)){var m=function(p){p=p.replace(/(<\!--\[CDATA\[|\]\]--\>)/g,"\n");p=p.replace(/^[\r\n]*|[\r\n]*$/g,"");p=p.replace(/^\s*(\/\/\s*<\!--|\/\/\s*<!\[CDATA\[|<\!--|<!\[CDATA\[)[\r\n]*/g,"");return p=p.replace(/\s*(\/\/\s*\]\]>|\/\/\s*--\>|\]\]>|--\>|\]\]--\>)\s*$/g,"")};c=c.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/gi,function(p,t,s){t||(t=' type="text/javascript"');t=t.replace(/src=\"([^\"]+)\"?/i,
-function(x,y){if(a.url_converter)y=i.encode(a.url_converter.call(a.url_converter_scope||i,i.decode(y),"src","script"));return'_mce_src="'+y+'"'});if(l.trim(s)){h.push(m(s));s="<\!--\nMCE_SCRIPT:"+(h.length-1)+"\n// --\>"}return"<mce:script"+t+">"+s+"</mce:script>"});c=c.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/gi,function(p,t,s){if(s){h.push(m(s));s="<\!--\nMCE_SCRIPT:"+(h.length-1)+"\n--\>"}return"<mce:style"+t+">"+s+"</mce:style><style "+t+' _mce_bogus="1">'+s+"</style>"});c=c.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g,
-function(p,t,s){return"<mce:noscript"+t+"><\!--"+i.encode(s).replace(/--/g,"&#45;&#45;")+"--\></mce:noscript>"})}c=c.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g,"<\!--[CDATA[$1]]--\>");c=function(p){return p.replace(f,function(t,s,x,y){return"<"+s+x.replace(e,function(C,A,M,X,E){A=A.toLowerCase();M=M||X||E||"";if(d[A]){if(M==="false"||M==="0")return;return A+'="'+A+'"'}if(n[A]&&x.indexOf("_mce_"+A)==-1){C=i.decode(M);if(a.url_converter&&(A=="src"||A=="href"))C=a.url_converter.call(a.url_converter_scope||
-i,C,A,s);if(A=="style")C=i.serializeStyle(i.parseStyle(C),A);return A+'="'+M+'" _mce_'+A+'="'+i.encode(C)+'"'}return C})+y+">"})}(c);c=c.replace(/MCE_SCRIPT:([0-9]+)/g,function(p,t){return h[t]})}return c},getOuterHTML:function(c){var i;c=this.get(c);if(!c)return null;if(c.outerHTML!==undefined)return c.outerHTML;i=(c.ownerDocument||this.doc).createElement("body");i.appendChild(c.cloneNode(true));return i.innerHTML},setOuterHTML:function(c,i,a){function h(p,t,s){s=s.createElement("body");s.innerHTML=
-t;for(t=s.lastChild;t;){m.insertAfter(t.cloneNode(true),p);t=t.previousSibling}m.remove(p)}var m=this;return this.run(c,function(p){p=m.get(p);if(p.nodeType==1){a=a||p.ownerDocument||m.doc;if(b)try{if(b&&p.nodeType==1)p.outerHTML=i;else h(p,i,a)}catch(t){h(p,i,a)}else h(p,i,a)}})},decode:function(c){var i,a;if(/&[\w#]+;/.test(c)){i=this.doc.createElement("div");i.innerHTML=c;i=i.firstChild;a="";if(i){do a+=i.nodeValue;while(i=i.nextSibling)}return a||c}return c},encode:function(c){return(""+c).replace(u,
-function(i){return r[i]})},insertAfter:function(c,i){i=this.get(i);return this.run(c,function(a){var h,m;h=i.parentNode;(m=i.nextSibling)?h.insertBefore(a,m):h.appendChild(a);return a})},isBlock:function(c){if(c.nodeType&&c.nodeType!==1)return false;c=c.nodeName||c;return g.test(c)},replace:function(c,i,a){if(k(i,"array"))c=c.cloneNode(true);return this.run(i,function(h){a&&q(l.grep(h.childNodes),function(m){c.appendChild(m)});return h.parentNode.replaceChild(c,h)})},rename:function(c,i){var a=this,
-h;if(c.nodeName!=i.toUpperCase()){h=a.create(i);q(a.getAttribs(c),function(m){a.setAttrib(h,m.nodeName,a.getAttrib(c,m.nodeName))});a.replace(h,c,1)}return h||c},findCommonAncestor:function(c,i){for(var a=c,h;a;){for(h=i;h&&a!=h;)h=h.parentNode;if(a==h)break;a=a.parentNode}if(!a&&c.ownerDocument)return c.ownerDocument.documentElement;return a},toHex:function(c){function i(h){h=parseInt(h).toString(16);return h.length>1?h:"0"+h}var a=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(c);
-if(a)c="#"+i(a[1])+i(a[2])+i(a[3]);return c},getClasses:function(){function c(t){q(t.imports,function(s){c(s)});q(t.cssRules||t.rules,function(s){switch(s.type||1){case 1:s.selectorText&&q(s.selectorText.split(","),function(x){x=x.replace(/^\s*|\s*$|^\s\./g,"");if(!(/\.mce/.test(x)||!/\.[\w\-]+$/.test(x))){m=x;x=x.replace(/.*\.([a-z0-9_\-]+).*/i,"$1");if(!(h&&!(x=h(x,m))))if(!a[x]){i.push({"class":x});a[x]=1}}});break;case 3:c(s.styleSheet)}})}var i=[],a={},h=this.settings.class_filter,m;if(this.classes)return this.classes;
-try{q(this.doc.styleSheets,c)}catch(p){}if(i.length>0)this.classes=i;return i},run:function(c,i,a){var h=this,m;if(h.doc&&typeof c==="string")c=h.get(c);if(!c)return false;a=a||this;if(!c.nodeType&&(c.length||c.length===0)){m=[];q(c,function(p,t){if(p){if(typeof p=="string")p=h.doc.getElementById(p);m.push(i.call(a,p,t))}});return m}return i.call(a,c)},getAttribs:function(c){var i;c=this.get(c);if(!c)return[];if(b){i=[];if(c.nodeName=="OBJECT")return c.attributes;c.nodeName==="OPTION"&&this.getAttrib(c,
-"selected")&&i.push({specified:1,nodeName:"selected"});c.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi,"").replace(/[\w:\-]+/gi,function(a){i.push({specified:1,nodeName:a})});return i}return c.attributes},destroy:function(c){this.events&&this.events.destroy();this.win=this.doc=this.root=this.events=null;c||l.removeUnload(this.destroy)},createRng:function(){var c=this.doc;return c.createRange?c.createRange():new l.dom.Range(this)},nodeIndex:function(c,i){var a=
-0,h,m;if(c){h=c.nodeType;for(c=c.previousSibling;c;c=c.previousSibling){m=c.nodeType;if(i&&m==3)if(m==h||!c.nodeValue.length)continue;a++;h=m}}return a},split:function(c,i,a){function h(x){var y,C=x.childNodes;if(!(x.nodeType==1&&x.getAttribute("_mce_type")=="bookmark")){for(y=C.length-1;y>=0;y--)h(C[y]);if(x.nodeType!=9){if(x.nodeType==3&&x.nodeValue.length>0)return;if(x.nodeType==1){C=x.childNodes;C.length==1&&C[0]&&C[0].nodeType==1&&C[0].getAttribute("_mce_type")=="bookmark"&&x.parentNode.insertBefore(C[0],
-x);if(C.length||/^(br|hr|input|img)$/i.test(x.nodeName))return}m.remove(x)}return x}}var m=this,p=m.createRng(),t,s;if(c&&i){p.setStart(c.parentNode,m.nodeIndex(c));p.setEnd(i.parentNode,m.nodeIndex(i));t=p.extractContents();p=m.createRng();p.setStart(i.parentNode,m.nodeIndex(i)+1);p.setEnd(c.parentNode,m.nodeIndex(c)+1);p=p.extractContents();s=c.parentNode;s.insertBefore(h(t),c);a?s.replaceChild(a,i):s.insertBefore(i,c);s.insertBefore(h(p),c);m.remove(c);return a||i}},bind:function(c,i,a,h){if(!this.events)this.events=
-new l.dom.EventUtils;return this.events.add(c,i,a,h||this)},unbind:function(c,i,a){if(!this.events)this.events=new l.dom.EventUtils;return this.events.remove(c,i,a)},_findSib:function(c,i,a){var h=this,m=i;if(c){if(k(m,"string"))m=function(p){return h.is(p,i)};for(c=c[a];c;c=c[a])if(m(c))return c}return null},_isRes:function(c){return/^(top|left|bottom|right|width|height)/i.test(c)||/;\s*(top|left|bottom|right|width|height)/i.test(c)}});l.DOM=new l.dom.DOMUtils(document,{process_html:0})})(tinymce);
-(function(l){function o(q){function k(E,D){r(t,E,D)}function j(E,D){r(s,E,D)}function b(E){k(E.parentNode,X(E))}function g(E){j(E.parentNode,X(E)+1)}function d(E,D){var B;if(E.nodeType==3)return E;if(D<0)return E;for(B=E.firstChild;B&&D>0;){--D;B=B.nextSibling}if(B)return B;return E}function n(E,D,B,K){var H,W;if(E==B){if(D==K)return 0;if(D<K)return-1;return 1}for(H=B;H&&H.parentNode!=E;)H=H.parentNode;if(H){W=0;for(B=E.firstChild;B!=H&&W<D;){W++;B=B.nextSibling}if(D<=W)return-1;return 1}for(H=E;H&&
-H.parentNode!=B;)H=H.parentNode;if(H){W=0;for(B=B.firstChild;B!=H&&W<K;){W++;B=B.nextSibling}if(W<K)return-1;return 1}for(D=q.findCommonAncestor(E,B);E&&E.parentNode!=D;)E=E.parentNode;E||(E=D);for(K=B;K&&K.parentNode!=D;)K=K.parentNode;K||(K=D);if(E==K)return 0;for(B=D.firstChild;B;){if(B==E)return-1;if(B==K)return 1;B=B.nextSibling}}function r(E,D,B){if(E){a[y]=D;a[x]=B}else{a[C]=D;a[A]=B}for(D=a[C];D.parentNode;)D=D.parentNode;for(B=a[y];B.parentNode;)B=B.parentNode;if(B==D)n(a[y],a[x],a[C],a[A])>
-0&&a.collapse(E);else a.collapse(E);a.collapsed=a[y]==a[C]&&a[x]==a[A];a.commonAncestorContainer=q.findCommonAncestor(a[y],a[C])}function u(E){var D,B=0,K=0,H;if(a[y]==a[C])return v(E);D=a[C];for(H=D.parentNode;H;D=H,H=H.parentNode){if(H==a[y]){var W=D;D=void 0;H=void 0;B=void 0;K=void 0;H=void 0;if(E!=p)D=h.createDocumentFragment();H=f(W,E);D&&D.appendChild(H);B=X(W)-a[x];if(!(B<=0))for(H=W.previousSibling;B>0;){K=H.previousSibling;H=i(H,E);D&&D.insertBefore(H,D.firstChild);--B;H=K}if(E!=m){a.setEndBefore(W);
-a.collapse(s)}E=D;return E}++B}D=a[y];for(H=D.parentNode;H;D=H,H=H.parentNode){if(H==a[C]){W=D;D=void 0;B=void 0;H=void 0;B=void 0;K=void 0;H=void 0;if(E!=p)D=h.createDocumentFragment();H=e(W,E);D&&D.appendChild(H);B=X(W);++B;B=a[A]-B;for(H=W.nextSibling;B>0;){K=H.nextSibling;H=i(H,E);D&&D.appendChild(H);--B;H=K}if(E!=m){a.setStartAfter(W);a.collapse(t)}return D}++K}K-=B;for(D=a[y];K>0;){D=D.parentNode;K--}for(B=a[C];K<0;){B=B.parentNode;K++}K=D.parentNode;for(H=B.parentNode;K!=H;K=K.parentNode,H=
-H.parentNode){D=K;B=H}var V;if(E!=p)W=h.createDocumentFragment();V=e(D,E);W&&W.appendChild(V);K=X(D);H=X(B);++K;K=H-K;for(V=D.nextSibling;K>0;){H=V.nextSibling;V=i(V,E);W&&W.appendChild(V);V=H;--K}V=f(B,E);W&&W.appendChild(V);if(E!=m){a.setStartAfter(D);a.collapse(t)}return W}function v(E){var D,B,K,H;if(E!=p)D=h.createDocumentFragment();if(a[x]==a[A])return D;if(a[y].nodeType==3){B=a[y].nodeValue;B=B.substring(a[x],a[A]);if(E!=m){a[y].deleteData(a[x],a[A]-a[x]);a.collapse(t)}if(E==p)return;D.appendChild(h.createTextNode(B));
-return D}K=d(a[y],a[x]);for(B=a[A]-a[x];B>0;){H=K.nextSibling;K=i(K,E);D&&D.appendChild(K);--B;K=H}E!=m&&a.collapse(t);return D}function f(E,D){var B=d(a[C],a[A]-1),K,H,W,V=B!=a[C];if(B==E)return c(B,V,s,D);K=B.parentNode;for(H=c(K,s,s,D);K;){for(;B;){W=B.previousSibling;B=c(B,V,s,D);D!=p&&H.insertBefore(B,H.firstChild);V=t;B=W}if(K==E)return H;B=K.previousSibling;K=K.parentNode;W=c(K,s,s,D);D!=p&&W.appendChild(H);H=W}}function e(E,D){var B=d(a[y],a[x]),K=B!=a[y],H,W,V;if(B==E)return c(B,K,t,D);H=
-B.parentNode;for(W=c(H,s,t,D);H;){for(;B;){V=B.nextSibling;B=c(B,K,t,D);D!=p&&W.appendChild(B);K=t;B=V}if(H==E)return W;B=H.nextSibling;H=H.parentNode;V=c(H,s,t,D);D!=p&&V.appendChild(W);W=V}}function c(E,D,B,K){var H;if(D)return i(E,K);if(E.nodeType==3){D=E.nodeValue;if(B){H=a[x];B=D.substring(H);D=D.substring(0,H)}else{H=a[A];B=D.substring(0,H);D=D.substring(H)}if(K!=m)E.nodeValue=D;if(K==p)return;E=E.cloneNode(s);E.nodeValue=B;return E}if(K!=p)return E.cloneNode(s)}function i(E,D){if(D!=p)return D==
-m?E.cloneNode(t):E;E.parentNode.removeChild(E)}var a=this,h=q.doc,m=1,p=2,t=true,s=false,x="startOffset",y="startContainer",C="endContainer",A="endOffset",M=tinymce.extend,X=q.nodeIndex;M(a,{startContainer:h,startOffset:0,endContainer:h,endOffset:0,collapsed:t,commonAncestorContainer:h,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:k,setEnd:j,setStartBefore:b,setStartAfter:function(E){k(E.parentNode,X(E)+1)},setEndBefore:function(E){j(E.parentNode,X(E))},setEndAfter:g,collapse:function(E){if(E){a[C]=
-a[y];a[A]=a[x]}else{a[y]=a[C];a[x]=a[A]}a.collapsed=t},selectNode:function(E){b(E);g(E)},selectNodeContents:function(E){k(E,0);j(E,E.nodeType===1?E.childNodes.length:E.nodeValue.length)},compareBoundaryPoints:function(E){var D=a[y],B=a[x],K=a[C],H=a[A];if(E===0)return n(D,B,D,B);if(E===1)return n(D,B,K,H);if(E===2)return n(K,H,K,H);if(E===3)return n(K,H,D,B)},deleteContents:function(){u(p)},extractContents:function(){return u(0)},cloneContents:function(){return u(m)},insertNode:function(E){var D=
-this[y],B=this[x],K;if((D.nodeType===3||D.nodeType===4)&&D.nodeValue)if(B)if(B>=D.nodeValue.length)q.insertAfter(E,D);else{B=D.splitText(B);D.parentNode.insertBefore(E,B)}else D.parentNode.insertBefore(E,D);else{if(D.childNodes.length>0)K=D.childNodes[B];K?D.insertBefore(E,K):D.appendChild(E)}},surroundContents:function(E){var D=a.extractContents();a.insertNode(E);E.appendChild(D);a.selectNode(E)},cloneRange:function(){return M(new o(q),{startContainer:a[y],startOffset:a[x],endContainer:a[C],endOffset:a[A],
-collapsed:a.collapsed,commonAncestorContainer:a.commonAncestorContainer})}})}l.Range=o})(tinymce.dom);
-(function(){tinymce.dom.TridentSelection=function(l){function o(){function b(r){var u,v,f,e=0,c,i,a,h;f=g.duplicate();f.collapse(r);u=j.create("a");a=f.parentElement();if(a.hasChildNodes()){a.appendChild(u);f.moveToElementText(u);h=g.compareEndPoints(r?"StartToStart":"EndToEnd",f);if(h>0){d[r?"setStartAfter":"setEndAfter"](a);j.remove(u)}else{v=tinymce.grep(a.childNodes);for(c=v.length-1;e<=c;){i=Math.floor((e+c)/2);a.insertBefore(u,v[i]);f.moveToElementText(u);h=g.compareEndPoints(r?"StartToStart":
-"EndToEnd",f);if(h>0)e=i+1;else if(h<0)c=i-1;else{found=true;break}}v=h>0||i==0?u.nextSibling:u.previousSibling;if(v.nodeType==1){j.remove(u);f=j.nodeIndex(v);v=v.parentNode;if(!r||i>0)f++}else{if(h>0||i==0){f.setEndPoint(r?"StartToStart":"EndToEnd",g);f=f.text.length}else{f.setEndPoint(r?"StartToStart":"EndToEnd",g);f=v.nodeValue.length-f.text.length}j.remove(u)}d[r?"setStart":"setEnd"](v,f)}}else d[r?"setStart":"setEnd"](a,0)}var g=l.getRng(),d=j.createRng(),n;n=g.item?g.item(0):g.parentElement();
-if(n.ownerDocument!=j.doc)return d;if(g.item||!n.hasChildNodes()){d.setStart(n.parentNode,j.nodeIndex(n));d.setEnd(d.startContainer,d.startOffset+1);return d}n=l.isCollapsed();b(true);n||b();return d}var q,k,j=l.dom;this.addRange=function(b){var g,d,n=l.dom.doc;d=n.body;var r,u,v,f,e,c;this.destroy();r=b.startContainer;u=b.startOffset;v=b.endContainer;f=b.endOffset;d.createTextRange();if(r==n||v==n){g=d.createTextRange();g.collapse();g.select()}else{if(r.nodeType==1&&r.hasChildNodes()){g=r.childNodes.length-
-1;if(u>g){e=1;r=r.childNodes[g]}else r=r.childNodes[u];if(r.nodeType==3)u=0}if(v.nodeType==1&&v.hasChildNodes()){g=v.childNodes.length-1;if(f==0){c=1;v=v.childNodes[0]}else{v=v.childNodes[Math.min(g,f-1)];if(v.nodeType==3)f=v.nodeValue.length}}if(r==v&&r.nodeType==1){if(/^(IMG|TABLE)$/.test(r.nodeName)&&u!=f){g=d.createControlRange();g.addElement(r)}else{g=d.createTextRange();if(!r.hasChildNodes()&&r.canHaveHTML)r.innerHTML="\ufeff";g.moveToElementText(r);if(r.innerHTML=="\ufeff"){g.collapse(true);
-r.removeChild(r.firstChild)}}u==f&&g.collapse(f<=b.endContainer.childNodes.length-1);g.select();g.scrollIntoView()}else{g=d.createTextRange();b=n.createElement("span");b.innerHTML=" ";if(r.nodeType==3){e?j.insertAfter(b,r):r.parentNode.insertBefore(b,r);g.moveToElementText(b);b.parentNode.removeChild(b);u>0&&g.move("character",u)}else{g.moveToElementText(r);e&&g.collapse(false)}if(r==v&&r.nodeType==3)try{g.moveEnd("character",f-u);g.select();g.scrollIntoView()}catch(i){}else{d=d.createTextRange();
-if(v.nodeType==3){v.parentNode.insertBefore(b,v);d.moveToElementText(b);b.parentNode.removeChild(b);d.move("character",f);g.setEndPoint("EndToStart",d)}else{d.moveToElementText(v);d.collapse(!!c);g.setEndPoint("EndToEnd",d)}g.select();g.scrollIntoView()}}}};this.getRangeAt=function(){if(!q||!tinymce.dom.RangeUtils.compareRanges(k,l.getRng())){q=o();k=l.getRng()}return q};this.destroy=function(){k=q=null};l.dom.boxModel&&function(){function b(f,e){var c=r.createTextRange();try{c.moveToPoint(f,e)}catch(i){c=
-null}return c}function g(f){if(f.button){if(f=b(f.x,f.y)){f.compareEndPoints("StartToStart",v)>0?f.setEndPoint("StartToStart",v):f.setEndPoint("EndToEnd",v);f.select()}}else d()}function d(){j.unbind(n,"mouseup",d);j.unbind(n,"mousemove",g);u=0}var n=j.doc,r=n.body,u,v;n.documentElement.unselectable=true;j.bind(n,"mousedown",function(f){if(f.target.nodeName==="HTML"){u&&d();u=1;if(v=b(f.x,f.y)){j.bind(n,"mouseup",d);j.bind(n,"mousemove",g);v.select()}}})}()}})();
-(function(){function l(a,h,m,p,t,s){t=0;for(var x=p.length;t<x;t++){var y=p[t];if(y){y=y[a];for(var C=false;y;){if(y.sizcache===m){C=p[y.sizset];break}if(y.nodeType===1&&!s){y.sizcache=m;y.sizset=t}if(y.nodeName.toLowerCase()===h){C=y;break}y=y[a]}p[t]=C}}}function o(a,h,m,p,t,s){t=0;for(var x=p.length;t<x;t++){var y=p[t];if(y){y=y[a];for(var C=false;y;){if(y.sizcache===m){C=p[y.sizset];break}if(y.nodeType===1){if(!s){y.sizcache=m;y.sizset=t}if(typeof h!=="string"){if(y===h){C=true;break}}else if(d.filter(h,
-[y]).length>0){C=y;break}}y=y[a]}p[t]=C}}}var q=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,k=0,j=Object.prototype.toString,b=false,g=true;[0,0].sort(function(){g=false;return 0});var d=function(a,h,m,p){m=m||[];var t=h=h||document;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!a||typeof a!=="string")return m;var s=[],x,y,C,A,M=true,X=d.isXML(h),E=a,D;do{q.exec("");if(x=q.exec(E)){E=x[3];s.push(x[1]);if(x[2]){A=
-x[3];break}}}while(x);if(s.length>1&&r.exec(a))if(s.length===2&&n.relative[s[0]])y=i(s[0]+s[1],h);else for(y=n.relative[s[0]]?[h]:d(s.shift(),h);s.length;){a=s.shift();if(n.relative[a])a+=s.shift();y=i(a,y)}else{if(!p&&s.length>1&&h.nodeType===9&&!X&&n.match.ID.test(s[0])&&!n.match.ID.test(s[s.length-1])){x=d.find(s.shift(),h,X);h=x.expr?d.filter(x.expr,x.set)[0]:x.set[0]}if(h){x=p?{expr:s.pop(),set:f(p)}:d.find(s.pop(),s.length===1&&(s[0]==="~"||s[0]==="+")&&h.parentNode?h.parentNode:h,X);y=x.expr?
-d.filter(x.expr,x.set):x.set;if(s.length>0)C=f(y);else M=false;for(;s.length;){x=D=s.pop();if(n.relative[D])x=s.pop();else D="";if(x==null)x=h;n.relative[D](C,x,X)}}else C=[]}C||(C=y);C||d.error(D||a);if(j.call(C)==="[object Array]")if(M)if(h&&h.nodeType===1)for(a=0;C[a]!=null;a++){if(C[a]&&(C[a]===true||C[a].nodeType===1&&d.contains(h,C[a])))m.push(y[a])}else for(a=0;C[a]!=null;a++)C[a]&&C[a].nodeType===1&&m.push(y[a]);else m.push.apply(m,C);else f(C,m);if(A){d(A,t,m,p);d.uniqueSort(m)}return m};
-d.uniqueSort=function(a){if(c){b=g;a.sort(c);if(b)for(var h=1;h<a.length;h++)a[h]===a[h-1]&&a.splice(h--,1)}return a};d.matches=function(a,h){return d(a,null,null,h)};d.find=function(a,h,m){var p;if(!a)return[];for(var t=0,s=n.order.length;t<s;t++){var x=n.order[t],y;if(y=n.leftMatch[x].exec(a)){var C=y[1];y.splice(1,1);if(C.substr(C.length-1)!=="\\"){y[1]=(y[1]||"").replace(/\\/g,"");p=n.find[x](y,h,m);if(p!=null){a=a.replace(n.match[x],"");break}}}}p||(p=h.getElementsByTagName("*"));return{set:p,
-expr:a}};d.filter=function(a,h,m,p){for(var t=a,s=[],x=h,y,C,A=h&&h[0]&&d.isXML(h[0]);a&&h.length;){for(var M in n.filter)if((y=n.leftMatch[M].exec(a))!=null&&y[2]){var X=n.filter[M],E,D;D=y[1];C=false;y.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(x===s)s=[];if(n.preFilter[M])if(y=n.preFilter[M](y,x,m,s,p,A)){if(y===true)continue}else C=E=true;if(y)for(var B=0;(D=x[B])!=null;B++)if(D){E=X(D,y,B,x);var K=p^!!E;if(m&&E!=null)if(K)C=true;else x[B]=false;else if(K){s.push(D);C=true}}if(E!==undefined){m||
-(x=s);a=a.replace(n.match[M],"");if(!C)return[];break}}}if(a===t)if(C==null)d.error(a);else break;t=a}return x};d.error=function(a){throw"Syntax error, unrecognized expression: "+a;};var n=d.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(a){return a.getAttribute("href")}},relative:{"+":function(a,h){var m=typeof h==="string",p=m&&!/\W/.test(h);m=m&&!p;if(p)h=h.toLowerCase();p=0;for(var t=a.length,s;p<t;p++)if(s=a[p]){for(;(s=s.previousSibling)&&s.nodeType!==1;);a[p]=m||s&&s.nodeName.toLowerCase()===
-h?s||false:s===h}m&&d.filter(h,a,true)},">":function(a,h){var m=typeof h==="string",p,t=0,s=a.length;if(m&&!/\W/.test(h))for(h=h.toLowerCase();t<s;t++){if(p=a[t]){m=p.parentNode;a[t]=m.nodeName.toLowerCase()===h?m:false}}else{for(;t<s;t++)if(p=a[t])a[t]=m?p.parentNode:p.parentNode===h;m&&d.filter(h,a,true)}},"":function(a,h,m){var p=k++,t=o,s;if(typeof h==="string"&&!/\W/.test(h)){s=h=h.toLowerCase();t=l}t("parentNode",h,p,a,s,m)},"~":function(a,h,m){var p=k++,t=o,s;if(typeof h==="string"&&!/\W/.test(h)){s=
-h=h.toLowerCase();t=l}t("previousSibling",h,p,a,s,m)}},find:{ID:function(a,h,m){if(typeof h.getElementById!=="undefined"&&!m)return(a=h.getElementById(a[1]))?[a]:[]},NAME:function(a,h){if(typeof h.getElementsByName!=="undefined"){for(var m=[],p=h.getElementsByName(a[1]),t=0,s=p.length;t<s;t++)p[t].getAttribute("name")===a[1]&&m.push(p[t]);return m.length===0?null:m}},TAG:function(a,h){return h.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,h,m,p,t,s){a=" "+a[1].replace(/\\/g,"")+" ";if(s)return a;
-s=0;for(var x;(x=h[s])!=null;s++)if(x)if(t^(x.className&&(" "+x.className+" ").replace(/[\t\n]/g," ").indexOf(a)>=0))m||p.push(x);else if(m)h[s]=false;return false},ID:function(a){return a[1].replace(/\\/g,"")},TAG:function(a){return a[1].toLowerCase()},CHILD:function(a){if(a[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=h[1]+(h[2]||1)-0;a[3]=h[3]-0}a[0]=k++;return a},ATTR:function(a,h,m,p,t,s){h=a[1].replace(/\\/g,
-"");if(!s&&n.attrMap[h])a[1]=n.attrMap[h];if(a[2]==="~=")a[4]=" "+a[4]+" ";return a},PSEUDO:function(a,h,m,p,t){if(a[1]==="not")if((q.exec(a[3])||"").length>1||/^\w/.test(a[3]))a[3]=d(a[3],null,null,h);else{a=d.filter(a[3],h,m,true^t);m||p.push.apply(p,a);return false}else if(n.match.POS.test(a[0])||n.match.CHILD.test(a[0]))return true;return a},POS:function(a){a.unshift(true);return a}},filters:{enabled:function(a){return a.disabled===false&&a.type!=="hidden"},disabled:function(a){return a.disabled===
-true},checked:function(a){return a.checked===true},selected:function(a){return a.selected===true},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,h,m){return!!d(m[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){return"text"===a.type},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===
-a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},setFilters:{first:function(a,h){return h===0},last:function(a,h,m,p){return h===p.length-1},even:function(a,h){return h%2===0},odd:function(a,h){return h%2===1},lt:function(a,h,m){return h<m[3]-0},gt:function(a,h,m){return h>m[3]-0},nth:function(a,h,m){return m[3]-
-0===h},eq:function(a,h,m){return m[3]-0===h}},filter:{PSEUDO:function(a,h,m,p){var t=h[1],s=n.filters[t];if(s)return s(a,m,h,p);else if(t==="contains")return(a.textContent||a.innerText||d.getText([a])||"").indexOf(h[3])>=0;else if(t==="not"){h=h[3];m=0;for(p=h.length;m<p;m++)if(h[m]===a)return false;return true}else d.error("Syntax error, unrecognized expression: "+t)},CHILD:function(a,h){var m=h[1],p=a;switch(m){case "only":case "first":for(;p=p.previousSibling;)if(p.nodeType===1)return false;if(m===
-"first")return true;p=a;case "last":for(;p=p.nextSibling;)if(p.nodeType===1)return false;return true;case "nth":m=h[2];var t=h[3];if(m===1&&t===0)return true;var s=h[0],x=a.parentNode;if(x&&(x.sizcache!==s||!a.nodeIndex)){var y=0;for(p=x.firstChild;p;p=p.nextSibling)if(p.nodeType===1)p.nodeIndex=++y;x.sizcache=s}p=a.nodeIndex-t;return m===0?p===0:p%m===0&&p/m>=0}},ID:function(a,h){return a.nodeType===1&&a.getAttribute("id")===h},TAG:function(a,h){return h==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===
-h},CLASS:function(a,h){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(a,h){var m=h[1];m=n.attrHandle[m]?n.attrHandle[m](a):a[m]!=null?a[m]:a.getAttribute(m);var p=m+"",t=h[2],s=h[4];return m==null?t==="!=":t==="="?p===s:t==="*="?p.indexOf(s)>=0:t==="~="?(" "+p+" ").indexOf(s)>=0:!s?p&&m!==false:t==="!="?p!==s:t==="^="?p.indexOf(s)===0:t==="$="?p.substr(p.length-s.length)===s:t==="|="?p===s||p.substr(0,s.length+1)===s+"-":false},POS:function(a,h,m,p){var t=n.setFilters[h[2]];
-if(t)return t(a,m,h,p)}}},r=n.match.POS,u=function(a,h){return"\\"+(h-0+1)},v;for(v in n.match){n.match[v]=RegExp(n.match[v].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[v]=RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[v].source.replace(/\\(\d+)/g,u))}var f=function(a,h){a=Array.prototype.slice.call(a,0);if(h){h.push.apply(h,a);return h}return a};try{Array.prototype.slice.call(document.documentElement.childNodes,0)}catch(e){f=function(a,h){var m=h||[],p=0;if(j.call(a)==="[object Array]")Array.prototype.push.apply(m,
-a);else if(typeof a.length==="number")for(var t=a.length;p<t;p++)m.push(a[p]);else for(;a[p];p++)m.push(a[p]);return m}}var c;if(document.documentElement.compareDocumentPosition)c=function(a,h){if(!a.compareDocumentPosition||!h.compareDocumentPosition){if(a==h)b=true;return a.compareDocumentPosition?-1:1}var m=a.compareDocumentPosition(h)&4?-1:a===h?0:1;if(m===0)b=true;return m};else if("sourceIndex"in document.documentElement)c=function(a,h){if(!a.sourceIndex||!h.sourceIndex){if(a==h)b=true;return a.sourceIndex?
--1:1}var m=a.sourceIndex-h.sourceIndex;if(m===0)b=true;return m};else if(document.createRange)c=function(a,h){if(!a.ownerDocument||!h.ownerDocument){if(a==h)b=true;return a.ownerDocument?-1:1}var m=a.ownerDocument.createRange(),p=h.ownerDocument.createRange();m.setStart(a,0);m.setEnd(a,0);p.setStart(h,0);p.setEnd(h,0);m=m.compareBoundaryPoints(Range.START_TO_END,p);if(m===0)b=true;return m};d.getText=function(a){for(var h="",m,p=0;a[p];p++){m=a[p];if(m.nodeType===3||m.nodeType===4)h+=m.nodeValue;
-else if(m.nodeType!==8)h+=d.getText(m.childNodes)}return h};(function(){var a=document.createElement("div"),h="script"+(new Date).getTime();a.innerHTML="<a name='"+h+"'/>";var m=document.documentElement;m.insertBefore(a,m.firstChild);if(document.getElementById(h)){n.find.ID=function(p,t,s){if(typeof t.getElementById!=="undefined"&&!s)return(t=t.getElementById(p[1]))?t.id===p[1]||typeof t.getAttributeNode!=="undefined"&&t.getAttributeNode("id").nodeValue===p[1]?[t]:undefined:[]};n.filter.ID=function(p,
-t){var s=typeof p.getAttributeNode!=="undefined"&&p.getAttributeNode("id");return p.nodeType===1&&s&&s.nodeValue===t}}m.removeChild(a);m=a=null})();(function(){var a=document.createElement("div");a.appendChild(document.createComment(""));if(a.getElementsByTagName("*").length>0)n.find.TAG=function(h,m){var p=m.getElementsByTagName(h[1]);if(h[1]==="*"){for(var t=[],s=0;p[s];s++)p[s].nodeType===1&&t.push(p[s]);p=t}return p};a.innerHTML="<a href='#'></a>";if(a.firstChild&&typeof a.firstChild.getAttribute!==
-"undefined"&&a.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};a=null})();document.querySelectorAll&&function(){var a=d,h=document.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){d=function(p,t,s,x){t=t||document;if(!x&&t.nodeType===9&&!d.isXML(t))try{return f(t.querySelectorAll(p),s)}catch(y){}return a(p,t,s,x)};for(var m in a)d[m]=a[m];h=null}}();(function(){var a=document.createElement("div");
-a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!a.getElementsByClassName||a.getElementsByClassName("e").length===0)){a.lastChild.className="e";if(a.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,m,p){if(typeof m.getElementsByClassName!=="undefined"&&!p)return m.getElementsByClassName(h[1])};a=null}}})();d.contains=document.compareDocumentPosition?function(a,h){return!!(a.compareDocumentPosition(h)&16)}:function(a,h){return a!==h&&
-(a.contains?a.contains(h):true)};d.isXML=function(a){return(a=(a?a.ownerDocument||a:0).documentElement)?a.nodeName!=="HTML":false};var i=function(a,h){for(var m=[],p="",t,s=h.nodeType?[h]:h;t=n.match.PSEUDO.exec(a);){p+=t[0];a=a.replace(n.match.PSEUDO,"")}a=n.relative[a]?a+"*":a;t=0;for(var x=s.length;t<x;t++)d(a,s[t],m);return d.filter(p,m)};window.tinymce.dom.Sizzle=d})();
-(function(l){var o=l.each,q=l.DOM,k=l.isIE,j;l.create("tinymce.dom.EventUtils",{EventUtils:function(){this.inits=[];this.events=[]},add:function(b,g,d,n){var r,u=this,v=u.events,f;if(g instanceof Array){f=[];o(g,function(e){f.push(u.add(b,e,d,n))});return f}if(b&&b.hasOwnProperty&&b instanceof Array){f=[];o(b,function(e){e=q.get(e);f.push(u.add(e,g,d,n))});return f}if(b=q.get(b)){r=function(e){if(!u.disabled){if((e=e||window.event)&&k){if(!e.target)e.target=e.srcElement;l.extend(e,u._stoppers)}if(!n)return d(e);
-return d.call(n,e)}};if(g=="unload"){l.unloads.unshift({func:r});return r}if(g=="init"){u.domLoaded?r():u.inits.push(r);return r}v.push({obj:b,name:g,func:d,cfunc:r,scope:n});u._add(b,g,r);return d}},remove:function(b,g,d){var n=this,r=n.events,u=false,v;if(b&&b.hasOwnProperty&&b instanceof Array){v=[];o(b,function(f){f=q.get(f);v.push(n.remove(f,g,d))});return v}b=q.get(b);o(r,function(f,e){if(f.obj==b&&f.name==g&&(!d||f.func==d||f.cfunc==d)){r.splice(e,1);n._remove(b,g,f.cfunc);u=true;return false}});
-return u},clear:function(b){var g=this.events,d,n;if(b){b=q.get(b);for(d=g.length-1;d>=0;d--){n=g[d];if(n.obj===b){this._remove(n.obj,n.name,n.cfunc);n.obj=n.cfunc=null;g.splice(d,1)}}}},cancel:function(b){if(!b)return false;this.stop(b);return this.prevent(b)},stop:function(b){if(b.stopPropagation)b.stopPropagation();else b.cancelBubble=true;return false},prevent:function(b){if(b.preventDefault)b.preventDefault();else b.returnValue=false;return false},destroy:function(){var b=this;o(b.events,function(g){b._remove(g.obj,
-g.name,g.cfunc);g.obj=g.cfunc=null});b.events=[];b=null},_add:function(b,g,d){if(b.attachEvent)b.attachEvent("on"+g,d);else if(b.addEventListener)b.addEventListener(g,d,false);else b["on"+g]=d},_remove:function(b,g,d){if(b)try{if(b.detachEvent)b.detachEvent("on"+g,d);else if(b.removeEventListener)b.removeEventListener(g,d,false);else b["on"+g]=null}catch(n){}},_pageInit:function(){if(!this.domLoaded){this.domLoaded=true;o(this.inits,function(b){b()});this.inits=[]}},_wait:function(b){var g=this,d=
-b.document;if(b.tinyMCE_GZ&&tinyMCE_GZ.loaded)g.domLoaded=1;else{if(d.attachEvent){d.attachEvent("onreadystatechange",function(){if(d.readyState==="complete"){d.detachEvent("onreadystatechange",arguments.callee);g._pageInit(b)}});d.documentElement.doScroll&&b==b.top&&function(){if(!g.domLoaded){try{d.documentElement.doScroll("left")}catch(n){setTimeout(arguments.callee,0);return}g._pageInit(b)}}()}else d.addEventListener&&g._add(b,"DOMContentLoaded",function(){g._pageInit(b)});g._add(b,"load",function(){g._pageInit(b)})}},
-_stoppers:{preventDefault:function(){this.returnValue=false},stopPropagation:function(){this.cancelBubble=true}}});j=l.dom.Event=new l.dom.EventUtils;j._wait(window);l.addUnload(function(){j.destroy()})})(tinymce);
-(function(l){l.dom.Element=function(o,q){var k=this,j;k.settings=q=q||{};k.id=o;k.dom=j=q.dom||l.DOM;l.isIE||j.get(k.id);l.each("getPos,getRect,getParent,add,setStyle,getStyle,setStyles,setAttrib,setAttribs,getAttrib,addClass,removeClass,hasClass,getOuterHTML,setOuterHTML,remove,show,hide,isHidden,setHTML,get".split(/,/),function(b){k[b]=function(){var g=[o],d;for(d=0;d<arguments.length;d++)g.push(arguments[d]);g=j[b].apply(j,g);k.update(b);return g}});l.extend(k,{on:function(b,g,d){return l.dom.Event.add(k.id,
-b,g,d)},getXY:function(){return{x:parseInt(k.getStyle("left")),y:parseInt(k.getStyle("top"))}},getSize:function(){var b=j.get(k.id);return{w:parseInt(k.getStyle("width")||b.clientWidth),h:parseInt(k.getStyle("height")||b.clientHeight)}},moveTo:function(b,g){k.setStyles({left:b,top:g})},moveBy:function(b,g){var d=k.getXY();k.moveTo(d.x+b,d.y+g)},resizeTo:function(b,g){k.setStyles({width:b,height:g})},resizeBy:function(b,g){var d=k.getSize();k.resizeTo(d.w+b,d.h+g)},update:function(b){if(l.isIE6&&q.blocker){b=
-b||"";if(!(b.indexOf("get")===0||b.indexOf("has")===0||b.indexOf("is")===0))if(b=="remove")j.remove(k.blocker);else{if(k.blocker)b=j.get(k.blocker);else{k.blocker=j.uniqueId();b=j.add(q.container||j.getRoot(),"iframe",{id:k.blocker,style:"position:absolute;",frameBorder:0,src:'javascript:""'});j.setStyle(b,"opacity",0)}j.setStyles(b,{left:k.getStyle("left",1),top:k.getStyle("top",1),width:k.getStyle("width",1),height:k.getStyle("height",1),display:k.getStyle("display",1),zIndex:parseInt(k.getStyle("zIndex",
-1)||0)-1})}}}})}})(tinymce);
-(function(l){var o=l.is,q=l.isIE,k=l.each;l.create("tinymce.dom.Selection",{Selection:function(j,b,g){var d=this;d.dom=j;d.win=b;d.serializer=g;k(["onBeforeSetContent","onBeforeGetContent","onSetContent","onGetContent"],function(n){d[n]=new l.util.Dispatcher(d)});if(!d.win.getSelection)d.tridentSel=new l.dom.TridentSelection(d);l.addUnload(d.destroy,d)},getContent:function(j){var b=this.getRng(),g=this.dom.create("body"),d=this.getSel(),n,r;j=j||{};n=r="";j.get=true;j.format=j.format||"html";this.onBeforeGetContent.dispatch(this,
-j);if(j.format=="text")return this.isCollapsed()?"":b.text||(d.toString?d.toString():"");if(b.cloneContents)(b=b.cloneContents())&&g.appendChild(b);else g.innerHTML=o(b.item)||o(b.htmlText)?b.item?b.item(0).outerHTML:b.htmlText:b.toString();if(/^\s/.test(g.innerHTML))n=" ";if(/\s+$/.test(g.innerHTML))r=" ";j.getInner=true;j.content=this.isCollapsed()?"":n+this.serializer.serialize(g,j)+r;this.onGetContent.dispatch(this,j);return j.content},setContent:function(j,b){var g=this.getRng(),d,n=this.win.document;
-b=b||{format:"html"};b.set=true;b.content=this.dom.processHTML(j);this.onBeforeSetContent.dispatch(this,b);j=b.content;if(g.insertNode){j+='<span id="__caret">_</span>';if(g.startContainer==n&&g.endContainer==n)n.body.innerHTML=j;else{g.deleteContents();if(n.body.childNodes.length==0)n.body.innerHTML=j;else g.insertNode(g.createContextualFragment(j))}d=this.dom.get("__caret");g=n.createRange();g.setStartBefore(d);g.setEndBefore(d);this.setRng(g);this.dom.remove("__caret")}else{if(g.item){n.execCommand("Delete",
-false,null);g=this.getRng()}g.pasteHTML(j)}this.onSetContent.dispatch(this,b)},getStart:function(){var j=this.getRng(),b,g;if(j.duplicate||j.item){if(j.item)return j.item(0);b=j.duplicate();b.collapse(1);b=b.parentElement();for(j=g=j.parentElement();g=g.parentNode;)if(g==b){b=j;break}if(b&&b.nodeName=="BODY")return b.firstChild||b}else{b=j.startContainer;if(b.nodeType==1&&b.hasChildNodes())b=b.childNodes[Math.min(b.childNodes.length-1,j.startOffset)];if(b&&b.nodeType==3)return b.parentNode}return b},
-getEnd:function(){var j=this.getRng(),b;if(j.duplicate||j.item){if(j.item)return j.item(0);j=j.duplicate();j.collapse(0);if((b=j.parentElement())&&b.nodeName=="BODY")return b.lastChild||b}else{b=j.endContainer;j=j.endOffset;if(b.nodeType==1&&b.hasChildNodes())b=b.childNodes[j>0?j-1:j];if(b&&b.nodeType==3)return b.parentNode}return b},getBookmark:function(j,b){function g(c,i){var a=0;k(n.select(c),function(h,m){if(h==i)a=m});return a}var d=this,n=d.dom,r,u,v,f,e;if(j==2)return function(){function c(m,
-p){var t=m[p?"startContainer":"endContainer"],s=m[p?"startOffset":"endOffset"],x=[],y,C=0;if(t.nodeType==3){if(b)for(y=t.previousSibling;y&&y.nodeType==3;y=y.previousSibling)s+=y.nodeValue.length;x.push(s)}else{y=t.childNodes;if(s>=y.length&&y.length){C=1;s=Math.max(0,y.length-1)}x.push(d.dom.nodeIndex(y[s],b)+C)}for(;t&&t!=a;t=t.parentNode)x.push(d.dom.nodeIndex(t,b));return x}var i=d.getRng(true),a=n.getRoot(),h={};h.start=c(i,true);if(!d.isCollapsed())h.end=c(i);return h}();if(j)return{rng:d.getRng()};
-r=d.getRng();v=n.uniqueId();f=tinyMCE.activeEditor.selection.isCollapsed();if(r.duplicate||r.item)if(r.item){e=r.item(0);u=e.nodeName;return{name:u,index:g(u,e)}}else{u=r.duplicate();r.collapse();r.pasteHTML('<span _mce_type="bookmark" id="'+v+'_start" style="overflow:hidden;line-height:0px">\ufeff</span>');if(!f){u.collapse(false);u.pasteHTML('<span _mce_type="bookmark" id="'+v+'_end" style="overflow:hidden;line-height:0px">\ufeff</span>')}}else{e=d.getNode();u=e.nodeName;if(u=="IMG")return{name:u,
-index:g(u,e)};u=r.cloneRange();if(!f){u.collapse(false);u.insertNode(n.create("span",{_mce_type:"bookmark",id:v+"_end",style:"overflow:hidden;line-height:0px"},"\ufeff"))}r.collapse(true);r.insertNode(n.create("span",{_mce_type:"bookmark",id:v+"_start",style:"overflow:hidden;line-height:0px"},"\ufeff"))}d.moveToBookmark({id:v,keep:1});return{id:v}},moveToBookmark:function(j){var b=this.dom,g,d,n,r,u,v;this.tridentSel&&this.tridentSel.destroy();if(j)if(j.start){g=b.createRng();d=b.getRoot();var f=
-function(c){var i=j[c?"start":"end"],a,h,m;if(i){h=d;for(a=i.length-1;a>=1;a--){m=h.childNodes;if(m.length)h=m[i[a]]}c?g.setStart(h,i[0]):g.setEnd(h,i[0])}};f(true);f();this.setRng(g)}else if(j.id){f=function(c){var i=b.get(j.id+"_"+c),a,h,m;m=j.keep;if(i){a=i.parentNode;if(c=="start"){if(m){a=i.firstChild;h=1}else h=b.nodeIndex(i);n=r=a;u=v=h}else{if(m){a=i.firstChild;h=1}else h=b.nodeIndex(i);r=a;v=h}if(!m){m=i.previousSibling;a=i.nextSibling;for(k(l.grep(i.childNodes),function(p){if(p.nodeType==
-3)p.nodeValue=p.nodeValue.replace(/\uFEFF/g,"")});i=b.get(j.id+"_"+c);)b.remove(i,1);if(m&&a&&m.nodeType==a.nodeType&&m.nodeType==3){h=m.nodeValue.length;m.appendData(a.nodeValue);b.remove(a);if(c=="start"){n=r=m;u=v=h}else{r=m;v=h}}}}};var e=function(c){if(!q&&b.isBlock(c)&&!c.innerHTML)c.innerHTML='<br _mce_bogus="1" />';return c};f("start");f("end");g=b.createRng();g.setStart(e(n),u);g.setEnd(e(r),v);this.setRng(g)}else if(j.name)this.select(b.select(j.name)[j.index]);else j.rng&&this.setRng(j.rng)},
-select:function(j,b){var g=this.dom,d=g.createRng();g=g.nodeIndex(j);d.setStart(j.parentNode,g);d.setEnd(j.parentNode,g+1);if(b){g=function(n,r){var u=new l.dom.TreeWalker(n,n);do{if(n.nodeType==3&&l.trim(n.nodeValue).length!=0){r?d.setStart(n,0):d.setEnd(n,n.nodeValue.length);break}if(n.nodeName=="BR"){r?d.setStartBefore(n):d.setEndBefore(n);break}}while(n=r?u.next():u.prev())};g(j,1);g(j)}this.setRng(d);return j},isCollapsed:function(){var j=this.getRng(),b=this.getSel();if(!j||j.item)return false;
-if(j.compareEndPoints)return j.compareEndPoints("StartToEnd",j)===0;return!b||j.collapsed},collapse:function(j){var b=this.getRng(),g;if(b.item){g=b.item(0);b=this.win.document.body.createTextRange();b.moveToElementText(g)}b.collapse(!!j);this.setRng(b)},getSel:function(){var j=this.win;return j.getSelection?j.getSelection():j.document.selection},getRng:function(j){var b,g;if(j&&this.tridentSel)return this.tridentSel.getRangeAt(0);try{if(b=this.getSel())g=b.rangeCount>0?b.getRangeAt(0):b.createRange?
-b.createRange():this.win.document.createRange()}catch(d){}g||(g=this.win.document.createRange?this.win.document.createRange():this.win.document.body.createTextRange());if(this.selectedRange&&this.explicitRange)if(g.compareBoundaryPoints(g.START_TO_START,this.selectedRange)===0&&g.compareBoundaryPoints(g.END_TO_END,this.selectedRange)===0)g=this.explicitRange;else this.explicitRange=this.selectedRange=null;return g},setRng:function(j){var b;if(this.tridentSel)if(j.cloneRange)this.tridentSel.addRange(j);
-else try{j.select()}catch(g){}else if(b=this.getSel()){this.explicitRange=j;b.removeAllRanges();b.addRange(j);this.selectedRange=b.getRangeAt(0)}},setNode:function(j){this.setContent(this.dom.getOuterHTML(j));return j},getNode:function(){var j=this.getRng(),b=this.getSel(),g;if(j.setStart){if(!j)return this.dom.getRoot();g=j.commonAncestorContainer;if(!j.collapsed){if(j.startContainer==j.endContainer)if(j.startOffset-j.endOffset<2)if(j.startContainer.hasChildNodes())g=j.startContainer.childNodes[j.startOffset];
-if(l.isWebKit&&b.anchorNode&&b.anchorNode.nodeType==1)return b.anchorNode.childNodes[b.anchorOffset]}if(g&&g.nodeType==3)return g.parentNode;return g}return j.item?j.item(0):j.parentElement()},getSelectedBlocks:function(j,b){var g=this.dom,d,n,r,u=[];d=g.getParent(j||this.getStart(),g.isBlock);n=g.getParent(b||this.getEnd(),g.isBlock);d&&u.push(d);if(d&&n&&d!=n)for(r=d;(r=r.nextSibling)&&r!=n;)g.isBlock(r)&&u.push(r);n&&d!=n&&u.push(n);return u},destroy:function(j){this.win=null;this.tridentSel&&
-this.tridentSel.destroy();j||l.removeUnload(this.destroy)}})})(tinymce);
-(function(l){l.create("tinymce.dom.XMLWriter",{node:null,XMLWriter:function(){this.doc=function(){var o=document.implementation;if(!o||!o.createDocument){try{return new ActiveXObject("MSXML2.DOMDocument")}catch(q){}try{return new ActiveXObject("Microsoft.XmlDom")}catch(k){}}else return o.createDocument("","",null)}();this.valid=l.isOpera||l.isWebKit;this.reset()},reset:function(){var o=this.doc;o.firstChild&&o.removeChild(o.firstChild);this.node=o.appendChild(o.createElement("html"))},writeStartElement:function(o){this.node=
-this.node.appendChild(this.doc.createElement(o))},writeAttribute:function(o,q){if(this.valid)q=q.replace(/>/g,"%MCGT%");this.node.setAttribute(o,q)},writeEndElement:function(){this.node=this.node.parentNode},writeFullEndElement:function(){var o=this.node;o.appendChild(this.doc.createTextNode(""));this.node=o.parentNode},writeText:function(o){if(this.valid)o=o.replace(/>/g,"%MCGT%");this.node.appendChild(this.doc.createTextNode(o))},writeCDATA:function(o){this.node.appendChild(this.doc.createCDATASection(o))},
-writeComment:function(o){if(l.isIE)o=o.replace(/^\-|\-$/g," ");this.node.appendChild(this.doc.createComment(o.replace(/\-\-/g," ")))},getContent:function(){var o;o=this.doc.xml||(new XMLSerializer).serializeToString(this.doc);o=o.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g,"");o=o.replace(/ ?\/>/g," />");if(this.valid)o=o.replace(/\%MCGT%/g,"&gt;");return o}})})(tinymce);
-(function(l){l.create("tinymce.dom.StringWriter",{str:null,tags:null,count:0,settings:null,indent:null,StringWriter:function(o){this.settings=l.extend({indent_char:" ",indentation:0},o);this.reset()},reset:function(){this.str=this.indent="";this.tags=[];this.count=0},writeStartElement:function(o){this._writeAttributesEnd();this.writeRaw("<"+o);this.tags.push(o);this.inAttr=true;this.count++;this.elementCount=this.count},writeAttribute:function(o,q){this.writeRaw(" "+this.encode(o)+'="'+this.encode(q)+
-'"')},writeEndElement:function(){var o;if(this.tags.length>0){o=this.tags.pop();this._writeAttributesEnd(1)&&this.writeRaw("</"+o+">");this.settings.indentation>0&&this.writeRaw("\n")}},writeFullEndElement:function(){if(this.tags.length>0){this._writeAttributesEnd();this.writeRaw("</"+this.tags.pop()+">");this.settings.indentation>0&&this.writeRaw("\n")}},writeText:function(o){this._writeAttributesEnd();this.writeRaw(this.encode(o));this.count++},writeCDATA:function(o){this._writeAttributesEnd();
-this.writeRaw("<![CDATA["+o+"]]\>");this.count++},writeComment:function(o){this._writeAttributesEnd();this.writeRaw("<\!-- "+o+"--\>");this.count++},writeRaw:function(o){this.str+=o},encode:function(o){return o.replace(/[<>&"]/g,function(q){switch(q){case "<":return"&lt;";case ">":return"&gt;";case "&":return"&amp;";case '"':return"&quot;"}return q})},getContent:function(){return this.str},_writeAttributesEnd:function(o){if(this.inAttr){this.inAttr=false;if(o&&this.elementCount==this.count){this.writeRaw(" />");
-return false}this.writeRaw(">");return true}}})})(tinymce);
-(function(l){function o(d){return d.replace(/([?+*])/g,".$1")}var q=l.extend,k=l.each,j=l.util.Dispatcher,b=l.isIE,g=l.isGecko;l.create("tinymce.dom.Serializer",{Serializer:function(d){var n=this;n.key=0;n.onPreProcess=new j(n);n.onPostProcess=new j(n);try{n.writer=new l.dom.XMLWriter}catch(r){n.writer=new l.dom.StringWriter}n.settings=d=q({dom:l.DOM,valid_nodes:0,node_filter:0,attr_filter:0,invalid_attrs:/^(_mce_|_moz_|sizset|sizcache)/,closed:/^(br|hr|input|meta|img|link|param|area)$/,entity_encoding:"named",
-entities:"160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro",
-valid_elements:"*[*]",extended_valid_elements:0,invalid_elements:0,fix_table_elements:1,fix_list_elements:true,fix_content_duplication:true,convert_fonts_to_spans:false,font_size_classes:0,apply_source_formatting:0,indent_mode:"simple",indent_char:"\t",indent_levels:1,remove_linebreaks:1,remove_redundant_brs:1,element_format:"xhtml"},d);n.dom=d.dom;n.schema=d.schema;if(d.entity_encoding=="named"&&!d.entities)d.entity_encoding="raw";d.remove_redundant_brs&&n.onPostProcess.add(function(u,v){v.content=
-v.content.replace(/(<br \/>\s*)+<\/(p|h[1-6]|div|li)>/gi,function(f,e,c){if(/^<br \/>\s*<\//.test(f))return"</"+c+">";return f})});d.element_format=="html"&&n.onPostProcess.add(function(u,v){v.content=v.content.replace(/<([^>]+) \/>/g,"<$1>")});d.fix_list_elements&&n.onPreProcess.add(function(u,v){function f(s,x){for(var y=x.split(","),C;(s=s.previousSibling)!=null;)for(C=0;C<y.length;C++)if(s.nodeName==y[C])return s;return null}var e,c,i=["ol","ul"],a,h,m,p=/^(OL|UL)$/,t;for(c=0;c<i.length;c++){e=
-n.dom.select(i[c],v.node);for(a=0;a<e.length;a++){h=e[a];m=h.parentNode;if(p.test(m.nodeName))if(t=f(h,"LI"))t.appendChild(h);else{t=n.dom.create("li");t.innerHTML="&nbsp;";t.appendChild(h);m.insertBefore(t,m.firstChild)}}}});d.fix_table_elements&&n.onPreProcess.add(function(u,v){if(!l.isOpera||opera.buildNumber()>=1767)k(n.dom.select("p table",v.node).reverse(),function(f){var e=n.dom.getParent(f.parentNode,"table,p");if(e.nodeName!="TABLE")try{n.dom.split(e,f)}catch(c){}})})},setEntities:function(d){var n,
-r={},u;if(!this.entityLookup){d=d.split(",");for(n=0;n<d.length;n+=2){u=d[n];if(!(u==34||u==38||u==60||u==62)){r[String.fromCharCode(d[n])]=d[n+1];parseInt(d[n]).toString(16)}}this.entityLookup=r}},setRules:function(d){this._setup();this.rules={};this.wildRules=[];this.validElements={};return this.addRules(d)},addRules:function(d){var n=this,r;if(d){n._setup();k(d.split(","),function(u){u=u.split(/\[|\]/);var v=u[0].split("/"),f,e,c,i=[];if(r)e=l.extend([],r.attribs);u.length>1&&k(u[1].split("|"),
-function(a){var h={},m;e=e||[];a=a.replace(/::/g,"~");a=/^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(a);a[2]=a[2].replace(/~/g,":");if(a[1]=="!"){f=f||[];f.push(a[2])}if(a[1]=="-")for(m=0;m<e.length;m++)if(e[m].name==a[2]){e.splice(m,1);return}switch(a[3]){case "=":h.defaultVal=a[4]||"";break;case ":":h.forcedVal=a[4];break;case "<":h.validVals=a[4].split("?")}if(/[*.?]/.test(a[2])){c=c||[];h.nameRE=RegExp("^"+o(a[2])+"$");c.push(h)}else{h.name=a[2];e.push(h)}i.push(a[2])});k(v,function(a,h){var m=
-a.charAt(0),p=1,t={};if(r){if(r.noEmpty)t.noEmpty=r.noEmpty;if(r.fullEnd)t.fullEnd=r.fullEnd;if(r.padd)t.padd=r.padd}switch(m){case "-":t.noEmpty=true;break;case "+":t.fullEnd=true;break;case "#":t.padd=true;break;default:p=0}v[h]=a=a.substring(p);n.validElements[a]=1;if(/[*.?]/.test(v[0])){t.nameRE=RegExp("^"+o(v[0])+"$");n.wildRules=n.wildRules||{};n.wildRules.push(t)}else{t.name=v[0];if(v[0]=="@")r=t;n.rules[a]=t}t.attribs=e;if(f)t.requiredAttribs=f;if(c){a="";k(i,function(s){if(a)a+="|";a+="("+
-o(s)+")"});t.validAttribsRE=RegExp("^"+a.toLowerCase()+"$");t.wildAttribs=c}})});d="";k(n.validElements,function(u,v){if(d)d+="|";if(v!="@")d+=v});n.validElementsRE=RegExp("^("+o(d.toLowerCase())+")$")}},findRule:function(d){var n=this.rules,r;this._setup();if(n=n[d])return n;n=this.wildRules;for(r=0;r<n.length;r++)if(n[r].nameRE.test(d))return n[r];return null},findAttribRule:function(d,n){var r,u=d.wildAttribs;for(r=0;r<u.length;r++)if(u[r].nameRE.test(n))return u[r];return null},serialize:function(d,
-n){var r=this,u,v,f,e;r._setup();n=n||{};n.format=n.format||"html";r.processObj=n;if(b){e=[];k(d.getElementsByTagName("option"),function(c){c=r.dom.getAttrib(c,"selected");e.push(c?c:null)})}d=d.cloneNode(true);b&&k(d.getElementsByTagName("option"),function(c,i){r.dom.setAttrib(c,"selected",e[i])});f=d.ownerDocument.implementation;if(f.createHTMLDocument&&l.isOpera&&opera.buildNumber()>=1767){u=f.createHTMLDocument("");k(d.nodeName=="BODY"?d.childNodes:[d],function(c){u.body.appendChild(u.importNode(c,
-true))});d=d.nodeName!="BODY"?u.body.firstChild:u.body;v=r.dom.doc;r.dom.doc=u}r.key=""+(parseInt(r.key)+1);if(!n.no_events){n.node=d;r.onPreProcess.dispatch(r,n)}r.writer.reset();r._info=n;r._serializeNode(d,n.getInner);n.content=r.writer.getContent();if(v)r.dom.doc=v;n.no_events||r.onPostProcess.dispatch(r,n);r._postProcess(n);n.node=null;return l.trim(n.content)},_postProcess:function(d){var n=this,r=n.settings,u=d.content,v;if(d.format=="html"){v=n._protect({content:u,patterns:[{pattern:/(<script[^>]*>)(.*?)(<\/script>)/g},
-{pattern:/(<noscript[^>]*>)(.*?)(<\/noscript>)/g},{pattern:/(<style[^>]*>)(.*?)(<\/style>)/g},{pattern:/(<pre[^>]*>)(.*?)(<\/pre>)/g,encode:1},{pattern:/(<\!--\[CDATA\[)(.*?)(\]\]--\>)/g}]});u=v.content;if(r.entity_encoding!=="raw")u=n._encode(u);if(!d.set){u=u.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g,r.entity_encoding=="numeric"?"<p$1>&#160;</p>":"<p$1>&nbsp;</p>");if(r.remove_linebreaks){u=u.replace(/\r?\n|\r/g," ");u=u.replace(/(<[^>]+>)\s+/g,"$1 ");u=u.replace(/\s+(<\/[^>]+>)/g," $1");u=u.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g,
-"<$1 $2>");u=u.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g,"<$1>");u=u.replace(/\s+<\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g,"</$1>")}if(r.apply_source_formatting&&r.indent_mode=="simple"){u=u.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g,"\n<$1$2$3>\n");u=u.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g,
-"\n<$1$2>");u=u.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g,"</$1>\n");u=u.replace(/\n\n/g,"\n")}}u=n._unprotect(u,v);u=u.replace(/<\!--\[CDATA\[([\s\S]+)\]\]--\>/g,"<![CDATA[$1]]\>");if(r.entity_encoding=="raw")u=u.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g,"<p$1>\u00a0</p>");u=u.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g,function(f,e,c){return"<noscript"+e+">"+n.dom.decode(c.replace(/<\!--|--\>/g,""))+"</noscript>"})}d.content=u},_serializeNode:function(d,
-n){var r=this.settings,u=this.writer,v,f,e,c,i,a,h,m,p,t,s,x,y;if(!r.node_filter||r.node_filter(d))switch(d.nodeType){case 1:if(d.hasAttribute?d.hasAttribute("_mce_bogus"):d.getAttribute("_mce_bogus"))return;t=x=false;v=d.hasChildNodes();m=d.getAttribute("_mce_name")||d.nodeName.toLowerCase();if(y=d.getAttribute("_mce_type"))if(this._info.cleanup)x=1;else return;if(b)if(d.scopeName!=="HTML"&&d.scopeName!=="html")m=d.scopeName+":"+m;if(m.indexOf("mce:")===0)m=m.substring(4);if(!x)if(!this.validElementsRE||
-!this.validElementsRE.test(m)||this.invalidElementsRE&&this.invalidElementsRE.test(m)||n){t=true;break}if(b){if(r.fix_content_duplication){if(d._mce_serialized==this.key)return;d._mce_serialized=this.key}if(m.charAt(0)=="/")m=m.substring(1)}else if(g)if(d.nodeName==="BR"&&d.getAttribute("type")=="_moz")return;if(r.validate_children){if(this.elementName&&!this.schema.isValid(this.elementName,m)){t=true;break}this.elementName=m}p=this.findRule(m);if(!p){t=true;break}m=p.name||m;s=r.closed.test(m);if(!v&&
-p.noEmpty||b&&!m){t=true;break}if(p.requiredAttribs){i=p.requiredAttribs;for(e=i.length-1;e>=0;e--)if(this.dom.getAttrib(d,i[e])!=="")break;if(e==-1){t=true;break}}u.writeStartElement(m);if(p.attribs){e=0;a=p.attribs;for(c=a.length;e<c;e++){i=a[e];h=this._getAttrib(d,i);h!==null&&u.writeAttribute(i.name,h)}}if(p.validAttribsRE){a=this.dom.getAttribs(d);for(e=a.length-1;e>-1;e--){i=a[e];if(i.specified){i=i.nodeName.toLowerCase();if(!(r.invalid_attrs.test(i)||!p.validAttribsRE.test(i))){c=this.findAttribRule(p,
-i);h=this._getAttrib(d,c,i);h!==null&&u.writeAttribute(i,h)}}}}y&&x&&u.writeAttribute("_mce_type",y);if(m==="script"&&l.trim(d.innerHTML)){u.writeText("// ");u.writeCDATA(d.innerHTML.replace(/<\!--|--\>|<\[CDATA\[|\]\]>/g,""));v=false;break}if(p.padd)if(v&&(f=d.firstChild)&&f.nodeType===1&&d.childNodes.length===1){if(f.hasAttribute?f.hasAttribute("_mce_bogus"):f.getAttribute("_mce_bogus"))u.writeText("\u00a0")}else v||u.writeText("\u00a0");break;case 3:if(r.validate_children&&this.elementName&&!this.schema.isValid(this.elementName,
-"#text"))return;return u.writeText(d.nodeValue);case 4:return u.writeCDATA(d.nodeValue);case 8:return u.writeComment(d.nodeValue)}else if(d.nodeType==1)v=d.hasChildNodes();if(v&&!s)for(f=d.firstChild;f;){this._serializeNode(f);this.elementName=m;f=f.nextSibling}t||(s?u.writeEndElement():u.writeFullEndElement())},_protect:function(d){function n(v){return v.replace(/[\r\n\\]/g,function(f){if(f==="\n")return"\\n";else if(f==="\\")return"\\\\";return"\\r"})}function r(v){return v.replace(/\\[\\rn]/g,
-function(f){if(f==="\\n")return"\n";else if(f==="\\\\")return"\\";return"\r"})}var u=this;d.items=d.items||[];k(d.patterns,function(v){d.content=r(n(d.content).replace(v.pattern,function(f,e,c,i){c=r(c);if(v.encode)c=u._encode(c);d.items.push(c);return e+"<\!--mce:"+(d.items.length-1)+"--\>"+i}))});return d},_unprotect:function(d,n){d=d.replace(/\<\!--mce:([0-9]+)--\>/g,function(r,u){return n.items[parseInt(u)]});n.items=[];return d},_encode:function(d){var n=this.settings,r;if(n.entity_encoding!==
-"raw"){if(n.entity_encoding.indexOf("named")!=-1){this.setEntities(n.entities);r=this.entityLookup;d=d.replace(/[\u007E-\uFFFF]/g,function(u){var v;if(v=r[u])u="&"+v+";";return u})}if(n.entity_encoding.indexOf("numeric")!=-1)d=d.replace(/[\u007E-\uFFFF]/g,function(u){return"&#"+u.charCodeAt(0)+";"})}return d},_setup:function(){var d=this.settings;if(!this.done){this.done=1;this.setRules(d.valid_elements);this.addRules(d.extended_valid_elements);if(d.invalid_elements)this.invalidElementsRE=RegExp("^("+
-o(d.invalid_elements.replace(/,/g,"|").toLowerCase())+")$");if(d.attrib_value_filter)this.attribValueFilter=d.attribValueFilter}},_getAttrib:function(d,n,r){var u;r=r||n.name;if(n.forcedVal&&(u=n.forcedVal)){if(u==="{$uid}")return this.dom.uniqueId();return u}u=this.dom.getAttrib(d,r);switch(r){case "rowspan":case "colspan":if(u=="1")u=""}if(this.attribValueFilter)u=this.attribValueFilter(r,u,d);if(n.validVals){for(d=n.validVals.length-1;d>=0;d--)if(u==n.validVals[d])break;if(d==-1)return null}if(u===
-""&&typeof n.defaultVal!="undefined"){u=n.defaultVal;if(u==="{$uid}")return this.dom.uniqueId();return u}else if(r=="class"&&this.processObj.get)u=u.replace(/\s?mceItem\w+\s?/g,"");if(u==="")return null;return u}})})(tinymce);
-(function(l){l.dom.ScriptLoader=function(){function o(d,n){function r(){u.remove(c);if(v)v.onreadystatechange=v.onload=v=null;n()}var u=l.DOM,v,f,e,c;c=u.uniqueId();if(l.isIE6){f=new l.util.URI(d);e=location;if(f.host==e.hostname&&f.port==e.port&&f.protocol+":"==e.protocol){l.util.XHR.send({url:l._addVer(f.getURI()),success:function(i){var a=u.create("script",{type:"text/javascript"});a.text=i;document.getElementsByTagName("head")[0].appendChild(a);u.remove(a);r()}});return}}v=u.create("script",{id:c,
-type:"text/javascript",src:l._addVer(d)});v.onload=r;v.onreadystatechange=function(){var i=v.readyState;if(i=="complete"||i=="loaded")r()};(document.getElementsByTagName("head")[0]||document.body).appendChild(v)}var q={},k=[],j={},b=[],g=0;this.isDone=function(d){return q[d]==2};this.markDone=function(d){q[d]=2};this.add=this.load=function(d,n,r){if(q[d]==void 0){k.push(d);q[d]=0}if(n){j[d]||(j[d]=[]);j[d].push({func:n,scope:r||this})}};this.loadQueue=function(d,n){this.loadScripts(k,d,n)};this.loadScripts=
-function(d,n,r){function u(f){l.each(j[f],function(e){e.func.call(e.scope)});j[f]=void 0}var v;b.push({func:n,scope:r||this});v=function(){var f=l.grep(d);d.length=0;l.each(f,function(e){if(q[e]==2)u(e);else if(q[e]!=1){q[e]=1;g++;o(e,function(){q[e]=2;g--;u(e);v()})}});if(!g){l.each(b,function(e){e.func.call(e.scope)});b.length=0}};v()}};l.ScriptLoader=new l.dom.ScriptLoader})(tinymce);
-tinymce.dom.TreeWalker=function(l,o){function q(j,b,g,d){if(j){if(!d&&j[b])return j[b];if(j!=o){if(b=j[g])return b;for(j=j.parentNode;j&&j!=o;j=j.parentNode)if(b=j[g])return b}}}var k=l;this.current=function(){return k};this.next=function(j){return k=q(k,"firstChild","nextSibling",j)};this.prev=function(j){return k=q(k,"lastChild","lastSibling",j)}};
-(function(){var l={};(function(o,q){function k(b){return b.replace(/[A-Z]+/g,function(g){return k(o[g])})}for(var j in o)if(o.hasOwnProperty(j))o[j]=k(o[j]);k(q).replace(/#/g,"#text").replace(/(\w+)\[([^\]]+)\]/g,function(b,g,d){var n={};d=d.split(/\|/);for(b=d.length-1;b>=0;b--)n[d[b]]=1;l[g]=n})})({Z:"#|H|K|N|O|P",Y:"#|X|form|R|Q",X:"p|T|div|U|W|isindex|fieldset|table",W:"pre|hr|blockquote|address|center|noframes",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"},"script[]style[]object[#|param|X|form|a|H|K|N|O|Q]param[]p[S]a[Z]br[]span[S]bdo[S]applet[#|param|X|form|a|H|K|N|O|Q]h1[S]img[]map[X|form|Q|area]h2[S]iframe[#|X|form|a|H|K|N|O|Q]h3[S]tt[S]i[S]b[S]u[S]s[S]strike[S]big[S]small[S]font[S]basefont[]em[S]strong[S]dfn[S]code[S]q[S]samp[S]kbd[S]var[S]cite[S]abbr[S]acronym[S]sub[S]sup[S]input[]select[optgroup|option]optgroup[option]option[]textarea[]label[S]button[#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]h4[S]ins[#|X|form|a|H|K|N|O|Q]h5[S]del[#|X|form|a|H|K|N|O|Q]h6[S]div[#|X|form|a|H|K|N|O|Q]ul[li]li[#|X|form|a|H|K|N|O|Q]ol[li]dl[dt|dd]dt[S]dd[#|X|form|a|H|K|N|O|Q]menu[li]dir[li]pre[ZA]hr[]blockquote[#|X|form|a|H|K|N|O|Q]address[S|p]center[#|X|form|a|H|K|N|O|Q]noframes[#|X|form|a|H|K|N|O|Q]isindex[]fieldset[#|legend|X|form|a|H|K|N|O|Q]legend[S]table[caption|col|colgroup|thead|tfoot|tbody|tr]caption[S]col[]colgroup[col]thead[tr]tr[th|td]th[#|X|form|a|H|K|N|O|Q]form[#|X|a|H|K|N|O|Q]noscript[#|X|form|a|H|K|N|O|Q]td[#|X|form|a|H|K|N|O|Q]tfoot[tr]tbody[tr]area[]base[]body[#|X|form|a|H|K|N|O|Q]");
-tinymce.dom.Schema=function(){this.isValid=function(o,q){var k=l[o];return!!(k&&(!q||k[q]))}}})();
-(function(l){l.dom.RangeUtils=function(o){this.walk=function(q,k){function j(i,a,h){for(var m=[];i&&i!=h;i=i[a])m.push(i);return m}function b(i,a){do{if(i.parentNode==a)return i;i=i.parentNode}while(i)}function g(i,a,h){var m=h?"nextSibling":"previousSibling";v=i;for(f=v.parentNode;v&&v!=a;v=f){f=v.parentNode;e=j(v==i?v:v[m],m);if(e.length){h||e.reverse();k(e)}}}var d=q.startContainer,n=q.startOffset,r=q.endContainer,u=q.endOffset,v,f,e,c;c=o.select("td.mceSelected,th.mceSelected");if(c.length>0)l.each(c,
-function(i){k([i])});else{if(d.nodeType==1&&d.hasChildNodes())d=d.childNodes[n];if(r.nodeType==1&&r.hasChildNodes())r=r.childNodes[Math.min(n==u?u:u-1,r.childNodes.length-1)];u=o.findCommonAncestor(d,r);if(d==r)return k([d]);for(v=d;v;v=v.parentNode){if(v==r)return g(d,u,true);if(v==u)break}for(v=r;v;v=v.parentNode){if(v==d)return g(r,u);if(v==u)break}n=b(d,u)||d;u=b(r,u)||r;g(d,n,true);e=j(n==d?n:n.nextSibling,"nextSibling",u==r?u.nextSibling:u);e.length&&k(e);g(r,u)}}};l.dom.RangeUtils.compareRanges=
-function(o,q){if(o&&q)if(o.item||o.duplicate){if(o.item&&q.item&&o.item(0)===q.item(0))return true;if(o.isEqual&&q.isEqual&&q.isEqual(o))return true}else return o.startContainer==q.startContainer&&o.startOffset==q.startOffset;return false}})(tinymce);
-(function(l){var o=l.DOM,q=l.is;l.create("tinymce.ui.Control",{Control:function(k,j){this.id=k;this.settings=j=j||{};this.rendered=false;this.onRender=new l.util.Dispatcher(this);this.classPrefix="";this.scope=j.scope||this;this.active=this.disabled=0},setDisabled:function(k){var j;if(k!=this.disabled){if((j=o.get(this.id))&&this.settings.unavailable_prefix)if(k){this.prevTitle=j.title;j.title=this.settings.unavailable_prefix+": "+j.title}else j.title=this.prevTitle;this.setState("Disabled",k);this.setState("Enabled",
-!k);this.disabled=k}},isDisabled:function(){return this.disabled},setActive:function(k){if(k!=this.active){this.setState("Active",k);this.active=k}},isActive:function(){return this.active},setState:function(k,j){var b=o.get(this.id);k=this.classPrefix+k;j?o.addClass(b,k):o.removeClass(b,k)},isRendered:function(){return this.rendered},renderHTML:function(){},renderTo:function(k){o.setHTML(k,this.renderHTML())},postRender:function(){var k;if(q(this.disabled)){k=this.disabled;this.disabled=-1;this.setDisabled(k)}if(q(this.active)){k=
-this.active;this.active=-1;this.setActive(k)}},remove:function(){o.remove(this.id);this.destroy()},destroy:function(){l.dom.Event.clear(this.id)}})})(tinymce);tinymce.create("tinymce.ui.Container:tinymce.ui.Control",{Container:function(l,o){this.parent(l,o);this.controls=[];this.lookup={}},add:function(l){this.lookup[l.id]=l;this.controls.push(l);return l},get:function(l){return this.lookup[l]}});
-tinymce.create("tinymce.ui.Separator:tinymce.ui.Control",{Separator:function(l,o){this.parent(l,o);this.classPrefix="mceSeparator"},renderHTML:function(){return tinymce.DOM.createHTML("span",{"class":this.classPrefix})}});
-(function(l){var o=l.is;l.create("tinymce.ui.MenuItem:tinymce.ui.Control",{MenuItem:function(q,k){this.parent(q,k);this.classPrefix="mceMenuItem"},setSelected:function(q){this.setState("Selected",q);this.selected=q},isSelected:function(){return this.selected},postRender:function(){this.parent();o(this.selected)&&this.setSelected(this.selected)}})})(tinymce);
-(function(l){var o=l.DOM,q=l.walk;l.create("tinymce.ui.Menu:tinymce.ui.MenuItem",{Menu:function(k,j){this.parent(k,j);this.items={};this.collapsed=false;this.menuCount=0;this.onAddItem=new l.util.Dispatcher(this)},expand:function(k){k&&q(this,function(j){j.expand&&j.expand()},"items",this);this.collapsed=false},collapse:function(k){k&&q(this,function(j){j.collapse&&j.collapse()},"items",this);this.collapsed=true},isCollapsed:function(){return this.collapsed},add:function(k){k.settings||(k=new l.ui.MenuItem(k.id||
-o.uniqueId(),k));this.onAddItem.dispatch(this,k);return this.items[k.id]=k},addSeparator:function(){return this.add({separator:true})},addMenu:function(k){k.collapse||(k=this.createMenu(k));this.menuCount++;return this.add(k)},hasMenus:function(){return this.menuCount!==0},remove:function(k){delete this.items[k.id]},removeAll:function(){q(this,function(k){k.removeAll?k.removeAll():k.remove();k.destroy()},"items",this);this.items={}},createMenu:function(k){k=new l.ui.Menu(k.id||o.uniqueId(),k);k.onAddItem.add(this.onAddItem.dispatch,
-this.onAddItem);return k}})})(tinymce);
-(function(l){var o=l.is,q=l.DOM,k=l.each,j=l.dom.Event,b=l.dom.Element;l.create("tinymce.ui.DropMenu:tinymce.ui.Menu",{DropMenu:function(g,d){d=d||{};d.container=d.container||q.doc.body;d.offset_x=d.offset_x||0;d.offset_y=d.offset_y||0;d.vp_offset_x=d.vp_offset_x||0;d.vp_offset_y=d.vp_offset_y||0;if(o(d.icons)&&!d.icons)d["class"]+=" mceNoIcons";this.parent(g,d);this.onShowMenu=new l.util.Dispatcher(this);this.onHideMenu=new l.util.Dispatcher(this);this.classPrefix="mceMenu"},createMenu:function(g){var d=
-this.settings;g.container=g.container||d.container;g.parent=this;g.constrain=g.constrain||d.constrain;g["class"]=g["class"]||d["class"];g.vp_offset_x=g.vp_offset_x||d.vp_offset_x;g.vp_offset_y=g.vp_offset_y||d.vp_offset_y;g=new l.ui.DropMenu(g.id||q.uniqueId(),g);g.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return g},update:function(){var g=this.settings,d=q.get("menu_"+this.id+"_tbl"),n=q.get("menu_"+this.id+"_co"),r,u;r=g.max_width?Math.min(d.clientWidth,g.max_width):d.clientWidth;u=
-g.max_height?Math.min(d.clientHeight,g.max_height):d.clientHeight;q.boxModel?this.element.setStyles({width:r,height:u}):this.element.setStyles({width:r+2,height:u+2});g.max_width&&q.setStyle(n,"width",r);if(g.max_height){q.setStyle(n,"height",u);d.clientHeight<g.max_height&&q.setStyle(n,"overflow","hidden")}},showMenu:function(g,d,n){var r=this,u=r.settings,v,f=q.getViewPort(),e,c,i,a,h=r.classPrefix;r.collapse(1);if(!r.isMenuVisible){if(r.rendered)v=q.get("menu_"+r.id);else{v=q.add(r.settings.container,
-r.renderNode());k(r.items,function(m){m.postRender()});r.element=new b("menu_"+r.id,{blocker:1,container:u.container})}l.isOpera||q.setStyles(v,{left:-65535,top:-65535});q.show(v);r.update();g+=u.offset_x||0;d+=u.offset_y||0;f.w-=4;f.h-=4;if(u.constrain){e=v.clientWidth-2;c=v.clientHeight-2;i=f.x+f.w;f=f.y+f.h;if(g+u.vp_offset_x+e>i)g=n?n-e:Math.max(0,i-u.vp_offset_x-e);if(d+u.vp_offset_y+c>f)d=Math.max(0,f-u.vp_offset_y-c)}q.setStyles(v,{left:g,top:d});r.element.update();r.isMenuVisible=1;r.mouseClickFunc=
-j.add(v,"click",function(m){var p;if((m=m.target)&&(m=q.getParent(m,"tr"))&&!q.hasClass(m,h+"ItemSub")){p=r.items[m.id];if(!p.isDisabled()){for(a=r;a;){a.hideMenu&&a.hideMenu();a=a.settings.parent}if(p.settings.onclick)p.settings.onclick(m);return j.cancel(m)}}});if(r.hasMenus())r.mouseOverFunc=j.add(v,"mouseover",function(m){var p;if((m=m.target)&&(m=q.getParent(m,"tr"))){p=r.items[m.id];r.lastMenu&&r.lastMenu.collapse(1);if(!p.isDisabled())if(m&&q.hasClass(m,h+"ItemSub")){m=q.getRect(m);p.showMenu(m.x+
-m.w-2,m.y-2,m.x);r.lastMenu=p;q.addClass(q.get(p.id).firstChild,h+"ItemActive")}}});r.onShowMenu.dispatch(r);if(u.keyboard_focus){j.add(v,"keydown",r._keyHandler,r);q.select("a","menu_"+r.id)[0].focus();r._focusIdx=0}}},hideMenu:function(g){var d=q.get("menu_"+this.id);if(this.isMenuVisible){j.remove(d,"mouseover",this.mouseOverFunc);j.remove(d,"click",this.mouseClickFunc);j.remove(d,"keydown",this._keyHandler);q.hide(d);this.isMenuVisible=0;g||this.collapse(1);this.element&&this.element.hide();if(g=
-q.get(this.id))q.removeClass(g.firstChild,this.classPrefix+"ItemActive");this.onHideMenu.dispatch(this)}},add:function(g){var d;g=this.parent(g);if(this.isRendered&&(d=q.get("menu_"+this.id)))this._add(q.select("tbody",d)[0],g);return g},collapse:function(g){this.parent(g);this.hideMenu(1)},remove:function(g){q.remove(g.id);this.destroy();return this.parent(g)},destroy:function(){var g=q.get("menu_"+this.id);j.remove(g,"mouseover",this.mouseOverFunc);j.remove(g,"click",this.mouseClickFunc);this.element&&
-this.element.remove();q.remove(g)},renderNode:function(){var g=this,d=g.settings,n,r,u;u=q.create("div",{id:"menu_"+g.id,"class":d["class"],style:"position:absolute;left:0;top:0;z-index:200000"});r=q.add(u,"div",{id:"menu_"+g.id+"_co","class":g.classPrefix+(d["class"]?" "+d["class"]:"")});g.element=new b("menu_"+g.id,{blocker:1,container:d.container});d.menu_line&&q.add(r,"span",{"class":g.classPrefix+"Line"});d=q.add(r,"table",{id:"menu_"+g.id+"_tbl",border:0,cellPadding:0,cellSpacing:0});n=q.add(d,
-"tbody");k(g.items,function(v){g._add(n,v)});g.rendered=true;return u},_keyHandler:function(g){function d(r){r=n._focusIdx+r;var u=q.select("a","menu_"+n.id)[r];if(u){n._focusIdx=r;u.focus()}}var n=this;switch(g.keyCode){case 38:d(-1);break;case 40:d(1);break;case 27:return this.hideMenu()}},_add:function(g,d){var n,r=d.settings,u,v,f=this.classPrefix;if(r.separator){u=q.add(g,"tr",{id:d.id,"class":f+"ItemSeparator"});q.add(u,"td",{"class":f+"ItemSeparator"});if(n=u.previousSibling)q.addClass(n,"mceLast")}else{n=
-u=q.add(g,"tr",{id:d.id,"class":f+"Item "+f+"ItemEnabled"});n=v=q.add(n,"td");n=q.add(n,"a",{href:"javascript:;",onclick:"return false;",onmousedown:"return false;"});q.addClass(v,r["class"]);v=q.add(n,"span",{"class":"mceIcon"+(r.icon?" mce_"+r.icon:"")});r.icon_src&&q.add(v,"img",{src:r.icon_src});n=q.add(n,r.element||"span",{"class":"mceText",title:d.settings.title},d.settings.title);d.settings.style&&q.setAttrib(n,"style",d.settings.style);g.childNodes.length==1&&q.addClass(u,"mceFirst");if((n=
-u.previousSibling)&&q.hasClass(n,f+"ItemSeparator"))q.addClass(u,"mceFirst");d.collapse&&q.addClass(u,f+"ItemSub");if(n=u.previousSibling)q.removeClass(n,"mceLast");q.addClass(u,"mceLast")}}})})(tinymce);
-(function(l){var o=l.DOM;l.create("tinymce.ui.Button:tinymce.ui.Control",{Button:function(q,k){this.parent(q,k);this.classPrefix="mceButton"},renderHTML:function(){var q=this.classPrefix,k=this.settings,j,b;b=o.encode(k.label||"");j='<a id="'+this.id+'" href="javascript:;" class="'+q+" "+q+"Enabled "+k["class"]+(b?" "+q+"Labeled":"")+'" onmousedown="return false;" onclick="return false;" title="'+o.encode(k.title)+'">';j+=k.image?'<img class="mceIcon" src="'+k.image+'" />'+b+"</a>":'<span class="mceIcon '+
-k["class"]+'"></span>'+(b?'<span class="'+q+'Label">'+b+"</span>":"")+"</a>";return j},postRender:function(){var q=this,k=q.settings;l.dom.Event.add(q.id,"click",function(j){if(!q.isDisabled())return k.onclick.call(k.scope,j)})}})})(tinymce);
-(function(l){var o=l.DOM,q=l.dom.Event,k=l.each,j=l.util.Dispatcher;l.create("tinymce.ui.ListBox:tinymce.ui.Control",{ListBox:function(b,g){this.parent(b,g);this.items=[];this.onChange=new j(this);this.onPostRender=new j(this);this.onAdd=new j(this);this.onRenderMenu=new l.util.Dispatcher(this);this.classPrefix="mceListBox"},select:function(b){var g=this,d,n;if(b==undefined)return g.selectByIndex(-1);n=b&&b.call?b:function(r){return r==b};if(b!=g.selectedValue){k(g.items,function(r,u){if(n(r.value)){d=
-1;g.selectByIndex(u);return false}});d||g.selectByIndex(-1)}},selectByIndex:function(b){var g,d;if(b!=this.selectedIndex){g=o.get(this.id+"_text");if(d=this.items[b]){this.selectedValue=d.value;this.selectedIndex=b;o.setHTML(g,o.encode(d.title));o.removeClass(g,"mceTitle")}else{o.setHTML(g,o.encode(this.settings.title));o.addClass(g,"mceTitle");this.selectedValue=this.selectedIndex=null}}},add:function(b,g,d){d=d||{};d=l.extend(d,{title:b,value:g});this.items.push(d);this.onAdd.dispatch(this,d)},
-getLength:function(){return this.items.length},renderHTML:function(){var b="";b=this.settings;var g=this.classPrefix;b='<table id="'+this.id+'" cellpadding="0" cellspacing="0" class="'+g+" "+g+"Enabled"+(b["class"]?" "+b["class"]:"")+'"><tbody><tr>';b+="<td>"+o.createHTML("a",{id:this.id+"_text",href:"javascript:;","class":"mceText",onclick:"return false;",onmousedown:"return false;"},o.encode(this.settings.title))+"</td>";b+="<td>"+o.createHTML("a",{id:this.id+"_open",tabindex:-1,href:"javascript:;",
-"class":"mceOpen",onclick:"return false;",onmousedown:"return false;"},"<span></span>")+"</td>";b+="</tr></tbody></table>";return b},showMenu:function(){var b=this,g,d=o.get(this.id),n;if(!(b.isDisabled()||b.items.length==0)){if(b.menu&&b.menu.isMenuVisible)return b.hideMenu();if(!b.isMenuRendered){b.renderMenu();b.isMenuRendered=true}o.getPos(this.settings.menu_container);g=o.getPos(d);n=b.menu;n.settings.offset_x=g.x;n.settings.offset_y=g.y;n.settings.keyboard_focus=!l.isOpera;b.oldID&&n.items[b.oldID].setSelected(0);
-k(b.items,function(r){if(r.value===b.selectedValue){n.items[r.id].setSelected(1);b.oldID=r.id}});n.showMenu(0,d.clientHeight);q.add(o.doc,"mousedown",b.hideMenu,b);o.addClass(b.id,b.classPrefix+"Selected")}},hideMenu:function(b){if(this.menu&&this.menu.isMenuVisible)if(!(b&&b.type=="mousedown"&&(b.target.id==this.id+"_text"||b.target.id==this.id+"_open")))if(!b||!o.getParent(b.target,".mceMenu")){o.removeClass(this.id,this.classPrefix+"Selected");q.remove(o.doc,"mousedown",this.hideMenu,this);this.menu.hideMenu()}},
-renderMenu:function(){var b=this,g;g=b.settings.control_manager.createDropMenu(b.id+"_menu",{menu_line:1,"class":b.classPrefix+"Menu mceNoIcons",max_width:150,max_height:150});g.onHideMenu.add(b.hideMenu,b);g.add({title:b.settings.title,"class":"mceMenuItemTitle",onclick:function(){b.settings.onselect("")!==false&&b.select("")}});k(b.items,function(d){if(d.value===undefined)g.add({title:d.title,"class":"mceMenuItemTitle",onclick:function(){b.settings.onselect("")!==false&&b.select("")}});else{d.id=
-o.uniqueId();d.onclick=function(){b.settings.onselect(d.value)!==false&&b.select(d.value)};g.add(d)}});b.onRenderMenu.dispatch(b,g);b.menu=g},postRender:function(){var b=this,g=b.classPrefix;q.add(b.id,"click",b.showMenu,b);q.add(b.id+"_text","focus",function(){if(!b._focused)b.keyDownHandler=q.add(b.id+"_text","keydown",function(d){var n=-1,r,u=d.keyCode;k(b.items,function(v,f){if(b.selectedValue==v.value)n=f});if(u==38)r=b.items[n-1];else if(u==40)r=b.items[n+1];else if(u==13){r=b.selectedValue;
-b.selectedValue=null;b.settings.onselect(r);return q.cancel(d)}if(r){b.hideMenu();b.select(r.value)}});b._focused=1});q.add(b.id+"_text","blur",function(){q.remove(b.id+"_text","keydown",b.keyDownHandler);b._focused=0});if(l.isIE6||!o.boxModel){q.add(b.id,"mouseover",function(){o.hasClass(b.id,g+"Disabled")||o.addClass(b.id,g+"Hover")});q.add(b.id,"mouseout",function(){o.hasClass(b.id,g+"Disabled")||o.removeClass(b.id,g+"Hover")})}b.onPostRender.dispatch(b,o.get(b.id))},destroy:function(){this.parent();
-q.clear(this.id+"_text");q.clear(this.id+"_open")}})})(tinymce);
-(function(l){var o=l.DOM,q=l.dom.Event,k=l.each;l.create("tinymce.ui.NativeListBox:tinymce.ui.ListBox",{NativeListBox:function(j,b){this.parent(j,b);this.classPrefix="mceNativeListBox"},setDisabled:function(j){o.get(this.id).disabled=j},isDisabled:function(){return o.get(this.id).disabled},select:function(j){var b=this,g,d;if(j==undefined)return b.selectByIndex(-1);d=j&&j.call?j:function(n){return n==j};if(j!=b.selectedValue){k(b.items,function(n,r){if(d(n.value)){g=1;b.selectByIndex(r);return false}});
-g||b.selectByIndex(-1)}},selectByIndex:function(j){o.get(this.id).selectedIndex=j+1;this.selectedValue=this.items[j]?this.items[j].value:null},add:function(j,b,g){g=g||{};g.value=b;this.isRendered()&&o.add(o.get(this.id),"option",g,j);j={title:j,value:b,attribs:g};this.items.push(j);this.onAdd.dispatch(this,j)},getLength:function(){return this.items.length},renderHTML:function(){var j;j=o.createHTML("option",{value:""},"-- "+this.settings.title+" --");k(this.items,function(b){j+=o.createHTML("option",
-{value:b.value},b.title)});return j=o.createHTML("select",{id:this.id,"class":"mceNativeListBox"},j)},postRender:function(){function j(g){if((g=b.items[g.target.selectedIndex-1])&&(g=g.value)){b.onChange.dispatch(b,g);if(b.settings.onselect)b.settings.onselect(g)}}var b=this;b.rendered=true;q.add(b.id,"change",j);q.add(b.id,"keydown",function(g){var d;q.remove(b.id,"change",void 0);d=q.add(b.id,"blur",function(){q.add(b.id,"change",j);q.remove(b.id,"blur",d)});if(g.keyCode==13||g.keyCode==32){j(g);
-return q.cancel(g)}});b.onPostRender.dispatch(b,o.get(b.id))}})})(tinymce);
-(function(l){var o=l.DOM,q=l.dom.Event;l.create("tinymce.ui.MenuButton:tinymce.ui.Button",{MenuButton:function(k,j){this.parent(k,j);this.onRenderMenu=new l.util.Dispatcher(this);j.menu_container=j.menu_container||o.doc.body},showMenu:function(){var k,j=o.get(this.id),b;if(!this.isDisabled()){if(!this.isMenuRendered){this.renderMenu();this.isMenuRendered=true}if(this.isMenuVisible)return this.hideMenu();o.getPos(this.settings.menu_container);k=o.getPos(j);b=this.menu;b.settings.offset_x=k.x;b.settings.offset_y=
-k.y;b.settings.vp_offset_x=k.x;b.settings.vp_offset_y=k.y;b.settings.keyboard_focus=this._focused;b.showMenu(0,j.clientHeight);q.add(o.doc,"mousedown",this.hideMenu,this);this.setState("Selected",1);this.isMenuVisible=1}},renderMenu:function(){var k;k=this.settings.control_manager.createDropMenu(this.id+"_menu",{menu_line:1,"class":this.classPrefix+"Menu",icons:this.settings.icons});k.onHideMenu.add(this.hideMenu,this);this.onRenderMenu.dispatch(this,k);this.menu=k},hideMenu:function(k){var j=this;
-if(!(k&&k.type=="mousedown"&&o.getParent(k.target,function(b){return b.id===j.id||b.id===j.id+"_open"}))){if(!k||!o.getParent(k.target,".mceMenu")){j.setState("Selected",0);q.remove(o.doc,"mousedown",j.hideMenu,j);j.menu&&j.menu.hideMenu()}j.isMenuVisible=0}},postRender:function(){var k=this,j=k.settings;q.add(k.id,"click",function(){if(!k.isDisabled()){if(j.onclick)j.onclick(k.value);k.showMenu()}})}})})(tinymce);
-(function(l){var o=l.DOM,q=l.dom.Event;l.create("tinymce.ui.SplitButton:tinymce.ui.MenuButton",{SplitButton:function(k,j){this.parent(k,j);this.classPrefix="mceSplitButton"},renderHTML:function(){var k,j=this.settings,b;k="<tbody><tr>";b=j.image?o.createHTML("img ",{src:j.image,"class":"mceAction "+j["class"]}):o.createHTML("span",{"class":"mceAction "+j["class"]},"");k+="<td>"+o.createHTML("a",{id:this.id+"_action",href:"javascript:;","class":"mceAction "+j["class"],onclick:"return false;",onmousedown:"return false;",
-title:j.title},b)+"</td>";b=o.createHTML("span",{"class":"mceOpen "+j["class"]});k+="<td>"+o.createHTML("a",{id:this.id+"_open",href:"javascript:;","class":"mceOpen "+j["class"],onclick:"return false;",onmousedown:"return false;",title:j.title},b)+"</td>";k+="</tr></tbody>";return o.createHTML("table",{id:this.id,"class":"mceSplitButton mceSplitButtonEnabled "+j["class"],cellpadding:"0",cellspacing:"0",onmousedown:"return false;",title:j.title},k)},postRender:function(){var k=this,j=k.settings;j.onclick&&
-q.add(k.id+"_action","click",function(){if(!k.isDisabled())j.onclick(k.value)});q.add(k.id+"_open","click",k.showMenu,k);q.add(k.id+"_open","focus",function(){k._focused=1});q.add(k.id+"_open","blur",function(){k._focused=0});if(l.isIE6||!o.boxModel){q.add(k.id,"mouseover",function(){o.hasClass(k.id,"mceSplitButtonDisabled")||o.addClass(k.id,"mceSplitButtonHover")});q.add(k.id,"mouseout",function(){o.hasClass(k.id,"mceSplitButtonDisabled")||o.removeClass(k.id,"mceSplitButtonHover")})}},destroy:function(){this.parent();
-q.clear(this.id+"_action");q.clear(this.id+"_open")}})})(tinymce);
-(function(l){var o=l.DOM,q=l.dom.Event,k=l.is,j=l.each;l.create("tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton",{ColorSplitButton:function(b,g){this.parent(b,g);this.settings=g=l.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"},
-this.settings);this.onShowMenu=new l.util.Dispatcher(this);this.onHideMenu=new l.util.Dispatcher(this);this.value=g.default_color},showMenu:function(){var b=this,g,d;if(!b.isDisabled()){if(!b.isMenuRendered){b.renderMenu();b.isMenuRendered=true}if(b.isMenuVisible)return b.hideMenu();g=o.get(b.id);o.show(b.id+"_menu");o.addClass(g,"mceSplitButtonSelected");d=o.getPos(g);o.setStyles(b.id+"_menu",{left:d.x,top:d.y+g.clientHeight,zIndex:2E5});g=0;q.add(o.doc,"mousedown",b.hideMenu,b);b.onShowMenu.dispatch(b);
-if(b._focused){b._keyHandler=q.add(b.id+"_menu","keydown",function(n){n.keyCode==27&&b.hideMenu()});o.select("a",b.id+"_menu")[0].focus()}b.isMenuVisible=1}},hideMenu:function(b){var g=this;if(!(b&&b.type=="mousedown"&&o.getParent(b.target,function(d){return d.id===g.id+"_open"}))){if(!b||!o.getParent(b.target,".mceSplitButtonMenu")){o.removeClass(g.id,"mceSplitButtonSelected");q.remove(o.doc,"mousedown",g.hideMenu,g);q.remove(g.id+"_menu","keydown",g._keyHandler);o.hide(g.id+"_menu")}g.onHideMenu.dispatch(g);
-g.isMenuVisible=0}},renderMenu:function(){var b=this,g,d=0,n=b.settings,r,u,v,f;f=o.add(n.menu_container,"div",{id:b.id+"_menu","class":n.menu_class+" "+n["class"],style:"position:absolute;left:0;top:-1000px;"});g=o.add(f,"div",{"class":n["class"]+" mceSplitButtonMenu"});o.add(g,"span",{"class":"mceMenuLine"});r=o.add(g,"table",{"class":"mceColorSplitMenu"});u=o.add(r,"tbody");d=0;j(k(n.colors,"array")?n.colors:n.colors.split(","),function(e){e=e.replace(/^#/,"");if(!d--){v=o.add(u,"tr");d=n.grid_width-
-1}r=o.add(v,"td");r=o.add(r,"a",{href:"javascript:;",style:{backgroundColor:"#"+e},_mce_color:"#"+e})});if(n.more_colors_func){r=o.add(u,"tr");r=o.add(r,"td",{colspan:n.grid_width,"class":"mceMoreColors"});r=o.add(r,"a",{id:b.id+"_more",href:"javascript:;",onclick:"return false;","class":"mceMoreColors"},n.more_colors_title);q.add(r,"click",function(e){n.more_colors_func.call(n.more_colors_scope||this);return q.cancel(e)})}o.addClass(g,"mceColorSplitMenu");q.add(b.id+"_menu","click",function(e){var c;
-e=e.target;if(e.nodeName=="A"&&(c=e.getAttribute("_mce_color")))b.setColor(c);return q.cancel(e)});return f},setColor:function(b){o.setStyle(this.id+"_preview","backgroundColor",b);this.value=b;this.hideMenu();this.settings.onselect(b)},postRender:function(){var b=this.id;this.parent();o.add(b+"_action","div",{id:b+"_preview","class":"mceColorPreview"});o.setStyle(this.id+"_preview","backgroundColor",this.value)},destroy:function(){this.parent();q.clear(this.id+"_menu");q.clear(this.id+"_more");o.remove(this.id+
-"_menu")}})})(tinymce);
-tinymce.create("tinymce.ui.Toolbar:tinymce.ui.Container",{renderHTML:function(){var l="",o,q,k=tinymce.DOM,j=this.settings,b,g,d,n;n=this.controls;for(b=0;b<n.length;b++){q=n[b];g=n[b-1];d=n[b+1];if(b===0){o="mceToolbarStart";if(q.Button)o+=" mceToolbarStartButton";else if(q.SplitButton)o+=" mceToolbarStartSplitButton";else if(q.ListBox)o+=" mceToolbarStartListBox";l+=k.createHTML("td",{"class":o},k.createHTML("span",null,"<\!-- IE --\>"))}if(g&&q.ListBox)if(g.Button||g.SplitButton)l+=k.createHTML("td",
-{"class":"mceToolbarEnd"},k.createHTML("span",null,"<\!-- IE --\>"));l+=k.stdMode?'<td style="position: relative">'+q.renderHTML()+"</td>":"<td>"+q.renderHTML()+"</td>";if(d&&q.ListBox)if(d.Button||d.SplitButton)l+=k.createHTML("td",{"class":"mceToolbarStart"},k.createHTML("span",null,"<\!-- IE --\>"))}o="mceToolbarEnd";if(q.Button)o+=" mceToolbarEndButton";else if(q.SplitButton)o+=" mceToolbarEndSplitButton";else if(q.ListBox)o+=" mceToolbarEndListBox";l+=k.createHTML("td",{"class":o},k.createHTML("span",
-null,"<\!-- IE --\>"));return k.createHTML("table",{id:this.id,"class":"mceToolbar"+(j["class"]?" "+j["class"]:""),cellpadding:"0",cellspacing:"0",align:this.settings.align||""},"<tbody><tr>"+l+"</tr></tbody>")}});
-(function(l){l.create("tinymce.AddOnManager",{items:[],urls:{},lookup:{},onAdd:new l.util.Dispatcher(this),get:function(o){return this.lookup[o]},requireLangPack:function(o){var q=l.settings;q&&q.language&&l.ScriptLoader.add(this.urls[o]+"/langs/"+q.language+".js")},add:function(o,q){this.items.push(q);this.lookup[o]=q;this.onAdd.dispatch(this,o,q);return q},load:function(o,q,k,j){if(!this.urls[o]){if(q.indexOf("/")!=0&&q.indexOf("://")==-1)q=l.baseURL+"/"+q;this.urls[o]=q.substring(0,q.lastIndexOf("/"));
-l.ScriptLoader.add(q,k,j)}}});l.PluginManager=new l.AddOnManager;l.ThemeManager=new l.AddOnManager})(tinymce);
-(function(l){var o=l.each,q=l.extend,k=l.DOM,j=l.dom.Event,b=l.explode,g=l.util.Dispatcher,d=0;l.documentBaseURL=window.location.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");/[\/\\]$/.test(l.documentBaseURL)||(l.documentBaseURL+="/");l.baseURL=(new l.util.URI(l.documentBaseURL)).toAbsolute(l.baseURL);l.baseURI=new l.util.URI(l.baseURL);l.onBeforeUnload=new g(l);j.add(window,"beforeunload",function(n){l.onBeforeUnload.dispatch(l,n)});l.onAddEditor=new g(l);l.onRemoveEditor=new g(l);l.EditorManager=
-q(l,{editors:[],i18n:{},activeEditor:null,init:function(n){function r(c,i,a){var h=c[i];if(h){if(l.is(h,"string")){a=(a=h.replace(/\.\w+$/,""))?l.resolve(a):0;h=l.resolve(h)}return h.apply(a||this,Array.prototype.slice.call(arguments,2))}}var u=this,v,f=[],e;n=q({theme:"simple",language:"en"},n);u.settings=n;j.add(document,"init",function(){var c,i;r(n,"onpageload");switch(n.mode){case "exact":c=n.elements||"";c.length>0&&o(b(c),function(a){if(k.get(a)){e=new l.Editor(a,n);f.push(e);e.render(1)}else o(document.forms,
-function(h){o(h.elements,function(m){if(m.name===a){a="mce_editor_"+d++;k.setAttrib(m,"id",a);e=new l.Editor(a,n);f.push(e);e.render(1)}})})});break;case "textareas":case "specific_textareas":o(k.select("textarea"),function(a){if(!(n.editor_deselector&&(n.editor_deselector.constructor===RegExp?n.editor_deselector.test(a.className):k.hasClass(a,n.editor_deselector))))if(!n.editor_selector||(n.editor_selector.constructor===RegExp?n.editor_selector.test(a.className):k.hasClass(a,n.editor_selector))){v=
-k.get(a.name);if(!a.id&&!v)a.id=a.name;if(!a.id||u.get(a.id))a.id=k.uniqueId();e=new l.Editor(a.id,n);f.push(e);e.render(1)}})}if(n.oninit){c=i=0;o(f,function(a){i++;if(a.initialized)c++;else a.onInit.add(function(){c++;c==i&&r(n,"oninit")});c==i&&r(n,"oninit")})}})},get:function(n){if(n===void 0)return this.editors;return this.editors[n]},getInstanceById:function(n){return this.get(n)},add:function(n){var r=this.editors;r[n.id]=n;r.push(n);this._setActive(n);this.onAddEditor.dispatch(this,n);return n},
-remove:function(n){var r,u=this.editors;if(!u[n.id])return null;delete u[n.id];for(r=0;r<u.length;r++)if(u[r]==n){u.splice(r,1);break}this.activeEditor==n&&this._setActive(u[0]);n.destroy();this.onRemoveEditor.dispatch(this,n);return n},execCommand:function(n,r,u){var v=this.get(u),f;switch(n){case "mceFocus":v.focus();return true;case "mceAddEditor":case "mceAddControl":this.get(u)||(new l.Editor(u,this.settings)).render();return true;case "mceAddFrameControl":f=u.window;f.tinyMCE=tinyMCE;f.tinymce=
-l;l.DOM.doc=f.document;l.DOM.win=f;v=new l.Editor(u.element_id,u);v.render();if(l.isIE){var e=function(){v.destroy();f.detachEvent("onunload",e);f=f.tinyMCE=f.tinymce=null};f.attachEvent("onunload",e)}u.page_window=null;return true;case "mceRemoveEditor":case "mceRemoveControl":v&&v.remove();return true;case "mceToggleEditor":if(!v){this.execCommand("mceAddControl",0,u);return true}v.isHidden()?v.show():v.hide();return true}if(this.activeEditor)return this.activeEditor.execCommand(n,r,u);return false},
-execInstanceCommand:function(n,r,u,v){if(n=this.get(n))return n.execCommand(r,u,v);return false},triggerSave:function(){o(this.editors,function(n){n.save()})},addI18n:function(n,r){var u=this.i18n;l.is(n,"string")?o(r,function(v,f){u[n+"."+f]=v}):o(n,function(v,f){o(v,function(e,c){o(e,function(i,a){if(c==="common")u[f+"."+a]=i;else u[f+"."+c+"."+a]=i})})})},_setActive:function(n){this.selectedInstance=this.activeEditor=n}})})(tinymce);
-(function(l){var o=l.DOM,q=l.dom.Event,k=l.extend,j=l.util.Dispatcher,b=l.each,g=l.isGecko,d=l.isIE,n=l.is,r=l.ThemeManager,u=l.PluginManager,v=l.explode;l.create("tinymce.Editor",{Editor:function(f,e){var c=this;c.id=c.editorId=f;c.execCommands={};c.queryStateCommands={};c.queryValueCommands={};c.isNotDirty=false;c.plugins={};b(["onPreInit","onBeforeRenderUI","onPostRender","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"],function(i){c[i]=new j(c)});c.settings=e=k({id:f,language:"en",docs_language:"en",theme:"simple",skin:"default",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:l.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:l.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",
-apply_source_formatting:1,directionality:"ltr",forced_root_block:"p",valid_elements:"@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big",
-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},e);c.documentBaseURI=new l.util.URI(e.document_base_url||l.documentBaseURL,{base_uri:tinyMCE.baseURI});c.baseURI=l.baseURI;c.execCallback("setup",c)},render:function(){var f=this,e=f.settings,c=f.id,i=l.ScriptLoader;if(q.domLoaded){tinyMCE.settings=e;if(f.getElement())if(!l.isIDevice){!/TEXTAREA|INPUT/i.test(f.getElement().nodeName)&&
-e.hidden_input&&o.getParent(c,"form")&&o.insertAfter(o.create("input",{type:"hidden",name:c}),c);if(l.WindowManager)f.windowManager=new l.WindowManager(f);e.encoding=="xml"&&f.onGetContent.add(function(a,h){if(h.save)h.content=o.encode(h.content)});e.add_form_submit_trigger&&f.onSubmit.addToTop(function(){if(f.initialized){f.save();f.isNotDirty=1}});if(e.add_unload_trigger)f._beforeUnload=tinyMCE.onBeforeUnload.add(function(){f.initialized&&!f.destroyed&&!f.isHidden()&&f.save({format:"raw",no_events:true})});
-l.addUnload(f.destroy,f);e.submit_patch&&f.onBeforeRenderUI.add(function(){var a=f.getElement().form;if(a)if(!a._mceOldSubmit){if(!a.submit.nodeType&&!a.submit.length){f.formElement=a;a._mceOldSubmit=a.submit;a.submit=function(){l.triggerSave();f.isNotDirty=1;return f.formElement._mceOldSubmit(f.formElement)}}a=null}});(function(){e.language&&i.add(l.baseURL+"/langs/"+e.language+".js");e.theme&&e.theme.charAt(0)!="-"&&!r.urls[e.theme]&&r.load(e.theme,"themes/"+e.theme+"/editor_template"+l.suffix+
-".js");b(v(e.plugins),function(a){a&&a.charAt(0)!="-"&&!u.urls[a]&&a!="safari"&&u.load(a,"plugins/"+a+"/editor_plugin"+l.suffix+".js")});i.loadQueue(function(){f.removed||f.init()})})()}}else q.add(document,"init",function(){f.render()})},init:function(){var f=this,e=f.settings,c,i,a=f.getElement(),h,m,p;l.add(f);if(e.theme){e.theme=e.theme.replace(/-/,"");h=r.get(e.theme);f.theme=new h;if(f.theme.init&&e.init_theme)f.theme.init(f,r.urls[e.theme]||l.documentBaseURL.replace(/\/$/,""))}b(v(e.plugins.replace(/\-/g,
-"")),function(t){var s=u.get(t),x=u.urls[t]||l.documentBaseURL.replace(/\/$/,"");if(s){s=new s(f,x);f.plugins[t]=s;s.init&&s.init(f,x)}});if(e.popup_css!==false)e.popup_css=e.popup_css?f.documentBaseURI.toAbsolute(e.popup_css):f.baseURI.toAbsolute("themes/"+e.theme+"/skins/"+e.skin+"/dialog.css");if(e.popup_css_add)e.popup_css+=","+f.documentBaseURI.toAbsolute(e.popup_css_add);f.controlManager=new l.ControlManager(f);if(e.custom_undo_redo){f.onBeforeExecCommand.add(function(t,s,x,y,C){if(s!="Undo"&&
-s!="Redo"&&s!="mceRepaint"&&(!C||!C.skip_undo))f.undoManager.hasUndo()||f.undoManager.add()});f.onExecCommand.add(function(t,s,x,y,C){if(s!="Undo"&&s!="Redo"&&s!="mceRepaint"&&(!C||!C.skip_undo))f.undoManager.add()})}f.onExecCommand.add(function(t,s){/^(FontName|FontSize)$/.test(s)||f.nodeChanged()});if(g){p=function(t,s){if(!s||!s.initial)f.execCommand("mceRepaint")};f.onUndo.add(p);f.onRedo.add(p);f.onSetContent.add(p)}f.onBeforeRenderUI.dispatch(f,f.controlManager);if(e.render_ui){c=e.width||a.style.width||
-a.offsetWidth;i=e.height||a.style.height||a.offsetHeight;f.orgDisplay=a.style.display;p=/^[0-9\.]+(|px)$/i;if(p.test(""+c))c=Math.max(parseInt(c)+(h.deltaWidth||0),100);if(p.test(""+i))i=Math.max(parseInt(i)+(h.deltaHeight||0),100);h=f.theme.renderUI({targetNode:a,width:c,height:i,deltaWidth:e.delta_width,deltaHeight:e.delta_height});f.editorContainer=h.editorContainer}if(document.domain&&location.hostname!=document.domain)l.relaxedDomain=document.domain;o.setStyles(h.sizeContainer||h.editorContainer,
-{width:c,height:i});i=(h.iframeHeight||i)+(typeof i=="number"?h.deltaHeight||0:"");if(i<100)i=100;f.iframeHTML=e.doctype+'<html><head xmlns="http://www.w3.org/1999/xhtml">';if(e.document_base_url!=l.documentBaseURL)f.iframeHTML+='<base href="'+f.documentBaseURI.getURI()+'" />';f.iframeHTML+='<meta http-equiv="X-UA-Compatible" content="IE=7" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';if(l.relaxedDomain)f.iframeHTML+='<script type="text/javascript">document.domain = "'+
-l.relaxedDomain+'";<\/script>';c=e.body_id||"tinymce";if(c.indexOf("=")!=-1){c=f.getParam("body_id","","hash");c=c[f.id]||c}e=e.body_class||"";if(e.indexOf("=")!=-1){e=f.getParam("body_class","","hash");e=e[f.id]||""}f.iframeHTML+='</head><body id="'+c+'" class="mceContentBody '+e+'"></body></html>';if(l.relaxedDomain)if(d||l.isOpera&&parseFloat(opera.version())>=9.5)m='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinyMCE.get("'+f.id+'");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';
-else if(l.isOpera)m='javascript:(function(){document.open();document.domain="'+document.domain+'";document.close();ed.setupIframe();})()';o.add(h.iframeContainer,"iframe",{id:f.id+"_ifr",src:m||'javascript:""',frameBorder:"0",style:{width:"100%",height:i}});f.contentAreaContainer=h.iframeContainer;o.get(h.editorContainer).style.display=f.orgDisplay;o.get(f.id).style.display="none";if(!d||!l.relaxedDomain)f.setupIframe();a=h=null},setupIframe:function(){var f=this,e=f.settings;o.get(f.id);var c=f.getDoc(),
-i;if(!d||!l.relaxedDomain){c.open();c.write(f.iframeHTML);c.close()}if(!d)try{if(!e.readonly)c.designMode="On"}catch(a){}if(d){i=f.getBody();o.hide(i);if(!e.readonly)i.contentEditable=true;o.show(i)}f.dom=new l.dom.DOMUtils(f.getDoc(),{keep_values:true,url_converter:f.convertURL,url_converter_scope:f,hex_colors:e.force_hex_style_colors,class_filter:e.class_filter,update_styles:1,fix_ie_paragraphs:1,valid_styles:e.valid_styles});f.schema=new l.dom.Schema;f.serializer=new l.dom.Serializer(k(e,{valid_elements:e.verify_html===
-false?"*[*]":e.valid_elements,dom:f.dom,schema:f.schema}));f.selection=new l.dom.Selection(f.dom,f.getWin(),f.serializer);f.formatter=new l.Formatter(this);f.formatter.register({alignleft:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"left"}},{selector:"img,table",styles:{"float":"left"}}],aligncenter:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"center"}},{selector:"img",styles:{display:"block",marginLeft:"auto",marginRight:"auto"}},{selector:"table",
-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",styles:{"float":"right"}}],alignfull:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"justify"}}],bold:[{inline:"strong"},{inline:"span",styles:{fontWeight:"bold"}},{inline:"b"}],italic:[{inline:"em"},{inline:"span",styles:{fontStyle:"italic"}},{inline:"i"}],underline:[{inline:"span",styles:{textDecoration:"underline"},
-exact:true},{inline:"u"}],strikethrough:[{inline:"span",styles:{textDecoration:"line-through"},exact:true},{inline:"u"}],forecolor:{inline:"span",styles:{color:"%value"}},hilitecolor:{inline:"span",styles:{backgroundColor:"%value"}},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"},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}]});b("p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp".split(/\s/),function(t){f.formatter.register(t,{block:t,remove:"all"})});f.formatter.register(f.settings.formats);f.undoManager=new l.UndoManager(f);f.undoManager.onAdd.add(function(t,s){if(!s.initial)return f.onChange.dispatch(f,
-s,t)});f.undoManager.onUndo.add(function(t,s){return f.onUndo.dispatch(f,s,t)});f.undoManager.onRedo.add(function(t,s){return f.onRedo.dispatch(f,s,t)});f.forceBlocks=new l.ForceBlocks(f,{forced_root_block:e.forced_root_block});f.editorCommands=new l.EditorCommands(f);f.serializer.onPreProcess.add(function(t,s){return f.onPreProcess.dispatch(f,s,t)});f.serializer.onPostProcess.add(function(t,s){return f.onPostProcess.dispatch(f,s,t)});f.onPreInit.dispatch(f);if(!e.gecko_spellcheck)f.getBody().spellcheck=
-0;e.readonly||f._addEvents();f.controlManager.onPostRender.dispatch(f,f.controlManager);f.onPostRender.dispatch(f);if(e.directionality)f.getBody().dir=e.directionality;if(e.nowrap)f.getBody().style.whiteSpace="nowrap";if(e.custom_elements){var h=function(t,s){b(v(e.custom_elements),function(x){var y;if(x.indexOf("~")===0){x=x.substring(1);y="span"}else y="div";s.content=s.content.replace(RegExp("<("+x+")([^>]*)>","g"),"<"+y+' _mce_name="$1"$2>');s.content=s.content.replace(RegExp("</("+x+")>","g"),
-"</"+y+">")})};f.onBeforeSetContent.add(h);f.onPostProcess.add(function(t,s){s.set&&h(t,s)})}e.handle_node_change_callback&&f.onNodeChange.add(function(t,s,x){f.execCallback("handle_node_change_callback",f.id,x,-1,-1,true,f.selection.isCollapsed())});e.save_callback&&f.onSaveContent.add(function(t,s){var x=f.execCallback("save_callback",f.id,s.content,f.getBody());if(x)s.content=x});e.onchange_callback&&f.onChange.add(function(t,s){f.execCallback("onchange_callback",f,s)});e.convert_newlines_to_brs&&
-f.onBeforeSetContent.add(function(t,s){if(s.initial)s.content=s.content.replace(/\r?\n/g,"<br />")});e.fix_nesting&&d&&f.onBeforeSetContent.add(function(t,s){s.content=f._fixNesting(s.content)});e.preformatted&&f.onPostProcess.add(function(t,s){s.content=s.content.replace(/^\s*<pre.*?>/,"");s.content=s.content.replace(/<\/pre>\s*$/,"");if(s.set)s.content='<pre class="mceItemHidden">'+s.content+"</pre>"});if(e.verify_css_classes)f.serializer.attribValueFilter=function(t,s){var x,y;if(t=="class"){if(!f.classesRE){y=
-f.dom.getClasses();if(y.length>0){x="";b(y,function(C){x+=(x?"|":"")+C["class"]});f.classesRE=RegExp("("+x+")","gi")}}return!f.classesRE||/(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(s)||f.classesRE.test(s)?s:""}return s};if(e.cleanup_callback){f.onBeforeSetContent.add(function(t,s){s.content=f.execCallback("cleanup_callback","insert_to_editor",s.content,s)});f.onPreProcess.add(function(t,s){s.set&&f.execCallback("cleanup_callback","insert_to_editor_dom",s.node,s);s.get&&f.execCallback("cleanup_callback",
-"get_from_editor_dom",s.node,s)});f.onPostProcess.add(function(t,s){if(s.set)s.content=f.execCallback("cleanup_callback","insert_to_editor",s.content,s);if(s.get)s.content=f.execCallback("cleanup_callback","get_from_editor",s.content,s)})}e.save_callback&&f.onGetContent.add(function(t,s){if(s.save)s.content=f.execCallback("save_callback",f.id,s.content,f.getBody())});e.handle_event_callback&&f.onEvent.add(function(t,s,x){f.execCallback("handle_event_callback",s,t,x)===false&&q.cancel(s)});f.onSetContent.add(function(){f.addVisual(f.getBody())});
-e.padd_empty_editor&&f.onPostProcess.add(function(t,s){s.content=s.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/,"")});if(g){var m=function(t){b(t.dom.select("a"),function(s){var x=s.parentNode;t.dom.isBlock(x)&&x.lastChild===s&&t.dom.add(x,"br",{_mce_bogus:1})})};f.onExecCommand.add(function(t,s){s==="CreateLink"&&m(t)});f.onSetContent.add(f.selection.onSetContent.add(m));if(!e.readonly)try{c.designMode="Off";c.designMode="On"}catch(p){}}setTimeout(function(){if(!f.removed){f.load({initial:true,
-format:e.cleanup_on_startup?"html":"raw"});f.startContent=f.getContent({format:"raw"});f.initialized=true;f.onInit.dispatch(f);f.execCallback("setupcontent_callback",f.id,f.getBody(),f.getDoc());f.execCallback("init_instance_callback",f);f.focus(true);f.nodeChanged({initial:1});e.content_css&&l.each(v(e.content_css),function(t){f.dom.loadCSS(f.documentBaseURI.toAbsolute(t))});e.auto_focus&&setTimeout(function(){var t=l.get(e.auto_focus);t.selection.select(t.getBody(),1);t.selection.collapse(1);t.getWin().focus()},
-100)}},1)},focus:function(f){var e;e=this.settings.content_editable;var c,i=this.getDoc();if(!f){f=this.selection.getRng();if(f.item)c=f.item(0);e||this.getWin().focus();if(c&&c.ownerDocument==i){f=i.body.createControlRange();f.addElement(c);f.select()}}if(l.activeEditor!=this){if((e=l.activeEditor)!=null)e.onDeactivate.dispatch(e,this);this.onActivate.dispatch(this,e)}l._setActive(this)},execCallback:function(f){var e=this.settings[f],c;if(e){if(this.callbackLookup&&(c=this.callbackLookup[f])){e=
-c.func;c=c.scope}if(n(e,"string")){c=(c=e.replace(/\.\w+$/,""))?l.resolve(c):0;e=l.resolve(e);this.callbackLookup=this.callbackLookup||{};this.callbackLookup[f]={func:e,scope:c}}return e.apply(c||this,Array.prototype.slice.call(arguments,1))}},translate:function(f){var e=this.settings.language||"en",c=l.i18n;if(!f)return"";return c[e+"."+f]||f.replace(/{\#([^}]+)\}/g,function(i,a){return c[e+"."+a]||"{#"+a+"}"})},getLang:function(f,e){return l.i18n[(this.settings.language||"en")+"."+f]||(n(e)?e:"{#"+
-f+"}")},getParam:function(f,e,c){var i=l.trim;f=n(this.settings[f])?this.settings[f]:e;var a;if(c==="hash"){a={};if(n(f,"string"))b(f.indexOf("=")>0?f.split(/[;,](?![^=;,]*(?:[;,]|$))/):f.split(","),function(h){h=h.split("=");if(h.length>1)a[i(h[0])]=i(h[1]);else a[i(h[0])]=i(h)});else a=f;return a}return f},nodeChanged:function(f){var e=this.selection,c=(d?e.getNode():e.getStart())||this.getBody();if(this.initialized){f=f||{};c=d&&c.ownerDocument!=this.getDoc()?this.getBody():c;f.parents=[];this.dom.getParent(c,
-function(i){if(i.nodeName=="BODY")return true;f.parents.push(i)});this.onNodeChange.dispatch(this,f?f.controlManager||this.controlManager:this.controlManager,c,e.isCollapsed(),f)}},addButton:function(f,e){this.buttons=this.buttons||{};this.buttons[f]=e},addCommand:function(f,e,c){this.execCommands[f]={func:e,scope:c||this}},addQueryStateHandler:function(f,e,c){this.queryStateCommands[f]={func:e,scope:c||this}},addQueryValueHandler:function(f,e,c){this.queryValueCommands[f]={func:e,scope:c||this}},
-addShortcut:function(f,e,c,i){var a=this,h;if(!a.settings.custom_shortcuts)return false;a.shortcuts=a.shortcuts||{};if(n(c,"string")){h=c;c=function(){a.execCommand(h,false,null)}}if(n(c,"object")){h=c;c=function(){a.execCommand(h[0],h[1],h[2])}}b(v(f),function(m){var p={func:c,scope:i||this,desc:e,alt:false,ctrl:false,shift:false};b(v(m,"+"),function(t){switch(t){case "alt":case "ctrl":case "shift":p[t]=true;break;default:p.charCode=t.charCodeAt(0);p.keyCode=t.toUpperCase().charCodeAt(0)}});a.shortcuts[(p.ctrl?
-"ctrl":"")+","+(p.alt?"alt":"")+","+(p.shift?"shift":"")+","+p.keyCode]=p});return true},execCommand:function(f,e,c,i){var a=this,h=0,m;if(!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(f)&&(!i||!i.skip_focus))a.focus();m={};a.onBeforeExecCommand.dispatch(a,f,e,c,m);if(m.terminate)return false;if(a.execCallback("execcommand_callback",a.id,a.selection.getNode(),f,e,c)){a.onExecCommand.dispatch(a,f,e,c,i);return true}if(m=a.execCommands[f]){m=m.func.call(m.scope,
-e,c);if(m!==true){a.onExecCommand.dispatch(a,f,e,c,i);return m}}b(a.plugins,function(p){if(p.execCommand&&p.execCommand(f,e,c)){a.onExecCommand.dispatch(a,f,e,c,i);h=1;return false}});if(h)return true;if(a.theme&&a.theme.execCommand&&a.theme.execCommand(f,e,c)){a.onExecCommand.dispatch(a,f,e,c,i);return true}if(l.GlobalCommands.execCommand(a,f,e,c)){a.onExecCommand.dispatch(a,f,e,c,i);return true}if(a.editorCommands.execCommand(f,e,c)){a.onExecCommand.dispatch(a,f,e,c,i);return true}a.getDoc().execCommand(f,
-e,c);a.onExecCommand.dispatch(a,f,e,c,i)},queryCommandState:function(f){var e;if(!this._isHidden()){if(e=this.queryStateCommands[f]){e=e.func.call(e.scope);if(e!==true)return e}e=this.editorCommands.queryCommandState(f);if(e!==-1)return e;try{return this.getDoc().queryCommandState(f)}catch(c){}}},queryCommandValue:function(f){var e;if(!this._isHidden()){if(e=this.queryValueCommands[f]){e=e.func.call(e.scope);if(e!==true)return e}e=this.editorCommands.queryCommandValue(f);if(n(e))return e;try{return this.getDoc().queryCommandValue(f)}catch(c){}}},
-show:function(){o.show(this.getContainer());o.hide(this.id);this.load()},hide:function(){var f=this.getDoc();d&&f&&f.execCommand("SelectAll");this.save();o.hide(this.getContainer());o.setStyle(this.id,"display",this.orgDisplay)},isHidden:function(){return!o.isHidden(this.id)},setProgressState:function(f,e,c){this.onSetProgressState.dispatch(this,f,e,c);return f},load:function(f){var e=this.getElement(),c;if(e){f=f||{};f.load=true;c=this.setContent(n(e.value)?e.value:e.innerHTML,f);f.element=e;f.no_events||
-this.onLoadContent.dispatch(this,f);f.element=null;return c}},save:function(f){var e=this,c=e.getElement(),i;if(c&&e.initialized){f=f||{};f.save=true;if(!f.no_events){e.undoManager.typing=0;e.undoManager.add()}f.element=c;i=f.content=e.getContent(f);f.no_events||e.onSaveContent.dispatch(e,f);i=f.content;if(/TEXTAREA|INPUT/i.test(c.nodeName))c.value=i;else{c.innerHTML=i;if(c=o.getParent(e.id,"form"))b(c.elements,function(a){if(a.name==e.id){a.value=i;return false}})}f.element=c=null;return i}},setContent:function(f,
-e){e=e||{};e.format=e.format||"html";e.set=true;e.content=f;e.no_events||this.onBeforeSetContent.dispatch(this,e);if(!l.isIE&&(f.length===0||/^\s+$/.test(f))){e.content=this.dom.setHTML(this.getBody(),'<br _mce_bogus="1" />');e.format="raw"}e.content=this.dom.setHTML(this.getBody(),l.trim(e.content));if(e.format!="raw"&&this.settings.cleanup){e.getInner=true;e.content=this.dom.setHTML(this.getBody(),this.serializer.serialize(this.getBody(),e))}e.no_events||this.onSetContent.dispatch(this,e);return e.content},
-getContent:function(f){var e;f=f||{};f.format=f.format||"html";f.get=true;f.no_events||this.onBeforeGetContent.dispatch(this,f);if(f.format!="raw"&&this.settings.cleanup){f.getInner=true;e=this.serializer.serialize(this.getBody(),f)}else e=this.getBody().innerHTML;e=e.replace(/^\s*|\s*$/g,"");f.content=e;f.no_events||this.onGetContent.dispatch(this,f);return f.content},isDirty:function(){return l.trim(this.startContent)!=l.trim(this.getContent({format:"raw",no_events:1}))&&!this.isNotDirty},getContainer:function(){if(!this.container)this.container=
-o.get(this.editorContainer||this.id+"_parent");return this.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return o.get(this.settings.content_element||this.id)},getWin:function(){var f;if(!this.contentWindow)if(f=o.get(this.id+"_ifr"))this.contentWindow=f.contentWindow;return this.contentWindow},getDoc:function(){var f;if(!this.contentDocument)if(f=this.getWin())this.contentDocument=f.document;return this.contentDocument},getBody:function(){return this.bodyElement||
-this.getDoc().body},convertURL:function(f,e,c){var i=this.settings;if(i.urlconverter_callback)return this.execCallback("urlconverter_callback",f,c,true,e);if(!i.convert_urls||c&&c.nodeName=="LINK"||f.indexOf("file:")===0)return f;if(i.relative_urls)return this.documentBaseURI.toRelative(f);return f=this.documentBaseURI.toAbsolute(f,i.remove_script_host)},addVisual:function(f){var e=this,c=e.settings;f=f||e.getBody();if(!n(e.hasVisual))e.hasVisual=c.visual;b(e.dom.select("table,a",f),function(i){var a;
-switch(i.nodeName){case "TABLE":a=e.dom.getAttrib(i,"border");if(!a||a=="0")e.hasVisual?e.dom.addClass(i,c.visual_table_class):e.dom.removeClass(i,c.visual_table_class);break;case "A":if(a=e.dom.getAttrib(i,"name"))e.hasVisual?e.dom.addClass(i,"mceItemAnchor"):e.dom.removeClass(i,"mceItemAnchor")}});e.onVisualAid.dispatch(e,f,e.hasVisual)},remove:function(){var f=this.getContainer();this.removed=1;this.hide();this.execCallback("remove_instance_callback",this);this.onRemove.dispatch(this);this.onExecCommand.listeners=
-[];l.remove(this);o.remove(f)},destroy:function(f){if(!this.destroyed){if(!f){l.removeUnload(this.destroy);tinyMCE.onBeforeUnload.remove(this._beforeUnload);this.theme&&this.theme.destroy&&this.theme.destroy();this.controlManager.destroy();this.selection.destroy();this.dom.destroy();if(!this.settings.content_editable){q.clear(this.getWin());q.clear(this.getDoc())}q.clear(this.getBody());q.clear(this.formElement)}if(this.formElement){this.formElement.submit=this.formElement._mceOldSubmit;this.formElement._mceOldSubmit=
-null}this.contentAreaContainer=this.formElement=this.container=this.settings.content_element=this.bodyElement=this.contentDocument=this.contentWindow=null;if(this.selection)this.selection=this.selection.win=this.selection.dom=this.selection.dom.doc=null;this.destroyed=1}},_addEvents:function(){function f(p,t){if(!e.removed)if(e.onEvent.dispatch(e,p,t)!==false)e[a[p.fakeType||p.type]].dispatch(e,p,t)}var e=this,c,i=e.settings,a={mouseup:"onMouseUp",mousedown:"onMouseDown",click:"onClick",keyup:"onKeyUp",
-keydown:"onKeyDown",keypress:"onKeyPress",submit:"onSubmit",reset:"onReset",contextmenu:"onContextMenu",dblclick:"onDblClick",paste:"onPaste"};b(a,function(p,t){switch(t){case "contextmenu":l.isOpera?e.dom.bind(e.getBody(),"mousedown",function(s){if(s.ctrlKey){s.fakeType="contextmenu";f(s)}}):e.dom.bind(e.getBody(),t,f);break;case "paste":e.dom.bind(e.getBody(),t,function(s){f(s)});break;case "submit":case "reset":e.dom.bind(e.getElement().form||o.getParent(e.id,"form"),t,f);break;default:e.dom.bind(i.content_editable?
-e.getBody():e.getDoc(),t,f)}});e.dom.bind(i.content_editable?e.getBody():g?e.getDoc():e.getWin(),"focus",function(){e.focus(true)});l.isGecko&&e.dom.bind(e.getDoc(),"DOMNodeInserted",function(p){var t;p=p.target;if(p.nodeType===1&&p.nodeName==="IMG"&&(t=p.getAttribute("_mce_src")))p.src=e.documentBaseURI.toAbsolute(t)});if(g){c=function(){var p=this.getDoc(),t=this.settings;if(g&&!t.readonly){if(this._isHidden())try{if(!t.content_editable)p.designMode="On"}catch(s){}try{p.execCommand("styleWithCSS",
-0,false)}catch(x){if(!this._isHidden())try{p.execCommand("useCSS",0,true)}catch(y){}}if(!t.table_inline_editing)try{p.execCommand("enableInlineTableEditing",false,false)}catch(C){}if(!t.object_resizing)try{p.execCommand("enableObjectResizing",false,false)}catch(A){}}};e.onBeforeExecCommand.add(c);e.onMouseDown.add(c)}l.isWebKit&&e.onClick.add(function(p,t){t=t.target;if(t.nodeName=="IMG"||t.nodeName=="A"&&e.dom.hasClass(t,"mceItemAnchor"))e.selection.getSel().setBaseAndExtent(t,0,t,1)});e.onMouseUp.add(e.nodeChanged);
-e.onKeyUp.add(function(p,t){var s=t.keyCode;if(s>=33&&s<=36||s>=37&&s<=40||s==13||s==45||s==46||s==8||l.isMac&&(s==91||s==93)||t.ctrlKey)e.nodeChanged()});e.onReset.add(function(){e.setContent(e.startContent,{format:"raw"})});if(i.custom_shortcuts){if(i.custom_undo_redo_keyboard_shortcuts){e.addShortcut("ctrl+z",e.getLang("undo_desc"),"Undo");e.addShortcut("ctrl+y",e.getLang("redo_desc"),"Redo")}e.addShortcut("ctrl+b",e.getLang("bold_desc"),"Bold");e.addShortcut("ctrl+i",e.getLang("italic_desc"),
-"Italic");e.addShortcut("ctrl+u",e.getLang("underline_desc"),"Underline");for(c=1;c<=6;c++)e.addShortcut("ctrl+"+c,"",["FormatBlock",false,"h"+c]);e.addShortcut("ctrl+7","",["FormatBlock",false,"<p>"]);e.addShortcut("ctrl+8","",["FormatBlock",false,"<div>"]);e.addShortcut("ctrl+9","",["FormatBlock",false,"<address>"]);var h=function(p){var t=null;if(!p.altKey&&!p.ctrlKey&&!p.metaKey)return t;b(e.shortcuts,function(s){if(!(l.isMac&&s.ctrl!=p.metaKey))if(!(!l.isMac&&s.ctrl!=p.ctrlKey))if(s.alt==p.altKey)if(s.shift==
-p.shiftKey)if(p.keyCode==s.keyCode||p.charCode&&p.charCode==s.charCode){t=s;return false}});return t};e.onKeyUp.add(function(p,t){if(h(t))return q.cancel(t)});e.onKeyPress.add(function(p,t){if(h(t))return q.cancel(t)});e.onKeyDown.add(function(p,t){var s=h(t);if(s){s.func.call(s.scope);return q.cancel(t)}})}if(l.isIE){e.dom.bind(e.getDoc(),"controlselect",function(p){var t=e.resizeInfo;p=p.target;if(p.nodeName==="IMG"){t&&e.dom.unbind(t.node,t.ev,t.cb);if(e.dom.hasClass(p,"mceItemNoResize")){ev="resizestart";
-t=e.dom.bind(p,"resizestart",q.cancel,q)}else{ev="resizeend";t=e.dom.bind(p,ev,function(s){var x;s=s.target;if(x=e.dom.getStyle(s,"width")){e.dom.setAttrib(s,"width",x.replace(/[^0-9%]+/g,""));e.dom.setStyle(s,"width","")}if(x=e.dom.getStyle(s,"height")){e.dom.setAttrib(s,"height",x.replace(/[^0-9%]+/g,""));e.dom.setStyle(s,"height","")}})}t=e.resizeInfo={node:p,ev:ev,cb:t}}});e.onKeyDown.add(function(p,t){switch(t.keyCode){case 8:if(e.selection.getRng().item){p.dom.remove(e.selection.getRng().item(0));
-return q.cancel(t)}}})}l.isOpera&&e.onClick.add(function(p,t){q.prevent(t)});if(i.custom_undo_redo){var m=function(){e.undoManager.typing=0;e.undoManager.add()};e.dom.bind(e.getDoc(),"focusout",function(){!e.removed&&e.undoManager.typing&&m()});e.onKeyUp.add(function(p,t){if(t.keyCode>=33&&t.keyCode<=36||t.keyCode>=37&&t.keyCode<=40||t.keyCode==13||t.keyCode==45||t.ctrlKey)m()});e.onKeyDown.add(function(p,t){var s,x,y,C;if(d&&t.keyCode==46){s=e.selection.getRng();if(s.parentElement){y=s.parentElement();
-x=s.duplicate();x.moveToElementText(y);x.setEndPoint("EndToEnd",s);C=x.text.length;if(t.ctrlKey){s.moveEnd("word",1);s.select()}e.selection.getSel().clear();if(s.parentElement()==y){try{y.innerHTML=y.innerHTML}catch(A){}x.moveToElementText(y);x.collapse();x.move("character",C);x.select()}t.preventDefault();return}}if(t.keyCode>=33&&t.keyCode<=36||t.keyCode>=37&&t.keyCode<=40||t.keyCode==13||t.keyCode==45)e.undoManager.typing&&m();else if(!e.undoManager.typing){e.undoManager.add();e.undoManager.typing=
-1}});e.onMouseDown.add(function(){e.undoManager.typing&&m()})}},_isHidden:function(){var f;if(!g)return 0;f=this.selection.getSel();return!f||!f.rangeCount||f.rangeCount==0},_fixNesting:function(f){var e=[],c;f=f.replace(/<(\/)?([^\s>]+)[^>]*?>/g,function(i,a,h){if(a==="/"){if(!e.length)return"";if(h!==e[e.length-1].tag){for(c=e.length-1;c>=0;c--)if(e[c].tag===h){e[c].close=1;break}return""}else{e.pop();if(e.length&&e[e.length-1].close){i=i+"</"+e[e.length-1].tag+">";e.pop()}}}else{if(/^(br|hr|input|meta|img|link|param)$/i.test(h))return i;
-if(/\/>$/.test(i))return i;e.push({tag:h})}return i});for(c=e.length-1;c>=0;c--)f+="</"+e[c].tag+">";return f}})})(tinymce);
-(function(l){var o=l.each,q=false;l.EditorCommands=function(k){function j(e){var c;e=e.toLowerCase();if(c=u.state[e])return c(e);return-1}function b(e,c){c=c||"exec";o(e,function(i,a){o(a.toLowerCase().split(","),function(h){u[c][h]=i})})}function g(e,c,i){if(c===void 0)c=q;if(i===void 0)i=null;return k.getDoc().execCommand(e,c,i)}function d(e,c){k.formatter.toggle(e,c?{value:c}:void 0)}var n=k.dom,r=k.selection,u={state:{},exec:{},value:{}},v=k.settings,f;l.extend(this,{execCommand:function(e,c,
-i){var a;e=e.toLowerCase();if(a=u.exec[e]){a(e,c,i);return true}return q},queryCommandState:j,queryCommandValue:function(e){var c;e=e.toLowerCase();if(c=u.value[e])return c(e);return q},addCommands:b});b({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){k.undoManager.add()},"Cut,Copy,Paste":function(e){var c=k.getDoc(),i;try{g(e)}catch(a){i=true}if(i||!c.queryCommandSupported(e))l.isGecko?k.windowManager.confirm(k.getLang("clipboard_msg"),function(h){h&&
-open("http://www.mozilla.org/editor/midasdemo/securityprefs.html","_blank")}):k.windowManager.alert(k.getLang("clipboard_no_support"))},unlink:function(e){r.isCollapsed()&&r.select(r.getNode());g(e);r.collapse(q)},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){var c=e.substring(7);o("left,center,right,full".split(","),function(i){c!=i&&k.formatter.remove("align"+i)});d("align"+c)},"InsertUnorderedList,InsertOrderedList":function(e){var c;g(e);if(e=n.getParent(r.getNode(),"ol,ul")){c=
-e.parentNode;if(/^(H[1-6]|P|ADDRESS|PRE)$/.test(c.nodeName)){f=r.getBookmark(void 0);n.split(c,e);r.moveToBookmark(f)}}},"Bold,Italic,Underline,Strikethrough":function(e){d(e)},"ForeColor,HiliteColor,FontName":function(e,c,i){d(e,i)},FontSize:function(e,c,i){var a;if(i>=1&&i<=7){a=l.explode(v.font_size_style_values);i=(c=l.explode(v.font_size_classes))?c[i-1]||i:a[i-1]||i}d(e,i)},RemoveFormat:function(e){k.formatter.remove(e)},mceBlockQuote:function(){d("blockquote")},FormatBlock:function(e,c,i){return d(i)},
-mceCleanup:function(){var e=r.getBookmark();k.setContent(k.getContent({cleanup:true}),{cleanup:true});r.moveToBookmark(e)},mceRemoveNode:function(e,c,i){e=i||r.getNode();if(e!=k.getBody()){f=r.getBookmark(void 0);k.dom.remove(e,true);r.moveToBookmark(f)}},mceSelectNodeDepth:function(e,c,i){var a=0;n.getParent(r.getNode(),function(h){if(h.nodeType==1&&a++==i){r.select(h);return q}},k.getBody())},mceSelectNode:function(e,c,i){r.select(i)},mceInsertContent:function(e,c,i){r.setContent(i)},mceInsertRawHTML:function(e,
-c,i){r.setContent("tiny_mce_marker");k.setContent(k.getContent().replace(/tiny_mce_marker/g,i))},mceSetContent:function(e,c,i){k.setContent(i)},"Indent,Outdent":function(e){var c,i,a;c=v.indentation;i=/[a-z%]+$/i.exec(c);c=parseInt(c);!j("InsertUnorderedList")&&!j("InsertOrderedList")?o(r.getSelectedBlocks(),function(h){if(e=="outdent"){a=Math.max(0,parseInt(h.style.paddingLeft||0)-c);n.setStyle(h,"paddingLeft",a?a+i:"")}else n.setStyle(h,"paddingLeft",parseInt(h.style.paddingLeft||0)+c+i)}):g(e)},
-mceRepaint:function(){if(l.isGecko)try{f=r.getBookmark(true);r.getSel()&&r.getSel().selectAllChildren(k.getBody());r.collapse(true);r.moveToBookmark(f)}catch(e){}},mceToggleFormat:function(e,c,i){k.formatter.toggle(i)},InsertHorizontalRule:function(){r.setContent("<hr />")},mceToggleVisualAid:function(){k.hasVisual=!k.hasVisual;k.addVisual()},mceReplaceContent:function(e,c,i){r.setContent(i.replace(/\{\$selection\}/g,r.getContent({format:"text"})))},mceInsertLink:function(e,c,i){e=n.getParent(r.getNode(),
-"a");if(l.is(i,"string"))i={href:i};if(e)i.href?n.setAttribs(e,i):k.dom.remove(e,true);else{g("CreateLink",q,"javascript:mctmp(0);");o(n.select("a[href=javascript:mctmp(0);]"),function(a){n.setAttribs(a,i)})}},selectAll:function(){var e=n.getRoot(),c=n.createRng();c.setStart(e,0);c.setEnd(e,e.childNodes.length);k.selection.setRng(c)}});b({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(e){e="align"+e.substring(7);return k.formatter.match(e)},"Bold,Italic,Underline,Strikethrough":function(e){return k.formatter.match(e)},
-mceBlockQuote:function(){return k.formatter.match("blockquote")},Outdent:function(){var e;if(v.inline_styles){if((e=n.getParent(r.getStart(),n.isBlock))&&parseInt(e.style.paddingLeft)>0)return true;if((e=n.getParent(r.getEnd(),n.isBlock))&&parseInt(e.style.paddingLeft)>0)return true}return j("InsertUnorderedList")||j("InsertOrderedList")||!v.inline_styles&&!!n.getParent(r.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(e){return n.getParent(r.getNode(),e=="insertunorderedlist"?
-"UL":"OL")}},"state");b({"FontSize,FontName":function(e){var c=0,i;if(i=n.getParent(r.getNode(),"span"))c=e=="fontsize"?i.style.fontSize:i.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase();return c}},"value");v.custom_undo_redo&&b({Undo:function(){k.undoManager.undo()},Redo:function(){k.undoManager.redo()}})}})(tinymce);
-(function(l){var o=l.util.Dispatcher;l.UndoManager=function(q){var k,j=0,b=[];return k={typing:0,onAdd:new o(k),onUndo:new o(k),onRedo:new o(k),add:function(g){var d;d=q.settings;var n;g=g||{};g.content=l.trim(q.getContent({format:"raw",no_events:1}));if((n=b[j])&&n.content==g.content)if(j>0||b.length==1)return null;if(d.custom_undo_redo_levels)if(b.length>d.custom_undo_redo_levels){for(d=0;d<b.length-1;d++)b[d]=b[d+1];b.length--;j=b.length}g.bookmark=q.selection.getBookmark(2,true);if(j<b.length-
-1)if(j==0)b=[];else b.length=j+1;b.push(g);j=b.length-1;k.onAdd.dispatch(k,g);q.isNotDirty=0;return g},undo:function(){var g;if(k.typing){k.add();k.typing=0}if(j>0){g=b[--j];q.setContent(g.content,{format:"raw"});q.selection.moveToBookmark(g.bookmark);k.onUndo.dispatch(k,g)}return g},redo:function(){var g;if(j<b.length-1){g=b[++j];q.setContent(g.content,{format:"raw"});q.selection.moveToBookmark(g.bookmark);k.onRedo.dispatch(k,g)}return g},clear:function(){b=[];j=k.typing=0},hasUndo:function(){return j>
-0||k.typing},hasRedo:function(){return j<b.length-1}}}})(tinymce);
-(function(l){function o(v,f){var e=f.ownerDocument.createRange();e.setStart(v.endContainer,v.endOffset);e.setEndAfter(f);return e.cloneContents().textContent.length==0}function q(v){v=v.innerHTML;v=v.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi,"-");v=v.replace(/<[^>]+>/g,"");return v.replace(/[ \u00a0\t\r\n]+/g,"")==""}function k(v,f,e){var c;if(q(e)){c=f.getParent(e,"ul,ol");if(!f.getParent(c.parentNode,"ul,ol")){f.split(c,e);c=f.create("p",0,'<br _mce_bogus="1" />');f.replace(c,e);v.select(c,
-1)}return u}return r}var j=l.dom.Event,b=l.isIE,g=l.isGecko,d=l.isOpera,n=l.each,r=true,u=false;l.create("tinymce.ForceBlocks",{ForceBlocks:function(v){function f(a,h){if(d)h.content=h.content.replace(e.reOpera,"</"+i+">");h.content=h.content.replace(e.rePadd,"<"+i+"$1$2$3$4$5$6>\u00a0</"+i+">");if(!b&&!d&&h.set){h.content=h.content.replace(e.reNbsp2BR1,"<"+i+"$1$2><br /></"+i+">");h.content=h.content.replace(e.reNbsp2BR2,"<"+i+"$1$2><br /></"+i+">")}else h.content=h.content.replace(e.reBR2Nbsp,"<"+
-i+"$1$2>\u00a0</"+i+">")}var e=this,c=v.settings,i;e.editor=v;e.dom=v.dom;i=(c.forced_root_block||"p").toLowerCase();c.element=i.toUpperCase();v.onPreInit.add(e.setup,e);e.reOpera=RegExp("(\\u00a0|&#160;|&nbsp;)</"+i+">","gi");e.rePadd=RegExp("<p( )([^>]+)><\\/p>|<p( )([^>]+)\\/>|<p( )([^>]+)>\\s+<\\/p>|<p><\\/p>|<p\\/>|<p>\\s+<\\/p>".replace(/p/g,i),"gi");e.reNbsp2BR1=RegExp("<p( )([^>]+)>[\\s\\u00a0]+<\\/p>|<p>[\\s\\u00a0]+<\\/p>".replace(/p/g,i),"gi");e.reNbsp2BR2=RegExp("<%p()([^>]+)>(&nbsp;|&#160;)<\\/%p>|<%p>(&nbsp;|&#160;)<\\/%p>".replace(/%p/g,
-i),"gi");e.reBR2Nbsp=RegExp("<p( )([^>]+)>\\s*<br \\/>\\s*<\\/p>|<p>\\s*<br \\/>\\s*<\\/p>".replace(/p/g,i),"gi");v.onBeforeSetContent.add(f);v.onPostProcess.add(f);if(c.forced_root_block){v.onInit.add(e.forceRoots,e);v.onSetContent.add(e.forceRoots,e);v.onBeforeGetContent.add(e.forceRoots,e)}},setup:function(){var v=this,f=v.editor,e=f.settings,c=f.dom,i=f.selection;if(e.forced_root_block){f.onBeforeExecCommand.add(v.forceRoots,v);f.onKeyUp.add(v.forceRoots,v);f.onPreProcess.add(v.forceRoots,v)}e.force_br_newlines&&
-b&&f.onKeyPress.add(function(a,h){var m;if(h.keyCode==13&&i.getNode().nodeName!="LI"){i.setContent('<br id="__" /> ',{format:"raw"});m=c.get("__");m.removeAttribute("id");i.select(m);i.collapse();return j.cancel(h)}});if(e.force_p_newlines){if(b){l.addUnload(function(){v._previousFormats=0});f.onKeyPress.add(function(a,h){v._previousFormats=0;if(h.keyCode==13&&!h.shiftKey&&a.selection.isCollapsed()&&e.keep_styles){var m;var p=a.selection.getStart(),t,s,x;do if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(p.nodeName)){if(t){s=
-p.cloneNode(false);s.appendChild(t);t=s}else t=x=p.cloneNode(false);t.removeAttribute("id")}while(p=p.parentNode);if(t)m={wrapper:t,inner:x};v._previousFormats=m}});f.onKeyUp.add(function(a,h){if(h.keyCode==13&&!h.shiftKey){var m=a.selection.getStart(),p=v._previousFormats;if(!m.hasChildNodes())if(m=c.getParent(m,c.isBlock)){m.innerHTML="";if(v._previousFormats){m.appendChild(p.wrapper);p.inner.innerHTML="\ufeff"}else m.innerHTML="\ufeff";i.select(m,1);a.getDoc().execCommand("Delete",false,null)}}})}else f.onKeyPress.add(function(a,
-h){h.keyCode==13&&!h.shiftKey&&!v.insertPara(h)&&j.cancel(h)});g&&f.onKeyDown.add(function(a,h){if((h.keyCode==8||h.keyCode==46)&&!h.shiftKey)v.backspaceDelete(h,h.keyCode==8)})}l.isWebKit&&f.onKeyPress.add(function(a,h){if(h.keyCode==13&&(h.shiftKey||e.force_br_newlines&&!c.getParent(i.getNode(),"h1,h2,h3,h4,h5,h6,ol,ul"))){var m=i.getRng(),p,t=c.create("div",null," "),s=c.getViewPort(a.getWin()).h;m.insertNode(p=c.create("br"));m.setStartAfter(p);m.setEndAfter(p);i.setRng(m);if(i.getSel().focusNode==
-p.previousSibling){i.select(c.insertAfter(c.doc.createTextNode("\u00a0"),p));i.collapse(r)}c.insertAfter(t,p);m=c.getPos(t).y;c.remove(t);m>s&&a.getWin().scrollTo(0,m);j.cancel(h)}});f.onPreProcess.add(function(a,h){n(c.select("p,h1,h2,h3,h4,h5,h6,div",h.node),function(m){q(m)&&n(c.select("span,em,strong,b,i",h.node),function(p){if(!p.hasChildNodes()){p.appendChild(a.getDoc().createTextNode("\u00a0"));return u}})})});if(b)if(e.element!="P"){f.onKeyPress.add(function(){v.lastElm=i.getNode().nodeName});
-f.onKeyUp.add(function(a,h){var m;m=i.getNode();if(a.getBody().childNodes.length===1&&m.nodeName=="P"){m=c.rename(m,e.element);i.select(m);i.collapse();a.nodeChanged()}else if(h.keyCode==13&&!h.shiftKey&&v.lastElm!="P")if(m=c.getParent(m,"p")){c.rename(m,e.element);a.nodeChanged()}})}},find:function(v,f,e){for(var c=this.editor.getDoc().createTreeWalker(v,4,null,u),i=-1;v=c.nextNode();){i++;if(f==0&&v==e)return i;if(f==1&&i==e)return v}return-1},forceRoots:function(v){v=this.editor;var f=v.getBody(),
-e=v.getDoc(),c=v.selection,i=c.getSel(),a=c.getRng(),h=-2,m,p,t,s,x,y=f.childNodes,C,A,M;for(C=y.length-1;C>=0;C--){x=y[C];if(x.nodeType===1&&x.getAttribute("_mce_type"))s=null;else if(x.nodeType===3||!this.dom.isBlock(x)&&x.nodeType!==8&&!/^(script|mce:script|style|mce:style)$/i.test(x.nodeName))if(s)s.hasChildNodes()?s.insertBefore(x,s.firstChild):s.appendChild(x);else{if(x.nodeType!=3||/[^\s]/g.test(x.nodeValue)){if(h==-2&&a)if(b){if(a.item){s=e.body.createTextRange();s.moveToElementText(a.item(0));
-a=s}s=e.body.createTextRange();s.moveToElementText(f);s.collapse(1);h=s.move("character",-16777215)*-1;s=a.duplicate();s.collapse(1);m=s.move("character",-16777215)*-1;s=a.duplicate();s.collapse(0);s=s.move("character",-16777215)*-1-m;h=m-h;m=s}else if(a.startContainer.nodeType==1&&(A=a.startContainer.childNodes[a.startOffset])&&A.nodeType==1){M=A.getAttribute("id");A.setAttribute("id","__mce")}else if(v.dom.getParent(a.startContainer,function(E){return E===f})){p=a.startOffset;t=a.endOffset;h=this.find(f,
-0,a.startContainer);m=this.find(f,0,a.endContainer)}s=v.dom.create(v.settings.forced_root_block);x.parentNode.replaceChild(s,x);s.appendChild(x)}}else s=null}if(h!=-2)if(b)try{a=i.createRange();a.moveToElementText(f);a.collapse(1);a.moveStart("character",h);a.moveEnd("character",m);a.select()}catch(X){}else{s=f.getElementsByTagName(v.settings.element)[0];a=e.createRange();h!=-1?a.setStart(this.find(f,1,h),p):a.setStart(s,0);m!=-1?a.setEnd(this.find(f,1,m),t):a.setEnd(s,0);if(i){i.removeAllRanges();
-i.addRange(a)}}else if(!b&&(A=v.dom.get("__mce"))){M?A.setAttribute("id",M):A.removeAttribute("id");a=e.createRange();a.setStartBefore(A);a.setEndBefore(A);c.setRng(a)}},getParentBlock:function(v){var f=this.dom;return f.getParent(v,f.isBlock)},insertPara:function(){function v(V,aa){var ea=[],Z,z;V.innerHTML="";if(i.keep_styles){z=aa;do if(/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(z.nodeName)){Z=z.cloneNode(u);e.setAttrib(Z,"id","");ea.push(Z)}while(z=z.parentNode)}if(ea.length>0){z=ea.length-1;
-for(Z=V;z>=0;z--)Z=Z.appendChild(ea[z]);ea[0].innerHTML=d?"&nbsp;":"<br />";return ea[0]}else V.innerHTML=d?"&nbsp;":"<br />"}var f=this.editor,e=f.dom,c=f.getDoc(),i=f.settings,a=f.selection.getSel(),h=a.getRangeAt(0),m=c.body,p,t,s,x,y,C,A,M,X,E,D,B,K=e.getViewPort(f.getWin()),H;p=c.createRange();p.setStart(a.anchorNode,a.anchorOffset);p.collapse(r);t=c.createRange();t.setStart(a.focusNode,a.focusOffset);t.collapse(r);x=(s=p.compareBoundaryPoints(p.START_TO_END,t)<0)?a.anchorNode:a.focusNode;y=
-s?a.anchorOffset:a.focusOffset;C=s?a.focusNode:a.anchorNode;s=s?a.focusOffset:a.anchorOffset;if(x===C&&/^(TD|TH)$/.test(x.nodeName)){x.firstChild.nodeName=="BR"&&e.remove(x.firstChild);if(x.childNodes.length==0)f.dom.add(x,i.element,null,"<br />");else{B=x.innerHTML;x.innerHTML="";f.dom.add(x,i.element,null,B)}M=f.dom.add(x,i.element,null,"<br />");h=c.createRange();h.selectNodeContents(M);h.collapse(1);f.selection.setRng(h);return u}if(x==m&&C==m&&m.firstChild&&f.dom.isBlock(m.firstChild)){x=C=x.firstChild;
-y=s=0;p=c.createRange();p.setStart(x,0);t=c.createRange();t.setStart(C,0)}x=x.nodeName=="HTML"?c.body:x;x=x.nodeName=="BODY"?x.firstChild:x;C=C.nodeName=="HTML"?c.body:C;C=C.nodeName=="BODY"?C.firstChild:C;A=this.getParentBlock(x);M=this.getParentBlock(C);X=A?A.nodeName:i.element;if(B=this.dom.getParent(A,"li,pre")){if(B.nodeName=="LI")return k(f.selection,this.dom,B);return r}if(A&&(A.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(e.getStyle(A,"position",1)))){X=i.element;A=null}if(M&&(M.nodeName==
-"CAPTION"||/absolute|relative|fixed/gi.test(e.getStyle(A,"position",1)))){X=i.element;M=null}if(/(TD|TABLE|TH|CAPTION)/.test(X)||A&&X=="DIV"&&/left|right/gi.test(e.getStyle(A,"float",1))){X=i.element;A=M=null}E=A&&A.nodeName==X?A.cloneNode(0):f.dom.create(X);M=M&&M.nodeName==X?M.cloneNode(0):f.dom.create(X);M.removeAttribute("id");if(/^(H[1-6])$/.test(X)&&o(h,A))M=f.dom.create(i.element);B=A=x;do{if(B==m||B.nodeType==9||this.dom.isBlock(B)||/(TD|TABLE|TH|CAPTION)/.test(B.nodeName))break;A=B}while(B=
-B.previousSibling?B.previousSibling:B.parentNode);B=D=C;do{if(B==m||B.nodeType==9||this.dom.isBlock(B)||/(TD|TABLE|TH|CAPTION)/.test(B.nodeName))break;D=B}while(B=B.nextSibling?B.nextSibling:B.parentNode);A.nodeName==X?p.setStart(A,0):p.setStartBefore(A);p.setEnd(x,y);E.appendChild(p.cloneContents()||c.createTextNode(""));try{t.setEndAfter(D)}catch(W){}t.setStart(C,s);M.appendChild(t.cloneContents()||c.createTextNode(""));h=c.createRange();if(!A.previousSibling&&A.parentNode.nodeName==X)h.setStartBefore(A.parentNode);
-else p.startContainer.nodeName==X&&p.startOffset==0?h.setStartBefore(p.startContainer):h.setStart(p.startContainer,p.startOffset);!D.nextSibling&&D.parentNode.nodeName==X?h.setEndAfter(D.parentNode):h.setEnd(t.endContainer,t.endOffset);h.deleteContents();d&&f.getWin().scrollTo(0,K.y);if(E.firstChild&&E.firstChild.nodeName==X)E.innerHTML=E.firstChild.innerHTML;if(M.firstChild&&M.firstChild.nodeName==X)M.innerHTML=M.firstChild.innerHTML;if(q(E))E.innerHTML="<br />";if(q(M))H=v(M,C);if(d&&parseFloat(opera.version())<
-9.5){h.insertNode(E);h.insertNode(M)}else{h.insertNode(M);h.insertNode(E)}M.normalize();E.normalize();h=c.createRange();h.selectNodeContents(g?c.createTreeWalker(H||M,NodeFilter.SHOW_TEXT,null,u).nextNode()||H||M:H||M);h.collapse(1);a.removeAllRanges();a.addRange(h);c=f.dom.getPos(M).y;a=M.clientHeight;if(c<K.y||c+a>K.y+K.h)f.getWin().scrollTo(0,c<K.y?c:c-K.h+25);return u},backspaceDelete:function(v,f){var e=this.editor,c=e.getBody(),i,a=e.selection,h=a.getRng(),m=h.startContainer,p;if(!f&&h.collapsed&&
-m.nodeType==1&&h.startOffset==m.childNodes.length){p=new l.dom.TreeWalker(m.lastChild,m);for(i=m.lastChild;i;i=p.prev())if(i.nodeType==3){h.setStart(i,i.nodeValue.length);h.collapse(true);a.setRng(h);return}}if(m&&e.dom.isBlock(m)&&!/^(TD|TH)$/.test(m.nodeName)&&f)if(m.childNodes.length==0||m.childNodes.length==1&&m.firstChild.nodeName=="BR"){for(i=m;(i=i.previousSibling)&&!e.dom.isBlock(i););if(i){if(m!=c.firstChild){for(c=e.dom.doc.createTreeWalker(i,NodeFilter.SHOW_TEXT,null,u);h=c.nextNode();)i=
-h;h=e.getDoc().createRange();h.setStart(i,i.nodeValue?i.nodeValue.length:0);h.setEnd(i,i.nodeValue?i.nodeValue.length:0);a.setRng(h);e.dom.remove(m)}return j.cancel(v)}}}})})(tinymce);
-(function(l){var o=l.dom.Event,q=l.each,k=l.extend;l.create("tinymce.ControlManager",{ControlManager:function(j,b){var g=this;b=b||{};g.editor=j;g.controls={};g.onAdd=new l.util.Dispatcher(g);g.onPostRender=new l.util.Dispatcher(g);g.prefix=b.prefix||j.id+"_";g._cls={};g.onPostRender.add(function(){q(g.controls,function(d){d.postRender()})})},get:function(j){return this.controls[this.prefix+j]||this.controls[j]},setActive:function(j,b){var g=null;if(g=this.get(j))g.setActive(b);return g},setDisabled:function(j,
-b){var g=null;if(g=this.get(j))g.setDisabled(b);return g},add:function(j){if(j){this.controls[j.id]=j;this.onAdd.dispatch(j,this)}return j},createControl:function(j){var b,g=this,d=g.editor;q(d.plugins,function(n){if(n.createControl)if(b=n.createControl(j,g))return false});switch(j){case "|":case "separator":return g.createSeparator()}if(!b&&d.buttons&&(b=d.buttons[j]))return g.createButton(j,b);return g.add(b)},createDropMenu:function(j,b,g){var d=this.editor,n,r,u;b=k({"class":"mceDropDown",constrain:d.settings.constrain_menus},
-b);b["class"]=b["class"]+" "+d.getParam("skin")+"Skin";if(u=d.getParam("skin_variant"))b["class"]+=" "+d.getParam("skin")+"Skin"+u.substring(0,1).toUpperCase()+u.substring(1);j=this.prefix+j;n=this.controls[j]=new (g||this._cls.dropmenu||l.ui.DropMenu)(j,b);n.onAddItem.add(function(v,f){var e=f.settings;e.title=d.getLang(e.title,e.title);if(!e.onclick)e.onclick=function(){if(e.cmd)d.execCommand(e.cmd,e.ui||false,e.value)}});d.onRemove.add(function(){n.destroy()});if(l.isIE){n.onShowMenu.add(function(){d.focus();
-r=d.selection.getBookmark(1)});n.onHideMenu.add(function(){if(r){d.selection.moveToBookmark(r);r=0}})}return this.add(n)},createListBox:function(j,b,g){var d=this.editor;if(this.get(j))return null;b.title=d.translate(b.title);b.scope=b.scope||d;if(!b.onselect)b.onselect=function(n){d.execCommand(b.cmd,b.ui||false,n||b.value)};b=k({title:b.title,"class":"mce_"+j,scope:b.scope,control_manager:this},b);j=this.prefix+j;if(d.settings.use_native_selects)g=new l.ui.NativeListBox(j,b);else{g=g||this._cls.listbox||
-l.ui.ListBox;g=new g(j,b)}this.controls[j]=g;l.isWebKit&&g.onPostRender.add(function(n,r){o.add(r,"mousedown",function(){d.bookmark=d.selection.getBookmark(1)});o.add(r,"focus",function(){d.selection.moveToBookmark(d.bookmark);d.bookmark=null})});g.hideMenu&&d.onMouseDown.add(g.hideMenu,g);return this.add(g)},createButton:function(j,b,g){var d=this.editor;if(this.get(j))return null;b.title=d.translate(b.title);b.label=d.translate(b.label);b.scope=b.scope||d;if(!b.onclick&&!b.menu_button)b.onclick=
-function(){d.execCommand(b.cmd,b.ui||false,b.value)};b=k({title:b.title,"class":"mce_"+j,unavailable_prefix:d.getLang("unavailable",""),scope:b.scope,control_manager:this},b);j=this.prefix+j;if(b.menu_button){g=g||this._cls.menubutton||l.ui.MenuButton;j=new g(j,b);d.onMouseDown.add(j.hideMenu,j)}else{g=this._cls.button||l.ui.Button;j=new g(j,b)}return this.add(j)},createMenuButton:function(j,b,g){b=b||{};b.menu_button=1;return this.createButton(j,b,g)},createSplitButton:function(j,b,g){var d=this.editor;
-if(this.get(j))return null;b.title=d.translate(b.title);b.scope=b.scope||d;if(!b.onclick)b.onclick=function(n){d.execCommand(b.cmd,b.ui||false,n||b.value)};if(!b.onselect)b.onselect=function(n){d.execCommand(b.cmd,b.ui||false,n||b.value)};b=k({title:b.title,"class":"mce_"+j,scope:b.scope,control_manager:this},b);j=this.prefix+j;j=this.add(new (g||this._cls.splitbutton||l.ui.SplitButton)(j,b));d.onMouseDown.add(j.hideMenu,j);return j},createColorSplitButton:function(j,b,g){var d=this.editor,n,r;if(this.get(j))return null;
-b.title=d.translate(b.title);b.scope=b.scope||d;if(!b.onclick)b.onclick=function(u){if(l.isIE)r=d.selection.getBookmark(1);d.execCommand(b.cmd,b.ui||false,u||b.value)};if(!b.onselect)b.onselect=function(u){d.execCommand(b.cmd,b.ui||false,u||b.value)};b=k({title:b.title,"class":"mce_"+j,menu_class:d.getParam("skin")+"Skin",scope:b.scope,more_colors_title:d.getLang("more_colors")},b);j=this.prefix+j;n=new (g||this._cls.colorsplitbutton||l.ui.ColorSplitButton)(j,b);d.onMouseDown.add(n.hideMenu,n);d.onRemove.add(function(){n.destroy()});
-if(l.isIE){n.onShowMenu.add(function(){d.focus();r=d.selection.getBookmark(1)});n.onHideMenu.add(function(){if(r){d.selection.moveToBookmark(r);r=0}})}return this.add(n)},createToolbar:function(j,b,g){j=this.prefix+j;b=new (g||this._cls.toolbar||l.ui.Toolbar)(j,b);if(this.get(j))return null;return this.add(b)},createSeparator:function(j){return new (j||this._cls.separator||l.ui.Separator)},setControlType:function(j,b){return this._cls[j.toLowerCase()]=b},destroy:function(){q(this.controls,function(j){j.destroy()});
-this.controls=null}})})(tinymce);
-(function(l){var o=l.util.Dispatcher,q=l.each,k=l.isIE,j=l.isOpera;l.create("tinymce.WindowManager",{WindowManager:function(b){this.editor=b;this.onOpen=new o(this);this.onClose=new o(this);this.params={};this.features={}},open:function(b,g){var d="",n=this.editor.settings.dialog_type=="modal",r,u,v;v=l.DOM.getViewPort();b=b||{};g=g||{};u=j?v.w:screen.width;v=j?v.h:screen.height;b.name=b.name||"mc_"+(new Date).getTime();b.width=parseInt(b.width||320);b.height=parseInt(b.height||240);b.resizable=true;
-b.left=b.left||parseInt(u/2)-b.width/2;b.top=b.top||parseInt(v/2)-b.height/2;g.inline=false;g.mce_width=b.width;g.mce_height=b.height;g.mce_auto_focus=b.auto_focus;if(n)if(k){b.center=true;b.help=false;b.dialogWidth=b.width+"px";b.dialogHeight=b.height+"px";b.scroll=b.scrollbars||false}q(b,function(e,c){if(l.is(e,"boolean"))e=e?"yes":"no";/^(name|url)$/.test(c)||(d+=k&&n?(d?";":"")+c+":"+e:(d?",":"")+c+"="+e)});this.features=b;this.params=g;this.onOpen.dispatch(this,b,g);u=b.url||b.file;u=l._addVer(u);
-try{if(k&&n){r=1;window.showModalDialog(u,window,d)}else r=window.open(u,b.name,d)}catch(f){}r||alert(this.editor.getLang("popup_blocked"))},close:function(b){b.close();this.onClose.dispatch(this)},createInstance:function(b,g,d,n,r,u){return new (l.resolve(b))(g,d,n,r,u)},confirm:function(b,g,d,n){g.call(d||this,(n||window).confirm(this._decode(this.editor.getLang(b,b))))},alert:function(b,g,d,n){(n||window).alert(this._decode(this.editor.getLang(b,b)));if(g)g.call(d||this)},resizeBy:function(b,g,
-d){d.resizeBy(b,g)},_decode:function(b){return l.DOM.decode(b).replace(/\\n/g,"\n")}})})(tinymce);
-(function(l){l.GlobalCommands=new function(){function o(b,g,d,n){if(typeof g=="string")g=[g];l.each(g,function(r){b[r.toLowerCase()]={func:d,scope:n}})}var q={},k={},j={};l.extend(this,{add:function(b,g,d){o(q,b,g,d)},addQueryStateHandler:function(b,g,d){o(k,b,g,d)},addQueryValueHandler:function(b,g,d){o(j,b,g,d)},execCommand:function(b,g,d,n,r){if(g=q[g.toLowerCase()])if(g.func.call(b||g.scope,d,n,r)!==false)return true},queryCommandValue:function(){if(cmd=j[cmd.toLowerCase()])return cmd.func.call(scope||
-cmd.scope,ui,value,args)},queryCommandState:function(){if(cmd=k[cmd.toLowerCase()])return cmd.func.call(scope||cmd.scope,ui,value,args)}})}})(tinymce);
-(function(l){l.Formatter=function(o){function q(z){return z.nodeType===1&&(z.face==="mceinline"||z.style.fontFamily==="mceinline")}function k(z){return z?y[z]:y}function j(z,F){if(z)if(typeof z!=="string")C(z,function(G,I){j(I,G)});else{F=F.length?F:[F];C(F,function(G){if(G.deep===ea)G.deep=!G.selector;if(G.split===ea)G.split=!G.selector||G.inline;if(G.remove===ea&&G.selector&&!G.inline)G.remove="none";if(G.selector&&G.inline){G.mixed=true;G.block_expand=true}if(typeof G.classes==="string")G.classes=
-G.classes.split(/\s+/)});y[z]=F}}function b(z,F,G){function I(O){var P=O.startContainer,J=O.startOffset;if(P.nodeType==1||P.nodeValue==="")if(P=P.nodeType==1?P.childNodes[J]:P){P=new X(P,P.parentNode);for(J=P.current();J;J=P.next())if(J.nodeType==3&&!e(J)){O.setStart(J,0);break}}return O}function T(O,P){P=P||N;if(O){C(P.styles,function(J,Q){A.setStyle(O,Q,f(J,F))});C(P.attributes,function(J,Q){A.setAttrib(O,Q,f(J,F))});C(P.classes,function(J){J=f(J,F);A.hasClass(O,J)||A.addClass(O,J)})}}function L(O){var P=
-[],J,Q;J=N.inline||N.block;Q=A.create(J);T(Q);E.walk(O,function(R){function ca(Y){var ba=Y.nodeName.toLowerCase(),da=Y.parentNode.nodeName.toLowerCase(),fa;if(u(ba,"br")){$=0;N.block&&A.remove(Y)}else if(N.wrapper&&d(Y,z,F))$=0;else if(N.block&&!N.wrapper&&/^(h[1-6]|p|div|pre|address|dl|dt|dd)$/.test(ba)){Y=A.rename(Y,J);T(Y);P.push(Y);$=0}else{if(N.selector){C(U,function(ga){if(A.is(Y,ga.selector)&&!q(Y)){T(Y,ga);fa=true}});if(!N.inline||fa){$=0;return}}if(D(J,ba)&&D(da,J)){if(!$){$=Q.cloneNode(V);
-Y.parentNode.insertBefore($,Y);P.push($)}$.appendChild(Y)}else{$=0;C(l.grep(Y.childNodes),ca);$=0}}}var $;C(R,ca)});C(P,function(R){function ca(Y){var ba,da;C(Y.childNodes,function(fa){if(fa.nodeType==1&&!p(fa)&&!q(fa)){ba=fa;return V}});if(ba&&r(ba,N)){da=ba.cloneNode(V);T(da);A.replace(da,Y,aa);A.remove(ba,1)}return da||Y}var $;$=function(Y){var ba=0;C(Y.childNodes,function(da){!e(da)&&!p(da)&&ba++});return ba}(R);if($===0)A.remove(R,1);else if(N.inline||N.wrapper){if(!N.exact&&$===1)R=ca(R);C(U,
-function(Y){C(A.select(Y.inline,R),function(ba){a(Y,F,ba,Y.exact?ba:null)})});if(d(R.parentNode,z,F)){A.remove(R,1);R=0;return aa}N.merge_with_parents&&A.getParent(R.parentNode,function(Y){if(d(Y,z,F)){A.remove(R,1);R=0;return aa}});if(R){R=t(m(R),R);R=t(R,m(R,aa))}}})}var U=k(z),N=U[0],S;if(N)if(G){S=A.createRng();S.setStartBefore(G);S.setEndAfter(G);L(i(S,U))}else if(!M.isCollapsed()||!N.inline){G=M.getBookmark();L(i(M.getRng(aa),U));M.moveToBookmark(G);M.setRng(I(M.getRng(aa)));o.nodeChanged()}else x("apply",
-z,F)}function g(z,F,G){function I(J){var Q,R,ca;Q=l.grep(J.childNodes);R=0;for(ca=S.length;R<ca;R++)if(a(S[R],F,J,J))break;if(O.deep){R=0;for(ca=Q.length;R<ca;R++)I(Q[R])}}function T(J){var Q;C(A.getParents(J.parentNode,void 0,A.getRoot()).reverse(),function(R){var ca;if(!Q&&R.id!="_start"&&R.id!="_end")if((ca=d(R,z,F))&&ca.split!==false)Q=R});return Q}function L(J,Q,R,ca){var $,Y,ba,da,fa,ga;if(J){ga=J.parentNode;for($=Q.parentNode;$&&$!=ga;$=$.parentNode){Y=$.cloneNode(V);for(fa=0;fa<S.length;fa++)if(a(S[fa],
-F,Y,Y)){Y=0;break}if(Y){ba&&Y.appendChild(ba);da||(da=Y);ba=Y}}if(ca&&(!O.mixed||!B(J)))Q=A.split(J,Q);if(ba){R.parentNode.insertBefore(ba,R);da.appendChild(R)}}return Q}function U(J){var Q=A.get(J?"_start":"_end"),R=Q[J?"firstChild":"lastChild"];if(p(R))R=R[J?"firstChild":"lastChild"];A.remove(Q,true);return R}function N(J){var Q,R;J=i(J,S,aa);if(O.split){Q=s(J,aa);R=s(J);if(Q!=R){Q=c(Q,"span",{id:"_start",_mce_type:"bookmark"});R=c(R,"span",{id:"_end",_mce_type:"bookmark"});L(T(Q),Q,Q,true);L(T(R),
-R,R,true);Q=U(aa);R=U()}else Q=R=L(T(Q),Q,Q,true);J.startContainer=Q.parentNode;J.startOffset=H(Q);J.endContainer=R.parentNode;J.endOffset=H(R)+1}E.walk(J,function(ca){C(ca,function($){I($)})})}var S=k(z),O=S[0],P;if(G){P=A.createRng();P.setStartBefore(G);P.setEndAfter(G);N(P)}else if(!M.isCollapsed()||!O.inline){G=M.getBookmark();N(M.getRng(aa));M.moveToBookmark(G);o.nodeChanged()}else x("remove",z,F)}function d(z,F,G,I){function T(N,S,O){var P,J,Q=S[O];if(Q)if(Q.length===ea)for(P in Q){if(Q.hasOwnProperty(P)){J=
-O==="attributes"?A.getAttrib(N,P):v(N,P);if(I&&!J&&!S.exact)return;if((!I||S.exact)&&!u(J,f(Q[P],G)))return}}else for(P=0;P<Q.length;P++)if(O==="attributes"?A.getAttrib(N,Q[P]):v(N,Q[P]))break;return S}var L=k(F),U;if(L&&z)for(U=0;U<L.length;U++){F=L[U];if(r(z,F)&&T(z,F,"attributes")&&T(z,F,"styles")){if(L=F.classes)for(U=0;U<L.length;U++)if(!A.hasClass(z,L[U]))return;return F}}}function n(z,F,G){function I(L){L=A.getParent(L,function(U){return!!d(U,z,F,true)});return d(L,z,F)}var T;if(G)return I(G);
-if(M.isCollapsed()){for(G=Z.apply.length-1;G>=0;G--)if(Z.apply[G].name==z)return true;for(G=Z.remove.length-1;G>=0;G--)if(Z.remove[G].name==z)return false;return I(M.getNode())}G=M.getNode();if(I(G))return aa;T=M.getStart();if(T!=G)if(I(T))return aa;return V}function r(z,F){if(u(z,F.inline))return aa;if(u(z,F.block))return aa;if(F.selector)return A.is(z,F.selector)}function u(z,F){z=z||"";F=F||"";z=""+(z.nodeName||z);F=""+(F.nodeName||F);return z.toLowerCase()==F.toLowerCase()}function v(z,F){var G=
-A.getStyle(z,F);if(F=="color"||F=="backgroundColor")G=A.toHex(G);if(F=="fontWeight"&&G==700)G="bold";return""+G}function f(z,F){if(typeof z!="string")z=z(F);else if(F)z=z.replace(/%(\w+)/g,function(G,I){return F[I]||G});return z}function e(z){return z&&z.nodeType===3&&/^([\s\r\n]+|)$/.test(z.nodeValue)}function c(z,F,G){F=A.create(F,G);z.parentNode.insertBefore(F,z);F.appendChild(z);return F}function i(z,F){function G(O,P,J,Q){var R;for(Q=Q||A.getRoot();;){R=O.parentNode;if(R==Q||!F[0].block_expand&&
-B(R))break;for(N=R[P];N&&N!=O;N=N[J]){if(N.nodeType==1&&!p(N))return O;if(N.nodeType==3&&!e(N))return O}O=O.parentNode}return O}var I=z.startContainer,T=z.startOffset,L=z.endContainer,U=z.endOffset,N,S;if(I.nodeType==1&&I.hasChildNodes()){S=I.childNodes.length-1;I=I.childNodes[T>S?S:T];if(I.nodeType==3)T=0}if(L.nodeType==1&&L.hasChildNodes()){S=L.childNodes.length-1;L=L.childNodes[U>S?S:U-1];if(L.nodeType==3)U=L.nodeValue.length}if(p(I.parentNode))I=I.parentNode;if(p(I))I=I.nextSibling||I;if(p(L.parentNode))L=
-L.parentNode;if(p(L))L=L.previousSibling||L;if(F[0].inline||F[0].block_expand){I=G(I,"firstChild","nextSibling");L=G(L,"lastChild","previousSibling")}if(F[0].selector&&F[0].expand!==V&&!F[0].inline){S=function(O,P){var J,Q,R;if(O.nodeType==3&&O.nodeValue.length==0&&O[P])O=O[P];J=A.getParents(O,void 0,A.getRoot());for(Q=0;Q<J.length;Q++)for(R=0;R<F.length;R++)if(A.is(J[Q],F[R].selector))return J[Q];return O};I=S(I,"previousSibling");L=S(L,"nextSibling")}if(F[0].block||F[0].selector){S=function(O,P){var J;
-F[0].wrapper||(J=A.getParent(O,F[0].block));J||(J=A.getParent(O.nodeType==3?O.parentNode:O,B));if(J&&F[0].wrapper)J=A.getParents(J,"ul,ol",A.getRoot()).reverse()[0]||J;if(!J)for(J=O;J[P]&&!B(J[P]);){J=J[P];if(u(J,"br"))break}return J||O};I=S(I,"previousSibling");L=S(L,"nextSibling");if(F[0].block){B(I)||(I=G(I,"firstChild","nextSibling"));B(L)||(L=G(L,"lastChild","previousSibling"))}}if(I.nodeType==1){T=H(I);I=I.parentNode}if(L.nodeType==1){U=H(L)+1;L=L.parentNode}return{startContainer:I,startOffset:T,
-endContainer:L,endOffset:U}}function a(z,F,G,I){var T,L,U;if(!r(G,z))return V;if(z.remove!="all"){C(z.styles,function(N,S){N=f(N,F);if(typeof S==="number"){S=N;I=0}if(!I||u(v(I,S),N))A.setStyle(G,S,"");U=1});if(U&&A.getAttrib(G,"style")==""){G.removeAttribute("style");G.removeAttribute("_mce_style")}C(z.attributes,function(N,S){var O;N=f(N,F);if(typeof S==="number"){S=N;I=0}if(!I||u(A.getAttrib(I,S),N)){if(S=="class")if(N=A.getAttrib(G,S)){O="";C(N.split(/\s+/),function(P){if(/mce\w+/.test(P))O+=
-(O?" ":"")+P});if(O){A.setAttrib(G,S,O);return}}S=="class"&&G.removeAttribute("className");W.test(S)&&G.removeAttribute("_mce_"+S);G.removeAttribute(S)}});C(z.classes,function(N){N=f(N,F);if(!I||A.hasClass(I,N))A.removeClass(G,N)});L=A.getAttribs(G);for(T=0;T<L.length;T++)if(L[T].nodeName.indexOf("_")!==0)return V}if(z.remove!="none"){h(G,z);return aa}}function h(z,F){var G=z.parentNode,I;if(F.block)if(K){if(G==A.getRoot())if(!F.list_block||!u(z,F.list_block))C(l.grep(z.childNodes),function(L){if(D(K,
-L.nodeName.toLowerCase()))if(I)I.appendChild(L);else I=c(L,K);else I=0})}else{var T=function(L,U,N){L=m(L,U,N);return!L||L.nodeName=="BR"||B(L)};if(B(z)&&!B(G)){!T(z,V)&&!T(z.firstChild,aa,1)&&z.insertBefore(A.create("br"),z.firstChild);!T(z,aa)&&!T(z.lastChild,V,1)&&z.appendChild(A.create("br"))}}F.selector&&F.inline&&!u(F.inline,z)||A.remove(z,1)}function m(z,F,G){if(z){F=F?"nextSibling":"previousSibling";for(z=G?z:z[F];z;z=z[F])if(z.nodeType==1||!e(z))return z}}function p(z){return z&&z.nodeType==
-1&&z.getAttribute("_mce_type")=="bookmark"}function t(z,F){function G(L,U){function N(O){var P={};C(A.getAttribs(O),function(J){J=J.nodeName.toLowerCase();if(J.indexOf("_")!==0&&J!=="style")P[J]=A.getAttrib(O,J)});return P}function S(O,P){var J,Q;for(Q in O)if(O.hasOwnProperty(Q)){J=P[Q];if(J===ea)return V;if(O[Q]!=J)return V;delete P[Q]}for(Q in P)if(P.hasOwnProperty(Q))return V;return aa}if(L.nodeName!=U.nodeName)return V;if(!S(N(L),N(U)))return V;if(!S(A.parseStyle(A.getAttrib(L,"style")),A.parseStyle(A.getAttrib(U,
-"style"))))return V;return aa}var I,T;if(z&&F){T=function(L,U){for(I=L;I;I=I[U]){if(I.nodeType==3&&!e(I))break;if(I.nodeType==1&&!p(I))return I}return L};z=T(z,"previousSibling");F=T(F,"nextSibling");if(G(z,F)){for(I=z.nextSibling;I&&I!=F;){T=I;I=I.nextSibling;z.appendChild(T)}A.remove(F);C(l.grep(F.childNodes),function(L){z.appendChild(L)});return z}}return F}function s(z,F){var G,I,T;G=z[F?"startContainer":"endContainer"];I=z[F?"startOffset":"endOffset"];if(G.nodeType==1){T=G.childNodes.length-
-1;!F&&I&&I--;G=G.childNodes[I>T?T:I]}return G}function x(z,F,G){function I(){return Z.apply.length||Z.remove.length}function T(N){C(Z.apply.reverse(),function(S){b(S.name,S.vars,N)});C(Z.remove.reverse(),function(S){g(S.name,S.vars,N)});A.remove(N,1);Z.apply=[];Z.remove=[]}var L=Z[z],U=Z[z=="apply"?"remove":"apply"];for(z=L.length-1;z>=0;z--)if(L[z].name==F)return;L.push({name:F,vars:G});for(z=U.length-1;z>=0;z--)U[z].name==F&&U.splice(z,1);if(I()){o.getDoc().execCommand("FontName",false,"mceinline");
-Z.lastRng=M.getRng();C(A.select("font,span"),function(N){var S;if(q(N)){S=M.getBookmark();T(N);M.moveToBookmark(S);o.nodeChanged()}});if(!Z.isListening&&I()){Z.isListening=true;C("onKeyDown,onKeyUp,onKeyPress,onMouseUp".split(","),function(N){o[N].addToTop(function(S,O){if(I()&&!l.dom.RangeUtils.compareRanges(Z.lastRng,M.getRng())){C(A.select("font,span"),function(P){var J;if(q(P))if(J=P.firstChild){T(P);P=A.createRng();P.setStart(J,J.nodeValue.length);P.setEnd(J,J.nodeValue.length);M.setRng(P);S.nodeChanged()}else A.remove(P)});
-if(O.type=="keyup"||O.type=="mouseup"){Z.apply=[];Z.remove=[]}}})})}}}var y={},C=l.each,A=o.dom,M=o.selection,X=l.dom.TreeWalker,E=new l.dom.RangeUtils(A),D=o.schema.isValid,B=A.isBlock,K=o.settings.forced_root_block,H=A.nodeIndex,W=/^(src|href|style)$/,V=false,aa=true,ea,Z={apply:[],remove:[]};l.extend(this,{get:k,register:j,apply:b,remove:g,toggle:function(z,F,G){n(z,F,G)?g(z,F,G):b(z,F,G)},match:n,matchAll:function(z,F){var G,I=[],T={},L,U;if(M.isCollapsed()){for(L=0;L<z.length;L++)for(G=Z.remove.length-
-1;G>=0;G--){U=z[L];if(Z.remove[G].name==U){T[U]=true;break}}for(G=Z.apply.length-1;G>=0;G--)for(L=0;L<z.length;L++){U=z[L];if(!T[U]&&Z.apply[G].name==U){T[U]=true;I.push(U)}}}G=M.getStart();A.getParent(G,function(N){var S,O;for(S=0;S<z.length;S++){O=z[S];if(!T[O]&&d(N,O,F)){T[O]=true;I.push(O)}}});return I},matchNode:d,canApply:function(z){z=k(z);var F,G,I,T;if(z){F=M.getStart();F=A.getParents(F,void 0,A.getRoot());for(I=z.length-1;I>=0;I--){T=z[I].selector;if(!T)return aa;for(G=F.length-1;G>=0;G--)if(A.is(F[G],
-T))return aa}}return V}})}})(tinymce);
-tinymce.onAddEditor.add(function(l,o){var q,k,j,b=o.settings;if(b.inline_styles){k=l.explode(b.font_size_style_values);var g=function(n,r){j.replace(j.create("span",{style:r}),n,1)};q={font:function(n,r){g(r,{backgroundColor:r.style.backgroundColor,color:r.color,fontFamily:r.face,fontSize:k[parseInt(r.size)-1]})},u:function(n,r){g(r,{textDecoration:"underline"})},strike:function(n,r){g(r,{textDecoration:"line-through"})}};var d=function(n,r){j=n.dom;b.convert_fonts_to_spans&&l.each(j.select("font,u,strike",
-r.node),function(u){q[u.nodeName.toLowerCase()](o.dom,u)})};o.onPreProcess.add(d);o.onInit.add(function(){o.selection.onSetContent.add(d)})}});
+(function(c){var i=/^\s*|\s*$/g,j="B".replace(/A(.)|B/,"$1")==="$1",g={majorVersion:"3",minorVersion:"4.2",releaseDate:"2011-04-07",_init:function(){function b(e){if(e.src&&/tiny_mce(|_gzip|_jquery|_prototype|_full)(_dev|_src)?.js/.test(e.src)){if(/_(src|dev)\.js/g.test(e.src))a.suffix="_src";if((m=e.src.indexOf("?"))!=-1)a.query=e.src.substring(m+1);a.baseURL=e.src.substring(0,e.src.lastIndexOf("/"));if(k&&a.baseURL.indexOf("://")==-1&&a.baseURL.indexOf("/")!==0)a.baseURL=k+a.baseURL;return a.baseURL}return null}
+var a=this,f=document,d=navigator,n=d.userAgent,k,m,o;a.isOpera=c.opera&&opera.buildNumber;a.isWebKit=/WebKit/.test(n);a.isIE=!a.isWebKit&&!a.isOpera&&/MSIE/gi.test(n)&&/Explorer/gi.test(d.appName);a.isIE6=a.isIE&&/MSIE [56]/.test(n);a.isGecko=!a.isWebKit&&/Gecko/.test(n);a.isMac=n.indexOf("Mac")!=-1;a.isAir=/adobeair/i.test(n);a.isIDevice=/(iPad|iPhone)/.test(n);if(c.tinyMCEPreInit)a.suffix=tinyMCEPreInit.suffix,a.baseURL=tinyMCEPreInit.base,a.query=tinyMCEPreInit.query;else{a.suffix="";n=f.getElementsByTagName("base");
+for(d=0;d<n.length;d++)if(o=n[d].href)/^https?:\/\/[^\/]+$/.test(o)&&(o+="/"),k=o?o.match(/.*\//)[0]:"";n=f.getElementsByTagName("script");for(d=0;d<n.length;d++)if(b(n[d]))return;if(f=f.getElementsByTagName("head")[0]){n=f.getElementsByTagName("script");for(d=0;d<n.length;d++)if(b(n[d]))break}}},is:function(b,a){if(!a)return b!==void 0;if(a=="array"&&b.hasOwnProperty&&b instanceof Array)return!0;return typeof b==a},makeMap:function(b,a,f){b=b||[];typeof b=="string"&&(b=b.split(a||","));f=f||{};for(a=
+b.length;a--;)f[b[a]]={};return f},each:function(b,a,f){var d,n;if(!b)return 0;f=f||b;if(b.length!==void 0){d=0;for(n=b.length;d<n;d++)if(a.call(f,b[d],d,b)===!1)return 0}else for(d in b)if(b.hasOwnProperty(d)&&a.call(f,b[d],d,b)===!1)return 0;return 1},map:function(b,a){var f=[];g.each(b,function(b){f.push(a(b))});return f},grep:function(b,a){var f=[];g.each(b,function(b){(!a||a(b))&&f.push(b)});return f},inArray:function(b,a){var f,d;if(b){f=0;for(d=b.length;f<d;f++)if(b[f]===a)return f}return-1},
+extend:function(b,a){var f,d,n=arguments;f=1;for(d=n.length;f<d;f++)a=n[f],g.each(a,function(a,d){a!==void 0&&(b[d]=a)});return b},trim:function(b){return(b?""+b:"").replace(i,"")},create:function(b,a,f){var d,n,k,m,o,e=0,b=/^((static) )?([\w.]+)(:([\w.]+))?/.exec(b);k=b[3].match(/(^|\.)(\w+)$/i)[2];n=this.createNS(b[3].replace(/\.\w+$/,""),f);if(!n[k])if(b[2]=="static"){if(n[k]=a,this.onCreate)this.onCreate(b[2],b[3],n[k])}else{a[k]||(a[k]=function(){},e=1);n[k]=a[k];this.extend(n[k].prototype,a);
+if(b[5])d=this.resolve(b[5]).prototype,m=b[5].match(/\.(\w+)$/i)[1],o=n[k],n[k]=e?function(){return d[m].apply(this,arguments)}:function(){this.parent=d[m];return o.apply(this,arguments)},n[k].prototype[k]=n[k],this.each(d,function(a,e){n[k].prototype[e]=d[e]}),this.each(a,function(a,e){d[e]?n[k].prototype[e]=function(){this.parent=d[e];return a.apply(this,arguments)}:e!=k&&(n[k].prototype[e]=a)});this.each(a["static"],function(a,e){n[k][e]=a});if(this.onCreate)this.onCreate(b[2],b[3],n[k].prototype)}},
+walk:function(b,a,f,d){d=d||this;b&&(f&&(b=b[f]),g.each(b,function(b,k){if(a.call(d,b,k,f)===!1)return!1;g.walk(b,a,f,d)}))},createNS:function(b,a){var f,d,a=a||c,b=b.split(".");for(f=0;f<b.length;f++)d=b[f],a[d]||(a[d]={}),a=a[d];return a},resolve:function(b,a){var f,d,a=a||c,b=b.split(".");f=0;for(d=b.length;f<d;f++)if(a=a[b[f]],!a)break;return a},addUnload:function(b,a){var f=this,b={func:b,scope:a||this};if(f.unloads)f.unloads.push(b);else{var d=function(){var a=f.unloads,b,o;if(a){for(o in a)(b=
+a[o])&&b.func&&b.func.call(b.scope,1);c.detachEvent?(c.detachEvent("onbeforeunload",n),c.detachEvent("onunload",d)):c.removeEventListener&&c.removeEventListener("unload",d,!1);f.unloads=w=d=0;c.CollectGarbage&&CollectGarbage()}},n=function(){var a=document;if(a.readyState=="interactive"){var b=function(){a.detachEvent("onstop",b);d&&d();a=0};a&&a.attachEvent("onstop",b);c.setTimeout(function(){a&&a.detachEvent("onstop",b)},0)}};c.attachEvent?(c.attachEvent("onunload",d),c.attachEvent("onbeforeunload",
+n)):c.addEventListener&&c.addEventListener("unload",d,!1);f.unloads=[b]}return b},removeUnload:function(b){var a=this.unloads,f=null;g.each(a,function(d,n){if(d&&d.func==b)return a.splice(n,1),f=b,!1});return f},explode:function(b,a){return b?g.map(b.split(a||","),g.trim):b},_addVer:function(b){var a;if(!this.query)return b;a=(b.indexOf("?")==-1?"?":"&")+this.query;if(b.indexOf("#")==-1)return b+a;return b.replace("#",a+"#")},_replace:function(b,a,f){if(j)return f.replace(b,function(){var b=a,f=arguments,
+k;for(k=0;k<f.length-2;k++)b=f[k]===void 0?b.replace(RegExp("\\$"+k,"g"),""):b.replace(RegExp("\\$"+k,"g"),f[k]);return b});return f.replace(b,a)}};g._init();c.tinymce=c.tinyMCE=g})(window);
+tinymce.create("tinymce.util.Dispatcher",{scope:null,listeners:null,Dispatcher:function(c){this.scope=c||this;this.listeners=[]},add:function(c,i){this.listeners.push({cb:c,scope:i||this.scope});return c},addToTop:function(c,i){this.listeners.unshift({cb:c,scope:i||this.scope});return c},remove:function(c){var i=this.listeners,j=null;tinymce.each(i,function(g,b){if(c==g.cb)return j=c,i.splice(b,1),!1});return j},dispatch:function(){var c,i=arguments,j,g=this.listeners;for(j=0;j<g.length;j++)if(c=
+g[j],c=c.cb.apply(c.scope,i),c===!1)break;return c}});
+(function(){var c=tinymce.each;tinymce.create("tinymce.util.URI",{URI:function(i,j){var g=this,b,i=tinymce.trim(i),j=g.settings=j||{};if(/^(mailto|tel|news|javascript|about|data):/i.test(i)||/^\s*#/.test(i))g.source=i;else if(i.indexOf("/")===0&&i.indexOf("//")!==0&&(i=(j.base_uri?j.base_uri.protocol||"http":"http")+"://mce_host"+i),/^\w*:?\/\//.test(i)||(i=(j.base_uri.protocol||"http")+"://mce_host"+g.toAbsPath(j.base_uri.path,i)),i=i.replace(/@@/g,"(mce_at)"),i=/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/.exec(i),
+c(["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],function(a,b){var d=i[b];d&&(d=d.replace(/\(mce_at\)/g,"@@"));g[a]=d}),b=j.base_uri){if(!g.protocol)g.protocol=b.protocol;if(!g.userInfo)g.userInfo=b.userInfo;if(!g.port&&g.host=="mce_host")g.port=b.port;if(!g.host||g.host=="mce_host")g.host=b.host;g.source=""}},setPath:function(c){c=/^(.*?)\/?(\w+)?$/.exec(c);this.path=c[0];this.directory=c[1];this.file=c[2];this.source=
+"";this.getURI()},toRelative:function(c){var j;if(c==="./")return c;c=new tinymce.util.URI(c,{base_uri:this});if(c.host!="mce_host"&&this.host!=c.host&&c.host||this.port!=c.port||this.protocol!=c.protocol)return c.getURI();j=this.toRelPath(this.path,c.path);c.query&&(j+="?"+c.query);c.anchor&&(j+="#"+c.anchor);return j},toAbsolute:function(c,j){c=new tinymce.util.URI(c,{base_uri:this});return c.getURI(this.host==c.host&&this.protocol==c.protocol?j:0)},toRelPath:function(c,j){var g,b=0,a="",f,d,c=
+c.substring(0,c.lastIndexOf("/")),c=c.split("/");g=j.split("/");if(c.length>=g.length){f=0;for(d=c.length;f<d;f++)if(f>=g.length||c[f]!=g[f]){b=f+1;break}}if(c.length<g.length){f=0;for(d=g.length;f<d;f++)if(f>=c.length||c[f]!=g[f]){b=f+1;break}}if(b==1)return j;f=0;for(d=c.length-(b-1);f<d;f++)a+="../";f=b-1;for(d=g.length;f<d;f++)a+=f!=b-1?"/"+g[f]:g[f];return a},toAbsPath:function(i,j){var g,b=0,a=[],f;f=/\/$/.test(j)?"/":"";i=i.split("/");j=j.split("/");c(i,function(b){b&&a.push(b)});i=a;g=j.length-
+1;for(a=[];g>=0;g--)j[g].length==0||j[g]=="."||(j[g]==".."?b++:b>0?b--:a.push(j[g]));g=i.length-b;g=g<=0?a.reverse().join("/"):i.slice(0,g).join("/")+"/"+a.reverse().join("/");g.indexOf("/")!==0&&(g="/"+g);f&&g.lastIndexOf("/")!==g.length-1&&(g+=f);return g},getURI:function(c){var j;if(!this.source||c)j="",c||(this.protocol&&(j+=this.protocol+"://"),this.userInfo&&(j+=this.userInfo+"@"),this.host&&(j+=this.host),this.port&&(j+=":"+this.port)),this.path&&(j+=this.path),this.query&&(j+="?"+this.query),
+this.anchor&&(j+="#"+this.anchor),this.source=j;return this.source}})})();
+(function(){var c=tinymce.each;tinymce.create("static tinymce.util.Cookie",{getHash:function(i){var i=this.get(i),j;i&&c(i.split("&"),function(c){c=c.split("=");j=j||{};j[unescape(c[0])]=unescape(c[1])});return j},setHash:function(i,j,g,b,a,f){var d="";c(j,function(a,b){d+=(!d?"":"&")+escape(b)+"="+escape(a)});this.set(i,d,g,b,a,f)},get:function(c){var j=document.cookie,g=c+"=",b;if(j){b=j.indexOf("; "+g);if(b==-1){if(b=j.indexOf(g),b!=0)return null}else b+=2;c=j.indexOf(";",b);if(c==-1)c=j.length;
+return unescape(j.substring(b+g.length,c))}},set:function(c,j,g,b,a,f){document.cookie=c+"="+escape(j)+(g?"; expires="+g.toGMTString():"")+(b?"; path="+escape(b):"")+(a?"; domain="+a:"")+(f?"; secure":"")},remove:function(c,j){var g=new Date;g.setTime(g.getTime()-1E3);this.set(c,"",g,j,g)}})})();
+(function(){function c(i,j){var g,b,a,j=j||'"';if(i==null)return"null";a=typeof i;if(a=="string")return b="\u0008b\tt\nn\u000cf\rr\"\"''\\\\",j+i.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g,function(a,d){if(j==='"'&&a==="'")return a;g=b.indexOf(d);if(g+1)return"\\"+b.charAt(g+1);a=d.charCodeAt().toString(16);return"\\u"+"0000".substring(a.length)+a})+j;if(a=="object"){if(i.hasOwnProperty&&i instanceof Array){g=0;for(b="[";g<i.length;g++)b+=(g>0?",":"")+c(i[g],j);return b+"]"}b="{";for(g in i)b+=typeof i[g]!=
+"function"?(b.length>1?","+j:j)+g+j+":"+c(i[g],j):"";return b+"}"}return""+i}tinymce.util.JSON={serialize:c,parse:function(c){try{return eval("("+c+")")}catch(j){}}}})();
+tinymce.create("static tinymce.util.XHR",{send:function(c){function i(a){j=0;try{j=new ActiveXObject(a)}catch(b){}return j}var j,g=window,b=0;c.scope=c.scope||this;c.success_scope=c.success_scope||c.scope;c.error_scope=c.error_scope||c.scope;c.async=c.async===!1?!1:!0;c.data=c.data||"";if(j=g.XMLHttpRequest?new XMLHttpRequest:i("Microsoft.XMLHTTP")||i("Msxml2.XMLHTTP")){j.overrideMimeType&&j.overrideMimeType(c.content_type);j.open(c.type||(c.data?"POST":"GET"),c.url,c.async);c.content_type&&j.setRequestHeader("Content-Type",
+c.content_type);j.setRequestHeader("X-Requested-With","XMLHttpRequest");j.send(c.data);var a=function(){!c.async||j.readyState==4||b++>1E4?(c.success&&b<1E4&&j.status==200?c.success.call(c.success_scope,""+j.responseText,j,c):c.error&&c.error.call(c.error_scope,b>1E4?"TIMED_OUT":"GENERAL",j,c),j=null):g.setTimeout(a,10)};if(!c.async)return a();g.setTimeout(a,10)}}});
+(function(){var c=tinymce.extend,i=tinymce.util.JSON,j=tinymce.util.XHR;tinymce.create("tinymce.util.JSONRequest",{JSONRequest:function(g){this.settings=c({},g);this.count=0},send:function(g){var b=g.error,a=g.success,g=c(this.settings,g);g.success=function(f,d){f=i.parse(f);typeof f=="undefined"&&(f={error:"JSON Parse error."});f.error?b.call(g.error_scope||g.scope,f.error,d):a.call(g.success_scope||g.scope,f.result)};g.error=function(a,d){b&&b.call(g.error_scope||g.scope,a,d)};g.data=i.serialize({id:g.id||
+"c"+this.count++,method:g.method,params:g.params});g.content_type="application/json";j.send(g)},"static":{sendRPC:function(c){return(new tinymce.util.JSONRequest).send(c)}}})})();
+(function(c){function i(a,b){var e,h,k,d={};if(a){a=a.split(",");b=b||10;for(e=0;e<a.length;e+=2)h=String.fromCharCode(parseInt(a[e],b)),g[h]||(k="&"+a[e+1]+";",d[h]=k,d[k]=h);return d}}var j,g,b,a=/[&\"\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,f=/[<>&\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,d=/[<>&\"\']/g,n=/&(#)?([\w]+);/g,k={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={'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;","&":"&amp;"};b={"&lt;":"<","&gt;":">","&amp;":"&","&quot;":'"',"&apos;":"'"};j=i("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);c.html=c.html||{};c.html.Entities={encodeRaw:function(b,k){return b.replace(k?a:f,function(a){return g[a]||a})},encodeAllRaw:function(a){return(""+a).replace(d,function(a){return g[a]||a})},encodeNumeric:function(b,k){return b.replace(k?a:f,function(a){if(a.length>1)return"&#"+((a.charCodeAt(0)-55296)*1024+(a.charCodeAt(1)-56320)+65536)+";";return g[a]||"&#"+a.charCodeAt(0)+";"})},encodeNamed:function(b,k,e){e=e||j;return b.replace(k?a:f,function(a){return g[a]||e[a]||a})},getEncodeFunc:function(b,
+k){function e(e,l){return e.replace(l?a:f,function(a){return g[a]||k[a]||"&#"+a.charCodeAt(0)+";"||a})}function h(a,e){return d.encodeNamed(a,e,k)}var d=c.html.Entities,k=i(k)||j,b=c.makeMap(b.replace(/\+/g,","));if(b.named&&b.numeric)return e;if(b.named){if(k)return h;return d.encodeNamed}if(b.numeric)return d.encodeNumeric;return d.encodeRaw},decode:function(a){return a.replace(n,function(a,e,h){if(e)return h=parseInt(h),h>65535?(h-=65536,String.fromCharCode(55296+(h>>10),56320+(h&1023))):k[h]||
+String.fromCharCode(h);if(!(e=b[a]))if(!(e=j[a]))e=document.createElement("div"),e.innerHTML=a,e=e.textContent||e.innerText||a;return e})}}})(tinymce);
+tinymce.html.Styles=function(c,i){function j(a,b,e,h){function k(a){a=parseInt(a).toString(16);return a.length>1?a:"0"+a}return"#"+k(b)+k(e)+k(h)}var g=/rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,b=/(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,a=/\s*([^:]+):\s*([^;]+);?/g,f=/\s+$/,d,n={},k,c=c||{};k="\\\" \\' \\; \\: ; : _".split(" ");for(d=0;d<k.length;d++)n[k[d]]="_"+d,n["_"+d]=k[d];return{toHex:function(a){return a.replace(g,
+j)},parse:function(k){function d(a,e){var h,b;if(h=l[a+"-top"+e])b=l[a+"-right"+e],h==b&&(h=l[a+"-bottom"+e],b==h&&(b=l[a+"-left"+e],h==b&&(l[a+e]=b,delete l[a+"-top"+e],delete l[a+"-right"+e],delete l[a+"-bottom"+e],delete l[a+"-left"+e])))}function e(a){var e=l[a],h;if(e&&!(e.indexOf(" ")<0)){e=e.split(" ");for(h=e.length;h--;)if(e[h]!==e[0])return!1;l[a]=e[0];return!0}}function h(a,h,b,k){e(h)&&e(b)&&e(k)&&(l[a]=l[h]+" "+l[b]+" "+l[k],delete l[h],delete l[b],delete l[k])}function p(a){t=!0;return n[a]}
+function u(a,e){t&&(a=a.replace(/_[0-9]/g,function(a){return n[a]}));e||(a=a.replace(/\\([\'\";:])/g,"$1"));return a}var l={},s,i,r,t,y=c.url_converter,z=c.url_converter_scope||this;if(k){for(k=k.replace(/\\[\"\';:_]/g,p).replace(/\"[^\"]+\"|\'[^\']+\'/g,function(a){return a.replace(/[;:]/g,p)});s=a.exec(k);){i=s[1].replace(f,"").toLowerCase();r=s[2].replace(f,"");if(i&&r.length>0){if(i==="font-weight"&&r==="700")r="bold";else if(i==="color"||i==="background-color")r=r.toLowerCase();r=r.replace(g,
+j);r=r.replace(b,function(a,e,l,h,b,k){if(b=b||k)return b=u(b),"'"+b.replace(/\'/g,"\\'")+"'";e=u(e||l||h);y&&(e=y.call(z,e,"style"));return"url('"+e.replace(/\'/g,"\\'")+"')"});l[i]=t?u(r,!0):r}a.lastIndex=s.index+s[0].length}d("border","");d("border","-width");d("border","-color");d("border","-style");d("padding","");d("margin","");h("border","border-width","border-style","border-color");l.border==="medium none"&&delete l.border}return l},serialize:function(a,b){function e(e){var b,k,d,f;if(b=i.styles[e]){k=
+0;for(d=b.length;k<d;k++)e=b[k],f=a[e],f!==void 0&&f.length>0&&(h+=(h.length>0?" ":"")+e+": "+f+";")}}var h="",k,d;if(b&&i&&i.styles)e("*"),e(k);else for(k in a)d=a[k],d!==void 0&&d.length>0&&(h+=(h.length>0?" ":"")+k+": "+d+";");return h}}};
+(function(c){function i(a,e){return a.split(e||",")}var j={},g,b,a,f,d,n,k=c.makeMap,m=c.each;b="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";b=k(b,",",k(b.toUpperCase()));j=function(a,e){function h(e){return e.replace(/[A-Z]+/g,function(e){return h(a[e])})}var b,d={};for(b in a)a.hasOwnProperty(b)&&(a[b]=h(a[b]));h(e).replace(/#/g,"#text").replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g,
+function(a,e,b,h){b=i(b,"|");d[e]={attributes:k(b),attributesOrder:b,children:k(h,"|",{"#comment":{}})}});return d}({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]");
+g=k("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,preload,autoplay,loop,controls");a=k("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source");f=c.extend(k("td,th,iframe,video,object"),a);d=k("pre,script,style");n=k("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr");c.html.Schema=function(o){function e(a){var e,b,h,d,f,m,n,o,s,g,p,j,u,r,I,E,L,G,Q=/^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,O=/^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,
+R=/[*?+]/;if(a){a=i(a);if(l["@"])E=l["@"].attributes,L=l["@"].attributesOrder;e=0;for(b=a.length;e<b;e++)if(f=Q.exec(a[e])){r=f[1];s=f[2];I=f[3];o=f[4];j={};u=[];m={attributes:j,attributesOrder:u};if(r==="#")m.paddEmpty=!0;if(r==="-")m.removeEmpty=!0;if(E){for(G in E)j[G]=E[G];u.push.apply(u,L)}if(o){o=i(o,"|");h=0;for(d=o.length;h<d;h++)if(f=O.exec(o[h])){n={};p=f[1];g=f[2].replace(/::/g,":");r=f[3];f=f[4];if(p==="!")m.attributesRequired=m.attributesRequired||[],m.attributesRequired.push(g),n.required=
+!0;if(p==="-")delete j[g],u.splice(c.inArray(u,g),1);else{if(r){if(r==="=")m.attributesDefault=m.attributesDefault||[],m.attributesDefault.push({name:g,value:f}),n.defaultValue=f;if(r===":")m.attributesForced=m.attributesForced||[],m.attributesForced.push({name:g,value:f}),n.forcedValue=f;if(r==="<")n.validValues=k(f,"?")}R.test(g)?(m.attributePatterns=m.attributePatterns||[],n.pattern=RegExp("^"+g.replace(/([?+*])/g,".$1")+"$"),m.attributePatterns.push(n)):(j[g]||u.push(g),j[g]=n)}}}!E&&s=="@"&&
+(E=j,L=u);if(I)m.outputName=s,l[I]=m;R.test(s)?(m.pattern=RegExp("^"+s.replace(/([?+*])/g,".$1")+"$"),B.push(m)):l[s]=m}}}function h(a){l={};B=[];e(a);m(j,function(a,e){s[e]=a.children})}function p(a){var e=/^(~)?(.+)$/;a&&m(i(a),function(a){var a=e.exec(a),l=a[1]==="~"?"span":"div",b=a[2];s[b]=s[l];m(s,function(a){a[l]&&(a[b]=a[l])})})}function u(a){var e=/^([+\-]?)(\w+)\[([^\]]+)\]$/;a&&m(i(a),function(a){var a=e.exec(a),l,b;a&&(l=(b=a[1])?s[a[2]]:s[a[2]]={"#comment":{}},l=s[a[2]],m(i(a[3],"|"),
+function(a){b==="-"?delete l[a]:l[a]={}}))})}var l={},s={},B=[],r,o=o||{};if(o.verify_html===!1)o.valid_elements="*[*]";o.valid_styles&&(r={},m(o.valid_styles,function(a,e){r[e]=c.explode(a)}));o.valid_elements?h(o.valid_elements):(m(j,function(a,e){l[e]={attributes:a.attributes,attributesOrder:a.attributesOrder};s[e]=a.children}),m(i("strong/b,em/i"),function(a){a=i(a,"/");l[a[1]].outputName=a[0]}),l.img.attributesDefault=[{name:"alt",value:""}],m(i("ol,ul,li,sub,sup,blockquote,tr,div,span,font,a,table,tbody"),
+function(a){l[a].removeEmpty=!0}),m(i("p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption"),function(a){l[a].paddEmpty=!0}));p(o.custom_elements);u(o.valid_children);e(o.extended_valid_elements);u("+ol[ul|ol],+ul[ul|ol]");o.invalid_elements&&c.each(c.explode(o.invalid_elements),function(a){l[a]&&delete l[a]});this.children=s;this.styles=r;this.getBoolAttrs=function(){return g};this.getBlockElements=function(){return b};this.getShortEndedElements=function(){return a};this.getSelfClosingElements=function(){return n};
+this.getNonEmptyElements=function(){return f};this.getWhiteSpaceElements=function(){return d};this.isValidChild=function(a,e){var l=s[a];return!(!l||!l[e])};this.getElementRule=function(a){var e=l[a],b;if(e)return e;for(b=B.length;b--;)if(e=B[b],e.pattern.test(a))return e};this.addValidElements=e;this.setValidElements=h;this.addCustomElements=p;this.addValidChildren=u};c.html.Schema.boolAttrMap=g;c.html.Schema.blockElementsMap=b})(tinymce);
+(function(c){c.html.SaxParser=function(i,j){var g=this,b=function(){},i=i||{};g.schema=j=j||new c.html.Schema;if(i.fix_self_closing!==!1)i.fix_self_closing=!0;c.each("comment cdata text start end pi doctype".split(" "),function(a){a&&(g[a]=i[a]||b)});g.parse=function(a){function b(a){var l,h;for(l=e.length;l--;)if(e[l].name===a)break;if(l>=0){for(h=e.length-1;h>=l;h--)a=e[h],a.valid&&d.end(a.name);e.length=l}}var d=this,n,k=0,m,o,e=[],h,g,u,l,s,B,r,t,y,z,x,v,q,A,D,C,H,F,K,M=0,N=c.html.Entities.decode,
+P;H=RegExp("<(?:(?:!--([\\w\\W]*?)--\>)|(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|(?:!DOCTYPE([\\w\\W]*?)>)|(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|(?:\\/([^>]+)>)|(?:([^\\s\\/<>]+)\\s*((?:[^\"'>]+(?:(?:\"[^\"]*\")|(?:'[^']*')|[^>]*))*)>))","g");F=/([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;K={script:/<\/script[^>]*>/gi,style:/<\/style[^>]*>/gi,noscript:/<\/noscript[^>]*>/gi};l=j.getShortEndedElements();C=j.getSelfClosingElements();s=j.getBoolAttrs();B=i.validate;
+for(P=i.fix_self_closing;n=H.exec(a);){k<n.index&&d.text(N(a.substr(k,n.index-k)));if(m=n[6])b(m.toLowerCase());else if(m=n[7]){m=m.toLowerCase();k=m in l;P&&C[m]&&e.length>0&&e[e.length-1].name===m&&b(m);if(!B||(r=j.getElementRule(m))){t=!0;if(B)x=r.attributes,v=r.attributePatterns;(z=n[8])?(h=[],h.map={},z.replace(F,function(a,e,l,b,k){e=e.toLowerCase();l=e in s?e:N(l||b||k||"");if(B&&e.indexOf("data-")!==0){a=x[e];if(!a&&v){for(b=v.length;b--;)if(a=v[b],a.pattern.test(e))break;b===-1&&(a=null)}if(!a)return;
+if(a.validValues&&!(l in a.validValues))return}h.map[e]=l;h.push({name:e,value:l})})):(h=[],h.map={});if(B){q=r.attributesRequired;A=r.attributesDefault;if(D=r.attributesForced)for(o=D.length;o--;)y=D[o],u=y.name,y=y.value,y==="{$uid}"&&(y="mce_"+M++),h.map[u]=y,h.push({name:u,value:y});if(A)for(o=A.length;o--;)if(y=A[o],u=y.name,!(u in h.map))y=y.value,y==="{$uid}"&&(y="mce_"+M++),h.map[u]=y,h.push({name:u,value:y});if(q){for(o=q.length;o--;)if(q[o]in h.map)break;o===-1&&(t=!1)}h.map["data-mce-bogus"]&&
+(t=!1)}t&&d.start(m,h,k)}else t=!1;if(o=K[m]){o.lastIndex=k=n.index+n[0].length;(n=o.exec(a))?(t&&(g=a.substr(k,n.index-k)),k=n.index+n[0].length):(g=a.substr(k),k=a.length);t&&g.length>0&&d.text(g,!0);t&&d.end(m);H.lastIndex=k;continue}k||(!z||z.indexOf("/")!=z.length-1?e.push({name:m,valid:t}):t&&d.end(m))}else(m=n[1])?d.comment(m):(m=n[2])?d.cdata(m):(m=n[3])?d.doctype(m):(m=n[4])&&d.pi(m,n[5]);k=n.index+n[0].length}k<a.length&&d.text(N(a.substr(k)));for(o=e.length-1;o>=0;o--)m=e[o],m.valid&&d.end(m.name)}}})(tinymce);
+(function(c){function i(a,b,d){var c;c=d?"lastChild":"firstChild";d=d?"prev":"next";if(a[c])return a[c];if(a!==b){if(c=a[d])return c;for(a=a.parent;a&&a!==b;a=a.parent)if(c=a[d])return c}}function j(a,b){this.name=a;this.type=b;if(b===1)this.attributes=[],this.attributes.map={}}var g=/^[ \t\r\n]*$/,b={"#text":3,"#comment":8,"#cdata":4,"#pi":7,"#doctype":10,"#document-fragment":11};c.extend(j.prototype,{replace:function(a){a.parent&&a.remove();this.insert(a,this);this.remove();return this},attr:function(a,
+b){var d,c;if(typeof a!=="string"){for(c in a)this.attr(c,a[c]);return this}if(d=this.attributes)if(b!==void 0){if(b===null){if(a in d.map){delete d.map[a];for(c=d.length;c--;)if(d[c].name===a){d.splice(c,1);break}}return this}if(a in d.map)for(c=d.length;c--;){if(d[c].name===a){d[c].value=b;break}}else d.push({name:a,value:b});d.map[a]=b;return this}else return d.map[a]},clone:function(){var a=new j(this.name,this.type),b,d,c,k,m;if(c=this.attributes){m=[];m.map={};b=0;for(d=c.length;b<d;b++)if(k=
+c[b],k.name!=="id")m[m.length]={name:k.name,value:k.value},m.map[k.name]=k.value;a.attributes=m}a.value=this.value;a.shortEnded=this.shortEnded;return a},wrap:function(a){this.parent.insert(a,this);a.append(this);return this},unwrap:function(){var a,b;for(a=this.firstChild;a;)b=a.next,this.insert(a,this,!0),a=b;this.remove()},remove:function(){var a=this.parent,b=this.next,d=this.prev;if(a){if(a.firstChild===this){if(a.firstChild=b)b.prev=null}else d.next=b;if(a.lastChild===this){if(a.lastChild=d)d.next=
+null}else b.prev=d;this.parent=this.next=this.prev=null}return this},append:function(a){var b;a.parent&&a.remove();(b=this.lastChild)?(b.next=a,a.prev=b,this.lastChild=a):this.lastChild=this.firstChild=a;a.parent=this;return a},insert:function(a,b,d){var c;a.parent&&a.remove();c=b.parent||this;d?(b===c.firstChild?c.firstChild=a:b.prev.next=a,a.prev=b.prev,a.next=b,b.prev=a):(b===c.lastChild?c.lastChild=a:b.next.prev=a,a.next=b.next,a.prev=b,b.next=a);a.parent=c;return a},getAll:function(a){var b,
+d=[];for(b=this.firstChild;b;b=i(b,this))b.name===a&&d.push(b);return d},empty:function(){var a,b,d;if(this.firstChild){a=[];for(d=this.firstChild;d;d=i(d,this))a.push(d);for(b=a.length;b--;)d=a[b],d.parent=d.firstChild=d.lastChild=d.next=d.prev=null}this.firstChild=this.lastChild=null;return this},isEmpty:function(a){var b=this.firstChild,d,c;if(b){do{if(b.type===1){if(b.attributes.map["data-mce-bogus"])continue;if(a[b.name])return!1;for(d=b.attributes.length;d--;)if(c=b.attributes[d].name,c==="name"||
+c.indexOf("data-")===0)return!1}if(b.type===3&&!g.test(b.value))return!1}while(b=i(b,this))}return!0}});c.extend(j,{create:function(a,c){var d,n;d=new j(a,b[a]||1);if(c)for(n in c)d.attr(n,c[n]);return d}});c.html.Node=j})(tinymce);
+(function(c){var i=c.html.Node;c.html.DomParser=function(j,g){function b(b){var k,e,h,d,f,l,n,j,r,t,y;t=c.makeMap("tr,td,th,tbody,thead,tfoot,table");r=g.getNonEmptyElements();for(k=0;k<b.length;k++)if(e=b[k],e.parent){d=[e];for(h=e.parent;h&&!g.isValidChild(h.name,e.name)&&!t[h.name];h=h.parent)d.push(h);if(h&&d.length>1){d.reverse();f=l=a.filterNode(d[0].clone());for(j=0;j<d.length-1;j++){g.isValidChild(l.name,d[j].name)?(n=a.filterNode(d[j].clone()),l.append(n)):n=l;for(l=d[j].firstChild;l&&l!=
+d[j+1];)y=l.next,n.append(l),l=y;l=n}f.isEmpty(r)?h.insert(e,d[0],!0):(h.insert(f,d[0],!0),h.insert(e,f));h=d[0];(h.isEmpty(r)||h.firstChild===h.lastChild&&h.firstChild.name==="br")&&h.empty().remove()}else if(e.parent)e.name==="li"?(h=e.prev)&&(h.name==="ul"||h.name==="ul")?h.append(e):(h=e.next)&&(h.name==="ul"||h.name==="ul")?h.insert(e,h.firstChild,!0):e.wrap(a.filterNode(new i("ul",1))):g.isValidChild(e.parent.name,"div")&&g.isValidChild("div",e.name)?e.wrap(a.filterNode(new i("div",1))):e.name===
+"style"||e.name==="script"?e.empty().remove():e.unwrap()}}var a=this,f={},d=[],n={},k={},j=j||{};j.validate="validate"in j?j.validate:!0;j.root_name=j.root_name||"body";a.schema=g=g||new c.html.Schema;a.filterNode=function(a){var b,e,h;e in f&&((h=n[e])?h.push(a):n[e]=[a]);for(b=d.length;b--;)e=d[b].name,e in a.attributes.map&&((h=k[e])?h.push(a):k[e]=[a]);return a};a.addNodeFilter=function(a,b){c.each(c.explode(a),function(a){var h=f[a];h||(f[a]=h=[]);h.push(b)})};a.addAttributeFilter=function(a,
+b){c.each(c.explode(a),function(a){var h;for(h=0;h<d.length;h++)if(d[h].name===a){d[h].callbacks.push(b);return}d.push({name:a,callbacks:[b]})})};a.parse=function(a,o){function e(a,e){var b=new i(a,e),l;a in f&&((l=n[a])?l.push(b):n[a]=[b]);return b}function h(a){for(var e,a=a.prev;a&&a.type===3;)e=a.value.replace(A,""),e.length>0?(a.value=e,a=a.prev):(e=a.prev,a.remove(),a=e)}var p,u,l,s,B,r,t,y,z,x,v,q=[],A,D,C,H,F,o=o||{};n={};k={};x=c.extend(c.makeMap("script,style,head,html,body,title,meta,param"),
+g.getBlockElements());F=g.getNonEmptyElements();H=g.children;z=j.validate;C=g.getWhiteSpaceElements();v=/^[ \t\r\n]+/;A=/[ \t\r\n]+$/;D=/[ \t\r\n]+/g;p=new c.html.SaxParser({validate:z,fix_self_closing:!z,cdata:function(a){l.append(e("#cdata",4)).value=a},text:function(a,b){var h;C[l.name]||(a=a.replace(D," "),l.lastChild&&x[l.lastChild.name]&&(a=a.replace(v,"")));if(a.length!==0)h=e("#text",3),h.raw=!!b,l.append(h).value=a},comment:function(a){l.append(e("#comment",8)).value=a},pi:function(a,b){l.append(e(a,
+7)).value=b;h(l)},doctype:function(a){l.append(e("#doctype",10)).value=a;h(l)},start:function(a,b,c){var m,f,n;if(m=z?g.getElementRule(a):{}){m=e(m.outputName||a,1);m.attributes=b;m.shortEnded=c;l.append(m);(f=H[l.name])&&H[m.name]&&!f[m.name]&&q.push(m);for(f=d.length;f--;)n=d[f].name,n in b.map&&((y=k[n])?y.push(m):k[n]=[m]);x[a]&&h(m);c||(l=m)}},end:function(a){var e,b;if(e=z?g.getElementRule(a):{}){if(x[a]){if(!C[l.name]){for(a=l.firstChild;a&&a.type===3;)b=a.value.replace(v,""),b.length>0?(a.value=
+b,a=a.next):(b=a.next,a.remove(),a=b);for(a=l.lastChild;a&&a.type===3;)b=a.value.replace(A,""),b.length>0?(a.value=b,a=a.prev):(b=a.prev,a.remove(),a=b)}if((a=l.prev)&&a.type===3)b=a.value.replace(v,""),b.length>0?a.value=b:a.remove()}if((e.removeEmpty||e.paddEmpty)&&l.isEmpty(F))if(e.paddEmpty)l.empty().append(new i("#text","3")).value="\u00a0";else if(!l.attributes.map.name){e=l.parent;l.empty().remove();l=e;return}l=l.parent}}},g);u=l=new i(j.root_name,11);p.parse(a);z&&b(q);for(t in n){y=f[t];
+p=n[t];for(r=p.length;r--;)p[r].parent||p.splice(r,1);s=0;for(B=y.length;s<B;s++)y[s](p,t,o)}s=0;for(B=d.length;s<B;s++)if(y=d[s],y.name in k){p=k[y.name];for(r=p.length;r--;)p[r].parent||p.splice(r,1);r=0;for(t=y.callbacks.length;r<t;r++)y.callbacks[r](p,y.name,o)}return u};j.remove_trailing_brs&&a.addNodeFilter("br",function(a){var b,e=a.length,h,k=g.getBlockElements(),d=g.getNonEmptyElements(),l,f,n;for(b=0;b<e;b++)if(h=a[b],l=h.parent,k[h.parent.name]&&h===l.lastChild){for(f=h.prev;f;){n=f.name;
+if(n!=="span"||f.attr("data-mce-type")!=="bookmark"){if(n!=="br")break;if(n==="br"){h=null;break}}f=f.prev}if(h&&(h.remove(),l.isEmpty(d)))if(elementRule=g.getElementRule(l.name),elementRule.removeEmpty)l.remove();else if(elementRule.paddEmpty)l.empty().append(new c.html.Node("#text",3)).value="\u00a0"}})}})(tinymce);
+tinymce.html.Writer=function(c){var i=[],j,g,b,a,f,c=c||{};j=c.indent;g=tinymce.makeMap(c.indent_before||"");b=tinymce.makeMap(c.indent_after||"");a=tinymce.html.Entities.getEncodeFunc(c.entity_encoding||"raw",c.entities);f=c.element_format=="html";return{start:function(d,c,k){var m,o,e;j&&g[d]&&i.length>0&&(m=i[i.length-1],m.length>0&&m!=="\n"&&i.push("\n"));i.push("<",d);if(c){m=0;for(o=c.length;m<o;m++)e=c[m],i.push(" ",e.name,'="',a(e.value,!0),'"')}i[i.length]=!k||f?">":" />";k&&j&&b[d]&&i.length>
+0&&(m=i[i.length-1],m.length>0&&m!=="\n"&&i.push("\n"))},end:function(a){i.push("</",a,">");j&&b[a]&&i.length>0&&(a=i[i.length-1],a.length>0&&a!=="\n"&&i.push("\n"))},text:function(b,c){b.length>0&&(i[i.length]=c?b:a(b))},cdata:function(a){i.push("<![CDATA[",a,"]]\>")},comment:function(a){i.push("<\!--",a,"--\>")},pi:function(a,b){b?i.push("<?",a," ",b,"?>"):i.push("<?",a,"?>");j&&i.push("\n")},doctype:function(a){i.push("<!DOCTYPE",a,">",j?"\n":"")},reset:function(){i.length=0},getContent:function(){return i.join("").replace(/\n$/,
+"")}}};
+(function(c){c.html.Serializer=function(i,j){var g=new c.html.Writer(i),i=i||{};i.validate="validate"in i?i.validate:!0;this.schema=j=j||new c.html.Schema;this.writer=g;this.serialize=function(b){function a(b){var k=c[b.type],m,o,e,h,p,i,l,s;if(k)k(b);else{k=b.name;m=b.shortEnded;o=b.attributes;if(d&&o&&o.length>1){p=[];p.map={};s=j.getElementRule(b.name);i=0;for(l=s.attributesOrder.length;i<l;i++)e=s.attributesOrder[i],e in o.map&&(h=o.map[e],p.map[e]=h,p.push({name:e,value:h}));i=0;for(l=o.length;i<
+l;i++)e=o[i].name,e in p.map||(h=o.map[e],p.map[e]=h,p.push({name:e,value:h}));o=p}g.start(b.name,o,m);if(!m){if(b=b.firstChild){do a(b);while(b=b.next)}g.end(k)}}}var c,d;d=i.validate;c={3:function(a){g.text(a.value,a.raw)},8:function(a){g.comment(a.value)},7:function(a){g.pi(a.name,a.value)},10:function(a){g.doctype(a.value)},4:function(a){g.cdata(a.value)},11:function(b){if(b=b.firstChild){do a(b);while(b=b.next)}}};g.reset();if(b.type==1&&!i.inner)a(b);else c[11](b);return g.getContent()}}})(tinymce);
+(function(c){var i=c.each,j=c.is,g=c.isWebKit,b=c.isIE,a=c.html.Entities,f=/^([a-z0-9],?)+$/i,d=c.html.Schema.blockElementsMap,n=/^[ \t\r\n]*$/;c.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(a,
+d){this.doc=a;this.win=window;this.files={};this.cssFlicker=!1;this.counter=0;this.stdMode=!c.isIE||a.documentMode>=8;this.boxModel=!c.isIE||a.compatMode=="CSS1Compat"||this.stdMode;this.hasOuterHTML="outerHTML"in a.createElement("a");this.settings=d=c.extend({keep_values:!1,hex_colors:1},d);this.schema=d.schema;this.styles=new c.html.Styles({url_converter:d.url_converter,url_converter_scope:d.url_converter_scope},d.schema);if(c.isIE6)try{a.execCommand("BackgroundImageCache",!1,!0)}catch(f){this.cssFlicker=
+!0}b&&"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(e){a.createElement(e)});c.addUnload(this.destroy,this)},getRoot:function(){var a=this.settings;return a&&this.get(a.root_element)||this.doc.body},getViewPort:function(a){var b,a=!a?this.win:a;b=a.document;b=this.boxModel?b.documentElement:b.body;return{x:a.pageXOffset||b.scrollLeft,y:a.pageYOffset||b.scrollTop,w:a.innerWidth||
+b.clientWidth,h:a.innerHeight||b.clientHeight}},getRect:function(a){var b,a=this.get(a);b=this.getPos(a);a=this.getSize(a);return{x:b.x,y:b.y,w:a.w,h:a.h}},getSize:function(a){var b,d,a=this.get(a);b=this.getStyle(a,"width");d=this.getStyle(a,"height");b.indexOf("px")===-1&&(b=0);d.indexOf("px")===-1&&(d=0);return{w:parseInt(b)||a.offsetWidth||a.clientWidth,h:parseInt(d)||a.offsetHeight||a.clientHeight}},getParent:function(a,b,d){return this.getParents(a,b,d,!1)},getParents:function(a,b,d,e){var h=
+this,c,f=h.settings,l=[],a=h.get(a),e=e===void 0;f.strict_root&&(d=d||h.getRoot());j(b,"string")&&(c=b,b=b==="*"?function(a){return a.nodeType==1}:function(a){return h.is(a,c)});for(;a;){if(a==d||!a.nodeType||a.nodeType===9)break;if(!b||b(a))if(e)l.push(a);else return a;a=a.parentNode}return e?l:null},get:function(a){var b;if(a&&this.doc&&typeof a=="string"&&(b=a,(a=this.doc.getElementById(a))&&a.id!==b))return this.doc.getElementsByName(b)[1];return a},getNext:function(a,b){return this._findSib(a,
+b,"nextSibling")},getPrev:function(a,b){return this._findSib(a,b,"previousSibling")},select:function(a,b){return c.dom.Sizzle(a,this.get(b)||this.get(this.settings.root_element)||this.doc,[])},is:function(a,b){var d;if(a.length===void 0){if(b==="*")return a.nodeType==1;if(f.test(b)){b=b.toLowerCase().split(/,/);a=a.nodeName.toLowerCase();for(d=b.length-1;d>=0;d--)if(b[d]==a)return!0;return!1}}return c.dom.Sizzle.matches(b,a.nodeType?[a]:a).length>0},add:function(a,b,d,e,h){var c=this;return this.run(a,
+function(a){var l;l=j(b,"string")?c.doc.createElement(b):b;c.setAttribs(l,d);e&&(e.nodeType?l.appendChild(e):c.setHTML(l,e));return!h?a.appendChild(l):l})},create:function(a,b,d){return this.add(this.doc.createElement(a),a,b,d,1)},createHTML:function(a,b,d){var e="",h;e+="<"+a;for(h in b)b.hasOwnProperty(h)&&(e+=" "+h+'="'+this.encode(b[h])+'"');if(typeof d!="undefined")return e+">"+d+"</"+a+">";return e+" />"},remove:function(a,b){return this.run(a,function(a){var e,h=a.parentNode;if(!h)return null;
+if(b)for(;e=a.firstChild;)!c.isIE||e.nodeType!==3||e.nodeValue?h.insertBefore(e,a):a.removeChild(e);return h.removeChild(a)})},setStyle:function(a,d,f){var e=this;return e.run(a,function(h){var g;g=h.style;d=d.replace(/-(\D)/g,function(a,b){return b.toUpperCase()});if(e.pixelStyles.test(d)&&(c.is(f,"number")||/^[\-0-9\.]+$/.test(f)))f+="px";switch(d){case "opacity":if(b&&(g.filter=f===""?"":"alpha(opacity="+f*100+")",!a.currentStyle||!a.currentStyle.hasLayout))g.display="inline-block";g[d]=g["-moz-opacity"]=
+g["-khtml-opacity"]=f||"";break;case "float":b?g.styleFloat=f:g.cssFloat=f;break;default:g[d]=f||""}e.settings.update_styles&&e.setAttrib(h,"data-mce-style")})},getStyle:function(a,d,c){if(a=this.get(a)){if(this.doc.defaultView&&c){d=d.replace(/[A-Z]/g,function(a){return"-"+a});try{return this.doc.defaultView.getComputedStyle(a,null).getPropertyValue(d)}catch(e){return null}}d=d.replace(/-(\D)/g,function(a,b){return b.toUpperCase()});d=="float"&&(d=b?"styleFloat":"cssFloat");if(a.currentStyle&&c)return a.currentStyle[d];
+return a.style?a.style[d]:void 0}},setStyles:function(a,b){var d=this,e=d.settings,h;h=e.update_styles;e.update_styles=0;i(b,function(b,e){d.setStyle(a,e,b)});e.update_styles=h;e.update_styles&&d.setAttrib(a,e.cssText)},removeAllAttribs:function(a){return this.run(a,function(a){var b,e=a.attributes;for(b=e.length-1;b>=0;b--)a.removeAttributeNode(e.item(b))})},setAttrib:function(a,b,d){var e=this;if(a&&b)return e.settings.strict&&(b=b.toLowerCase()),this.run(a,function(a){var k=e.settings;switch(b){case "style":if(!j(d,
+"string")){i(d,function(b,l){e.setStyle(a,l,b)});return}k.keep_values&&(d&&!e._isRes(d)?a.setAttribute("data-mce-style",d,2):a.removeAttribute("data-mce-style",2));a.style.cssText=d;break;case "class":a.className=d||"";break;case "src":case "href":k.keep_values&&(k.url_converter&&(d=k.url_converter.call(k.url_converter_scope||e,d,b,a)),e.setAttrib(a,"data-mce-"+b,d,2));break;case "shape":a.setAttribute("data-mce-style",d)}j(d)&&d!==null&&d.length!==0?a.setAttribute(b,""+d,2):a.removeAttribute(b,2)})},
+setAttribs:function(a,b){var d=this;return this.run(a,function(a){i(b,function(b,k){d.setAttrib(a,k,b)})})},getAttrib:function(a,d,f){var e,a=this.get(a);if(!a||a.nodeType!==1)return!1;j(f)||(f="");if(/^(src|href|style|coords|shape)$/.test(d)&&(e=a.getAttribute("data-mce-"+d)))return e;b&&this.props[d]&&(e=(e=a[this.props[d]])&&e.nodeValue?e.nodeValue:e);e||(e=a.getAttribute(d,2));if(/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(d)){if(a[this.props[d]]===
+!0&&e==="")return d;return e?d:""}if(a.nodeName==="FORM"&&a.getAttributeNode(d))return a.getAttributeNode(d).nodeValue;if(d==="style"&&(e=e||a.style.cssText))e=this.serializeStyle(this.parseStyle(e),a.nodeName),this.settings.keep_values&&!this._isRes(e)&&a.setAttribute("data-mce-style",e);g&&d==="class"&&e&&(e=e.replace(/(apple|webkit)\-[a-z\-]+/gi,""));if(b)switch(d){case "rowspan":case "colspan":e===1&&(e="");break;case "size":if(e==="+0"||e===20||e===0)e="";break;case "width":case "height":case "vspace":case "checked":case "disabled":case "readonly":e===
+0&&(e="");break;case "hspace":e===-1&&(e="");break;case "maxlength":case "tabindex":if(e===32768||e===2147483647||e==="32768")e="";break;case "multiple":case "compact":case "noshade":case "nowrap":if(e===65535)return d;return f;case "shape":e=e.toLowerCase();break;default:d.indexOf("on")===0&&e&&(e=c._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/,"$1",""+e))}return e!==void 0&&e!==null&&e!==""?""+e:f},getPos:function(a,d){var c=0,e=0,h=this.doc,a=this.get(a),d=d||h.body;if(a){if(b&&!this.stdMode)return a=
+a.getBoundingClientRect(),e=this.boxModel?h.documentElement:h.body,c=this.getStyle(this.select("html")[0],"borderWidth"),c=(c=="medium"||this.boxModel&&!this.isIE6)&&2||c,{x:a.left+e.scrollLeft-c,y:a.top+e.scrollTop-c};for(h=a;h&&h!=d&&h.nodeType;)c+=h.offsetLeft||0,e+=h.offsetTop||0,h=h.offsetParent;for(h=a.parentNode;h&&h!=d&&h.nodeType;)c-=h.scrollLeft||0,e-=h.scrollTop||0,h=h.parentNode}return{x:c,y:e}},parseStyle:function(a){return this.styles.parse(a)},serializeStyle:function(a,b){return this.styles.serialize(a,
+b)},loadCSS:function(a){var d=this,f=d.doc,e;a||(a="");e=d.select("head")[0];i(a.split(","),function(a){var k;if(!d.files[a]){d.files[a]=!0;k=d.create("link",{rel:"stylesheet",href:c._addVer(a)});if(b&&f.documentMode&&f.recalc)k.onload=function(){f.recalc&&f.recalc();k.onload=null};e.appendChild(k)}})},addClass:function(a,b){return this.run(a,function(a){var e;if(!b)return 0;if(this.hasClass(a,b))return a.className;e=this.removeClass(a,b);return a.className=(e!=""?e+" ":"")+b})},removeClass:function(a,
+b){var d=this,e;return d.run(a,function(a){var f;if(d.hasClass(a,b))return e||(e=RegExp("(^|\\s+)"+b+"(\\s+|$)","g")),f=a.className.replace(e," "),f=c.trim(f!=" "?f:""),a.className=f,f||(a.removeAttribute("class"),a.removeAttribute("className")),f;return a.className})},hasClass:function(a,b){a=this.get(a);if(!a||!b)return!1;return(" "+a.className+" ").indexOf(" "+b+" ")!==-1},show:function(a){return this.setStyle(a,"display","block")},hide:function(a){return this.setStyle(a,"display","none")},isHidden:function(a){a=
+this.get(a);return!a||a.style.display=="none"||this.getStyle(a,"display")=="none"},uniqueId:function(a){return(!a?"mce_":a)+this.counter++},setHTML:function(a,d){var c=this;return c.run(a,function(a){if(b){for(;a.firstChild;)a.removeChild(a.firstChild);try{a.innerHTML="<br />"+d,a.removeChild(a.firstChild)}catch(h){a=c.create("div"),a.innerHTML="<br />"+d,i(a.childNodes,function(b,d){d&&a.appendChild(b)})}}else a.innerHTML=d;return d})},getOuterHTML:function(a){var b,a=this.get(a);if(!a)return null;
+if(a.nodeType===1&&this.hasOuterHTML)return a.outerHTML;b=(a.ownerDocument||this.doc).createElement("body");b.appendChild(a.cloneNode(!0));return b.innerHTML},setOuterHTML:function(a,d,c){function e(a,b,e){e=e.createElement("body");e.innerHTML=b;for(b=e.lastChild;b;)h.insertAfter(b.cloneNode(!0),a),b=b.previousSibling;h.remove(a)}var h=this;return this.run(a,function(a){a=h.get(a);if(a.nodeType==1)if(c=c||a.ownerDocument||h.doc,b)try{b&&a.nodeType==1?a.outerHTML=d:e(a,d,c)}catch(f){e(a,d,c)}else e(a,
+d,c)})},decode:a.decode,encode:a.encodeAllRaw,insertAfter:function(a,b){b=this.get(b);return this.run(a,function(a){var e,d;e=b.parentNode;(d=b.nextSibling)?e.insertBefore(a,d):e.appendChild(a);return a})},isBlock:function(a){var b=a.nodeType;if(b)return!!(b===1&&d[a.nodeName]);return!!d[a]},replace:function(a,b,d){j(b,"array")&&(a=a.cloneNode(!0));return this.run(b,function(b){d&&i(c.grep(b.childNodes),function(b){a.appendChild(b)});return b.parentNode.replaceChild(a,b)})},rename:function(a,b){var d=
+this,e;a.nodeName!=b.toUpperCase()&&(e=d.create(b),i(d.getAttribs(a),function(b){d.setAttrib(e,b.nodeName,d.getAttrib(a,b.nodeName))}),d.replace(e,a,1));return e||a},findCommonAncestor:function(a,b){for(var d=a,e;d;){for(e=b;e&&d!=e;)e=e.parentNode;if(d==e)break;d=d.parentNode}if(!d&&a.ownerDocument)return a.ownerDocument.documentElement;return d},toHex:function(a){function b(a){a=parseInt(a).toString(16);return a.length>1?a:"0"+a}var d=/^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(a);
+d&&(a="#"+b(d[1])+b(d[2])+b(d[3]));return a},getClasses:function(){function a(f){i(f.imports,function(b){a(b)});i(f.cssRules||f.rules,function(l){switch(l.type||1){case 1:l.selectorText&&i(l.selectorText.split(","),function(a){a=a.replace(/^\s*|\s*$|^\s\./g,"");if(!/\.mce/.test(a)&&/\.[\w\-]+$/.test(a)&&(h=a,a=c._replace(/.*\.([a-z0-9_\-]+).*/i,"$1",a),(!e||(a=e(a,h)))&&!d[a]))b.push({"class":a}),d[a]=1});break;case 3:a(l.styleSheet)}})}var b=[],d={},e=this.settings.class_filter,h;if(this.classes)return this.classes;
+try{i(this.doc.styleSheets,a)}catch(f){}if(b.length>0)this.classes=b;return b},run:function(a,b,d){var e=this,h;e.doc&&typeof a==="string"&&(a=e.get(a));if(!a)return!1;d=d||this;if(!a.nodeType&&(a.length||a.length===0))return h=[],i(a,function(a,c){a&&(typeof a=="string"&&(a=e.doc.getElementById(a)),h.push(b.call(d,a,c)))}),h;return b.call(d,a)},getAttribs:function(a){var d,a=this.get(a);if(!a)return[];if(b){d=[];if(a.nodeName=="OBJECT")return a.attributes;a.nodeName==="OPTION"&&this.getAttrib(a,
+"selected")&&d.push({specified:1,nodeName:"selected"});a.cloneNode(!1).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi,"").replace(/[\w:\-]+/gi,function(a){d.push({specified:1,nodeName:a})});return d}return a.attributes},isEmpty:function(a,b){var d,e,h,f;if(a=a.firstChild){h=new c.dom.TreeWalker(a);b=b||this.schema?this.schema.getNonEmptyElements():null;do{e=a.nodeType;if(e===1){if(a.getAttribute("data-mce-bogus"))continue;if(b&&b[a.nodeName.toLowerCase()])return!1;this.getAttribs(a);
+for(d=a.attributes.length;d--;)if(f=a.attributes[d].nodeName,f==="name"||f.indexOf("data-")===0)return!1}if(e===3&&!n.test(a.nodeValue))return!1}while(a=h.next())}return!0},destroy:function(a){this.events&&this.events.destroy();this.win=this.doc=this.root=this.events=null;a||c.removeUnload(this.destroy)},createRng:function(){var a=this.doc;return a.createRange?a.createRange():new c.dom.Range(this)},nodeIndex:function(a,b){var d=0,e,h,c;if(a){e=a.nodeType;for(a=a.previousSibling;a;a=a.previousSibling){h=
+a.nodeType;if(b&&h==3){c=!1;try{c=a.nodeValue.length}catch(f){}if(h==e||!c)continue}d++;e=h}}return d},split:function(a,b,d){function e(a){var b,d=a.childNodes,l=a.nodeType;if(!(l==1&&a.getAttribute("data-mce-type")=="bookmark")){for(b=d.length-1;b>=0;b--)e(d[b]);if(l!=9){if(l==3&&a.nodeValue.length>0){if(!h.isBlock(a.parentNode)||c.trim(a.nodeValue).length>0)return}else if(l==1&&(d=a.childNodes,d.length==1&&d[0]&&d[0].nodeType==1&&d[0].getAttribute("data-mce-type")=="bookmark"&&a.parentNode.insertBefore(d[0],
+a),d.length||/^(br|hr|input|img)$/i.test(a.nodeName)))return;h.remove(a)}return a}}var h=this,f=h.createRng(),g,l;if(a&&b)return f.setStart(a.parentNode,h.nodeIndex(a)),f.setEnd(b.parentNode,h.nodeIndex(b)),g=f.extractContents(),f=h.createRng(),f.setStart(b.parentNode,h.nodeIndex(b)+1),f.setEnd(a.parentNode,h.nodeIndex(a)+1),f=f.extractContents(),l=a.parentNode,l.insertBefore(e(g),a),d?l.replaceChild(d,b):l.insertBefore(b,a),l.insertBefore(e(f),a),h.remove(a),d||b},bind:function(a,b,d,e){if(!this.events)this.events=
+new c.dom.EventUtils;return this.events.add(a,b,d,e||this)},unbind:function(a,b,d){if(!this.events)this.events=new c.dom.EventUtils;return this.events.remove(a,b,d)},_findSib:function(a,b,d){var e=this,h=b;if(a){j(h,"string")&&(h=function(a){return e.is(a,b)});for(a=a[d];a;a=a[d])if(h(a))return a}return null},_isRes:function(a){return/^(top|left|bottom|right|width|height)/i.test(a)||/;\s*(top|left|bottom|right|width|height)/i.test(a)}});c.DOM=new c.dom.DOMUtils(document,{process_html:0})})(tinymce);
+(function(c){function i(c){function g(a,b){k(t,a,b)}function b(a,b){k(y,a,b)}function a(a){g(a.parentNode,D(a))}function f(a){b(a.parentNode,D(a)+1)}function d(a,b){var e;if(a.nodeType==3)return a;if(b<0)return a;for(e=a.firstChild;e&&b>0;)--b,e=e.nextSibling;if(e)return e;return a}function n(a,b,e,d){var l,h;if(a==e){if(b==d)return 0;if(b<d)return-1;return 1}for(l=e;l&&l.parentNode!=a;)l=l.parentNode;if(l){h=0;for(e=a.firstChild;e!=l&&h<b;)h++,e=e.nextSibling;if(b<=h)return-1;return 1}for(l=a;l&&
+l.parentNode!=e;)l=l.parentNode;if(l){h=0;for(e=e.firstChild;e!=l&&h<d;)h++,e=e.nextSibling;if(h<d)return-1;return 1}for(b=c.findCommonAncestor(a,e);a&&a.parentNode!=b;)a=a.parentNode;a||(a=b);for(d=e;d&&d.parentNode!=b;)d=d.parentNode;d||(d=b);if(a==d)return 0;for(e=b.firstChild;e;){if(e==a)return-1;if(e==d)return 1;e=e.nextSibling}}function k(a,b,e){a?(l[x]=b,l[z]=e):(l[v]=b,l[q]=e);for(b=l[v];b.parentNode;)b=b.parentNode;for(e=l[x];e.parentNode;)e=e.parentNode;e==b?n(l[x],l[z],l[v],l[q])>0&&l.collapse(a):
+l.collapse(a);l.collapsed=l[x]==l[v]&&l[z]==l[q];l.commonAncestorContainer=c.findCommonAncestor(l[x],l[v])}function m(a){var b,d=0,c=0,f;if(l[x]==l[v])return o(a);b=l[v];for(f=b.parentNode;f;b=f,f=f.parentNode){if(f==l[x]){var g=b;f=c=d=f=b=void 0;a!=r&&(b=s.createDocumentFragment());f=e(g,a);b&&b.appendChild(f);d=D(g)-l[z];if(!(d<=0))for(f=g.previousSibling;d>0;)c=f.previousSibling,f=u(f,a),b&&b.insertBefore(f,b.firstChild),--d,f=c;a!=B&&(l.setEndBefore(g),l.collapse(y));a=b;return a}++d}b=l[x];
+for(f=b.parentNode;f;b=f,f=f.parentNode){if(f==l[v]){g=b;f=c=d=f=d=b=void 0;a!=r&&(b=s.createDocumentFragment());f=h(g,a);b&&b.appendChild(f);d=D(g);++d;d=l[q]-d;for(f=g.nextSibling;d>0;)c=f.nextSibling,f=u(f,a),b&&b.appendChild(f),--d,f=c;a!=B&&(l.setStartAfter(g),l.collapse(t));return b}++c}c-=d;for(b=l[x];c>0;)b=b.parentNode,c--;for(d=l[v];c<0;)d=d.parentNode,c++;c=b.parentNode;for(f=d.parentNode;c!=f;c=c.parentNode,f=f.parentNode)b=c,d=f;var k;a!=r&&(g=s.createDocumentFragment());k=h(b,a);g&&
+g.appendChild(k);c=D(b);f=D(d);++c;c=f-c;for(k=b.nextSibling;c>0;)f=k.nextSibling,k=u(k,a),g&&g.appendChild(k),k=f,--c;k=e(d,a);g&&g.appendChild(k);a!=B&&(l.setStartAfter(b),l.collapse(t));return g}function o(a){var b,e,h,f;a!=r&&(b=s.createDocumentFragment());if(l[z]==l[q])return b;if(l[x].nodeType==3){e=l[x].nodeValue;e=e.substring(l[z],l[q]);a!=B&&(l[x].deleteData(l[z],l[q]-l[z]),l.collapse(t));if(a==r)return;b.appendChild(s.createTextNode(e));return b}h=d(l[x],l[z]);for(e=l[q]-l[z];e>0;)f=h.nextSibling,
+h=u(h,a),b&&b.appendChild(h),--e,h=f;a!=B&&l.collapse(t);return b}function e(a,b){var e=d(l[v],l[q]-1),h,f,c,g=e!=l[v];if(e==a)return p(e,g,y,b);h=e.parentNode;for(f=p(h,y,y,b);h;){for(;e;)c=e.previousSibling,e=p(e,g,y,b),b!=r&&f.insertBefore(e,f.firstChild),g=t,e=c;if(h==a)return f;e=h.previousSibling;h=h.parentNode;c=p(h,y,y,b);b!=r&&c.appendChild(f);f=c}}function h(a,b){var e=d(l[x],l[z]),h=e!=l[x],f,c,g;if(e==a)return p(e,h,t,b);f=e.parentNode;for(c=p(f,y,t,b);f;){for(;e;)g=e.nextSibling,e=p(e,
+h,t,b),b!=r&&c.appendChild(e),h=t,e=g;if(f==a)return c;e=f.nextSibling;f=f.parentNode;g=p(f,y,t,b);b!=r&&g.appendChild(c);c=g}}function p(a,b,e,d){var h;if(b)return u(a,d);if(a.nodeType==3){b=a.nodeValue;e?(h=l[z],e=b.substring(h),b=b.substring(0,h)):(h=l[q],e=b.substring(0,h),b=b.substring(h));if(d!=B)a.nodeValue=b;if(d==r)return;a=a.cloneNode(y);a.nodeValue=e;return a}if(d!=r)return a.cloneNode(y)}function u(a,b){if(b!=r)return b==B?a.cloneNode(t):a;a.parentNode.removeChild(a)}var l=this,s=c.doc,
+B=1,r=2,t=!0,y=!1,z="startOffset",x="startContainer",v="endContainer",q="endOffset",A=tinymce.extend,D=c.nodeIndex;A(l,{startContainer:s,startOffset:0,endContainer:s,endOffset:0,collapsed:t,commonAncestorContainer:s,START_TO_START:0,START_TO_END:1,END_TO_END:2,END_TO_START:3,setStart:g,setEnd:b,setStartBefore:a,setStartAfter:function(a){g(a.parentNode,D(a)+1)},setEndBefore:function(a){b(a.parentNode,D(a))},setEndAfter:f,collapse:function(a){a?(l[v]=l[x],l[q]=l[z]):(l[x]=l[v],l[z]=l[q]);l.collapsed=
+t},selectNode:function(b){a(b);f(b)},selectNodeContents:function(a){g(a,0);b(a,a.nodeType===1?a.childNodes.length:a.nodeValue.length)},compareBoundaryPoints:function(a,b){var e=l[x],d=l[z],h=l[v],f=l[q],c=b.startContainer,g=b.startOffset,k=b.endContainer,s=b.endOffset;if(a===0)return n(e,d,c,g);if(a===1)return n(h,f,c,g);if(a===2)return n(h,f,k,s);if(a===3)return n(e,d,k,s)},deleteContents:function(){m(r)},extractContents:function(){return m(0)},cloneContents:function(){return m(B)},insertNode:function(a){var b=
+this[x],e=this[z],d;(b.nodeType===3||b.nodeType===4)&&b.nodeValue?e?e>=b.nodeValue.length?c.insertAfter(a,b):(e=b.splitText(e),b.parentNode.insertBefore(a,e)):b.parentNode.insertBefore(a,b):(b.childNodes.length>0&&(d=b.childNodes[e]),d?b.insertBefore(a,d):b.appendChild(a))},surroundContents:function(a){var b=l.extractContents();l.insertNode(a);a.appendChild(b);l.selectNode(a)},cloneRange:function(){return A(new i(c),{startContainer:l[x],startOffset:l[z],endContainer:l[v],endOffset:l[q],collapsed:l.collapsed,
+commonAncestorContainer:l.commonAncestorContainer})}})}c.Range=i})(tinymce.dom);
+(function(){tinymce.dom.TridentSelection=function(c){function i(){function b(e){var d,c,j,l=0,s,i,m,o;j=f.duplicate();j.collapse(e);d=a.create("a");m=j.parentElement();if(m.hasChildNodes())if(m.appendChild(d),j.moveToElementText(d),o=f.compareEndPoints(e?"StartToStart":"EndToEnd",j),o>0)g[e?"setStartAfter":"setEndAfter"](m),a.remove(d);else{c=tinymce.grep(m.childNodes);for(s=c.length-1;l<=s;)if(i=Math.floor((l+s)/2),m.insertBefore(d,c[i]),j.moveToElementText(d),o=f.compareEndPoints(e?"StartToStart":
+"EndToEnd",j),o>0)l=i+1;else if(o<0)s=i-1;else{found=!0;break}c=o>0||i==0?d.nextSibling:d.previousSibling;c.nodeType==1?(a.remove(d),j=a.nodeIndex(c),c=c.parentNode,(!e||i>0)&&j++):(o>0||i==0?(j.setEndPoint(e?"StartToStart":"EndToEnd",f),j=j.text.length):(j.setEndPoint(e?"StartToStart":"EndToEnd",f),j=c.nodeValue.length-j.text.length),a.remove(d));g[e?"setStart":"setEnd"](c,j)}else g[e?"setStart":"setEnd"](m,0)}var f=c.getRng(),g=a.createRng(),j,i;j=f.item?f.item(0):f.parentElement();if(j.ownerDocument!=
+a.doc)return g;i=c.isCollapsed();if(f.item||!j.hasChildNodes())return i?(g.setStart(j,0),g.setEnd(j,0)):(g.setStart(j.parentNode,a.nodeIndex(j)),g.setEnd(g.startContainer,g.startOffset+1)),g;b(!0);i||b();return g}var j="\ufeff",g,b,a=c.dom,f=!0;this.addRange=function(b){function g(b){var d,c,n,s,i;n=a.create("a");d=b?o:h;c=b?e:p;s=k.duplicate();if(d==u||d==u.documentElement)d=l,c=0;d.nodeType==3?(d.parentNode.insertBefore(n,d),s.moveToElementText(n),s.moveStart("character",c),a.remove(n),k.setEndPoint(b?
+"StartToStart":"EndToEnd",s)):(i=d.childNodes,i.length?(c>=i.length?a.insertAfter(n,i[i.length-1]):d.insertBefore(n,i[c]),s.moveToElementText(n)):(n=u.createTextNode(j),d.appendChild(n),s.moveToElementText(n.parentNode),s.collapse(f)),k.setEndPoint(b?"StartToStart":"EndToEnd",s),a.remove(n))}var k,i,o,e,h,p,u=c.dom.doc,l=u.body;this.destroy();o=b.startContainer;e=b.startOffset;h=b.endContainer;p=b.endOffset;k=l.createTextRange();if(o==h&&o.nodeType==1&&e==p-1&&e==p-1)try{i=l.createControlRange();
+i.addElement(o.childNodes[e]);i.select();return}catch(s){}g(!0);g();k.select()};this.getRangeAt=function(){if(!g||!tinymce.dom.RangeUtils.compareRanges(b,c.getRng()))g=i(),b=c.getRng();return g};this.destroy=function(){b=g=null}}})();
+(function(){function c(a,b,e,d,h,f){for(var h=0,c=d.length;h<c;h++){var g=d[h];if(g){for(var g=g[a],k=!1;g;){if(g.sizcache===e){k=d[g.sizset];break}if(g.nodeType===1&&!f)g.sizcache=e,g.sizset=h;if(g.nodeName.toLowerCase()===b){k=g;break}g=g[a]}d[h]=k}}}function i(a,b,e,h,f,c){for(var f=0,g=h.length;f<g;f++){var k=h[f];if(k){for(var k=k[a],n=!1;k;){if(k.sizcache===e){n=h[k.sizset];break}if(k.nodeType===1){if(!c)k.sizcache=e,k.sizset=f;if(typeof b!=="string"){if(k===b){n=!0;break}}else if(d.filter(b,
+[k]).length>0){n=k;break}}k=k[a]}h[f]=n}}}var j=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,g=0,b=Object.prototype.toString,a=!1,f=!0;[0,0].sort(function(){f=!1;return 0});var d=function(a,h,f,c){var f=f||[],g=h=h||document;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!a||typeof a!=="string")return f;var i=[],m,o,p,q,A=!0,D=d.isXML(h),C=a,H;do if(j.exec(""),m=j.exec(C))if(C=m[3],i.push(m[1]),m[2]){q=m[3];break}while(m);
+if(i.length>1&&k.exec(a))if(i.length===2&&n.relative[i[0]])o=u(i[0]+i[1],h);else for(o=n.relative[i[0]]?[h]:d(i.shift(),h);i.length;)a=i.shift(),n.relative[a]&&(a+=i.shift()),o=u(a,o);else if(!c&&i.length>1&&h.nodeType===9&&!D&&n.match.ID.test(i[0])&&!n.match.ID.test(i[i.length-1])&&(m=d.find(i.shift(),h,D),h=m.expr?d.filter(m.expr,m.set)[0]:m.set[0]),h){m=c?{expr:i.pop(),set:e(c)}:d.find(i.pop(),i.length===1&&(i[0]==="~"||i[0]==="+")&&h.parentNode?h.parentNode:h,D);o=m.expr?d.filter(m.expr,m.set):
+m.set;for(i.length>0?p=e(o):A=!1;i.length;)m=H=i.pop(),n.relative[H]?m=i.pop():H="",m==null&&(m=h),n.relative[H](p,m,D)}else p=[];p||(p=o);p||d.error(H||a);if(b.call(p)==="[object Array]")if(A)if(h&&h.nodeType===1)for(a=0;p[a]!=null;a++)p[a]&&(p[a]===!0||p[a].nodeType===1&&d.contains(h,p[a]))&&f.push(o[a]);else for(a=0;p[a]!=null;a++)p[a]&&p[a].nodeType===1&&f.push(o[a]);else f.push.apply(f,p);else e(p,f);q&&(d(q,g,f,c),d.uniqueSort(f));return f};d.uniqueSort=function(b){if(p&&(a=f,b.sort(p),a))for(var e=
+1;e<b.length;e++)b[e]===b[e-1]&&b.splice(e--,1);return b};d.matches=function(a,b){return d(a,null,null,b)};d.find=function(a,b,e){var d;if(!a)return[];for(var h=0,f=n.order.length;h<f;h++){var c=n.order[h],g;if(g=n.leftMatch[c].exec(a)){var k=g[1];g.splice(1,1);if(k.substr(k.length-1)!=="\\"&&(g[1]=(g[1]||"").replace(/\\/g,""),d=n.find[c](g,b,e),d!=null)){a=a.replace(n.match[c],"");break}}}d||(d=b.getElementsByTagName("*"));return{set:d,expr:a}};d.filter=function(a,b,e,h){for(var f=a,c=[],g=b,k,i,
+j=b&&b[0]&&d.isXML(b[0]);a&&b.length;){for(var m in n.filter)if((k=n.leftMatch[m].exec(a))!=null&&k[2]){var o=n.filter[m],p,u;u=k[1];i=!1;k.splice(1,1);if(u.substr(u.length-1)!=="\\"){g===c&&(c=[]);if(n.preFilter[m])if(k=n.preFilter[m](k,g,e,c,h,j)){if(k===!0)continue}else i=p=!0;if(k)for(var F=0;(u=g[F])!=null;F++)if(u){p=o(u,k,F,g);var K=h^!!p;e&&p!=null?K?i=!0:g[F]=!1:K&&(c.push(u),i=!0)}if(p!==void 0){e||(g=c);a=a.replace(n.match[m],"");if(!i)return[];break}}}if(a===f)if(i==null)d.error(a);else break;
+f=a}return g};d.error=function(a){throw"Syntax error, unrecognized expression: "+a;};var n=d.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(a){return a.getAttribute("href")}},relative:{"+":function(a,b){var e=typeof b==="string",h=e&&!/\W/.test(b),e=e&&!h;h&&(b=b.toLowerCase());for(var h=0,f=a.length,c;h<f;h++)if(c=a[h]){for(;(c=c.previousSibling)&&c.nodeType!==1;);a[h]=e||c&&c.nodeName.toLowerCase()===b?c||!1:c===b}e&&d.filter(b,a,!0)},">":function(a,b){var e=typeof b===
+"string",h,f=0,c=a.length;if(e&&!/\W/.test(b))for(b=b.toLowerCase();f<c;f++){if(h=a[f])e=h.parentNode,a[f]=e.nodeName.toLowerCase()===b?e:!1}else{for(;f<c;f++)(h=a[f])&&(a[f]=e?h.parentNode:h.parentNode===b);e&&d.filter(b,a,!0)}},"":function(a,b,e){var d=g++,h=i,f;typeof b==="string"&&!/\W/.test(b)&&(f=b=b.toLowerCase(),h=c);h("parentNode",b,d,a,f,e)},"~":function(a,b,e){var d=g++,h=i,f;typeof b==="string"&&!/\W/.test(b)&&(f=b=b.toLowerCase(),h=c);h("previousSibling",b,d,a,f,e)}},find:{ID:function(a,
+b,e){if(typeof b.getElementById!=="undefined"&&!e)return(a=b.getElementById(a[1]))?[a]:[]},NAME:function(a,b){if(typeof b.getElementsByName!=="undefined"){for(var e=[],d=b.getElementsByName(a[1]),h=0,f=d.length;h<f;h++)d[h].getAttribute("name")===a[1]&&e.push(d[h]);return e.length===0?null:e}},TAG:function(a,b){return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,e,d,h,f){a=" "+a[1].replace(/\\/g,"")+" ";if(f)return a;for(var f=0,c;(c=b[f])!=null;f++)c&&(h^(c.className&&(" "+c.className+
+" ").replace(/[\t\n]/g," ").indexOf(a)>=0)?e||d.push(c):e&&(b[f]=!1));return!1},ID:function(a){return a[1].replace(/\\/g,"")},TAG:function(a){return a[1].toLowerCase()},CHILD:function(a){if(a[1]==="nth"){var b=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0;a[3]=b[3]-0}a[0]=g++;return a},ATTR:function(a,b,e,d,h,f){b=a[1].replace(/\\/g,"");!f&&n.attrMap[b]&&(a[1]=n.attrMap[b]);a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},
+PSEUDO:function(a,b,e,h,f){if(a[1]==="not")if((j.exec(a[3])||"").length>1||/^\w/.test(a[3]))a[3]=d(a[3],null,null,b);else return a=d.filter(a[3],b,e,1^f),e||h.push.apply(h,a),!1;else if(n.match.POS.test(a[0])||n.match.CHILD.test(a[0]))return!0;return a},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){return a.selected===!0},parent:function(a){return!!a.firstChild},
+empty:function(a){return!a.firstChild},has:function(a,b,e){return!!d(e[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){return"text"===a.type},radio:function(a){return"radio"===a.type},checkbox:function(a){return"checkbox"===a.type},file:function(a){return"file"===a.type},password:function(a){return"password"===a.type},submit:function(a){return"submit"===a.type},image:function(a){return"image"===a.type},reset:function(a){return"reset"===a.type},button:function(a){return"button"===
+a.type||a.nodeName.toLowerCase()==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)}},setFilters:{first:function(a,b){return b===0},last:function(a,b,e,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,e){return b<e[3]-0},gt:function(a,b,e){return b>e[3]-0},nth:function(a,b,e){return e[3]-0===b},eq:function(a,b,e){return e[3]-0===b}},filter:{PSEUDO:function(a,b,e,h){var f=b[1],c=n.filters[f];if(c)return c(a,
+e,b,h);else if(f==="contains")return(a.textContent||a.innerText||d.getText([a])||"").indexOf(b[3])>=0;else if(f==="not"){b=b[3];e=0;for(h=b.length;e<h;e++)if(b[e]===a)return!1;return!0}else d.error("Syntax error, unrecognized expression: "+f)},CHILD:function(a,b){var e=b[1],d=a;switch(e){case "only":case "first":for(;d=d.previousSibling;)if(d.nodeType===1)return!1;if(e==="first")return!0;d=a;case "last":for(;d=d.nextSibling;)if(d.nodeType===1)return!1;return!0;case "nth":var e=b[2],h=b[3];if(e===
+1&&h===0)return!0;var f=b[0],c=a.parentNode;if(c&&(c.sizcache!==f||!a.nodeIndex)){for(var g=0,d=c.firstChild;d;d=d.nextSibling)if(d.nodeType===1)d.nodeIndex=++g;c.sizcache=f}d=a.nodeIndex-h;return e===0?d===0:d%e===0&&d/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var e=b[1],e=n.attrHandle[e]?
+n.attrHandle[e](a):a[e]!=null?a[e]:a.getAttribute(e),d=e+"",h=b[2],f=b[4];return e==null?h==="!=":h==="="?d===f:h==="*="?d.indexOf(f)>=0:h==="~="?(" "+d+" ").indexOf(f)>=0:!f?d&&e!==!1:h==="!="?d!==f:h==="^="?d.indexOf(f)===0:h==="$="?d.substr(d.length-f.length)===f:h==="|="?d===f||d.substr(0,f.length+1)===f+"-":!1},POS:function(a,b,e,d){var h=n.setFilters[b[2]];if(h)return h(a,e,b,d)}}},k=n.match.POS,m=function(a,b){return"\\"+(b-0+1)},o;for(o in n.match)n.match[o]=RegExp(n.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),
+n.leftMatch[o]=RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[o].source.replace(/\\(\d+)/g,m));var e=function(a,b){a=Array.prototype.slice.call(a,0);if(b)return b.push.apply(b,a),b;return a};try{Array.prototype.slice.call(document.documentElement.childNodes,0)}catch(h){e=function(a,e){var d=e||[],h=0;if(b.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length==="number")for(var f=a.length;h<f;h++)d.push(a[h]);else for(;a[h];h++)d.push(a[h]);return d}}var p;document.documentElement.compareDocumentPosition?
+p=function(b,e){if(!b.compareDocumentPosition||!e.compareDocumentPosition)return b==e&&(a=!0),b.compareDocumentPosition?-1:1;var d=b.compareDocumentPosition(e)&4?-1:b===e?0:1;d===0&&(a=!0);return d}:"sourceIndex"in document.documentElement?p=function(b,e){if(!b.sourceIndex||!e.sourceIndex)return b==e&&(a=!0),b.sourceIndex?-1:1;var d=b.sourceIndex-e.sourceIndex;d===0&&(a=!0);return d}:document.createRange&&(p=function(b,e){if(!b.ownerDocument||!e.ownerDocument)return b==e&&(a=!0),b.ownerDocument?-1:
+1;var d=b.ownerDocument.createRange(),h=e.ownerDocument.createRange();d.setStart(b,0);d.setEnd(b,0);h.setStart(e,0);h.setEnd(e,0);d=d.compareBoundaryPoints(Range.START_TO_END,h);d===0&&(a=!0);return d});d.getText=function(a){for(var b="",e,h=0;a[h];h++)e=a[h],e.nodeType===3||e.nodeType===4?b+=e.nodeValue:e.nodeType!==8&&(b+=d.getText(e.childNodes));return b};(function(){var a=document.createElement("div"),b="script"+(new Date).getTime();a.innerHTML="<a name='"+b+"'/>";var e=document.documentElement;
+e.insertBefore(a,e.firstChild);if(document.getElementById(b))n.find.ID=function(a,b,e){if(typeof b.getElementById!=="undefined"&&!e)return(b=b.getElementById(a[1]))?b.id===a[1]||typeof b.getAttributeNode!=="undefined"&&b.getAttributeNode("id").nodeValue===a[1]?[b]:void 0:[]},n.filter.ID=function(a,b){var e=typeof a.getAttributeNode!=="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&e&&e.nodeValue===b};e.removeChild(a);e=a=null})();(function(){var a=document.createElement("div");a.appendChild(document.createComment(""));
+if(a.getElementsByTagName("*").length>0)n.find.TAG=function(a,b){var e=b.getElementsByTagName(a[1]);if(a[1]==="*"){for(var d=[],h=0;e[h];h++)e[h].nodeType===1&&d.push(e[h]);e=d}return e};a.innerHTML="<a href='#'></a>";if(a.firstChild&&typeof a.firstChild.getAttribute!=="undefined"&&a.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(a){return a.getAttribute("href",2)};a=null})();document.querySelectorAll&&function(){var a=d,b=document.createElement("div");b.innerHTML="<p class='TEST'></p>";
+if(!(b.querySelectorAll&&b.querySelectorAll(".TEST").length===0)){d=function(b,h,f,c){h=h||document;if(!c&&h.nodeType===9&&!d.isXML(h))try{return e(h.querySelectorAll(b),f)}catch(g){}return a(b,h,f,c)};for(var h in a)d[h]=a[h];b=null}}();(function(){var a=document.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(a.getElementsByClassName&&a.getElementsByClassName("e").length!==0&&(a.lastChild.className="e",a.getElementsByClassName("e").length!==1))n.order.splice(1,
+0,"CLASS"),n.find.CLASS=function(a,b,e){if(typeof b.getElementsByClassName!=="undefined"&&!e)return b.getElementsByClassName(a[1])},a=null})();d.contains=document.compareDocumentPosition?function(a,b){return!!(a.compareDocumentPosition(b)&16)}:function(a,b){return a!==b&&(a.contains?a.contains(b):!0)};d.isXML=function(a){return(a=(a?a.ownerDocument||a:0).documentElement)?a.nodeName!=="HTML":!1};var u=function(a,b){for(var e=[],h="",f,c=b.nodeType?[b]:b;f=n.match.PSEUDO.exec(a);)h+=f[0],a=a.replace(n.match.PSEUDO,
+"");a=n.relative[a]?a+"*":a;f=0;for(var g=c.length;f<g;f++)d(a,c[f],e);return d.filter(h,e)};window.tinymce.dom.Sizzle=d})();
+(function(c){var i=c.each,j=c.DOM,g=c.isIE,b;c.create("tinymce.dom.EventUtils",{EventUtils:function(){this.inits=[];this.events=[]},add:function(a,b,d,n){var k,m=this,o=m.events,e;if(b instanceof Array)return e=[],i(b,function(b){e.push(m.add(a,b,d,n))}),e;if(a&&a.hasOwnProperty&&a instanceof Array)return e=[],i(a,function(a){a=j.get(a);e.push(m.add(a,b,d,n))}),e;if(a=j.get(a)){k=function(a){if(!m.disabled){if((a=a||window.event)&&g){if(!a.target)a.target=a.srcElement;c.extend(a,m._stoppers)}if(!n)return d(a);
+return d.call(n,a)}};if(b=="unload")return c.unloads.unshift({func:k}),k;if(b=="init")return m.domLoaded?k():m.inits.push(k),k;o.push({obj:a,name:b,func:d,cfunc:k,scope:n});m._add(a,b,k);return d}},remove:function(a,b,d){var c=this,g=c.events,m=!1,o;if(a&&a.hasOwnProperty&&a instanceof Array)return o=[],i(a,function(a){a=j.get(a);o.push(c.remove(a,b,d))}),o;a=j.get(a);i(g,function(e,h){if(e.obj==a&&e.name==b&&(!d||e.func==d||e.cfunc==d))return g.splice(h,1),c._remove(a,b,e.cfunc),m=!0,!1});return m},
+clear:function(a){var b=this.events,d,c;if(a){a=j.get(a);for(d=b.length-1;d>=0;d--)if(c=b[d],c.obj===a)this._remove(c.obj,c.name,c.cfunc),c.obj=c.cfunc=null,b.splice(d,1)}},cancel:function(a){if(!a)return!1;this.stop(a);return this.prevent(a)},stop:function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0;return!1},prevent:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1;return!1},destroy:function(){var a=this;i(a.events,function(b){a._remove(b.obj,b.name,b.cfunc);b.obj=
+b.cfunc=null});a.events=[];a=null},_add:function(a,b,d){a.attachEvent?a.attachEvent("on"+b,d):a.addEventListener?a.addEventListener(b,d,!1):a["on"+b]=d},_remove:function(a,b,d){if(a)try{a.detachEvent?a.detachEvent("on"+b,d):a.removeEventListener?a.removeEventListener(b,d,!1):a["on"+b]=null}catch(c){}},_pageInit:function(){if(!this.domLoaded)this.domLoaded=!0,i(this.inits,function(a){a()}),this.inits=[]},_wait:function(a){var b=this,d=a.document;a.tinyMCE_GZ&&tinyMCE_GZ.loaded?b.domLoaded=1:(d.attachEvent?
+(d.attachEvent("onreadystatechange",function(){d.readyState==="complete"&&(d.detachEvent("onreadystatechange",arguments.callee),b._pageInit(a))}),d.documentElement.doScroll&&a==a.top&&function(){if(!b.domLoaded){try{d.documentElement.doScroll("left")}catch(c){setTimeout(arguments.callee,0);return}b._pageInit(a)}}()):d.addEventListener&&b._add(a,"DOMContentLoaded",function(){b._pageInit(a)}),b._add(a,"load",function(){b._pageInit(a)}))},_stoppers:{preventDefault:function(){this.returnValue=!1},stopPropagation:function(){this.cancelBubble=
+!0}}});b=c.dom.Event=new c.dom.EventUtils;b._wait(window);c.addUnload(function(){b.destroy()})})(tinymce);
+(function(c){c.dom.Element=function(i,j){var g=this,b;g.settings=j=j||{};g.id=i;g.dom=b=j.dom||c.DOM;c.isIE||b.get(g.id);c.each("getPos,getRect,getParent,add,setStyle,getStyle,setStyles,setAttrib,setAttribs,getAttrib,addClass,removeClass,hasClass,getOuterHTML,setOuterHTML,remove,show,hide,isHidden,setHTML,get".split(/,/),function(a){g[a]=function(){var c=[i],d;for(d=0;d<arguments.length;d++)c.push(arguments[d]);c=b[a].apply(b,c);g.update(a);return c}});c.extend(g,{on:function(a,b,d){return c.dom.Event.add(g.id,
+a,b,d)},getXY:function(){return{x:parseInt(g.getStyle("left")),y:parseInt(g.getStyle("top"))}},getSize:function(){var a=b.get(g.id);return{w:parseInt(g.getStyle("width")||a.clientWidth),h:parseInt(g.getStyle("height")||a.clientHeight)}},moveTo:function(a,b){g.setStyles({left:a,top:b})},moveBy:function(a,b){var d=g.getXY();g.moveTo(d.x+a,d.y+b)},resizeTo:function(a,b){g.setStyles({width:a,height:b})},resizeBy:function(a,b){var d=g.getSize();g.resizeTo(d.w+a,d.h+b)},update:function(a){if(c.isIE6&&j.blocker&&
+(a=a||"",!(a.indexOf("get")===0||a.indexOf("has")===0||a.indexOf("is")===0)))a=="remove"?b.remove(g.blocker):(g.blocker?a=b.get(g.blocker):(g.blocker=b.uniqueId(),a=b.add(j.container||b.getRoot(),"iframe",{id:g.blocker,style:"position:absolute;",frameBorder:0,src:'javascript:""'}),b.setStyle(a,"opacity",0)),b.setStyles(a,{left:g.getStyle("left",1),top:g.getStyle("top",1),width:g.getStyle("width",1),height:g.getStyle("height",1),display:g.getStyle("display",1),zIndex:parseInt(g.getStyle("zIndex",1)||
+0)-1}))}})}})(tinymce);
+(function(c){var i=c.is,j=c.isIE,g=c.each;c.create("tinymce.dom.Selection",{Selection:function(b,a,f){var d=this;d.dom=b;d.win=a;d.serializer=f;g(["onBeforeSetContent","onBeforeGetContent","onSetContent","onGetContent"],function(a){d[a]=new c.util.Dispatcher(d)});if(!d.win.getSelection)d.tridentSel=new c.dom.TridentSelection(d);c.isIE&&b.boxModel&&this._fixIESelection();c.addUnload(d.destroy,d)},getContent:function(b){var a=this.getRng(),c=this.dom.create("body"),d=this.getSel(),g,k,b=b||{};g=k="";
+b.get=!0;b.format=b.format||"html";this.onBeforeGetContent.dispatch(this,b);if(b.format=="text")return this.isCollapsed()?"":a.text||(d.toString?d.toString():"");a.cloneContents?(a=a.cloneContents())&&c.appendChild(a):c.innerHTML=i(a.item)||i(a.htmlText)?a.item?a.item(0).outerHTML:a.htmlText:a.toString();/^\s/.test(c.innerHTML)&&(g=" ");/\s+$/.test(c.innerHTML)&&(k=" ");b.getInner=!0;b.content=this.isCollapsed()?"":g+this.serializer.serialize(c,b)+k;this.onGetContent.dispatch(this,b);return b.content},
+setContent:function(b,a){var c=this.getRng(),d,g=this.win.document,k,a=a||{format:"html"};a.set=!0;a.content=b;a.no_events||this.onBeforeSetContent.dispatch(this,a);b=a.content;c.insertNode?(b+='<span id="__caret">_</span>',c.startContainer==g&&c.endContainer==g?g.body.innerHTML=b:(c.deleteContents(),g.body.childNodes.length==0?g.body.innerHTML=b:c.createContextualFragment?c.insertNode(c.createContextualFragment(b)):(d=g.createDocumentFragment(),k=g.createElement("div"),d.appendChild(k),k.outerHTML=
+b,c.insertNode(d))),d=this.dom.get("__caret"),c=g.createRange(),c.setStartBefore(d),c.setEndBefore(d),this.setRng(c),this.dom.remove("__caret"),this.setRng(c)):(c.item&&(g.execCommand("Delete",!1,null),c=this.getRng()),c.pasteHTML(b));a.no_events||this.onSetContent.dispatch(this,a)},getStart:function(){var d;var b=this.getRng(),a,c;if(b.duplicate||b.item){if(b.item)return b.item(0);a=b.duplicate();a.collapse(1);a=a.parentElement();for(d=c=b.parentElement(),b=d;c=c.parentNode;)if(c==a){a=b;break}}else if(a=
+b.startContainer,a.nodeType==1&&a.hasChildNodes()&&(a=a.childNodes[Math.min(a.childNodes.length-1,b.startOffset)]),a&&a.nodeType==3)return a.parentNode;return a},getEnd:function(){var b=this.getRng(),a;if(b.duplicate||b.item){if(b.item)return b.item(0);b=b.duplicate();b.collapse(0);if((a=b.parentElement())&&a.nodeName=="BODY")return a.lastChild||a}else if(a=b.endContainer,b=b.endOffset,a.nodeType==1&&a.hasChildNodes()&&(a=a.childNodes[b>0?b-1:b]),a&&a.nodeType==3)return a.parentNode;return a},getBookmark:function(b,
+a){function c(a,b){var e=0;g(i.select(a),function(a,d){a==b&&(e=d)});return e}var d=this,i=d.dom,k,j,o,e,h;if(b==2)return function(){function b(e,c){var f=e[c?"startContainer":"endContainer"],g=e[c?"startOffset":"endOffset"],l=[],k,i=0;if(f.nodeType==3){if(a)for(k=f.previousSibling;k&&k.nodeType==3;k=k.previousSibling)g+=k.nodeValue.length;l.push(g)}else k=f.childNodes,g>=k.length&&k.length&&(i=1,g=Math.max(0,k.length-1)),l.push(d.dom.nodeIndex(k[g],a)+i);for(;f&&f!=h;f=f.parentNode)l.push(d.dom.nodeIndex(f,
+a));return l}var e=d.getRng(!0),h=i.getRoot(),c={};c.start=b(e,!0);if(!d.isCollapsed())c.end=b(e);return c}();if(b)return{rng:d.getRng()};k=d.getRng();o=i.uniqueId();e=tinyMCE.activeEditor.selection.isCollapsed();if(k.duplicate||k.item)if(k.item)return h=k.item(0),j=h.nodeName,{name:j,index:c(j,h)};else{j=k.duplicate();try{k.collapse(),k.pasteHTML('<span data-mce-type="bookmark" id="'+o+'_start" style="overflow:hidden;line-height:0px">\ufeff</span>'),e||(j.collapse(!1),k.moveToElementText(j.parentElement()),
+k.compareEndPoints("StartToEnd",j)==0&&j.move("character",-1),j.pasteHTML('<span data-mce-type="bookmark" id="'+o+'_end" style="overflow:hidden;line-height:0px">\ufeff</span>'))}catch(p){return null}}else{h=d.getNode();j=h.nodeName;if(j=="IMG")return{name:j,index:c(j,h)};j=k.cloneRange();e||(j.collapse(!1),j.insertNode(i.create("span",{"data-mce-type":"bookmark",id:o+"_end",style:"overflow:hidden;line-height:0px"},"\ufeff")));k.collapse(!0);k.insertNode(i.create("span",{"data-mce-type":"bookmark",
+id:o+"_start",style:"overflow:hidden;line-height:0px"},"\ufeff"))}d.moveToBookmark({id:o,keep:1});return{id:o}},moveToBookmark:function(b){var a=this.dom,f,d,i,k,m,o;this.tridentSel&&this.tridentSel.destroy();if(b)if(b.start){f=a.createRng();d=a.getRoot();var e=function(a){var e=b[a?"start":"end"],h,c,g;if(e){g=e[0];c=d;for(h=e.length-1;h>=1;h--){c=c.childNodes;if(e[h]>c.length-1)return;c=c[e[h]]}c.nodeType===3&&(g=Math.min(e[0],c.nodeValue.length));c.nodeType===1&&(g=Math.min(e[0],c.childNodes.length));
+a?f.setStart(c,g):f.setEnd(c,g)}return!0};e(!0)&&e()&&this.setRng(f)}else if(b.id){var e=function(e){var d=a.get(b.id+"_"+e),h,f,j;j=b.keep;if(d&&(h=d.parentNode,e=="start"?(j?(h=d.firstChild,f=1):f=a.nodeIndex(d),i=k=h,m=o=f):(j?(h=d.firstChild,f=1):f=a.nodeIndex(d),k=h,o=f),!j)){j=d.previousSibling;h=d.nextSibling;for(g(c.grep(d.childNodes),function(a){if(a.nodeType==3)a.nodeValue=a.nodeValue.replace(/\uFEFF/g,"")});d=a.get(b.id+"_"+e);)a.remove(d,1);if(j&&h&&j.nodeType==h.nodeType&&j.nodeType==
+3&&!c.isOpera)f=j.nodeValue.length,j.appendData(h.nodeValue),a.remove(h),e=="start"?(i=k=j,m=o=f):(k=j,o=f)}},h=function(b){if(a.isBlock(b)&&!b.innerHTML)b.innerHTML=!j?'<br data-mce-bogus="1" />':" ";return b};e("start");e("end");i&&(f=a.createRng(),f.setStart(h(i),m),f.setEnd(h(k),o),this.setRng(f))}else b.name?this.select(a.select(b.name)[b.index]):b.rng&&this.setRng(b.rng)},select:function(b,a){var f=this.dom,d=f.createRng();b&&(f=f.nodeIndex(b),d.setStart(b.parentNode,f),d.setEnd(b.parentNode,
+f+1),a&&(f=function(a,b){var f=new c.dom.TreeWalker(a,a);do{if(a.nodeType==3&&c.trim(a.nodeValue).length!=0){b?d.setStart(a,0):d.setEnd(a,a.nodeValue.length);break}if(a.nodeName=="BR"){b?d.setStartBefore(a):d.setEndBefore(a);break}}while(a=b?f.next():f.prev())},f(b,1),f(b)),this.setRng(d));return b},isCollapsed:function(){var b=this.getRng(),a=this.getSel();if(!b||b.item)return!1;if(b.compareEndPoints)return b.compareEndPoints("StartToEnd",b)===0;return!a||b.collapsed},collapse:function(b){var a=
+this.getRng(),c;a.item&&(c=a.item(0),a=this.win.document.body.createTextRange(),a.moveToElementText(c));a.collapse(!!b);this.setRng(a)},getSel:function(){var b=this.win;return b.getSelection?b.getSelection():b.document.selection},getRng:function(b){var a,f,d=this.win.document;if(b&&this.tridentSel)return this.tridentSel.getRangeAt(0);try{if(a=this.getSel())f=a.rangeCount>0?a.getRangeAt(0):a.createRange?a.createRange():d.createRange()}catch(g){}c.isIE&&f&&f.setStart&&d.selection.createRange().item&&
+(b=d.selection.createRange().item(0),f=d.createRange(),f.setStartBefore(b),f.setEndAfter(b));f||(f=d.createRange?d.createRange():d.body.createTextRange());if(this.selectedRange&&this.explicitRange)f.compareBoundaryPoints(f.START_TO_START,this.selectedRange)===0&&f.compareBoundaryPoints(f.END_TO_END,this.selectedRange)===0?f=this.explicitRange:this.explicitRange=this.selectedRange=null;return f},setRng:function(b){var a;if(this.tridentSel)if(b.cloneRange)this.tridentSel.addRange(b);else try{b.select()}catch(c){}else if(a=
+this.getSel()){this.explicitRange=b;try{a.removeAllRanges()}catch(d){}a.addRange(b);this.selectedRange=a.getRangeAt(0)}},setNode:function(b){this.setContent(this.dom.getOuterHTML(b));return b},getNode:function(){var b=this.getRng();this.getSel();var a,c=b.startContainer,d=b.endContainer;if(!b)return this.dom.getRoot();if(b.setStart){a=b.commonAncestorContainer;if(!b.collapsed&&(b.startContainer==b.endContainer&&b.endOffset-b.startOffset<2&&b.startContainer.hasChildNodes()&&(a=b.startContainer.childNodes[b.startOffset]),
+c.nodeType===3&&d.nodeType===3)){var g=function(a,b){for(var d=a;a&&a.nodeType===3&&a.length===0;)a=b?a.nextSibling:a.previousSibling;return a||d},c=c.length===b.startOffset?g(c.nextSibling,!0):c.parentNode,d=b.endOffset===0?g(d.previousSibling,!1):d.parentNode;if(c&&c===d)return c}if(a&&a.nodeType==3)return a.parentNode;return a}return b.item?b.item(0):b.parentElement()},getSelectedBlocks:function(b,a){var c=this.dom,d,g,k,j=[];d=c.getParent(b||this.getStart(),c.isBlock);g=c.getParent(a||this.getEnd(),
+c.isBlock);d&&j.push(d);if(d&&g&&d!=g)for(k=d;(k=k.nextSibling)&&k!=g;)c.isBlock(k)&&j.push(k);g&&d!=g&&j.push(g);return j},destroy:function(b){this.win=null;this.tridentSel&&this.tridentSel.destroy();b||c.removeUnload(this.destroy)},_fixIESelection:function(){function b(a,b){var e=k.createTextRange();try{e.moveToPoint(a,b)}catch(d){e=null}return e}function a(a){if(a.button){if(a=b(a.x,a.y))a.compareEndPoints("StartToStart",i)>0?a.setEndPoint("StartToStart",i):a.setEndPoint("EndToEnd",i),a.select()}else c()}
+function c(){var b=g.selection.createRange();i&&!b.item&&b.compareEndPoints("StartToEnd",b)===0&&i.select();d.unbind(g,"mouseup",c);d.unbind(g,"mousemove",a);i=j=0}var d=this.dom,g=d.doc,k=g.body,j,i,e;g.documentElement.unselectable=!0;d.bind(g,["mousedown","contextmenu"],function(h){if(h.target.nodeName==="HTML"&&(j&&c(),e=g.documentElement,!(e.scrollHeight>e.clientHeight)&&(j=1,i=b(h.x,h.y))))d.bind(g,"mouseup",c),d.bind(g,"mousemove",a),d.win.focus(),i.select()})}})})(tinymce);
+(function(c){c.dom.Serializer=function(i,j,g){var b,a,f=c.isIE,d=c.each,n;if(!i.apply_source_formatting)i.indent=!1;i.remove_trailing_brs=!0;j=j||c.DOM;g=g||new c.html.Schema(i);i.entity_encoding=i.entity_encoding||"named";b=new c.util.Dispatcher(self);a=new c.util.Dispatcher(self);n=new c.html.DomParser(i,g);n.addAttributeFilter("src,href,style",function(a,b){for(var d=a.length,e,c,f="data-mce-"+b,g=i.url_converter,l=i.url_converter_scope;d--;)e=a[d],c=e.attributes.map[f],c!==void 0?(e.attr(b,c.length>
+0?c:null),e.attr(f,null)):(c=e.attributes.map[b],b==="style"?c=j.serializeStyle(j.parseStyle(c),e.name):g&&(c=g.call(l,c,b,e.name)),e.attr(b,c.length>0?c:null))});n.addAttributeFilter("class",function(a){for(var b=a.length,d,e;b--;)d=a[b],e=d.attr("class").replace(/\s*mce(Item\w+|Selected)\s*/g,""),d.attr("class",e.length>0?e:null)});n.addAttributeFilter("data-mce-type",function(a,b,d){for(var b=a.length,e;b--;)e=a[b],e.attributes.map["data-mce-type"]==="bookmark"&&!d.cleanup&&e.remove()});n.addNodeFilter("script,style",
+function(a,b){function d(a){return a.replace(/(<\!--\[CDATA\[|\]\]--\>)/g,"\n").replace(/^[\r\n]*|[\r\n]*$/g,"").replace(/^\s*(\/\/\s*<\!--|\/\/\s*<!\[CDATA\[|<\!--|<!\[CDATA\[)[\r\n]*/g,"").replace(/\s*(\/\/\s*\]\]>|\/\/\s*--\>|\]\]>|--\>|\]\]--\>)\s*$/g,"")}for(var e=a.length,c,f;e--;)if(c=a[e],f=c.firstChild?c.firstChild.value:"",b==="script"){if(c.attr("type",(c.attr("type")||"text/javascript").replace(/^mce\-/,"")),f.length>0)c.firstChild.value="// <![CDATA[\n"+d(f)+"\n// ]]\>"}else if(f.length>
+0)c.firstChild.value="<\!--\n"+d(f)+"\n--\>"});n.addNodeFilter("#comment",function(a){for(var b=a.length,d;b--;)if(d=a[b],d.value.indexOf("[CDATA[")===0)d.name="#cdata",d.type=4,d.value=d.value.replace(/^\[CDATA\[|\]\]$/g,"");else if(d.value.indexOf("mce:protected ")===0)d.name="#text",d.type=3,d.raw=!0,d.value=unescape(d.value).substr(14)});n.addNodeFilter("xml:namespace,input",function(a,b){for(var d=a.length,e;d--;)e=a[d],e.type===7?e.remove():e.type===1&&b==="input"&&!("type"in e.attributes.map)&&
+e.attr("type","text")});i.fix_list_elements&&n.addNodeFilter("ul,ol",function(a){for(var b=a.length,d,e;b--;)d=a[b],e=d.parent,(e.name==="ul"||e.name==="ol")&&d.prev&&d.prev.name==="li"&&d.prev.append(d)});n.addAttributeFilter("data-mce-src,data-mce-href,data-mce-style",function(a,b){for(var d=a.length;d--;)a[d].attr(b,null)});return{schema:g,addNodeFilter:n.addNodeFilter,addAttributeFilter:n.addAttributeFilter,onPreProcess:b,onPostProcess:a,serialize:function(k,m){var o,e,h;f&&j.select("script,style,select").length>
+0?(o=k.innerHTML,k=k.cloneNode(!1),j.setHTML(k,o)):k=k.cloneNode(!0);o=k.ownerDocument.implementation;if(o.createHTMLDocument)e=o.createHTMLDocument(""),d(k.nodeName=="BODY"?k.childNodes:[k],function(a){e.body.appendChild(e.importNode(a,!0))}),k=k.nodeName!="BODY"?e.body.firstChild:e.body,h=j.doc,j.doc=e;m=m||{};m.format=m.format||"html";if(!m.no_events)m.node=k,b.dispatch(self,m);o=new c.html.Serializer(i,g);m.content=o.serialize(n.parse(m.getInner?k.innerHTML:c.trim(j.getOuterHTML(k),m),m));if(!m.cleanup)m.content=
+m.content.replace(/\uFEFF/g,"");m.no_events||a.dispatch(self,m);if(h)j.doc=h;m.node=null;return m.content},addRules:function(a){g.addValidElements(a)},setRules:function(a){g.setValidElements(a)}}}})(tinymce);
+(function(c){c.dom.ScriptLoader=function(){function i(a,b){function f(){j.remove(u);if(e)e.onreadystatechange=e.onload=e=null;b()}function g(){typeof console!=="undefined"&&console.log&&console.log("Failed to load: "+a)}var j=c.DOM,e,h,i,u;u=j.uniqueId();if(c.isIE6&&(h=new c.util.URI(a),i=location,h.host==i.hostname&&h.port==i.port&&h.protocol+":"==i.protocol&&h.protocol.toLowerCase()!="file")){c.util.XHR.send({url:c._addVer(h.getURI()),success:function(a){var b=j.create("script",{type:"text/javascript"});
+b.text=a;document.getElementsByTagName("head")[0].appendChild(b);j.remove(b);f()},error:g});return}e=j.create("script",{id:u,type:"text/javascript",src:c._addVer(a)});if(!c.isIE)e.onload=f;e.onerror=g;if(!c.isOpera)e.onreadystatechange=function(){var a=e.readyState;(a=="complete"||a=="loaded")&&f()};(document.getElementsByTagName("head")[0]||document.body).appendChild(e)}var j={},g=[],b={},a=[],f=0;this.isDone=function(a){return j[a]==2};this.markDone=function(a){j[a]=2};this.add=this.load=function(a,
+c,f){j[a]==void 0&&(g.push(a),j[a]=0);c&&(b[a]||(b[a]=[]),b[a].push({func:c,scope:f||this}))};this.loadQueue=function(a,b){this.loadScripts(g,a,b)};this.loadScripts=function(d,g,k){function m(a){c.each(b[a],function(a){a.func.call(a.scope)});b[a]=void 0}var o;a.push({func:g,scope:k||this});o=function(){var b=c.grep(d);d.length=0;c.each(b,function(a){j[a]==2?m(a):j[a]!=1&&(j[a]=1,f++,i(a,function(){j[a]=2;f--;m(a);o()}))});if(!f)c.each(a,function(a){a.func.call(a.scope)}),a.length=0};o()}};c.ScriptLoader=
+new c.dom.ScriptLoader})(tinymce);tinymce.dom.TreeWalker=function(c,i){function j(b,a,c,d){if(b){if(!d&&b[a])return b[a];if(b!=i){if(a=b[c])return a;for(b=b.parentNode;b&&b!=i;b=b.parentNode)if(a=b[c])return a}}}var g=c;this.current=function(){return g};this.next=function(b){return g=j(g,"firstChild","nextSibling",b)};this.prev=function(b){return g=j(g,"lastChild","previousSibling",b)}};
+(function(c){c.dom.RangeUtils=function(i){this.walk=function(j,g){function b(a,b,e){for(var d=[];a&&a!=e;a=a[b])d.push(a);return d}function a(a,b){do{if(a.parentNode==b)return a;a=a.parentNode}while(a)}function f(a,d,c){var f=c?"nextSibling":"previousSibling";o=a;for(e=o.parentNode;o&&o!=d;o=e)e=o.parentNode,h=b(o==a?o:o[f],f),h.length&&(c||h.reverse(),g(h))}var d=j.startContainer,n=j.startOffset,k=j.endContainer,m=j.endOffset,o,e,h,p;p=i.select("td.mceSelected,th.mceSelected");if(p.length>0)c.each(p,
+function(a){g([a])});else{d.nodeType==1&&d.hasChildNodes()&&(d=d.childNodes[n]);k.nodeType==1&&k.hasChildNodes()&&(k=k.childNodes[Math.min(m-1,k.childNodes.length-1)]);m=i.findCommonAncestor(d,k);if(d==k)return g([d]);for(o=d;o;o=o.parentNode){if(o==k)return f(d,m,!0);if(o==m)break}for(o=k;o;o=o.parentNode){if(o==d)return f(k,m);if(o==m)break}n=a(d,m)||d;m=a(k,m)||k;f(d,n,!0);h=b(n==d?n:n.nextSibling,"nextSibling",m==k?m.nextSibling:m);h.length&&g(h);f(k,m)}}};c.dom.RangeUtils.compareRanges=function(c,
+j){if(c&&j)if(c.item||c.duplicate){if(c.item&&j.item&&c.item(0)===j.item(0))return!0;if(c.isEqual&&j.isEqual&&j.isEqual(c))return!0}else return c.startContainer==j.startContainer&&c.startOffset==j.startOffset;return!1}})(tinymce);
+(function(c){var i=c.dom.Event,j=c.each;c.create("tinymce.ui.KeyboardNavigation",{KeyboardNavigation:function(g,b){var a=this,f=g.root,d=g.items,n=g.enableUpDown,k=g.enableLeftRight||!g.enableUpDown,m=g.excludeFromTabOrder,o,e,h,p,u,b=b||c.DOM;o=function(a){u=a.target.id};e=function(a){b.setAttrib(a.target.id,"tabindex","-1")};p=function(){var a=b.get(u);b.setAttrib(a,"tabindex","0");a.focus()};a.focus=function(){b.get(u).focus()};a.destroy=function(){j(d,function(a){b.unbind(b.get(a.id),"focus",
+o);b.unbind(b.get(a.id),"blur",e)});b.unbind(b.get(f),"focus",p);b.unbind(b.get(f),"keydown",h);d=b=f=a.focus=o=e=h=p=null;a.destroy=function(){}};a.moveFocus=function(a,e){var c=-1,h;if(u){j(d,function(a,b){if(a.id===u)return c=b,!1});c+=a;c<0?c=d.length-1:c>=d.length&&(c=0);h=d[c];b.setAttrib(u,"tabindex","-1");b.setAttrib(h.id,"tabindex","0");b.get(h.id).focus();if(g.actOnFocus)g.onAction(h.id);e&&i.cancel(e)}};h=function(b){switch(b.keyCode){case 37:k&&a.moveFocus(-1);break;case 39:k&&a.moveFocus(1);
+break;case 38:n&&a.moveFocus(-1);break;case 40:n&&a.moveFocus(1);break;case 27:g.onCancel&&(g.onCancel(),i.cancel(b));break;case 14:case 13:case 32:g.onAction&&(g.onAction(u),i.cancel(b))}};j(d,function(a,d){var c;if(!a.id)a.id=b.uniqueId("_mce_item_");m?(b.bind(a.id,"blur",e),c="-1"):c=d===0?"0":"-1";b.setAttrib(a.id,"tabindex",c);b.bind(b.get(a.id),"focus",o)});if(d[0])u=d[0].id;b.setAttrib(f,"tabindex","-1");b.bind(b.get(f),"focus",p);b.bind(b.get(f),"keydown",h)}})})(tinymce);
+(function(c){var i=c.DOM,j=c.is;c.create("tinymce.ui.Control",{Control:function(g,b,a){this.id=g;this.settings=b=b||{};this.rendered=!1;this.onRender=new c.util.Dispatcher(this);this.classPrefix="";this.scope=b.scope||this;this.active=this.disabled=0;this.editor=a},setAriaProperty:function(c,b){var a=i.get(this.id+"_aria")||i.get(this.id);a&&i.setAttrib(a,"aria-"+c,!!b)},focus:function(){i.get(this.id).focus()},setDisabled:function(c){if(c!=this.disabled)this.setAriaProperty("disabled",c),this.setState("Disabled",
+c),this.setState("Enabled",!c),this.disabled=c},isDisabled:function(){return this.disabled},setActive:function(c){if(c!=this.active)this.setState("Active",c),this.active=c,this.setAriaProperty("pressed",c)},isActive:function(){return this.active},setState:function(c,b){var a=i.get(this.id),c=this.classPrefix+c;b?i.addClass(a,c):i.removeClass(a,c)},isRendered:function(){return this.rendered},renderHTML:function(){},renderTo:function(c){i.setHTML(c,this.renderHTML())},postRender:function(){var c;if(j(this.disabled))c=
+this.disabled,this.disabled=-1,this.setDisabled(c);if(j(this.active))c=this.active,this.active=-1,this.setActive(c)},remove:function(){i.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,i,j){this.parent(c,i,j);this.controls=[];this.lookup={}},add:function(c){this.lookup[c.id]=c;this.controls.push(c);return c},get:function(c){return this.lookup[c]}});
+tinymce.create("tinymce.ui.Separator:tinymce.ui.Control",{Separator:function(c,i){this.parent(c,i);this.classPrefix="mceSeparator";this.setDisabled(!0)},renderHTML:function(){return tinymce.DOM.createHTML("span",{"class":this.classPrefix,role:"separator","aria-orientation":"vertical",tabindex:"-1"})}});
+(function(c){var i=c.is;c.create("tinymce.ui.MenuItem:tinymce.ui.Control",{MenuItem:function(c,g){this.parent(c,g);this.classPrefix="mceMenuItem"},setSelected:function(c){this.setState("Selected",c);this.setAriaProperty("checked",!!c);this.selected=c},isSelected:function(){return this.selected},postRender:function(){this.parent();i(this.selected)&&this.setSelected(this.selected)}})})(tinymce);
+(function(c){var i=c.DOM,j=c.walk;c.create("tinymce.ui.Menu:tinymce.ui.MenuItem",{Menu:function(g,b){this.parent(g,b);this.items={};this.collapsed=!1;this.menuCount=0;this.onAddItem=new c.util.Dispatcher(this)},expand:function(c){c&&j(this,function(b){b.expand&&b.expand()},"items",this);this.collapsed=!1},collapse:function(c){c&&j(this,function(b){b.collapse&&b.collapse()},"items",this);this.collapsed=!0},isCollapsed:function(){return this.collapsed},add:function(g){g.settings||(g=new c.ui.MenuItem(g.id||
+i.uniqueId(),g));this.onAddItem.dispatch(this,g);return this.items[g.id]=g},addSeparator:function(){return this.add({separator:!0})},addMenu:function(c){c.collapse||(c=this.createMenu(c));this.menuCount++;return this.add(c)},hasMenus:function(){return this.menuCount!==0},remove:function(c){delete this.items[c.id]},removeAll:function(){j(this,function(c){c.removeAll?c.removeAll():c.remove();c.destroy()},"items",this);this.items={}},createMenu:function(g){g=new c.ui.Menu(g.id||i.uniqueId(),g);g.onAddItem.add(this.onAddItem.dispatch,
+this.onAddItem);return g}})})(tinymce);
+(function(c){var i=c.is,j=c.DOM,g=c.each,b=c.dom.Event,a=c.dom.Element;c.create("tinymce.ui.DropMenu:tinymce.ui.Menu",{DropMenu:function(a,b){b=b||{};b.container=b.container||j.doc.body;b.offset_x=b.offset_x||0;b.offset_y=b.offset_y||0;b.vp_offset_x=b.vp_offset_x||0;b.vp_offset_y=b.vp_offset_y||0;i(b.icons)&&!b.icons&&(b["class"]+=" mceNoIcons");this.parent(a,b);this.onShowMenu=new c.util.Dispatcher(this);this.onHideMenu=new c.util.Dispatcher(this);this.classPrefix="mceMenu"},createMenu:function(a){var b=
+this.settings;a.container=a.container||b.container;a.parent=this;a.constrain=a.constrain||b.constrain;a["class"]=a["class"]||b["class"];a.vp_offset_x=a.vp_offset_x||b.vp_offset_x;a.vp_offset_y=a.vp_offset_y||b.vp_offset_y;a.keyboard_focus=b.keyboard_focus;a=new c.ui.DropMenu(a.id||j.uniqueId(),a);a.onAddItem.add(this.onAddItem.dispatch,this.onAddItem);return a},focus:function(){this.keyboardNav&&this.keyboardNav.focus()},update:function(){var a=this.settings,b=j.get("menu_"+this.id+"_tbl"),c=j.get("menu_"+
+this.id+"_co"),g,i;g=a.max_width?Math.min(b.clientWidth,a.max_width):b.clientWidth;i=a.max_height?Math.min(b.clientHeight,a.max_height):b.clientHeight;j.boxModel?this.element.setStyles({width:g,height:i}):this.element.setStyles({width:g+2,height:i+2});a.max_width&&j.setStyle(c,"width",g);a.max_height&&(j.setStyle(c,"height",i),b.clientHeight<a.max_height&&j.setStyle(c,"overflow","hidden"))},showMenu:function(f,d,i){var k=this,m=k.settings,o,e=j.getViewPort(),h,p,u,l,s=k.classPrefix;k.collapse(1);
+if(!k.isMenuVisible){k.rendered?o=j.get("menu_"+k.id):(o=j.add(k.settings.container,k.renderNode()),g(k.items,function(a){a.postRender()}),k.element=new a("menu_"+k.id,{blocker:1,container:m.container}));c.isOpera||j.setStyles(o,{left:-65535,top:-65535});j.show(o);k.update();f+=m.offset_x||0;d+=m.offset_y||0;e.w-=4;e.h-=4;m.constrain&&(h=o.clientWidth-2,p=o.clientHeight-2,u=e.x+e.w,e=e.y+e.h,f+m.vp_offset_x+h>u&&(f=i?i-h:Math.max(0,u-m.vp_offset_x-h)),d+m.vp_offset_y+p>e&&(d=Math.max(0,e-m.vp_offset_y-
+p)));j.setStyles(o,{left:f,top:d});k.element.update();k.isMenuVisible=1;k.mouseClickFunc=b.add(o,"click",function(a){var e;if((a=a.target)&&(a=j.getParent(a,"tr"))&&!j.hasClass(a,s+"ItemSub"))if(e=k.items[a.id],!e.isDisabled()){for(l=k;l;)l.hideMenu&&l.hideMenu(),l=l.settings.parent;if(e.settings.onclick)e.settings.onclick(a);return b.cancel(a)}});if(k.hasMenus())k.mouseOverFunc=b.add(o,"mouseover",function(a){var b;if((a=a.target)&&(a=j.getParent(a,"tr")))if(b=k.items[a.id],k.lastMenu&&k.lastMenu.collapse(1),
+!b.isDisabled()&&a&&j.hasClass(a,s+"ItemSub"))a=j.getRect(a),b.showMenu(a.x+a.w-2,a.y-2,a.x),k.lastMenu=b,j.addClass(j.get(b.id).firstChild,s+"ItemActive")});b.add(o,"keydown",k._keyHandler,k);k.onShowMenu.dispatch(k);m.keyboard_focus&&k._setupKeyboardNav()}},hideMenu:function(a){var d=j.get("menu_"+this.id),c;if(this.isMenuVisible)this.keyboardNav&&this.keyboardNav.destroy(),b.remove(d,"mouseover",this.mouseOverFunc),b.remove(d,"click",this.mouseClickFunc),b.remove(d,"keydown",this._keyHandler),
+j.hide(d),this.isMenuVisible=0,a||this.collapse(1),this.element&&this.element.hide(),(c=j.get(this.id))&&j.removeClass(c.firstChild,this.classPrefix+"ItemActive"),this.onHideMenu.dispatch(this)},add:function(a){var b,a=this.parent(a);this.isRendered&&(b=j.get("menu_"+this.id))&&this._add(j.select("tbody",b)[0],a);return a},collapse:function(a){this.parent(a);this.hideMenu(1)},remove:function(a){j.remove(a.id);this.destroy();return this.parent(a)},destroy:function(){var a=j.get("menu_"+this.id);this.keyboardNav&&
+this.keyboardNav.destroy();b.remove(a,"mouseover",this.mouseOverFunc);b.remove(j.select("a",a),"focus",this.mouseOverFunc);b.remove(a,"click",this.mouseClickFunc);b.remove(a,"keydown",this._keyHandler);this.element&&this.element.remove();j.remove(a)},renderNode:function(){var b=this,d=b.settings,c,i,m;m=j.create("div",{role:"listbox",id:"menu_"+b.id,"class":d["class"],style:"position:absolute;left:0;top:0;z-index:200000;outline:0"});b.settings.parent&&j.setAttrib(m,"aria-parent","menu_"+b.settings.parent.id);
+i=j.add(m,"div",{role:"presentation",id:"menu_"+b.id+"_co","class":b.classPrefix+(d["class"]?" "+d["class"]:"")});b.element=new a("menu_"+b.id,{blocker:1,container:d.container});d.menu_line&&j.add(i,"span",{"class":b.classPrefix+"Line"});d=j.add(i,"table",{role:"presentation",id:"menu_"+b.id+"_tbl",border:0,cellPadding:0,cellSpacing:0});c=j.add(d,"tbody");g(b.items,function(a){b._add(c,a)});b.rendered=!0;return m},_setupKeyboardNav:function(){var a,b,g=this;a=j.select("#menu_"+g.id)[0];b=j.select("a[role=option]",
+"menu_"+g.id);b.splice(0,0,a);g.keyboardNav=new c.ui.KeyboardNavigation({root:"menu_"+g.id,items:b,onCancel:function(){g.hideMenu()},enableUpDown:!0});a.focus()},_keyHandler:function(a){switch(a.keyCode){case 37:this.settings.parent&&(this.hideMenu(),this.settings.parent.focus(),b.cancel(a));break;case 39:this.mouseOverFunc&&this.mouseOverFunc(a)}},_add:function(a,b){var c,g=b.settings,i,o,e,h=this.classPrefix;g.separator?(o=j.add(a,"tr",{id:b.id,"class":h+"ItemSeparator"}),j.add(o,"td",{"class":h+
+"ItemSeparator"}),(c=o.previousSibling)&&j.addClass(c,"mceLast")):(c=o=j.add(a,"tr",{id:b.id,"class":h+"Item "+h+"ItemEnabled"}),c=e=j.add(c,g.titleItem?"th":"td"),c=i=j.add(c,"a",{id:b.id+"_aria",role:g.titleItem?"presentation":"option",href:"javascript:;",onclick:"return false;",onmousedown:"return false;"}),g.parent&&(j.setAttrib(i,"aria-haspopup","true"),j.setAttrib(i,"aria-owns","menu_"+b.id)),j.addClass(e,g["class"]),i=j.add(c,"span",{"class":"mceIcon"+(g.icon?" mce_"+g.icon:"")}),g.icon_src&&
+j.add(i,"img",{src:g.icon_src}),c=j.add(c,g.element||"span",{"class":"mceText",title:b.settings.title},b.settings.title),b.settings.style&&j.setAttrib(c,"style",b.settings.style),a.childNodes.length==1&&j.addClass(o,"mceFirst"),(c=o.previousSibling)&&j.hasClass(c,h+"ItemSeparator")&&j.addClass(o,"mceFirst"),b.collapse&&j.addClass(o,h+"ItemSub"),(c=o.previousSibling)&&j.removeClass(c,"mceLast"),j.addClass(o,"mceLast"))}})})(tinymce);
+(function(c){var i=c.DOM;c.create("tinymce.ui.Button:tinymce.ui.Control",{Button:function(c,g,b){this.parent(c,g,b);this.classPrefix="mceButton"},renderHTML:function(){var c=this.classPrefix,g=this.settings,b,a;a=i.encode(g.label||"");b='<a role="button" id="'+this.id+'" href="javascript:;" class="'+c+" "+c+"Enabled "+g["class"]+(a?" "+c+"Labeled":"")+'" onmousedown="return false;" onclick="return false;" aria-labelledby="'+this.id+'_voice" title="'+i.encode(g.title)+'">';b+=g.image?'<img class="mceIcon" src="'+
+g.image+'" alt="'+i.encode(g.title)+'" />'+a:'<span class="mceIcon '+g["class"]+'"></span>'+(a?'<span class="'+c+'Label">'+a+"</span>":"");b+='<span class="mceVoiceLabel mceIconOnly" style="display: none;" id="'+this.id+'_voice">'+g.title+"</span>";b+="</a>";return b},postRender:function(){var i=this,g=i.settings;c.dom.Event.add(i.id,"click",function(b){if(!i.isDisabled())return g.onclick.call(g.scope,b)})}})})(tinymce);
+(function(c){var i=c.DOM,j=c.dom.Event,g=c.each,b=c.util.Dispatcher;c.create("tinymce.ui.ListBox:tinymce.ui.Control",{ListBox:function(a,f,d){this.parent(a,f,d);this.items=[];this.onChange=new b(this);this.onPostRender=new b(this);this.onAdd=new b(this);this.onRenderMenu=new c.util.Dispatcher(this);this.classPrefix="mceListBox"},select:function(a){var b=this,c,i;if(a==void 0)return b.selectByIndex(-1);i=a&&a.call?a:function(b){return b==a};a!=b.selectedValue&&(g(b.items,function(a,g){if(i(a.value))return c=
+1,b.selectByIndex(g),!1}),c||b.selectByIndex(-1))},selectByIndex:function(a){var b,c;if(a!=this.selectedIndex)b=i.get(this.id+"_text"),(c=this.items[a])?(this.selectedValue=c.value,this.selectedIndex=a,i.setHTML(b,i.encode(c.title)),i.removeClass(b,"mceTitle"),i.setAttrib(this.id,"aria-valuenow",c.title)):(i.setHTML(b,i.encode(this.settings.title)),i.addClass(b,"mceTitle"),this.selectedValue=this.selectedIndex=null,i.setAttrib(this.id,"aria-valuenow",this.settings.title))},add:function(a,b,d){d=d||
+{};d=c.extend(d,{title:a,value:b});this.items.push(d);this.onAdd.dispatch(this,d)},getLength:function(){return this.items.length},renderHTML:function(){var a="",a=this.settings,b=this.classPrefix,a='<span role="button" aria-haspopup="true" aria-labelledby="'+this.id+'_text" aria-describedby="'+this.id+'_voiceDesc"><table role="presentation" tabindex="0" id="'+this.id+'" cellpadding="0" cellspacing="0" class="'+b+" "+b+"Enabled"+(a["class"]?" "+a["class"]:"")+'"><tbody><tr>';a+="<td>"+i.createHTML("span",
+{id:this.id+"_voiceDesc","class":"voiceLabel",style:"display:none;"},this.settings.title);a+=i.createHTML("a",{id:this.id+"_text",tabindex:-1,href:"javascript:;","class":"mceText",onclick:"return false;",onmousedown:"return false;"},i.encode(this.settings.title))+"</td>";a+="<td>"+i.createHTML("a",{id:this.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>";a+="</tr></tbody></table></span>";return a},showMenu:function(){var a=this,b,d=i.get(this.id),n;if(!(a.isDisabled()||a.items.length==0)){if(a.menu&&a.menu.isMenuVisible)return a.hideMenu();if(!a.isMenuRendered)a.renderMenu(),a.isMenuRendered=!0;i.getPos(this.settings.menu_container);b=i.getPos(d);n=a.menu;n.settings.offset_x=b.x;n.settings.offset_y=b.y;n.settings.keyboard_focus=!c.isOpera;a.oldID&&n.items[a.oldID].setSelected(0);g(a.items,function(b){if(b.value===a.selectedValue)n.items[b.id].setSelected(1),
+a.oldID=b.id});n.showMenu(0,d.clientHeight);j.add(i.doc,"mousedown",a.hideMenu,a);i.addClass(a.id,a.classPrefix+"Selected")}},hideMenu:function(a){if(this.menu&&this.menu.isMenuVisible&&(i.removeClass(this.id,this.classPrefix+"Selected"),!a||!(a.type=="mousedown"&&(a.target.id==this.id+"_text"||a.target.id==this.id+"_open"))))if(!a||!i.getParent(a.target,".mceMenu"))i.removeClass(this.id,this.classPrefix+"Selected"),j.remove(i.doc,"mousedown",this.hideMenu,this),this.menu.hideMenu()},renderMenu:function(){var a=
+this,b;b=a.settings.control_manager.createDropMenu(a.id+"_menu",{menu_line:1,"class":a.classPrefix+"Menu mceNoIcons",max_width:150,max_height:150});b.onHideMenu.add(function(){a.hideMenu();a.focus()});b.add({title:a.settings.title,"class":"mceMenuItemTitle",onclick:function(){a.settings.onselect("")!==!1&&a.select("")}});g(a.items,function(c){c.value===void 0?b.add({title:c.title,"class":"mceMenuItemTitle",onclick:function(){a.settings.onselect("")!==!1&&a.select("")}}):(c.id=i.uniqueId(),c.onclick=
+function(){a.settings.onselect(c.value)!==!1&&a.select(c.value)},b.add(c))});a.onRenderMenu.dispatch(a,b);a.menu=b},postRender:function(){var a=this,b=a.classPrefix;j.add(a.id,"click",a.showMenu,a);j.add(a.id,"keydown",function(b){b.keyCode==32&&(a.showMenu(b),j.cancel(b))});j.add(a.id,"focus",function(){if(!a._focused)a.keyDownHandler=j.add(a.id,"keydown",function(b){b.keyCode==40&&(a.showMenu(),j.cancel(b))}),a.keyPressHandler=j.add(a.id,"keypress",function(b){var c;if(b.keyCode==13)c=a.selectedValue,
+a.selectedValue=null,j.cancel(b),a.settings.onselect(c)});a._focused=1});j.add(a.id,"blur",function(){j.remove(a.id,"keydown",a.keyDownHandler);j.remove(a.id,"keypress",a.keyPressHandler);a._focused=0});if(c.isIE6||!i.boxModel)j.add(a.id,"mouseover",function(){i.hasClass(a.id,b+"Disabled")||i.addClass(a.id,b+"Hover")}),j.add(a.id,"mouseout",function(){i.hasClass(a.id,b+"Disabled")||i.removeClass(a.id,b+"Hover")});a.onPostRender.dispatch(a,i.get(a.id))},destroy:function(){this.parent();j.clear(this.id+
+"_text");j.clear(this.id+"_open")}})})(tinymce);
+(function(c){var i=c.DOM,j=c.dom.Event,g=c.each;c.create("tinymce.ui.NativeListBox:tinymce.ui.ListBox",{NativeListBox:function(b,a){this.parent(b,a);this.classPrefix="mceNativeListBox"},setDisabled:function(b){i.get(this.id).disabled=b;this.setAriaProperty("disabled",b)},isDisabled:function(){return i.get(this.id).disabled},select:function(b){var a=this,c,d;if(b==void 0)return a.selectByIndex(-1);d=b&&b.call?b:function(a){return a==b};b!=a.selectedValue&&(g(a.items,function(b,g){if(d(b.value))return c=
+1,a.selectByIndex(g),!1}),c||a.selectByIndex(-1))},selectByIndex:function(b){i.get(this.id).selectedIndex=b+1;this.selectedValue=this.items[b]?this.items[b].value:null},add:function(b,a,c){c=c||{};c.value=a;this.isRendered()&&i.add(i.get(this.id),"option",c,b);b={title:b,value:a,attribs:c};this.items.push(b);this.onAdd.dispatch(this,b)},getLength:function(){return this.items.length},renderHTML:function(){var b;b=i.createHTML("option",{value:""},"-- "+this.settings.title+" --");g(this.items,function(a){b+=
+i.createHTML("option",{value:a.value},a.title)});b=i.createHTML("select",{id:this.id,"class":"mceNativeListBox","aria-labelledby":this.id+"_aria"},b);b+=i.createHTML("span",{id:this.id+"_aria",style:"display: none"},this.settings.title);return b},postRender:function(){function b(b){if((b=a.items[b.target.selectedIndex-1])&&(b=b.value))if(a.onChange.dispatch(a,b),a.settings.onselect)a.settings.onselect(b)}var a=this,c=!0;a.rendered=!0;j.add(a.id,"change",b);j.add(a.id,"keydown",function(d){var g;j.remove(a.id,
+"change",void 0);c=!1;g=j.add(a.id,"blur",function(){c||(c=!0,j.add(a.id,"change",b),j.remove(a.id,"blur",g))});if(d.keyCode==13||d.keyCode==32)return b(d),j.cancel(d)});a.onPostRender.dispatch(a,i.get(a.id))}})})(tinymce);
+(function(c){var i=c.DOM,j=c.dom.Event;c.create("tinymce.ui.MenuButton:tinymce.ui.Button",{MenuButton:function(g,b,a){this.parent(g,b,a);this.onRenderMenu=new c.util.Dispatcher(this);b.menu_container=b.menu_container||i.doc.body},showMenu:function(){var c,b=i.get(this.id),a;if(!this.isDisabled()){if(!this.isMenuRendered)this.renderMenu(),this.isMenuRendered=!0;if(this.isMenuVisible)return this.hideMenu();i.getPos(this.settings.menu_container);c=i.getPos(b);a=this.menu;a.settings.offset_x=c.x;a.settings.offset_y=
+c.y;a.settings.vp_offset_x=c.x;a.settings.vp_offset_y=c.y;a.settings.keyboard_focus=this._focused;a.showMenu(0,b.clientHeight);j.add(i.doc,"mousedown",this.hideMenu,this);this.setState("Selected",1);this.isMenuVisible=1}},renderMenu:function(){var c=this,b;b=c.settings.control_manager.createDropMenu(c.id+"_menu",{menu_line:1,"class":this.classPrefix+"Menu",icons:c.settings.icons});b.onHideMenu.add(function(){c.hideMenu();c.focus()});c.onRenderMenu.dispatch(c,b);c.menu=b},hideMenu:function(c){var b=
+this;if(!c||!(c.type=="mousedown"&&i.getParent(c.target,function(a){return a.id===b.id||a.id===b.id+"_open"}))){if(!c||!i.getParent(c.target,".mceMenu"))b.setState("Selected",0),j.remove(i.doc,"mousedown",b.hideMenu,b),b.menu&&b.menu.hideMenu();b.isMenuVisible=0}},postRender:function(){var c=this,b=c.settings;j.add(c.id,"click",function(){if(!c.isDisabled()){if(b.onclick)b.onclick(c.value);c.showMenu()}})}})})(tinymce);
+(function(c){var i=c.DOM,j=c.dom.Event;c.create("tinymce.ui.SplitButton:tinymce.ui.MenuButton",{SplitButton:function(c,b,a){this.parent(c,b,a);this.classPrefix="mceSplitButton"},renderHTML:function(){var c,b=this.settings,a;c="<tbody><tr>";a=b.image?i.createHTML("img ",{src:b.image,role:"presentation","class":"mceAction "+b["class"]}):i.createHTML("span",{"class":"mceAction "+b["class"]},"");a+=i.createHTML("span",{"class":"mceVoiceLabel mceIconOnly",id:this.id+"_voice",style:"display:none;"},b.title);
+c+="<td >"+i.createHTML("a",{role:"button",id:this.id+"_action",tabindex:"-1",href:"javascript:;","class":"mceAction "+b["class"],onclick:"return false;",onmousedown:"return false;",title:b.title},a)+"</td>";a=i.createHTML("span",{"class":"mceOpen "+b["class"]},'<span style="display:none;" class="mceIconOnly" aria-hidden="true">\u25bc</span>');c+="<td >"+i.createHTML("a",{role:"button",id:this.id+"_open",tabindex:"-1",href:"javascript:;","class":"mceOpen "+b["class"],onclick:"return false;",onmousedown:"return false;",
+title:b.title},a)+"</td>";c+="</tr></tbody>";c=i.createHTML("table",{id:this.id,role:"presentation",tabindex:"0","class":"mceSplitButton mceSplitButtonEnabled "+b["class"],cellpadding:"0",cellspacing:"0",title:b.title},c);return i.createHTML("span",{role:"button","aria-labelledby":this.id+"_voice","aria-haspopup":"true"},c)},postRender:function(){var g=this,b=g.settings,a;b.onclick&&(a=function(a){g.isDisabled()||(b.onclick(g.value),j.cancel(a))},j.add(g.id+"_action","click",a),j.add(g.id,["click",
+"keydown"],function(b){if((b.keyCode===32||b.keyCode===13||b.keyCode===14)&&!b.altKey&&!b.ctrlKey&&!b.metaKey)a(),j.cancel(b);else if(b.type==="click"||b.keyCode===40)g.showMenu(),j.cancel(b)}));j.add(g.id+"_open","click",function(a){g.showMenu();j.cancel(a)});j.add([g.id,g.id+"_open"],"focus",function(){g._focused=1});j.add([g.id,g.id+"_open"],"blur",function(){g._focused=0});if(c.isIE6||!i.boxModel)j.add(g.id,"mouseover",function(){i.hasClass(g.id,"mceSplitButtonDisabled")||i.addClass(g.id,"mceSplitButtonHover")}),
+j.add(g.id,"mouseout",function(){i.hasClass(g.id,"mceSplitButtonDisabled")||i.removeClass(g.id,"mceSplitButtonHover")})},destroy:function(){this.parent();j.clear(this.id+"_action");j.clear(this.id+"_open");j.clear(this.id)}})})(tinymce);
+(function(c){var i=c.DOM,j=c.dom.Event,g=c.is,b=c.each;c.create("tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton",{ColorSplitButton:function(a,b,d){this.parent(a,b,d);this.settings=b=c.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"},
+this.settings);this.onShowMenu=new c.util.Dispatcher(this);this.onHideMenu=new c.util.Dispatcher(this);this.value=b.default_color},showMenu:function(){var a=this,b,c;if(!a.isDisabled()){if(!a.isMenuRendered)a.renderMenu(),a.isMenuRendered=!0;if(a.isMenuVisible)return a.hideMenu();b=i.get(a.id);i.show(a.id+"_menu");i.addClass(b,"mceSplitButtonSelected");c=i.getPos(b);i.setStyles(a.id+"_menu",{left:c.x,top:c.y+b.clientHeight,zIndex:2E5});b=0;j.add(i.doc,"mousedown",a.hideMenu,a);a.onShowMenu.dispatch(a);
+if(a._focused)a._keyHandler=j.add(a.id+"_menu","keydown",function(b){b.keyCode==27&&a.hideMenu()}),i.select("a",a.id+"_menu")[0].focus();a.isMenuVisible=1}},hideMenu:function(a){var b=this;if(b.isMenuVisible&&(!a||!(a.type=="mousedown"&&i.getParent(a.target,function(a){return a.id===b.id+"_open"})))){if(!a||!i.getParent(a.target,".mceSplitButtonMenu"))i.removeClass(b.id,"mceSplitButtonSelected"),j.remove(i.doc,"mousedown",b.hideMenu,b),j.remove(b.id+"_menu","keydown",b._keyHandler),i.hide(b.id+"_menu");
+b.isMenuVisible=0}},renderMenu:function(){var a=this,f,d=0,n=a.settings,k,m,o,e,h;e=i.add(n.menu_container,"div",{role:"listbox",id:a.id+"_menu","class":n.menu_class+" "+n["class"],style:"position:absolute;left:0;top:-1000px;"});f=i.add(e,"div",{"class":n["class"]+" mceSplitButtonMenu"});i.add(f,"span",{"class":"mceMenuLine"});k=i.add(f,"table",{role:"presentation","class":"mceColorSplitMenu"});m=i.add(k,"tbody");d=0;b(g(n.colors,"array")?n.colors:n.colors.split(","),function(b){b=b.replace(/^#/,
+"");d--||(o=i.add(m,"tr"),d=n.grid_width-1);k=i.add(o,"td");k=i.add(k,"a",{role:"option",href:"javascript:;",style:{backgroundColor:"#"+b},title:a.editor.getLang("colors."+b,b),"data-mce-color":"#"+b});if(a.editor.forcedHighContrastMode)k=i.add(k,"canvas",{width:16,height:16,"aria-hidden":"true"}),k.getContext&&(h=k.getContext("2d"))?(h.fillStyle="#"+b,h.fillRect(0,0,16,16)):i.remove(k)});n.more_colors_func&&(k=i.add(m,"tr"),k=i.add(k,"td",{colspan:n.grid_width,"class":"mceMoreColors"}),k=i.add(k,
+"a",{role:"option",id:a.id+"_more",href:"javascript:;",onclick:"return false;","class":"mceMoreColors"},n.more_colors_title),j.add(k,"click",function(a){n.more_colors_func.call(n.more_colors_scope||this);return j.cancel(a)}));i.addClass(f,"mceColorSplitMenu");new c.ui.KeyboardNavigation({root:a.id+"_menu",items:i.select("a",a.id+"_menu"),onCancel:function(){a.hideMenu();a.focus()}});j.add(a.id+"_menu","mousedown",function(a){return j.cancel(a)});j.add(a.id+"_menu","click",function(b){var e;(b=i.getParent(b.target,
+"a",m))&&b.nodeName.toLowerCase()=="a"&&(e=b.getAttribute("data-mce-color"))&&a.setColor(e);return j.cancel(b)});return e},setColor:function(a){this.displayColor(a);this.hideMenu();this.settings.onselect(a)},displayColor:function(a){i.setStyle(this.id+"_preview","backgroundColor",a);this.value=a},postRender:function(){var a=this.id;this.parent();i.add(a+"_action","div",{id:a+"_preview","class":"mceColorPreview"});i.setStyle(this.id+"_preview","backgroundColor",this.value)},destroy:function(){this.parent();
+j.clear(this.id+"_menu");j.clear(this.id+"_more");i.remove(this.id+"_menu")}})})(tinymce);
+(function(c){var i=c.DOM,j=c.each,g=c.dom.Event;c.create("tinymce.ui.ToolbarGroup:tinymce.ui.Container",{renderHTML:function(){var b=[],a=this.controls,f=c.each,d=this.settings;b.push('<div id="'+this.id+'" role="group" aria-labelledby="'+this.id+'_voice">');b.push("<span role='application'>");b.push('<span id="'+this.id+'_voice" class="mceVoiceLabel" style="display:none;">'+i.encode(d.name)+"</span>");f(a,function(a){b.push(a.renderHTML())});b.push("</span>");b.push("</div>");return b.join("")},
+focus:function(){this.keyNav.focus()},postRender:function(){var b=this,a=[];j(b.controls,function(b){j(b.controls,function(b){b.id&&a.push(b)})});b.keyNav=new c.ui.KeyboardNavigation({root:b.id,items:a,onCancel:function(){b.editor.focus()},excludeFromTabOrder:!b.settings.tab_focus_toolbar})},destroy:function(){this.parent();this.keyNav.destroy();g.clear(this.id)}})})(tinymce);
+(function(c){var i=c.DOM;c.create("tinymce.ui.Toolbar:tinymce.ui.Container",{renderHTML:function(){var c="",g,b,a=this.settings,f,d,n,k;k=this.controls;for(f=0;f<k.length;f++){b=k[f];d=k[f-1];n=k[f+1];f===0&&(g="mceToolbarStart",b.Button?g+=" mceToolbarStartButton":b.SplitButton?g+=" mceToolbarStartSplitButton":b.ListBox&&(g+=" mceToolbarStartListBox"),c+=i.createHTML("td",{"class":g},i.createHTML("span",null,"<\!-- IE --\>")));if(d&&b.ListBox&&(d.Button||d.SplitButton))c+=i.createHTML("td",{"class":"mceToolbarEnd"},
+i.createHTML("span",null,"<\!-- IE --\>"));c+=i.stdMode?'<td style="position: relative">'+b.renderHTML()+"</td>":"<td>"+b.renderHTML()+"</td>";if(n&&b.ListBox&&(n.Button||n.SplitButton))c+=i.createHTML("td",{"class":"mceToolbarStart"},i.createHTML("span",null,"<\!-- IE --\>"))}g="mceToolbarEnd";b.Button?g+=" mceToolbarEndButton":b.SplitButton?g+=" mceToolbarEndSplitButton":b.ListBox&&(g+=" mceToolbarEndListBox");c+=i.createHTML("td",{"class":g},i.createHTML("span",null,"<\!-- IE --\>"));return i.createHTML("table",
+{id:this.id,"class":"mceToolbar"+(a["class"]?" "+a["class"]:""),cellpadding:"0",cellspacing:"0",align:this.settings.align||"",role:"presentation",tabindex:"-1"},"<tbody><tr>"+c+"</tr></tbody>")}})})(tinymce);
+(function(c){var i=c.util.Dispatcher;c.create("tinymce.AddOnManager",{AddOnManager:function(){this.items=[];this.urls={};this.lookup={};this.onAdd=new i(this)},get:function(c){return this.lookup[c]},requireLangPack:function(i){var g=c.settings;g&&g.language&&g.language_load!==!1&&c.ScriptLoader.add(this.urls[i]+"/langs/"+g.language+".js")},add:function(c,g){this.items.push(g);this.lookup[c]=g;this.onAdd.dispatch(this,c,g);return g},load:function(i,g,b,a){this.urls[i]||(g.indexOf("/")!=0&&g.indexOf("://")==
+-1&&(g=c.baseURL+"/"+g),this.urls[i]=g.substring(0,g.lastIndexOf("/")),this.lookup[i]||c.ScriptLoader.add(g,b,a))}});c.PluginManager=new c.AddOnManager;c.ThemeManager=new c.AddOnManager})(tinymce);
+(function(c){var i=c.each,j=c.extend,g=c.DOM,b=c.dom.Event,a=c.explode,f=c.util.Dispatcher,d=0;c.documentBaseURL=window.location.href.replace(/[\?#].*$/,"").replace(/[\/\\][^\/]+$/,"");/[\/\\]$/.test(c.documentBaseURL)||(c.documentBaseURL+="/");c.baseURL=(new c.util.URI(c.documentBaseURL)).toAbsolute(c.baseURL);c.baseURI=new c.util.URI(c.baseURL);c.onBeforeUnload=new f(c);b.add(window,"beforeunload",function(a){c.onBeforeUnload.dispatch(c,a)});c.onAddEditor=new f(c);c.onRemoveEditor=new f(c);c.EditorManager=
+j(c,{editors:[],i18n:{},activeEditor:null,init:function(f){function k(a,b,e){var d=a[b];if(d)return c.is(d,"string")&&(e=(e=d.replace(/\.\w+$/,""))?c.resolve(e):0,d=c.resolve(d)),d.apply(e||this,Array.prototype.slice.call(arguments,2))}var m=this,o,e=[],h,f=j({theme:"simple",language:"en"},f);m.settings=f;b.add(document,"init",function(){var b,j;k(f,"onpageload");switch(f.mode){case "exact":b=f.elements||"";b.length>0&&i(a(b),function(a){g.get(a)?(h=new c.Editor(a,f),e.push(h),h.render(1)):i(document.forms,
+function(b){i(b.elements,function(b){b.name===a&&(a="mce_editor_"+d++,g.setAttrib(b,"id",a),h=new c.Editor(a,f),e.push(h),h.render(1))})})});break;case "textareas":case "specific_textareas":i(g.select("textarea"),function(a){if(!f.editor_deselector||!(f.editor_deselector.constructor===RegExp?f.editor_deselector.test(a.className):g.hasClass(a,f.editor_deselector)))if(!f.editor_selector||(f.editor_selector.constructor===RegExp?f.editor_selector.test(a.className):g.hasClass(a,f.editor_selector))){o=
+g.get(a.name);if(!a.id&&!o)a.id=a.name;if(!a.id||m.get(a.id))a.id=g.uniqueId();h=new c.Editor(a.id,f);e.push(h);h.render(1)}})}f.oninit&&(b=j=0,i(e,function(a){j++;a.initialized?b++:a.onInit.add(function(){b++;b==j&&k(f,"oninit")});b==j&&k(f,"oninit")}))})},get:function(a){if(a===void 0)return this.editors;return this.editors[a]},getInstanceById:function(a){return this.get(a)},add:function(a){var b=this.editors;b[a.id]=a;b.push(a);this._setActive(a);this.onAddEditor.dispatch(this,a);return a},remove:function(a){var b,
+c=this.editors;if(!c[a.id])return null;delete c[a.id];for(b=0;b<c.length;b++)if(c[b]==a){c.splice(b,1);break}this.activeEditor==a&&this._setActive(c[0]);a.destroy();this.onRemoveEditor.dispatch(this,a);return a},execCommand:function(a,b,d){var f=this.get(d),e;switch(a){case "mceFocus":return f.focus(),!0;case "mceAddEditor":case "mceAddControl":return this.get(d)||(new c.Editor(d,this.settings)).render(),!0;case "mceAddFrameControl":e=d.window;e.tinyMCE=tinyMCE;e.tinymce=c;c.DOM.doc=e.document;c.DOM.win=
+e;f=new c.Editor(d.element_id,d);f.render();if(c.isIE){var h=function(){var k;f.destroy();e.detachEvent("onunload",h);k=e.tinyMCE=e.tinymce=null,e=k};e.attachEvent("onunload",h)}d.page_window=null;return!0;case "mceRemoveEditor":case "mceRemoveControl":return f&&f.remove(),!0;case "mceToggleEditor":if(!f)return this.execCommand("mceAddControl",0,d),!0;f.isHidden()?f.show():f.hide();return!0}if(this.activeEditor)return this.activeEditor.execCommand(a,b,d);return!1},execInstanceCommand:function(a,b,
+c,d){if(a=this.get(a))return a.execCommand(b,c,d);return!1},triggerSave:function(){i(this.editors,function(a){a.save()})},addI18n:function(a,b){var d=this.i18n;c.is(a,"string")?i(b,function(b,e){d[a+"."+e]=b}):i(a,function(a,b){i(a,function(a,c){i(a,function(a,h){c==="common"?d[b+"."+h]=a:d[b+"."+c+"."+h]=a})})})},_setActive:function(a){this.selectedInstance=this.activeEditor=a}})})(tinymce);
+(function(c){var i=c.DOM,j=c.dom.Event,g=c.extend,b=c.util.Dispatcher,a=c.each,f=c.isGecko,d=c.isIE,n=c.is,k=c.ThemeManager,m=c.PluginManager,o=c.explode;c.create("tinymce.Editor",{Editor:function(e,d){var f=this;f.id=f.editorId=e;f.execCommands={};f.queryStateCommands={};f.queryValueCommands={};f.isNotDirty=!1;f.plugins={};a(["onPreInit","onBeforeRenderUI","onPostRender","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"],function(a){f[a]=new b(f)});f.settings=d=g({id:e,language:"en",docs_language:"en",theme:"simple",skin:"default",delta_width:0,delta_height:0,popup_css:"",plugins:"",document_base_url:c.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:c.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",
+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:!0,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:!0,
+entity_encoding:"named",url_converter:f.convertURL,url_converter_scope:f,ie7_compat:!0},d);f.documentBaseURI=new c.util.URI(d.document_base_url||c.documentBaseURL,{base_uri:tinyMCE.baseURI});f.baseURI=c.baseURI;f.contentCSS=[];f.execCallback("setup",f)},render:function(){var b=this,d=b.settings,f=b.id,g=c.ScriptLoader;if(j.domLoaded){if(tinyMCE.settings=d,b.getElement()&&!c.isIDevice){!/TEXTAREA|INPUT/i.test(b.getElement().nodeName)&&d.hidden_input&&i.getParent(f,"form")&&i.insertAfter(i.create("input",
+{type:"hidden",name:f}),f);if(c.WindowManager)b.windowManager=new c.WindowManager(b);d.encoding=="xml"&&b.onGetContent.add(function(a,b){if(b.save)b.content=i.encode(b.content)});d.add_form_submit_trigger&&b.onSubmit.addToTop(function(){if(b.initialized)b.save(),b.isNotDirty=1});if(d.add_unload_trigger)b._beforeUnload=tinyMCE.onBeforeUnload.add(function(){b.initialized&&!b.destroyed&&!b.isHidden()&&b.save({format:"raw",no_events:!0})});c.addUnload(b.destroy,b);d.submit_patch&&b.onBeforeRenderUI.add(function(){var a=
+b.getElement().form;if(a&&!a._mceOldSubmit){if(!a.submit.nodeType&&!a.submit.length)b.formElement=a,a._mceOldSubmit=a.submit,a.submit=function(){c.triggerSave();b.isNotDirty=1;return b.formElement._mceOldSubmit(b.formElement)};a=null}});(function(){d.language&&d.language_load!==!1&&g.add(c.baseURL+"/langs/"+d.language+".js");d.theme&&d.theme.charAt(0)!="-"&&!k.urls[d.theme]&&k.load(d.theme,"themes/"+d.theme+"/editor_template"+c.suffix+".js");a(o(d.plugins),function(a){a&&a.charAt(0)!="-"&&!m.urls[a]&&
+a!="safari"&&m.load(a,"plugins/"+a+"/editor_plugin"+c.suffix+".js")});g.loadQueue(function(){b.removed||b.init()})})()}}else j.add(document,"init",function(){b.render()})},init:function(){var b=this,h=b.settings,g,j,l=b.getElement(),n,B,r;c.add(b);h.aria_label=h.aria_label||i.getAttrib(l,"aria-label",b.getLang("aria.rich_text_area"));if(h.theme)h.theme=h.theme.replace(/-/,""),n=k.get(h.theme),b.theme=new n,b.theme.init&&h.init_theme&&b.theme.init(b,k.urls[h.theme]||c.documentBaseURL.replace(/\/$/,
+""));a(o(h.plugins.replace(/\-/g,"")),function(a){var d=m.get(a),h=m.urls[a]||c.documentBaseURL.replace(/\/$/,"");d&&(d=new d(b,h),b.plugins[a]=d,d.init&&d.init(b,h))});if(h.popup_css!==!1)h.popup_css=h.popup_css?b.documentBaseURI.toAbsolute(h.popup_css):b.baseURI.toAbsolute("themes/"+h.theme+"/skins/"+h.skin+"/dialog.css");h.popup_css_add&&(h.popup_css+=","+b.documentBaseURI.toAbsolute(h.popup_css_add));b.controlManager=new c.ControlManager(b);h.custom_undo_redo&&(b.onBeforeExecCommand.add(function(a,
+c,d,h,f){c!="Undo"&&c!="Redo"&&c!="mceRepaint"&&(!f||!f.skip_undo)&&b.undoManager.beforeChange()}),b.onExecCommand.add(function(a,c,d,h,f){c!="Undo"&&c!="Redo"&&c!="mceRepaint"&&(!f||!f.skip_undo)&&b.undoManager.add()}));b.onExecCommand.add(function(a,c){/^(FontName|FontSize)$/.test(c)||b.nodeChanged()});f&&(r=function(a,c){(!c||!c.initial)&&b.execCommand("mceRepaint")},b.onUndo.add(r),b.onRedo.add(r),b.onSetContent.add(r));b.onBeforeRenderUI.dispatch(b,b.controlManager);if(h.render_ui)g=h.width||
+l.style.width||l.offsetWidth,j=h.height||l.style.height||l.offsetHeight,b.orgDisplay=l.style.display,r=/^[0-9\.]+(|px)$/i,r.test(""+g)&&(g=Math.max(parseInt(g)+(n.deltaWidth||0),100)),r.test(""+j)&&(j=Math.max(parseInt(j)+(n.deltaHeight||0),100)),n=b.theme.renderUI({targetNode:l,width:g,height:j,deltaWidth:h.delta_width,deltaHeight:h.delta_height}),b.editorContainer=n.editorContainer;if(document.domain&&location.hostname!=document.domain)c.relaxedDomain=document.domain;i.setStyles(n.sizeContainer||
+n.editorContainer,{width:g,height:j});h.content_css&&c.each(o(h.content_css),function(a){b.contentCSS.push(b.documentBaseURI.toAbsolute(a))});j=(n.iframeHeight||j)+(typeof j=="number"?n.deltaHeight||0:"");j<100&&(j=100);b.iframeHTML=h.doctype+'<html><head xmlns="http://www.w3.org/1999/xhtml">';h.document_base_url!=c.documentBaseURL&&(b.iframeHTML+='<base href="'+b.documentBaseURI.getURI()+'" />');b.iframeHTML+=h.ie7_compat?'<meta http-equiv="X-UA-Compatible" content="IE=7" />':'<meta http-equiv="X-UA-Compatible" content="IE=edge" />';
+b.iframeHTML+='<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';if(!f||!/Firefox\/2/.test(navigator.userAgent)){for(g=0;g<b.contentCSS.length;g++)b.iframeHTML+='<link type="text/css" rel="stylesheet" href="'+b.contentCSS[g]+'" />';b.contentCSS=[]}g=h.body_id||"tinymce";g.indexOf("=")!=-1&&(g=b.getParam("body_id","","hash"),g=g[b.id]||g);l=h.body_class||"";l.indexOf("=")!=-1&&(l=b.getParam("body_class","","hash"),l=l[b.id]||"");b.iframeHTML+='</head><body id="'+g+'" class="mceContentBody '+
+l+'"></body></html>';if(c.relaxedDomain&&(d||c.isOpera&&parseFloat(opera.version())<11))B='javascript:(function(){document.open();document.domain="'+document.domain+'";var ed = window.parent.tinyMCE.get("'+b.id+'");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';i.add(n.iframeContainer,"iframe",{id:b.id+"_ifr",src:B||'javascript:""',frameBorder:"0",title:h.aria_label,style:{width:"100%",height:j}});b.contentAreaContainer=n.iframeContainer;i.get(n.editorContainer).style.display=
+b.orgDisplay;i.get(b.id).style.display="none";i.setAttrib(b.id,"aria-hidden",!0);(!c.relaxedDomain||!B)&&b.setupIframe();l=n=null},setupIframe:function(){var b=this,h=b.settings;i.get(b.id);var g=b.getDoc(),k;if(!d||!c.relaxedDomain)if(g.open(),g.write(b.iframeHTML),g.close(),c.relaxedDomain)g.domain=c.relaxedDomain;if(!d)try{if(!h.readonly)g.designMode="On"}catch(l){}if(d){k=b.getBody();i.hide(k);if(!h.readonly)k.contentEditable=!0;i.show(k)}b.schema=new c.html.Schema(h);b.dom=new c.dom.DOMUtils(b.getDoc(),
+{keep_values:!0,url_converter:b.convertURL,url_converter_scope:b,hex_colors:h.force_hex_style_colors,class_filter:h.class_filter,update_styles:1,fix_ie_paragraphs:1,schema:b.schema});b.parser=new c.html.DomParser(h,b.schema);b.parser.addAttributeFilter("name",function(a){for(var b=a.length,c,d,e,h;b--;)if(h=a[b],h.name==="a"&&h.firstChild){e=h.parent;c=h.lastChild;do d=c.prev,e.insert(c,h),c=d;while(c)}});b.parser.addAttributeFilter("src,href,style",function(a,c){for(var d=a.length,h,f=b.dom,g;d--;)h=
+a[d],g=h.attr(c),c==="style"?h.attr("data-mce-style",f.serializeStyle(f.parseStyle(g),h.name)):h.attr("data-mce-"+c,b.convertURL(g,c,h.name))});b.parser.addNodeFilter("script",function(a){for(var b=a.length;b--;)a[b].attr("type","mce-text/javascript")});b.parser.addNodeFilter("#cdata",function(a){for(var b=a.length,c;b--;)c=a[b],c.type=8,c.name="#comment",c.value="[CDATA["+c.value+"]]"});b.parser.addNodeFilter("p,h1,h2,h3,h4,h5,h6,div",function(a){for(var d=a.length,h,f=b.schema.getNonEmptyElements();d--;)if(h=
+a[d],h.isEmpty(f))h.empty().append(new c.html.Node("br",1)).shortEnded=!0});b.serializer=new c.dom.Serializer(h,b.dom,b.schema);b.selection=new c.dom.Selection(b.dom,b.getWin(),b.serializer);b.formatter=new c.Formatter(this);b.formatter.register({alignleft:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"left"}},{selector:"img,table",collapsed:!1,styles:{"float":"left"}}],aligncenter:[{selector:"p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li",styles:{textAlign:"center"}},{selector:"img",
+collapsed:!1,styles:{display:"block",marginLeft:"auto",marginRight:"auto"}},{selector:"table",collapsed:!1,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:!1,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:!0},{inline:"u",remove:"all"}],strikethrough:[{inline:"span",styles:{textDecoration:"line-through"},exact:!0},{inline:"strike",remove:"all"}],forecolor:{inline:"span",styles:{color:"%value"},wrap_links:!1},hilitecolor:{inline:"span",styles:{backgroundColor:"%value"},wrap_links:!1},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"},removeformat:[{selector:"b,strong,em,i,font,u,strike",remove:"all",split:!0,expand:!1,block_expand:!0,deep:!0},{selector:"span",attributes:["style","class"],remove:"empty",split:!0,expand:!1,deep:!0},{selector:"*",attributes:["style","class"],split:!1,expand:!1,deep:!0}]});a("p h1 h2 h3 h4 h5 h6 div address pre div code dt dd samp".split(/\s/),
+function(a){b.formatter.register(a,{block:a,remove:"all"})});b.formatter.register(b.settings.formats);b.undoManager=new c.UndoManager(b);b.undoManager.onAdd.add(function(a,c){if(a.hasUndo())return b.onChange.dispatch(b,c,a)});b.undoManager.onUndo.add(function(a,c){return b.onUndo.dispatch(b,c,a)});b.undoManager.onRedo.add(function(a,c){return b.onRedo.dispatch(b,c,a)});b.forceBlocks=new c.ForceBlocks(b,{forced_root_block:h.forced_root_block});b.editorCommands=new c.EditorCommands(b);b.serializer.onPreProcess.add(function(a,
+c){return b.onPreProcess.dispatch(b,c,a)});b.serializer.onPostProcess.add(function(a,c){return b.onPostProcess.dispatch(b,c,a)});b.onPreInit.dispatch(b);if(!h.gecko_spellcheck)b.getBody().spellcheck=0;h.readonly||b._addEvents();b.controlManager.onPostRender.dispatch(b,b.controlManager);b.onPostRender.dispatch(b);if(h.directionality)b.getBody().dir=h.directionality;if(h.nowrap)b.getBody().style.whiteSpace="nowrap";h.handle_node_change_callback&&b.onNodeChange.add(function(a,c,d){b.execCallback("handle_node_change_callback",
+b.id,d,-1,-1,!0,b.selection.isCollapsed())});h.save_callback&&b.onSaveContent.add(function(a,c){var d=b.execCallback("save_callback",b.id,c.content,b.getBody());if(d)c.content=d});h.onchange_callback&&b.onChange.add(function(a,c){b.execCallback("onchange_callback",b,c)});h.protect&&b.onBeforeSetContent.add(function(b,c){h.protect&&a(h.protect,function(a){c.content=c.content.replace(a,function(a){return"<\!--mce:protected "+escape(a)+"--\>"})})});h.convert_newlines_to_brs&&b.onBeforeSetContent.add(function(a,
+b){if(b.initial)b.content=b.content.replace(/\r?\n/g,"<br />")});h.preformatted&&b.onPostProcess.add(function(a,b){b.content=b.content.replace(/^\s*<pre.*?>/,"");b.content=b.content.replace(/<\/pre>\s*$/,"");if(b.set)b.content='<pre class="mceItemHidden">'+b.content+"</pre>"});if(h.verify_css_classes)b.serializer.attribValueFilter=function(c,d){var h,f;if(c=="class"){if(!b.classesRE&&(f=b.dom.getClasses(),f.length>0))h="",a(f,function(a){h+=(h?"|":"")+a["class"]}),b.classesRE=RegExp("("+h+")","gi");
+return!b.classesRE||/(\bmceItem\w+\b|\bmceTemp\w+\b)/g.test(d)||b.classesRE.test(d)?d:""}return d};h.cleanup_callback&&(b.onBeforeSetContent.add(function(a,c){c.content=b.execCallback("cleanup_callback","insert_to_editor",c.content,c)}),b.onPreProcess.add(function(a,c){c.set&&b.execCallback("cleanup_callback","insert_to_editor_dom",c.node,c);c.get&&b.execCallback("cleanup_callback","get_from_editor_dom",c.node,c)}),b.onPostProcess.add(function(a,c){if(c.set)c.content=b.execCallback("cleanup_callback",
+"insert_to_editor",c.content,c);if(c.get)c.content=b.execCallback("cleanup_callback","get_from_editor",c.content,c)}));h.save_callback&&b.onGetContent.add(function(a,c){if(c.save)c.content=b.execCallback("save_callback",b.id,c.content,b.getBody())});h.handle_event_callback&&b.onEvent.add(function(a,c,d){b.execCallback("handle_event_callback",c,a,d)===!1&&j.cancel(c)});b.onSetContent.add(function(){b.addVisual(b.getBody())});h.padd_empty_editor&&b.onPostProcess.add(function(a,b){b.content=b.content.replace(/^(<p[^>]*>(&nbsp;|&#160;|\s|\u00a0|)<\/p>[\r\n]*|<br \/>[\r\n]*)$/,
+"")});if(f){var m=function(b){a(b.dom.select("a"),function(a){var c=a.parentNode;b.dom.isBlock(c)&&c.lastChild===a&&b.dom.add(c,"br",{"data-mce-bogus":1})})};b.onExecCommand.add(function(a,b){b==="CreateLink"&&m(a)});b.onSetContent.add(b.selection.onSetContent.add(m));if(!h.readonly)try{g.designMode="Off",g.designMode="On"}catch(n){}}setTimeout(function(){if(!b.removed)b.load({initial:!0,format:"html"}),b.startContent=b.getContent({format:"raw"}),b.undoManager.add(),b.initialized=!0,b.onInit.dispatch(b),
+b.execCallback("setupcontent_callback",b.id,b.getBody(),b.getDoc()),b.execCallback("init_instance_callback",b),b.focus(!0),b.nodeChanged({initial:1}),a(b.contentCSS,function(a){b.dom.loadCSS(a)}),h.auto_focus&&setTimeout(function(){var a=c.get(h.auto_focus);a.selection.select(a.getBody(),1);a.selection.collapse(1);a.getWin().focus()},100)},1)},focus:function(a){var b,d=this.settings.content_editable,f,g=this.getDoc();a||(a=this.selection.getRng(),a.item&&(f=a.item(0)),d||this.getWin().focus(),f&&
+f.ownerDocument==g&&(a=g.body.createControlRange(),a.addElement(f),a.select()));if(c.activeEditor!=this)(b=c.activeEditor)!=null&&b.onDeactivate.dispatch(b,this),this.onActivate.dispatch(this,b);c._setActive(this)},execCallback:function(a){var b=this.settings[a],d;if(b){if(this.callbackLookup&&(d=this.callbackLookup[a]))b=d.func,d=d.scope;if(n(b,"string"))d=(d=b.replace(/\.\w+$/,""))?c.resolve(d):0,b=c.resolve(b),this.callbackLookup=this.callbackLookup||{},this.callbackLookup[a]={func:b,scope:d};
+return b.apply(d||this,Array.prototype.slice.call(arguments,1))}},translate:function(a){var b=this.settings.language||"en",d=c.i18n;if(!a)return"";return d[b+"."+a]||a.replace(/{\#([^}]+)\}/g,function(a,c){return d[b+"."+c]||"{#"+c+"}"})},getLang:function(a,b){return c.i18n[(this.settings.language||"en")+"."+a]||(n(b)?b:"{#"+a+"}")},getParam:function(b,d,f){var g=c.trim,b=n(this.settings[b])?this.settings[b]:d,i;if(f==="hash")return i={},n(b,"string")?a(b.indexOf("=")>0?b.split(/[;,](?![^=;,]*(?:[;,]|$))/):
+b.split(","),function(a){a=a.split("=");a.length>1?i[g(a[0])]=g(a[1]):i[g(a[0])]=g(a)}):i=b,i;return b},nodeChanged:function(a){var b=this.selection,c=b.getStart()||this.getBody();if(this.initialized)a=a||{},c=d&&c.ownerDocument!=this.getDoc()?this.getBody():c,a.parents=[],this.dom.getParent(c,function(b){if(b.nodeName=="BODY")return!0;a.parents.push(b)}),this.onNodeChange.dispatch(this,a?a.controlManager||this.controlManager:this.controlManager,c,b.isCollapsed(),a)},addButton:function(a,b){this.buttons=
+this.buttons||{};this.buttons[a]=b},addCommand:function(a,b,c){this.execCommands[a]={func:b,scope:c||this}},addQueryStateHandler:function(a,b,c){this.queryStateCommands[a]={func:b,scope:c||this}},addQueryValueHandler:function(a,b,c){this.queryValueCommands[a]={func:b,scope:c||this}},addShortcut:function(b,c,d,f){var g=this,i;if(!g.settings.custom_shortcuts)return!1;g.shortcuts=g.shortcuts||{};n(d,"string")&&(i=d,d=function(){g.execCommand(i,!1,null)});n(d,"object")&&(i=d,d=function(){g.execCommand(i[0],
+i[1],i[2])});a(o(b),function(b){var e={func:d,scope:f||this,desc:c,alt:!1,ctrl:!1,shift:!1};a(o(b,"+"),function(a){switch(a){case "alt":case "ctrl":case "shift":e[a]=!0;break;default:e.charCode=a.charCodeAt(0),e.keyCode=a.toUpperCase().charCodeAt(0)}});g.shortcuts[(e.ctrl?"ctrl":"")+","+(e.alt?"alt":"")+","+(e.shift?"shift":"")+","+e.keyCode]=e});return!0},execCommand:function(b,c,d,f){var g=this,i=0,j;!/^(mceAddUndoLevel|mceEndUndoLevel|mceBeginUndoLevel|mceRepaint|SelectAll)$/.test(b)&&(!f||!f.skip_focus)&&
+g.focus();j={};g.onBeforeExecCommand.dispatch(g,b,c,d,j);if(j.terminate)return!1;if(g.execCallback("execcommand_callback",g.id,g.selection.getNode(),b,c,d))return g.onExecCommand.dispatch(g,b,c,d,f),!0;if(j=g.execCommands[b])if(j=j.func.call(j.scope,c,d),j!==!0)return g.onExecCommand.dispatch(g,b,c,d,f),j;a(g.plugins,function(a){if(a.execCommand&&a.execCommand(b,c,d))return g.onExecCommand.dispatch(g,b,c,d,f),i=1,!1});if(i)return!0;if(g.theme&&g.theme.execCommand&&g.theme.execCommand(b,c,d))return g.onExecCommand.dispatch(g,
+b,c,d,f),!0;if(g.editorCommands.execCommand(b,c,d))return g.onExecCommand.dispatch(g,b,c,d,f),!0;g.getDoc().execCommand(b,c,d);g.onExecCommand.dispatch(g,b,c,d,f)},queryCommandState:function(a){var b;if(!this._isHidden()){if(b=this.queryStateCommands[a])if(b=b.func.call(b.scope),b!==!0)return b;b=this.editorCommands.queryCommandState(a);if(b!==-1)return b;try{return this.getDoc().queryCommandState(a)}catch(c){}}},queryCommandValue:function(a){var b;if(!this._isHidden()){if(b=this.queryValueCommands[a])if(b=
+b.func.call(b.scope),b!==!0)return b;b=this.editorCommands.queryCommandValue(a);if(n(b))return b;try{return this.getDoc().queryCommandValue(a)}catch(c){}}},show:function(){i.show(this.getContainer());i.hide(this.id);this.load()},hide:function(){var a=this.getDoc();d&&a&&a.execCommand("SelectAll");this.save();i.hide(this.getContainer());i.setStyle(this.id,"display",this.orgDisplay)},isHidden:function(){return!i.isHidden(this.id)},setProgressState:function(a,b,c){this.onSetProgressState.dispatch(this,
+a,b,c);return a},load:function(a){var b=this.getElement(),c;if(b)return a=a||{},a.load=!0,c=this.setContent(n(b.value)?b.value:b.innerHTML,a),a.element=b,a.no_events||this.onLoadContent.dispatch(this,a),a.element=null,c},save:function(b){var c=this,d=c.getElement(),f,g;if(d&&c.initialized){b=b||{};b.save=!0;if(!b.no_events)c.undoManager.typing=!1,c.undoManager.add();b.element=d;f=b.content=c.getContent(b);b.no_events||c.onSaveContent.dispatch(c,b);f=b.content;/TEXTAREA|INPUT/i.test(d.nodeName)?d.value=
+f:(d.innerHTML=f,(g=i.getParent(c.id,"form"))&&a(g.elements,function(a){if(a.name==c.id)return a.value=f,!1}));b.element=d=null;return f}},setContent:function(a,b){var d=this.getBody(),b=b||{};b.format=b.format||"html";b.set=!0;b.content=a;b.no_events||this.onBeforeSetContent.dispatch(this,b);a=b.content;if(!c.isIE&&(a.length===0||/^\s+$/.test(a)))d.innerHTML='<br data-mce-bogus="1" />';else return b.format!=="raw"&&(a=(new c.html.Serializer({},this.schema)).serialize(this.parser.parse(a))),b.content=
+c.trim(a),this.dom.setHTML(d,b.content),b.no_events||this.onSetContent.dispatch(this,b),b.content},getContent:function(a){var b,a=a||{};a.format=a.format||"html";a.get=!0;a.no_events||this.onBeforeGetContent.dispatch(this,a);b=a.format=="raw"?this.getBody().innerHTML:this.serializer.serialize(this.getBody(),a);a.content=c.trim(b);a.no_events||this.onGetContent.dispatch(this,a);return a.content},isDirty:function(){return c.trim(this.startContent)!=c.trim(this.getContent({format:"raw",no_events:1}))&&
+!this.isNotDirty},getContainer:function(){if(!this.container)this.container=i.get(this.editorContainer||this.id+"_parent");return this.container},getContentAreaContainer:function(){return this.contentAreaContainer},getElement:function(){return i.get(this.settings.content_element||this.id)},getWin:function(){var a;if(!this.contentWindow&&(a=i.get(this.id+"_ifr")))this.contentWindow=a.contentWindow;return this.contentWindow},getDoc:function(){var a;if(!this.contentDocument&&(a=this.getWin()))this.contentDocument=
+a.document;return this.contentDocument},getBody:function(){return this.bodyElement||this.getDoc().body},convertURL:function(a,b,c){var d=this.settings;if(d.urlconverter_callback)return this.execCallback("urlconverter_callback",a,c,!0,b);if(!d.convert_urls||c&&c.nodeName=="LINK"||a.indexOf("file:")===0)return a;if(d.relative_urls)return this.documentBaseURI.toRelative(a);return a=this.documentBaseURI.toAbsolute(a,d.remove_script_host)},addVisual:function(b){var c=this,d=c.settings,b=b||c.getBody();
+if(!n(c.hasVisual))c.hasVisual=d.visual;a(c.dom.select("table,a",b),function(a){var b;switch(a.nodeName){case "TABLE":b=c.dom.getAttrib(a,"border");if(!b||b=="0")c.hasVisual?c.dom.addClass(a,d.visual_table_class):c.dom.removeClass(a,d.visual_table_class);break;case "A":(b=c.dom.getAttrib(a,"name"))&&(c.hasVisual?c.dom.addClass(a,"mceItemAnchor"):c.dom.removeClass(a,"mceItemAnchor"))}});c.onVisualAid.dispatch(c,b,c.hasVisual)},remove:function(){var a=this.getContainer();this.removed=1;this.hide();
+this.execCallback("remove_instance_callback",this);this.onRemove.dispatch(this);this.onExecCommand.listeners=[];c.remove(this);i.remove(a)},destroy:function(a){if(!this.destroyed){a||(c.removeUnload(this.destroy),tinyMCE.onBeforeUnload.remove(this._beforeUnload),this.theme&&this.theme.destroy&&this.theme.destroy(),this.controlManager.destroy(),this.selection.destroy(),this.dom.destroy(),this.settings.content_editable||(j.clear(this.getWin()),j.clear(this.getDoc())),j.clear(this.getBody()),j.clear(this.formElement));
+if(this.formElement)this.formElement.submit=this.formElement._mceOldSubmit,this.formElement._mceOldSubmit=null;this.contentAreaContainer=this.formElement=this.container=this.settings.content_element=this.bodyElement=this.contentDocument=this.contentWindow=null;if(this.selection)this.selection=this.selection.win=this.selection.dom=this.selection.dom.doc=null;this.destroyed=1}},_addEvents:function(){function b(a,c){h.removed||h.onEvent.dispatch(h,a,c)!==!1&&h[m[a.fakeType||a.type]].dispatch(h,a,c)}
+var h=this,g,k=h.settings,l=h.dom,m={mouseup:"onMouseUp",mousedown:"onMouseDown",click:"onClick",keyup:"onKeyUp",keydown:"onKeyDown",keypress:"onKeyPress",submit:"onSubmit",reset:"onReset",contextmenu:"onContextMenu",dblclick:"onDblClick",paste:"onPaste"};a(m,function(a,c){switch(c){case "contextmenu":l.bind(h.getDoc(),c,b);break;case "paste":l.bind(h.getBody(),c,function(a){b(a)});break;case "submit":case "reset":l.bind(h.getElement().form||i.getParent(h.id,"form"),c,b);break;default:l.bind(k.content_editable?
+h.getBody():h.getDoc(),c,b)}});l.bind(k.content_editable?h.getBody():f?h.getDoc():h.getWin(),"focus",function(){h.focus(!0)});c.isGecko&&l.bind(h.getDoc(),"DOMNodeInserted",function(a){var b,a=a.target;if(a.nodeType===1&&a.nodeName==="IMG"&&(b=a.getAttribute("data-mce-src")))a.src=h.documentBaseURI.toAbsolute(b)});f&&(g=function(){var a=this.getDoc(),b=this.settings;if(f&&!b.readonly){if(this._isHidden())try{if(!b.content_editable)a.designMode="On"}catch(c){}try{a.execCommand("styleWithCSS",0,!1)}catch(d){if(!this._isHidden())try{a.execCommand("useCSS",
+0,!0)}catch(e){}}if(!b.table_inline_editing)try{a.execCommand("enableInlineTableEditing",!1,!1)}catch(h){}if(!b.object_resizing)try{a.execCommand("enableObjectResizing",!1,!1)}catch(g){}}},h.onBeforeExecCommand.add(g),h.onMouseDown.add(g));c.isWebKit&&h.onClick.add(function(a,b){b=b.target;if(b.nodeName=="IMG"||b.nodeName=="A"&&l.hasClass(b,"mceItemAnchor"))h.selection.getSel().setBaseAndExtent(b,0,b,1),h.nodeChanged()});h.onMouseUp.add(h.nodeChanged);h.onKeyUp.add(function(a,b){var d=b.keyCode;(d>=
+33&&d<=36||d>=37&&d<=40||d==13||d==45||d==46||d==8||c.isMac&&(d==91||d==93)||b.ctrlKey)&&h.nodeChanged()});h.onReset.add(function(){h.setContent(h.startContent,{format:"raw"})});if(k.custom_shortcuts){k.custom_undo_redo_keyboard_shortcuts&&(h.addShortcut("ctrl+z",h.getLang("undo_desc"),"Undo"),h.addShortcut("ctrl+y",h.getLang("redo_desc"),"Redo"));h.addShortcut("ctrl+b",h.getLang("bold_desc"),"Bold");h.addShortcut("ctrl+i",h.getLang("italic_desc"),"Italic");h.addShortcut("ctrl+u",h.getLang("underline_desc"),
+"Underline");for(g=1;g<=6;g++)h.addShortcut("ctrl+"+g,"",["FormatBlock",!1,"h"+g]);h.addShortcut("ctrl+7","",["FormatBlock",!1,"<p>"]);h.addShortcut("ctrl+8","",["FormatBlock",!1,"<div>"]);h.addShortcut("ctrl+9","",["FormatBlock",!1,"<address>"]);var n=function(b){var d=null;if(!b.altKey&&!b.ctrlKey&&!b.metaKey)return d;a(h.shortcuts,function(a){if(!(c.isMac&&a.ctrl!=b.metaKey)&&(c.isMac||a.ctrl==b.ctrlKey))if(a.alt==b.altKey&&a.shift==b.shiftKey&&(b.keyCode==a.keyCode||b.charCode&&b.charCode==a.charCode))return d=
+a,!1});return d};h.onKeyUp.add(function(a,b){if(n(b))return j.cancel(b)});h.onKeyPress.add(function(a,b){if(n(b))return j.cancel(b)});h.onKeyDown.add(function(a,b){var c=n(b);if(c)return c.func.call(c.scope),j.cancel(b)})}c.isIE&&(l.bind(h.getDoc(),"controlselect",function(a){var b=h.resizeInfo,a=a.target;if(a.nodeName==="IMG")b&&l.unbind(b.node,b.ev,b.cb),l.hasClass(a,"mceItemNoResize")?(ev="resizestart",b=l.bind(a,"resizestart",j.cancel,j)):(ev="resizeend",b=l.bind(a,ev,function(a){var b,a=a.target;
+if(b=l.getStyle(a,"width"))l.setAttrib(a,"width",b.replace(/[^0-9%]+/g,"")),l.setStyle(a,"width","");if(b=l.getStyle(a,"height"))l.setAttrib(a,"height",b.replace(/[^0-9%]+/g,"")),l.setStyle(a,"height","")})),b=h.resizeInfo={node:a,ev:ev,cb:b}}),h.onKeyDown.add(function(a,b){var c;switch(b.keyCode){case 8:if(c=h.getDoc().selection,c.createRange&&c.createRange().item)return a.dom.remove(c.createRange().item(0)),j.cancel(b)}}));c.isOpera&&h.onClick.add(function(a,b){j.prevent(b)});if(k.custom_undo_redo){var o=
+function(){h.undoManager.typing=!1;h.undoManager.add()};l.bind(h.getDoc(),"focusout",function(){!h.removed&&h.undoManager.typing&&o()});h.dom.bind(h.dom.getRoot(),"dragend",function(){o()});h.onKeyUp.add(function(a,b){var c,e;if(d&&b.keyCode==8&&(c=h.selection.getRng(),c.parentElement))c=c.parentElement(),e=h.selection.getBookmark(),c.innerHTML=c.innerHTML,h.selection.moveToBookmark(e);(b.keyCode>=33&&b.keyCode<=36||b.keyCode>=37&&b.keyCode<=40||b.keyCode==13||b.keyCode==45||b.ctrlKey)&&o()});h.onKeyDown.add(function(a,
+b){var e,f;f=b.keyCode;if(d&&f==46&&(e=h.selection.getRng(),e.parentElement)){f=e.parentElement();if(!h.undoManager.typing)h.undoManager.beforeChange(),h.undoManager.typing=!0,h.undoManager.add();b.ctrlKey&&(e.moveEnd("word",1),e.select());h.selection.getSel().clear();if(e.parentElement()==f){e=h.selection.getBookmark();try{f.innerHTML=f.innerHTML}catch(g){}h.selection.moveToBookmark(e)}b.preventDefault();return}if(f>=33&&f<=36||f>=37&&f<=40||f==13||f==45)c.isIE&&f==13&&h.undoManager.beforeChange(),
+h.undoManager.typing&&o();else if((f<16||f>20)&&f!=224&&f!=91&&!h.undoManager.typing)h.undoManager.beforeChange(),h.undoManager.add(),h.undoManager.typing=!0});h.onMouseDown.add(function(){h.undoManager.typing&&o()})}if(c.isGecko){var t=function(){var b=h.dom.getAttribs(h.selection.getStart().cloneNode(!1));return function(){var c=h.selection.getStart();h.dom.removeAllAttribs(c);a(b,function(a){c.setAttributeNode(a.cloneNode(!0))})}},y=function(){var a=h.selection;return!a.isCollapsed()&&a.getStart()!=
+a.getEnd()};h.onKeyPress.add(function(a,b){var c;if((b.keyCode==8||b.keyCode==46)&&y())return c=t(),h.getDoc().execCommand("delete",!1,null),c(),j.cancel(b)});h.dom.bind(h.getDoc(),"cut",function(){var a;y()&&(a=t(),h.onKeyUp.addToTop(j.cancel,j),setTimeout(function(){a();h.onKeyUp.remove(j.cancel,j)},0))})}},_isHidden:function(){var a;if(!f)return 0;a=this.selection.getSel();return!a||!a.rangeCount||a.rangeCount==0}})})(tinymce);
+(function(c){var i=c.each,j=!0,g=!1;c.EditorCommands=function(b){function a(a,b,c){var d,a=a.toLowerCase();if(d=e.exec[a])return d(a,b,c),j;return g}function f(a){var b,a=a.toLowerCase();if(b=e.state[a])return b(a);return-1}function d(a,b){b=b||"exec";i(a,function(a,c){i(c.toLowerCase().split(","),function(c){e[b][c]=a})})}function n(a,c,d){c===void 0&&(c=g);d===void 0&&(d=null);return b.getDoc().execCommand(a,c,d)}function k(a,c){b.formatter.toggle(a,c?{value:c}:void 0)}var m=b.dom,o=b.selection,
+e={state:{},exec:{},value:{}},h=b.settings,p;c.extend(this,{execCommand:a,queryCommandState:f,queryCommandValue:function(a){var b,a=a.toLowerCase();if(b=e.value[a])return b(a);return g},addCommands:d});d({"mceResetDesignMode,mceBeginUndoLevel":function(){},"mceEndUndoLevel,mceAddUndoLevel":function(){b.undoManager.add()},"Cut,Copy,Paste":function(a){var d=b.getDoc(),e;try{n(a)}catch(h){e=j}if(e||!d.queryCommandSupported(a))c.isGecko?b.windowManager.confirm(b.getLang("clipboard_msg"),function(a){a&&
+open("http://www.mozilla.org/editor/midasdemo/securityprefs.html","_blank")}):b.windowManager.alert(b.getLang("clipboard_no_support"))},unlink:function(a){o.isCollapsed()&&o.select(o.getNode());n(a);o.collapse(g)},"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(c){var d=c.substring(7);i("left,center,right,full".split(","),function(a){d!=a&&b.formatter.remove("align"+a)});k("align"+d);a("mceRepaint")},"InsertUnorderedList,InsertOrderedList":function(a){var b;n(a);if(a=m.getParent(o.getNode(),
+"ol,ul"))b=a.parentNode,/^(H[1-6]|P|ADDRESS|PRE)$/.test(b.nodeName)&&(p=o.getBookmark(void 0),m.split(b,a),o.moveToBookmark(p))},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(a){k(a)},"ForeColor,HiliteColor,FontName":function(a,b,c){k(a,c)},FontSize:function(a,b,d){var e;d>=1&&d<=7&&(e=c.explode(h.font_size_style_values),d=(b=c.explode(h.font_size_classes))?b[d-1]||d:e[d-1]||d);k(a,d)},RemoveFormat:function(a){b.formatter.remove(a)},mceBlockQuote:function(){k("blockquote")},
+FormatBlock:function(a,b,c){return k(c||"p")},mceCleanup:function(){var a=o.getBookmark();b.setContent(b.getContent({cleanup:j}),{cleanup:j});o.moveToBookmark(a)},mceRemoveNode:function(a,c,d){a=d||o.getNode();a!=b.getBody()&&(p=o.getBookmark(void 0),b.dom.remove(a,j),o.moveToBookmark(p))},mceSelectNodeDepth:function(a,c,d){var e=0;m.getParent(o.getNode(),function(a){if(a.nodeType==1&&e++==d)return o.select(a),g},b.getBody())},mceSelectNode:function(a,b,c){o.select(c)},mceInsertContent:function(a,
+d,e){function h(a,b,d){for(b=new c.dom.TreeWalker(d?a.nextSibling:a.previousSibling,b);a=b.current();){if(a.nodeType==3&&c.trim(a.nodeValue).length||a.nodeName=="BR"||a.nodeName=="IMG")return a;d?b.next():b.prev()}}var f,g,a={content:e,format:"html"};o.onBeforeSetContent.dispatch(o,a);e=a.content;e.indexOf("{$caret}")==-1&&(e+="{$caret}");o.setContent('<span id="__mce">\ufeff</span>',{no_events:!1});m.setOuterHTML("__mce",e.replace(/\{\$caret\}/,'<span data-mce-type="bookmark" id="__mce">\ufeff</span>'));
+d=m.select("#__mce")[0];g=m.getRoot();if(d.previousSibling&&m.isBlock(d.previousSibling)||d.parentNode==g)(e=h(d,g))&&(e.nodeName=="BR"?e.parentNode.insertBefore(d,e):m.insertAfter(d,e));for(;d;){if(d===g){m.setOuterHTML(f,(new c.html.Serializer({},b.schema)).serialize(b.parser.parse(m.getOuterHTML(f))));break}f=d;d=d.parentNode}if(d=m.select("#__mce")[0])if(e=h(d,g)||h(d,g,!0),m.remove(d),e){f=m.createRng();e.nodeType==3?(f.setStart(e,e.length),f.setEnd(e,e.length)):e.nodeName=="BR"?(f.setStartBefore(e),
+f.setEndBefore(e)):(f.setStartAfter(e),f.setEndAfter(e));o.setRng(f);if(!c.isIE){e=m.create("span",null,"\u00a0");f.insertNode(e);f=m.getRect(e);d=m.getViewPort(b.getWin());if(f.y>d.y+d.h||f.y<d.y||f.x>d.x+d.w||f.x<d.x)b.getBody().scrollLeft=f.x,b.getBody().scrollTop=f.y;m.remove(e)}o.collapse(!0)}o.onSetContent.dispatch(o,a);b.addVisual()},mceInsertRawHTML:function(a,c,d){o.setContent("tiny_mce_marker");b.setContent(b.getContent().replace(/tiny_mce_marker/g,function(){return d}))},mceSetContent:function(a,
+c,d){b.setContent(d)},"Indent,Outdent":function(a){var b,c,d;b=h.indentation;c=/[a-z%]+$/i.exec(b);b=parseInt(b);!f("InsertUnorderedList")&&!f("InsertOrderedList")?i(o.getSelectedBlocks(),function(e){a=="outdent"?(d=Math.max(0,parseInt(e.style.paddingLeft||0)-b),m.setStyle(e,"paddingLeft",d?d+c:"")):m.setStyle(e,"paddingLeft",parseInt(e.style.paddingLeft||0)+b+c)}):n(a)},mceRepaint:function(){if(c.isGecko)try{p=o.getBookmark(j),o.getSel()&&o.getSel().selectAllChildren(b.getBody()),o.collapse(j),o.moveToBookmark(p)}catch(a){}},
+mceToggleFormat:function(a,c,d){b.formatter.toggle(d)},InsertHorizontalRule:function(){b.execCommand("mceInsertContent",!1,"<hr />")},mceToggleVisualAid:function(){b.hasVisual=!b.hasVisual;b.addVisual()},mceReplaceContent:function(a,c,d){b.execCommand("mceInsertContent",!1,d.replace(/\{\$selection\}/g,o.getContent({format:"text"})))},mceInsertLink:function(a,d,e){var a=m.getParent(o.getNode(),"a"),h,f;c.is(e,"string")&&(e={href:e});e.href=e.href.replace(" ","%20");if(a)e.href?m.setAttribs(a,e):b.dom.remove(a,
+j);else{if(c.isWebKit&&(h=m.getParent(o.getNode(),"img")))f=h.style.cssFloat,h.style.cssFloat=null;n("CreateLink",g,"javascript:mctmp(0);");if(f)h.style.cssFloat=f;i(m.select("a[href='javascript:mctmp(0);']"),function(a){m.setAttribs(a,e)})}},selectAll:function(){var a=m.getRoot(),c=m.createRng();c.setStart(a,0);c.setEnd(a,a.childNodes.length);b.selection.setRng(c)}});d({"JustifyLeft,JustifyCenter,JustifyRight,JustifyFull":function(a){a="align"+a.substring(7);return b.formatter.match(a)},"Bold,Italic,Underline,Strikethrough,Superscript,Subscript":function(a){return b.formatter.match(a)},
+mceBlockQuote:function(){return b.formatter.match("blockquote")},Outdent:function(){var a;if(h.inline_styles){if((a=m.getParent(o.getStart(),m.isBlock))&&parseInt(a.style.paddingLeft)>0)return j;if((a=m.getParent(o.getEnd(),m.isBlock))&&parseInt(a.style.paddingLeft)>0)return j}return f("InsertUnorderedList")||f("InsertOrderedList")||!h.inline_styles&&!!m.getParent(o.getNode(),"BLOCKQUOTE")},"InsertUnorderedList,InsertOrderedList":function(a){return m.getParent(o.getNode(),a=="insertunorderedlist"?
+"UL":"OL")}},"state");d({"FontSize,FontName":function(a){var b=0,c;if(c=m.getParent(o.getNode(),"span"))b=a=="fontsize"?c.style.fontSize:c.style.fontFamily.replace(/, /g,",").replace(/[\'\"]/g,"").toLowerCase();return b}},"value");h.custom_undo_redo&&d({Undo:function(){b.undoManager.undo()},Redo:function(){b.undoManager.redo()}})}})(tinymce);
+(function(c){var i=c.util.Dispatcher;c.UndoManager=function(j){var g,b=0,a=[];return g={typing:!1,onAdd:new i(g),onUndo:new i(g),onRedo:new i(g),beforeChange:function(){if(a[b])a[b].beforeBookmark=j.selection.getBookmark(2,!0)},add:function(f){var d;d=j.settings;var i,f=f||{};f.content=c.trim(j.getContent({format:"raw",no_events:1}));if((i=a[b])&&i.content==f.content)return null;if(d.custom_undo_redo_levels&&a.length>d.custom_undo_redo_levels){for(d=0;d<a.length-1;d++)a[d]=a[d+1];a.length--;b=a.length}f.bookmark=
+j.selection.getBookmark(2,!0);if(b<a.length-1)a.length=b+1;a.push(f);b=a.length-1;g.onAdd.dispatch(g,f);j.isNotDirty=0;return f},undo:function(){var c;if(g.typing)g.add(),g.typing=!1;b>0&&(c=a[--b],j.setContent(c.content,{format:"raw"}),j.selection.moveToBookmark(c.beforeBookmark),g.onUndo.dispatch(g,c));return c},redo:function(){var c;b<a.length-1&&(c=a[++b],j.setContent(c.content,{format:"raw"}),j.selection.moveToBookmark(c.bookmark),g.onRedo.dispatch(g,c));return c},clear:function(){a=[];b=0;g.typing=
+!1},hasUndo:function(){return b>0||this.typing},hasRedo:function(){return b<a.length-1&&!this.typing}}}})(tinymce);
+(function(c){function i(a,b){var c=b.ownerDocument.createRange();c.setStart(a.endContainer,a.endOffset);c.setEndAfter(b);return c.cloneContents().textContent.length==0}function j(a,b,c){var e;if(b.isEmpty(c))return e=b.getParent(c,"ul,ol"),b.getParent(e.parentNode,"ul,ol")||(b.split(e,c),e=b.create("p",0,'<br data-mce-bogus="1" />'),b.replace(e,c),a.select(e,1)),n;return d}var g=c.dom.Event,b=c.isIE,a=c.isGecko,f=c.isOpera,d=!0,n=!1;c.create("tinymce.ForceBlocks",{ForceBlocks:function(a){var b=this,
+c=a.settings,d;b.editor=a;b.dom=a.dom;d=(c.forced_root_block||"p").toLowerCase();c.element=d.toUpperCase();a.onPreInit.add(b.setup,b);c.forced_root_block&&(a.onInit.add(b.forceRoots,b),a.onSetContent.add(b.forceRoots,b),a.onBeforeGetContent.add(b.forceRoots,b),a.onExecCommand.add(function(a,c){c=="mceInsertContent"&&(b.forceRoots(),a.nodeChanged())}))},setup:function(){var f=this,i=f.editor,j=i.settings,e=i.dom,h=i.selection;j.forced_root_block&&(i.onBeforeExecCommand.add(f.forceRoots,f),i.onKeyUp.add(f.forceRoots,
+f),i.onPreProcess.add(f.forceRoots,f));j.force_br_newlines&&b&&i.onKeyPress.add(function(a,b){var c;if(b.keyCode==13&&h.getNode().nodeName!="LI")return h.setContent('<br id="__" /> ',{format:"raw"}),c=e.get("__"),c.removeAttribute("id"),h.select(c),h.collapse(),g.cancel(b)});j.force_p_newlines&&(b?(c.addUnload(function(){f._previousFormats=0}),i.onKeyPress.add(function(a,b){f._previousFormats=0;if(b.keyCode==13&&!b.shiftKey&&a.selection.isCollapsed()&&j.keep_styles){var c;var d=a.selection.getStart(),
+e,h,g;do/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(d.nodeName)&&(e?(h=d.cloneNode(!1),h.appendChild(e),e=h):e=g=d.cloneNode(!1),e.removeAttribute("id"));while(d=d.parentNode);e&&(c={wrapper:e,inner:g});f._previousFormats=c}}),i.onKeyUp.add(function(a,b){if(b.keyCode==13&&!b.shiftKey){var c=a.selection.getStart(),d=f._previousFormats;if(!c.hasChildNodes()&&d&&(c=e.getParent(c,e.isBlock))&&c.nodeName!="LI")c.innerHTML="",f._previousFormats?(c.appendChild(d.wrapper),d.inner.innerHTML="\ufeff"):c.innerHTML=
+"\ufeff",h.select(c,1),h.collapse(!0),a.getDoc().execCommand("Delete",!1,null),f._previousFormats=0}})):i.onKeyPress.add(function(a,b){b.keyCode==13&&!b.shiftKey&&!f.insertPara(b)&&g.cancel(b)}),a&&i.onKeyDown.add(function(a,b){(b.keyCode==8||b.keyCode==46)&&!b.shiftKey&&f.backspaceDelete(b,b.keyCode==8)}));c.isWebKit&&i.onKeyPress.add(function(a,b){if(b.keyCode==13&&(b.shiftKey||j.force_br_newlines&&!e.getParent(h.getNode(),"h1,h2,h3,h4,h5,h6,ol,ul"))){var c=h.getRng(),f,i=e.create("div",null," "),
+k=e.getViewPort(a.getWin()).h;c.insertNode(f=e.create("br"));c.setStartAfter(f);c.setEndAfter(f);h.setRng(c);h.getSel().focusNode==f.previousSibling&&(h.select(e.insertAfter(e.doc.createTextNode("\u00a0"),f)),h.collapse(d));e.insertAfter(i,f);c=e.getPos(i).y;e.remove(i);c>k&&a.getWin().scrollTo(0,c);g.cancel(b)}});b&&j.element!="P"&&(i.onKeyPress.add(function(){f.lastElm=h.getNode().nodeName}),i.onKeyUp.add(function(a,b){var c;c=h.getNode();if(a.getBody().childNodes.length===1&&c.nodeName=="P")c=
+e.rename(c,j.element),h.select(c),h.collapse(),a.nodeChanged();else if(b.keyCode==13&&!b.shiftKey&&f.lastElm!="P"&&(c=e.getParent(c,"p")))e.rename(c,j.element),a.nodeChanged()}))},find:function(a,b,c){for(var d=this.editor.getDoc().createTreeWalker(a,4,null,n),f=-1;a=d.nextNode();){f++;if(b==0&&a==c)return f;if(b==1&&f==c)return a}return-1},forceRoots:function(a){var a=this.editor,c=a.getBody(),d=a.getDoc(),e=a.selection,f=e.getSel(),g=e.getRng(),i=-2,j,n,B,r,t,y=c.childNodes,z,x,v;for(z=y.length-
+1;z>=0;z--)if(t=y[z],t.nodeType===1&&t.getAttribute("data-mce-type"))r=null;else if(t.nodeType===3||!this.dom.isBlock(t)&&t.nodeType!==8&&!/^(script|mce:script|style|mce:style)$/i.test(t.nodeName))if(r)r.hasChildNodes()?r.insertBefore(t,r.firstChild):r.appendChild(t);else{if(t.nodeType!=3||/[^\s]/g.test(t.nodeValue)){if(i==-2&&g)if(!b||g.setStart)if(g.startContainer.nodeType==1&&(x=g.startContainer.childNodes[g.startOffset])&&x.nodeType==1)v=x.getAttribute("id"),x.setAttribute("id","__mce");else{if(a.dom.getParent(g.startContainer,
+function(a){return a===c}))n=g.startOffset,B=g.endOffset,i=this.find(c,0,g.startContainer),j=this.find(c,0,g.endContainer)}else g.item&&(r=d.body.createTextRange(),r.moveToElementText(g.item(0)),g=r),r=d.body.createTextRange(),r.moveToElementText(c),r.collapse(1),i=r.move("character",-16777215)*-1,r=g.duplicate(),r.collapse(1),j=r.move("character",-16777215)*-1,r=g.duplicate(),r.collapse(0),r=r.move("character",-16777215)*-1-j,i=j-i,j=r;r=a.dom.create(a.settings.forced_root_block);t.parentNode.replaceChild(r,
+t);r.appendChild(t)}}else r=null;if(i!=-2)if(!b||g.setStart)r=c.getElementsByTagName(a.settings.element)[0],g=d.createRange(),i!=-1?g.setStart(this.find(c,1,i),n):g.setStart(r,0),j!=-1?g.setEnd(this.find(c,1,j),B):g.setEnd(r,0),f&&(f.removeAllRanges(),f.addRange(g));else try{g=f.createRange(),g.moveToElementText(c),g.collapse(1),g.moveStart("character",i),g.moveEnd("character",j),g.select()}catch(q){}else if((!b||g.setStart)&&(x=a.dom.get("__mce")))v?x.setAttribute("id",v):x.removeAttribute("id"),
+g=d.createRange(),g.setStartBefore(x),g.setEndBefore(x),e.setRng(g)},getParentBlock:function(a){var b=this.dom;return b.getParent(a,b.isBlock)},insertPara:function(){var k;function b(a,c){var d=[],e,i;a.innerHTML="";if(h.keep_styles){i=c;do/^(SPAN|STRONG|B|EM|I|FONT|STRIKE|U)$/.test(i.nodeName)&&(e=i.cloneNode(n),g.setAttrib(e,"id",""),d.push(e));while(i=i.parentNode)}if(d.length>0){i=d.length-1;for(e=a;i>=0;i--)e=e.appendChild(d[i]);d[0].innerHTML=f?"\u00a0":"<br />";return d[0]}else a.innerHTML=
+f?"\u00a0":"<br />"}var c=this.editor,g=c.dom,e=c.getDoc(),h=c.settings,p=c.selection.getSel(),u=p.getRangeAt(0),l=e.body,s,B,r,t,y,z,x,v,q,A,D,C,H=g.getViewPort(c.getWin()),F;c.undoManager.beforeChange();s=e.createRange();s.setStart(p.anchorNode,p.anchorOffset);s.collapse(d);B=e.createRange();B.setStart(p.focusNode,p.focusOffset);B.collapse(d);t=(r=s.compareBoundaryPoints(s.START_TO_END,B)<0)?p.anchorNode:p.focusNode;y=r?p.anchorOffset:p.focusOffset;z=r?p.focusNode:p.anchorNode;r=r?p.focusOffset:
+p.anchorOffset;if(t===z&&/^(TD|TH)$/.test(t.nodeName))return t.firstChild.nodeName=="BR"&&g.remove(t.firstChild),t.childNodes.length==0?c.dom.add(t,h.element,null,"<br />"):(C=t.innerHTML,t.innerHTML="",c.dom.add(t,h.element,null,C)),v=c.dom.add(t,h.element,null,"<br />"),u=e.createRange(),u.selectNodeContents(v),u.collapse(1),c.selection.setRng(u),n;if(t==l&&z==l&&l.firstChild&&c.dom.isBlock(l.firstChild))k=z=t.firstChild,t=k,y=r=0,s=e.createRange(),s.setStart(t,0),B=e.createRange(),B.setStart(z,
+0);t=t.nodeName=="HTML"?e.body:t;t=t.nodeName=="BODY"?t.firstChild:t;z=z.nodeName=="HTML"?e.body:z;z=z.nodeName=="BODY"?z.firstChild:z;x=this.getParentBlock(t);v=this.getParentBlock(z);q=x?x.nodeName:h.element;if(C=this.dom.getParent(x,"li,pre")){if(C.nodeName=="LI")return j(c.selection,this.dom,C);return d}if(x&&(x.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(g.getStyle(x,"position",1))))q=h.element,x=null;if(v&&(v.nodeName=="CAPTION"||/absolute|relative|fixed/gi.test(g.getStyle(x,"position",
+1))))q=h.element,v=null;if(/(TD|TABLE|TH|CAPTION)/.test(q)||x&&q=="DIV"&&/left|right/gi.test(g.getStyle(x,"float",1)))q=h.element,x=v=null;A=x&&x.nodeName==q?x.cloneNode(0):c.dom.create(q);v=v&&v.nodeName==q?v.cloneNode(0):c.dom.create(q);v.removeAttribute("id");/^(H[1-6])$/.test(q)&&i(u,x)&&(v=c.dom.create(h.element));C=x=t;do{if(C==l||C.nodeType==9||this.dom.isBlock(C)||/(TD|TABLE|TH|CAPTION)/.test(C.nodeName))break;x=C}while(C=C.previousSibling?C.previousSibling:C.parentNode);C=D=z;do{if(C==l||
+C.nodeType==9||this.dom.isBlock(C)||/(TD|TABLE|TH|CAPTION)/.test(C.nodeName))break;D=C}while(C=C.nextSibling?C.nextSibling:C.parentNode);x.nodeName==q?s.setStart(x,0):s.setStartBefore(x);s.setEnd(t,y);A.appendChild(s.cloneContents()||e.createTextNode(""));try{B.setEndAfter(D)}catch(K){}B.setStart(z,r);v.appendChild(B.cloneContents()||e.createTextNode(""));u=e.createRange();!x.previousSibling&&x.parentNode.nodeName==q?u.setStartBefore(x.parentNode):s.startContainer.nodeName==q&&s.startOffset==0?u.setStartBefore(s.startContainer):
+u.setStart(s.startContainer,s.startOffset);!D.nextSibling&&D.parentNode.nodeName==q?u.setEndAfter(D.parentNode):u.setEnd(B.endContainer,B.endOffset);u.deleteContents();f&&c.getWin().scrollTo(0,H.y);if(A.firstChild&&A.firstChild.nodeName==q)A.innerHTML=A.firstChild.innerHTML;if(v.firstChild&&v.firstChild.nodeName==q)v.innerHTML=v.firstChild.innerHTML;if(g.isEmpty(A))A.innerHTML="<br />";g.isEmpty(v)&&(F=b(v,z));f&&parseFloat(opera.version())<9.5?(u.insertNode(A),u.insertNode(v)):(u.insertNode(v),u.insertNode(A));
+v.normalize();A.normalize();u=e.createRange();u.selectNodeContents(a?e.createTreeWalker(F||v,NodeFilter.SHOW_TEXT,null,n).nextNode()||F||v:F||v);u.collapse(1);p.removeAllRanges();p.addRange(u);e=c.dom.getPos(v).y;if(e<H.y||e+25>H.y+H.h)c.getWin().scrollTo(0,e<H.y?e:e-H.h+25);c.undoManager.add();return n},backspaceDelete:function(a,b){var d=this.editor,e=d.getBody(),f,i=d.selection,j=i.getRng(),l=j.startContainer,s;if(!b&&j.collapsed&&l.nodeType==1&&j.startOffset==l.childNodes.length){s=new c.dom.TreeWalker(l.lastChild,
+l);for(f=l.lastChild;f;f=s.prev())if(f.nodeType==3){j.setStart(f,f.nodeValue.length);j.collapse(!0);i.setRng(j);return}}if(l&&d.dom.isBlock(l)&&!/^(TD|TH)$/.test(l.nodeName)&&b&&(l.childNodes.length==0||l.childNodes.length==1&&l.firstChild.nodeName=="BR")){for(f=l;(f=f.previousSibling)&&!d.dom.isBlock(f););if(f){if(l!=e.firstChild){for(e=d.dom.doc.createTreeWalker(f,NodeFilter.SHOW_TEXT,null,n);j=e.nextNode();)f=j;j=d.getDoc().createRange();j.setStart(f,f.nodeValue?f.nodeValue.length:0);j.setEnd(f,
+f.nodeValue?f.nodeValue.length:0);i.setRng(j);d.dom.remove(l)}return g.cancel(a)}}}})})(tinymce);
+(function(c){var i=c.dom.Event,j=c.each,g=c.extend;c.create("tinymce.ControlManager",{ControlManager:function(b,a){var f=this,a=a||{};f.editor=b;f.controls={};f.onAdd=new c.util.Dispatcher(f);f.onPostRender=new c.util.Dispatcher(f);f.prefix=a.prefix||b.id+"_";f._cls={};f.onPostRender.add(function(){j(f.controls,function(a){a.postRender()})})},get:function(b){return this.controls[this.prefix+b]||this.controls[b]},setActive:function(b,a){var c=null;(c=this.get(b))&&c.setActive(a);return c},setDisabled:function(b,
+a){var c=null;(c=this.get(b))&&c.setDisabled(a);return c},add:function(b){b&&(this.controls[b.id]=b,this.onAdd.dispatch(b,this));return b},createControl:function(b){var a,c=this,d=c.editor;j(d.plugins,function(d){if(d.createControl&&(a=d.createControl(b,c)))return!1});switch(b){case "|":case "separator":return c.createSeparator()}if(!a&&d.buttons&&(a=d.buttons[b]))return c.createButton(b,a);return c.add(a)},createDropMenu:function(b,a,f){var d=this.editor,i,j,m,a=g({"class":"mceDropDown",constrain:d.settings.constrain_menus},
+a);a["class"]=a["class"]+" "+d.getParam("skin")+"Skin";if(m=d.getParam("skin_variant"))a["class"]+=" "+d.getParam("skin")+"Skin"+m.substring(0,1).toUpperCase()+m.substring(1);b=this.prefix+b;i=this.controls[b]=new (f||this._cls.dropmenu||c.ui.DropMenu)(b,a);i.onAddItem.add(function(a,b){var c=b.settings;c.title=d.getLang(c.title,c.title);if(!c.onclick)c.onclick=function(){c.cmd&&d.execCommand(c.cmd,c.ui||!1,c.value)}});d.onRemove.add(function(){i.destroy()});c.isIE&&(i.onShowMenu.add(function(){d.focus();
+j=d.selection.getBookmark(1)}),i.onHideMenu.add(function(){j&&(d.selection.moveToBookmark(j),j=0)}));return this.add(i)},createListBox:function(b,a,f){var d=this.editor;if(this.get(b))return null;a.title=d.translate(a.title);a.scope=a.scope||d;if(!a.onselect)a.onselect=function(b){d.execCommand(a.cmd,a.ui||!1,b||a.value)};a=g({title:a.title,"class":"mce_"+b,scope:a.scope,control_manager:this},a);b=this.prefix+b;d.settings.use_native_selects?f=new c.ui.NativeListBox(b,a):(f=f||this._cls.listbox||c.ui.ListBox,
+f=new f(b,a,d));this.controls[b]=f;c.isWebKit&&f.onPostRender.add(function(a,b){i.add(b,"mousedown",function(){d.bookmark=d.selection.getBookmark(1)});i.add(b,"focus",function(){d.selection.moveToBookmark(d.bookmark);d.bookmark=null})});f.hideMenu&&d.onMouseDown.add(f.hideMenu,f);return this.add(f)},createButton:function(b,a,f){var d=this.editor;if(this.get(b))return null;a.title=d.translate(a.title);a.label=d.translate(a.label);a.scope=a.scope||d;if(!a.onclick&&!a.menu_button)a.onclick=function(){d.execCommand(a.cmd,
+a.ui||!1,a.value)};a=g({title:a.title,"class":"mce_"+b,unavailable_prefix:d.getLang("unavailable",""),scope:a.scope,control_manager:this},a);b=this.prefix+b;a.menu_button?(f=f||this._cls.menubutton||c.ui.MenuButton,b=new f(b,a,d),d.onMouseDown.add(b.hideMenu,b)):(f=this._cls.button||c.ui.Button,b=new f(b,a));return this.add(b)},createMenuButton:function(b,a,c){a=a||{};a.menu_button=1;return this.createButton(b,a,c)},createSplitButton:function(b,a,f){var d=this.editor;if(this.get(b))return null;a.title=
+d.translate(a.title);a.scope=a.scope||d;if(!a.onclick)a.onclick=function(b){d.execCommand(a.cmd,a.ui||!1,b||a.value)};if(!a.onselect)a.onselect=function(b){d.execCommand(a.cmd,a.ui||!1,b||a.value)};a=g({title:a.title,"class":"mce_"+b,scope:a.scope,control_manager:this},a);b=this.prefix+b;b=this.add(new (f||this._cls.splitbutton||c.ui.SplitButton)(b,a,d));d.onMouseDown.add(b.hideMenu,b);return b},createColorSplitButton:function(b,a,f){var d=this.editor,i,j;if(this.get(b))return null;a.title=d.translate(a.title);
+a.scope=a.scope||d;if(!a.onclick)a.onclick=function(b){c.isIE&&(j=d.selection.getBookmark(1));d.execCommand(a.cmd,a.ui||!1,b||a.value)};if(!a.onselect)a.onselect=function(b){d.execCommand(a.cmd,a.ui||!1,b||a.value)};a=g({title:a.title,"class":"mce_"+b,menu_class:d.getParam("skin")+"Skin",scope:a.scope,more_colors_title:d.getLang("more_colors")},a);b=this.prefix+b;i=new (f||this._cls.colorsplitbutton||c.ui.ColorSplitButton)(b,a,d);d.onMouseDown.add(i.hideMenu,i);d.onRemove.add(function(){i.destroy()});
+c.isIE&&(i.onShowMenu.add(function(){d.focus();j=d.selection.getBookmark(1)}),i.onHideMenu.add(function(){j&&(d.selection.moveToBookmark(j),j=0)}));return this.add(i)},createToolbar:function(b,a,f){b=this.prefix+b;a=new (f||this._cls.toolbar||c.ui.Toolbar)(b,a,this.editor);if(this.get(b))return null;return this.add(a)},createToolbarGroup:function(b,a,f){b=this.prefix+b;a=new (f||this._cls.toolbarGroup||c.ui.ToolbarGroup)(b,a,this.editor);if(this.get(b))return null;return this.add(a)},createSeparator:function(b){return new (b||
+this._cls.separator||c.ui.Separator)},setControlType:function(b,a){return this._cls[b.toLowerCase()]=a},destroy:function(){j(this.controls,function(b){b.destroy()});this.controls=null}})})(tinymce);
+(function(c){var i=c.util.Dispatcher,j=c.each,g=c.isIE,b=c.isOpera;c.create("tinymce.WindowManager",{WindowManager:function(a){this.editor=a;this.onOpen=new i(this);this.onClose=new i(this);this.params={};this.features={}},open:function(a,f){var d="",i=this.editor.settings.dialog_type=="modal",k,m,o;o=c.DOM.getViewPort();a=a||{};f=f||{};m=b?o.w:screen.width;o=b?o.h:screen.height;a.name=a.name||"mc_"+(new Date).getTime();a.width=parseInt(a.width||320);a.height=parseInt(a.height||240);a.resizable=!0;
+a.left=a.left||parseInt(m/2)-a.width/2;a.top=a.top||parseInt(o/2)-a.height/2;f.inline=!1;f.mce_width=a.width;f.mce_height=a.height;f.mce_auto_focus=a.auto_focus;if(i&&g)a.center=!0,a.help=!1,a.dialogWidth=a.width+"px",a.dialogHeight=a.height+"px",a.scroll=a.scrollbars||!1;j(a,function(a,b){c.is(a,"boolean")&&(a=a?"yes":"no");/^(name|url)$/.test(b)||(d+=g&&i?(d?";":"")+b+":"+a:(d?",":"")+b+"="+a)});this.features=a;this.params=f;this.onOpen.dispatch(this,a,f);m=a.url||a.file;m=c._addVer(m);try{g&&i?
+(k=1,window.showModalDialog(m,window,d)):k=window.open(m,a.name,d)}catch(e){}k||alert(this.editor.getLang("popup_blocked"))},close:function(a){a.close();this.onClose.dispatch(this)},createInstance:function(a,b,d,g,i,j){return new (c.resolve(a))(b,d,g,i,j)},confirm:function(a,b,c,g){b.call(c||this,(g||window).confirm(this._decode(this.editor.getLang(a,a))))},alert:function(a,b,c,g){(g||window).alert(this._decode(this.editor.getLang(a,a)));b&&b.call(c||this)},resizeBy:function(a,b,c){c.resizeBy(a,b)},
+_decode:function(a){return c.DOM.decode(a).replace(/\\n/g,"\n")}})})(tinymce);
+(function(c){c.Formatter=function(i){function j(a){return a.nodeType===1&&(a.face==="mceinline"||a.style.fontFamily==="mceinline")}function g(a){return a?x[a]:x}function b(a,c){a&&(typeof a!=="string"?v(a,function(a,c){b(c,a)}):(c=c.length?c:[c],v(c,function(a){if(a.deep===L)a.deep=!a.selector;if(a.split===L)a.split=!a.selector||a.inline;if(a.remove===L&&a.selector&&!a.inline)a.remove="none";if(a.selector&&a.inline)a.mixed=!0,a.block_expand=!0;if(typeof a.classes==="string")a.classes=a.classes.split(/\s+/)}),
+x[a]=c))}function a(a,b,f){function n(a){var b=a.startContainer,c=a.startOffset;if(b.nodeType==1||b.nodeValue==="")if(b=b.nodeType==1?b.childNodes[c]:b){b=new D(b,b.parentNode);for(c=b.current();c;c=b.next())if(c.nodeType==3&&!h(c)){a.setStart(c,0);break}}return a}function o(a,c){c=c||J;a&&(v(c.styles,function(c,d){q.setStyle(a,d,e(c,b))}),v(c.attributes,function(c,d){q.setAttrib(a,d,e(c,b))}),v(c.classes,function(c){c=e(c,b);q.hasClass(a,c)||q.addClass(a,c)}))}function p(e){var f=[],g,i;g=J.inline||
+J.block;i=q.create(g);o(i);C.walk(e,function(e){function h(e){var l=e.nodeName.toLowerCase(),n=e.parentNode.nodeName.toLowerCase(),p;if(m(l,"br"))k=0,J.block&&q.remove(e);else if(J.wrapper&&d(e,a,b))k=0;else if(J.block&&!J.wrapper&&/^(h[1-6]|p|div|pre|address|dl|dt|dd)$/.test(l))e=q.rename(e,g),o(e),f.push(e),k=0;else{if(J.selector&&(v(s,function(a){!("collapsed"in a&&a.collapsed!==S)&&q.is(e,a.selector)&&!j(e)&&(o(e,a),p=!0)}),!J.inline||p)){k=0;return}H(g,l)&&H(n,g)&&!(e.nodeType===3&&e.nodeValue.length===
+1&&e.nodeValue.charCodeAt(0)===65279)?(k||(k=i.cloneNode(I),e.parentNode.insertBefore(k,e),f.push(k)),k.appendChild(e)):(k=0,v(c.grep(e.childNodes),h),k=0)}}var k;v(e,h)});J.wrap_links===!1&&v(f,function(a){function b(a){var d,e,g;if(a.nodeName==="A"){e=i.cloneNode(I);f.push(e);g=c.grep(a.childNodes);for(d=0;d<g.length;d++)e.appendChild(g[d]);a.appendChild(e)}v(c.grep(a.childNodes),b)}b(a)});v(f,function(c){function e(a){var b,c;v(a.childNodes,function(a){if(a.nodeType==1&&!r(a)&&!j(a))return b=a,
+I});b&&k(b,J)&&(c=b.cloneNode(I),o(c),q.replace(c,a,E),q.remove(b,1));return c||a}var g;g=function(a){var b=0;v(a.childNodes,function(a){!h(a)&&!r(a)&&b++});return b}(c);if((f.length>1||!F(c))&&g===0)q.remove(c,1);else if(J.inline||J.wrapper){!J.exact&&g===1&&(c=e(c));v(s,function(a){v(q.select(a.inline,c),function(c){var d;if(a.wrap_links===!1){d=c.parentNode;do if(d.nodeName==="A")return;while(d=d.parentNode)}l(a,b,c,a.exact?c:null)})});if(d(c.parentNode,a,b))return q.remove(c,1),c=0,E;J.merge_with_parents&&
+q.getParent(c.parentNode,function(e){if(d(e,a,b))return q.remove(c,1),c=0,E});c&&(c=t(B(c),c),c=t(c,B(c,E)))}})}var s=g(a),J=s[0],x,S=A.isCollapsed();if(J)if(f)x=q.createRng(),x.setStartBefore(f),x.setEndAfter(f),p(u(x,s));else if(!S||!J.inline||q.select("td.mceSelected,th.mceSelected").length){x=i.selection.getNode();f=A.getBookmark();p(u(A.getRng(E),s));if(J.styles&&(J.styles.color||J.styles.textDecoration))c.walk(x,O,"childNodes"),O(x);A.moveToBookmark(f);A.setRng(n(A.getRng(E)));i.nodeChanged()}else z("apply",
+a,b)}function f(a,b,e){function f(a){var b=a.startContainer,c=a.startOffset,d;if(b.nodeType==3&&c>=b.nodeValue.length-1)b=b.parentNode,c=M(b)+1;if(b.nodeType==1){d=b.childNodes;b=d[Math.min(c,d.length-1)];b=new D(b);c>d.length-1&&b.next();for(c=b.current();c;c=b.next())if(c.nodeType==3&&!h(c)){b=q.create("a",null,N);c.parentNode.insertBefore(b,c);a.setStart(c,0);A.setRng(a);q.remove(b);break}}}function j(a){var d,e,f;d=c.grep(a.childNodes);e=0;for(f=t.length;e<f;e++)if(l(t[e],b,a,a))break;if(x.deep){e=
+0;for(f=d.length;e<f;e++)j(d[e])}}function k(c){var e;v(q.getParents(c.parentNode,void 0,q.getRoot()).reverse(),function(c){var f;!e&&c.id!="_start"&&c.id!="_end"&&(f=d(c,a,b))&&f.split!==!1&&(e=c)});return e}function m(a,c,d,e){var f,g,h,i,j,k;if(a){k=a.parentNode;for(f=c.parentNode;f&&f!=k;f=f.parentNode){g=f.cloneNode(I);for(j=0;j<t.length;j++)if(l(t[j],b,g,g)){g=0;break}g&&(h&&g.appendChild(h),i||(i=g),h=g)}if(e&&(!x.mixed||!F(a)))c=q.split(a,c);h&&(d.parentNode.insertBefore(h,d),i.appendChild(d))}return c}
+function o(a){var b=q.get(a?"_start":"_end"),c=b[a?"firstChild":"lastChild"];r(c)&&(c=c[a?"firstChild":"lastChild"]);q.remove(b,!0);return c}function s(a){var b,c,a=u(a,t,E);if(x.split)b=y(a,E),c=y(a),b!=c?(b=p(b,"span",{id:"_start","data-mce-type":"bookmark"}),c=p(c,"span",{id:"_end","data-mce-type":"bookmark"}),m(k(b),b,b,!0),m(k(c),c,c,!0),b=o(E),c=o()):b=c=m(k(b),b,b,!0),a.startContainer=b.parentNode,a.startOffset=M(b),a.endContainer=c.parentNode,a.endOffset=M(c)+1;C.walk(a,function(a){v(a,function(a){j(a);
+a.nodeType===1&&i.dom.getStyle(a,"text-decoration")==="underline"&&a.parentNode&&Q(a.parentNode)==="underline"&&l({deep:!1,exact:!0,inline:"span",styles:{textDecoration:"underline"}},null,a)})})}var t=g(a),x=t[0],B;e?(B=q.createRng(),B.setStartBefore(e),B.setEndAfter(e),s(B)):!A.isCollapsed()||!x.inline||q.select("td.mceSelected,th.mceSelected").length?(e=A.getBookmark(),s(A.getRng(E)),A.moveToBookmark(e),n(a,b,A.getStart())&&f(A.getRng(!0)),i.nodeChanged()):z("remove",a,b)}function d(a,b,c,d){function f(a,
+b,g){var h,i,j=b[g];if(j)if(j.length===L)for(h in j){if(j.hasOwnProperty(h)){i=g==="attributes"?q.getAttrib(a,h):o(a,h);if(d&&!i&&!b.exact)return;if((!d||b.exact)&&!m(i,e(j[h],c)))return}}else for(h=0;h<j.length;h++)if(g==="attributes"?q.getAttrib(a,j[h]):o(a,j[h]))break;return b}var h=g(b),i;if(h&&a)for(i=0;i<h.length;i++)if(b=h[i],k(a,b)&&f(a,b,"attributes")&&f(a,b,"styles")){if(h=b.classes)for(i=0;i<h.length;i++)if(!q.hasClass(a,h[i]))return;return b}}function n(a,b,c){function e(c){c=q.getParent(c,
+function(c){return!!d(c,a,b,!0)});return d(c,a,b)}var f;if(c)return e(c);if(A.isCollapsed()){for(c=G.apply.length-1;c>=0;c--)if(G.apply[c].name==a)return!0;for(c=G.remove.length-1;c>=0;c--)if(G.remove[c].name==a)return!1;return e(A.getNode())}c=A.getNode();if(e(c))return E;f=A.getStart();if(f!=c&&e(f))return E;return I}function k(a,b){if(m(a,b.inline))return E;if(m(a,b.block))return E;if(b.selector)return q.is(a,b.selector)}function m(a,b){a=a||"";b=b||"";a=""+(a.nodeName||a);b=""+(b.nodeName||b);
+return a.toLowerCase()==b.toLowerCase()}function o(a,b){var c=q.getStyle(a,b);if(b=="color"||b=="backgroundColor")c=q.toHex(c);b=="fontWeight"&&c==700&&(c="bold");return""+c}function e(a,b){typeof a!="string"?a=a(b):b&&(a=a.replace(/%(\w+)/g,function(a,c){return b[c]||a}));return a}function h(a){return a&&a.nodeType===3&&/^([\s\r\n]+|)$/.test(a.nodeValue)}function p(a,b,c){b=q.create(b,c);a.parentNode.insertBefore(b,a);b.appendChild(a);return b}function u(a,b){function c(a,d,e,f){for(var g,f=f||q.getRoot();;){g=
+a.parentNode;if(g==f||!b[0].block_expand&&F(g))break;for(j=g[d];j&&j!=a;j=j[e]){if(j.nodeType==1&&!r(j))return a;if(j.nodeType==3&&!h(j))return a}a=a.parentNode}return a}function d(a,b){for(b===L&&(b=a.nodeType===3?a.length:a.childNodes.length);a&&a.hasChildNodes();)(a=a.childNodes[b])&&(b=a.nodeType===3?a.length:a.childNodes.length);return{node:a,offset:b}}var e=a.startContainer,f=a.startOffset,g=a.endContainer,i=a.endOffset,j,k;e.nodeType==1&&e.hasChildNodes()&&(k=e.childNodes.length-1,e=e.childNodes[f>
+k?k:f],e.nodeType==3&&(f=0));if(g.nodeType==1&&g.hasChildNodes()&&(k=g.childNodes.length-1,g=g.childNodes[i>k?k:i-1],g.nodeType==3))i=g.nodeValue.length;if(r(e.parentNode))e=e.parentNode;r(e)&&(e=e.nextSibling||e);if(r(g.parentNode))i=q.nodeIndex(g),g=g.parentNode;if(r(g)&&g.previousSibling)g=g.previousSibling,i=g.length;if(b[0].inline&&(k=d(g,i),k.node)){for(;k.node&&k.offset===0&&k.node.previousSibling;)k=d(k.node.previousSibling);if(k.node&&k.offset>0&&k.node.nodeType===3&&k.node.nodeValue.charAt(k.offset-
+1)===" ")if(k.offset>1)g=k.node,g.splitText(k.offset-1);else if(k.node.previousSibling)g=k.node.previousSibling}if(b[0].inline||b[0].block_expand)e=c(e,"firstChild","nextSibling"),g=c(g,"lastChild","previousSibling");b[0].selector&&b[0].expand!==I&&!b[0].inline&&(k=function(c,d){var e,f,g,h;c.nodeType==3&&c.nodeValue.length==0&&c[d]&&(c=c[d]);e=q.getParents(c,void 0,q.getRoot());for(f=0;f<e.length;f++)for(g=0;g<b.length;g++)if(h=b[g],!("collapsed"in h&&h.collapsed!==a.collapsed)&&q.is(e[f],h.selector))return e[f];
+return c},e=k(e,"previousSibling"),g=k(g,"nextSibling"));if(b[0].block||b[0].selector)k=function(a,c){var d;b[0].wrapper||(d=q.getParent(a,b[0].block));d||(d=q.getParent(a.nodeType==3?a.parentNode:a,F));d&&b[0].wrapper&&(d=q.getParents(d,"ul,ol",q.getRoot()).reverse()[0]||d);if(!d)for(d=a;d[c]&&!F(d[c]);)if(d=d[c],m(d,"br"))break;return d||a},e=k(e,"previousSibling"),g=k(g,"nextSibling"),b[0].block&&(F(e)||(e=c(e,"firstChild","nextSibling")),F(g)||(g=c(g,"lastChild","previousSibling")));if(e.nodeType==
+1)f=M(e),e=e.parentNode;if(g.nodeType==1)i=M(g)+1,g=g.parentNode;return{startContainer:e,startOffset:f,endContainer:g,endOffset:i}}function l(a,b,c,d){var f,g,h;if(!k(c,a))return I;if(a.remove!="all"){v(a.styles,function(a,f){a=e(a,b);typeof f==="number"&&(f=a,d=0);(!d||m(o(d,f),a))&&q.setStyle(c,f,"");h=1});h&&q.getAttrib(c,"style")==""&&(c.removeAttribute("style"),c.removeAttribute("data-mce-style"));v(a.attributes,function(a,f){var g,a=e(a,b);typeof f==="number"&&(f=a,d=0);if(!d||m(q.getAttrib(d,
+f),a)){if(f=="class"&&(a=q.getAttrib(c,f)))if(g="",v(a.split(/\s+/),function(a){/mce\w+/.test(a)&&(g+=(g?" ":"")+a)}),g){q.setAttrib(c,f,g);return}f=="class"&&c.removeAttribute("className");P.test(f)&&c.removeAttribute("data-mce-"+f);c.removeAttribute(f)}});v(a.classes,function(a){a=e(a,b);(!d||q.hasClass(d,a))&&q.removeClass(c,a)});g=q.getAttribs(c);for(f=0;f<g.length;f++)if(g[f].nodeName.indexOf("_")!==0)return I}if(a.remove!="none")return s(c,a),E}function s(a,b){var d=a.parentNode,e;if(b.block)if(K)d==
+q.getRoot()&&(!b.list_block||!m(a,b.list_block))&&v(c.grep(a.childNodes),function(a){H(K,a.nodeName.toLowerCase())?e?e.appendChild(a):e=p(a,K):e=0});else{var f=function(a,b,c){a=B(a,b,c);return!a||a.nodeName=="BR"||F(a)};F(a)&&!F(d)&&(!f(a,I)&&!f(a.firstChild,E,1)&&a.insertBefore(q.create("br"),a.firstChild),!f(a,E)&&!f(a.lastChild,I,1)&&a.appendChild(q.create("br")))}(!b.selector||!b.inline||m(b.inline,a))&&q.remove(a,1)}function B(a,b,c){if(a){b=b?"nextSibling":"previousSibling";for(a=c?a:a[b];a;a=
+a[b])if(a.nodeType==1||!h(a))return a}}function r(a){return a&&a.nodeType==1&&a.getAttribute("data-mce-type")=="bookmark"}function t(a,b){function d(a,b){function c(a){var b={};v(q.getAttribs(a),function(c){c=c.nodeName.toLowerCase();c.indexOf("_")!==0&&c!=="style"&&(b[c]=q.getAttrib(a,c))});return b}function e(a,b){var c,d;for(d in a)if(a.hasOwnProperty(d)){c=b[d];if(c===L)return I;if(a[d]!=c)return I;delete b[d]}for(d in b)if(b.hasOwnProperty(d))return I;return E}if(a.nodeName!=b.nodeName)return I;
+if(!e(c(a),c(b)))return I;if(!e(q.parseStyle(q.getAttrib(a,"style")),q.parseStyle(q.getAttrib(b,"style"))))return I;return E}var e,f;if(a&&b&&(f=function(a,b){for(e=a;e;e=e[b]){if(e.nodeType==3&&e.nodeValue.length!==0)break;if(e.nodeType==1&&!r(e))return e}return a},a=f(a,"previousSibling"),b=f(b,"nextSibling"),d(a,b))){for(e=a.nextSibling;e&&e!=b;)f=e,e=e.nextSibling,a.appendChild(f);q.remove(b);v(c.grep(b.childNodes),function(b){a.appendChild(b)});return a}return b}function y(a,b){var c,d,e;c=a[b?
+"startContainer":"endContainer"];d=a[b?"startOffset":"endOffset"];c.nodeType==1&&(e=c.childNodes.length-1,!b&&d&&d--,c=c.childNodes[d>e?e:d]);return c}function z(b,d,e){function g(){return G.apply.length||G.remove.length}function h(b){v(G.apply.reverse(),function(c){a(c.name,c.vars,b);c.name==="forecolor"&&c.vars.value&&O(b.parentNode)});v(G.remove.reverse(),function(a){f(a.name,a.vars,b)});q.remove(b,1);G.apply=[];G.remove=[]}for(var k=G[b],l=G[b=="apply"?"remove":"apply"],b=k.length-1;b>=0;b--)if(k[b].name==
+d)return;k.push({name:d,vars:e});for(b=l.length-1;b>=0;b--)l[b].name==d&&l.splice(b,1);if(g()&&(i.getDoc().execCommand("FontName",!1,"mceinline"),G.lastRng=A.getRng(),v(q.select("font,span"),function(a){var b;j(a)&&(b=A.getBookmark(),h(a),A.moveToBookmark(b),i.nodeChanged())}),!G.isListening&&g()))G.isListening=!0,v("onKeyDown,onKeyUp,onKeyPress,onMouseUp".split(","),function(a){i[a].addToTop(function(a,b){if(g()&&!c.dom.RangeUtils.compareRanges(G.lastRng,A.getRng())&&(v(q.select("font,span"),function(b){var c;
+if(j(b))(c=b.firstChild)?(h(b),b=q.createRng(),b.setStart(c,c.nodeValue.length),b.setEnd(c,c.nodeValue.length),A.setRng(b),a.nodeChanged()):q.remove(b)}),b.type=="keyup"||b.type=="mouseup"))G.apply=[],G.remove=[]})})}var x={},v=c.each,q=i.dom,A=i.selection,D=c.dom.TreeWalker,C=new c.dom.RangeUtils(q),H=i.schema.isValidChild,F=q.isBlock,K=i.settings.forced_root_block,M=q.nodeIndex,N="\ufeff",P=/^(src|href|style)$/,I=!1,E=!0,L,G={apply:[],remove:[]},Q=function(a){var b;i.dom.getParent(a,function(a){return(b=
+i.dom.getStyle(a,"text-decoration"))&&b!=="none"});return b},O=function(a){var b;a.nodeType===1&&a.parentNode&&a.parentNode.nodeType===1&&(b=Q(a.parentNode),i.dom.getStyle(a,"color")&&b?i.dom.setStyle(a,"text-decoration",b):i.dom.getStyle(a,"textdecoration")===b&&i.dom.setStyle(a,"text-decoration",null))};c.extend(this,{get:g,register:b,apply:a,remove:f,toggle:function(b,c,d){var e=g(b);n(b,c,d)&&(!("toggle"in e[0])||e[0].toggle)?f(b,c,d):a(b,c,d)},match:n,matchAll:function(a,b){var c,e=[],f={},g,
+h;if(A.isCollapsed()){for(g=0;g<a.length;g++)for(c=G.remove.length-1;c>=0;c--)if(h=a[g],G.remove[c].name==h){f[h]=!0;break}for(c=G.apply.length-1;c>=0;c--)for(g=0;g<a.length;g++)h=a[g],!f[h]&&G.apply[c].name==h&&(f[h]=!0,e.push(h))}c=A.getStart();q.getParent(c,function(c){var g,h;for(g=0;g<a.length;g++)h=a[g],!f[h]&&d(c,h,b)&&(f[h]=!0,e.push(h))});return e},matchNode:d,canApply:function(a){var a=g(a),b,c,d,e;if(a){b=A.getStart();b=q.getParents(b,void 0,q.getRoot());for(d=a.length-1;d>=0;d--){e=a[d].selector;
+if(!e)return E;for(c=b.length-1;c>=0;c--)if(q.is(b[c],e))return E}}return I}})}})(tinymce);
+tinymce.onAddEditor.add(function(c,i){var j,g,b,a=i.settings;if(a.inline_styles){g=c.explode(a.font_size_style_values);var f=function(a,d){c.each(d,function(c,d){c&&b.setStyle(a,d,c)});b.rename(a,"span")};j={font:function(a,b){f(b,{backgroundColor:b.style.backgroundColor,color:b.color,fontFamily:b.face,fontSize:g[parseInt(b.size)-1]})},u:function(a,b){f(b,{textDecoration:"underline"})},strike:function(a,b){f(b,{textDecoration:"line-through"})}};var d=function(d,f){b=d.dom;a.convert_fonts_to_spans&&
+c.each(b.select("font,u,strike",f.node),function(a){j[a.nodeName.toLowerCase()](i.dom,a)})};i.onPreProcess.add(d);i.onSetContent.add(d);i.onInit.add(function(){i.selection.onSetContent.add(d)})}});
index 3ef3acb1fdc96824b8c7a357dfb4ee4d47ebe2bb..f859d24e6a6788d5890a02f76f96c81ff2749580 100644 (file)
@@ -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)},0)},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){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}}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);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
index 9db8d18fe0c0ce10dbdbf53ec5bda35e5d01796a..c1d47fcb7fc145df6a6b7f0dc015e76ceaf9c12a 100644 (file)
@@ -1,13 +1,13 @@
 (function(win) {\r
        var whiteSpaceRe = /^\s*|\s*$/g,\r
-               undefined;\r
+               undefined, isRegExpBroken = 'B'.replace(/A(.)|B/, '$1') === '$1';\r
 \r
        var tinymce = {\r
                majorVersion : '3',\r
 \r
-               minorVersion : '3.7',\r
+               minorVersion : '4.2',\r
 \r
-               releaseDate : '2010-06-10',\r
+               releaseDate : '2011-04-07',\r
 \r
                _init : function() {\r
                        var t = this, d = document, na = navigator, ua = na.userAgent, i, nl, n, base, p, v;\r
@@ -52,7 +52,7 @@
                        }\r
 \r
                        function getBase(n) {\r
-                               if (n.src && /tiny_mce(|_gzip|_jquery|_prototype)(_dev|_src)?.js/.test(n.src)) {\r
+                               if (n.src && /tiny_mce(|_gzip|_jquery|_prototype|_full)(_dev|_src)?.js/.test(n.src)) {\r
                                        if (/_(src|dev)\.js/g.test(n.src))\r
                                                t.suffix = '_src';\r
 \r
                        return typeof(o) == t;\r
                },\r
 \r
+               makeMap : function(items, delim, map) {\r
+                       var i;\r
+\r
+                       items = items || [];\r
+                       delim = delim || ',';\r
+\r
+                       if (typeof(items) == "string")\r
+                               items = items.split(delim);\r
+\r
+                       map = map || {};\r
+\r
+                       i = items.length;\r
+                       while (i--)\r
+                               map[items[i]] = {};\r
+\r
+                       return map;\r
+               },\r
+\r
                each : function(o, cb, s) {\r
                        var n, l;\r
 \r
                        return (s ? '' + s : '').replace(whiteSpaceRe, '');\r
                },\r
 \r
-               create : function(s, p) {\r
+               create : function(s, p, root) {\r
                        var t = this, sp, ns, cn, scn, c, de = 0;\r
 \r
                        // Parse : <prefix> <class>:<super class>\r
                        cn = s[3].match(/(^|\.)(\w+)$/i)[2]; // Class name\r
 \r
                        // Create namespace for new class\r
-                       ns = t.createNS(s[3].replace(/\.\w+$/, ''));\r
+                       ns = t.createNS(s[3].replace(/\.\w+$/, ''), root);\r
 \r
                        // Class already exists\r
                        if (ns[cn])\r
                                return u + v;\r
 \r
                        return u.replace('#', v + '#');\r
+               },\r
+\r
+               // Fix function for IE 9 where regexps isn't working correctly\r
+               // Todo: remove me once MS fixes the bug\r
+               _replace : function(find, replace, str) {\r
+                       // On IE9 we have to fake $x replacement\r
+                       if (isRegExpBroken) {\r
+                               return str.replace(find, function() {\r
+                                       var val = replace, args = arguments, i;\r
+\r
+                                       for (i = 0; i < args.length - 2; i++) {\r
+                                               if (args[i] === undefined) {\r
+                                                       val = val.replace(new RegExp('\\$' + i, 'g'), '');\r
+                                               } else {\r
+                                                       val = val.replace(new RegExp('\\$' + i, 'g'), args[i]);\r
+                                               }\r
+                                       }\r
+\r
+                                       return val;\r
+                               });\r
+                       }\r
+\r
+                       return str.replace(find, replace);\r
                }\r
 \r
                };\r
 \r
        // Expose tinymce namespace to the global namespace (window)\r
        win.tinymce = win.tinyMCE = tinymce;\r
-})(window);\r
+\r
+       // Describe the different namespaces\r
+\r
+       })(window);\r
 \r
 \r
 tinymce.create('tinymce.util.Dispatcher', {\r
@@ -805,9 +849,11 @@ tinymce.create('tinymce.util.Dispatcher', {
        });\r
 })();\r
 \r
-tinymce.create('static tinymce.util.JSON', {\r
-       serialize : function(o) {\r
-               var i, v, s = tinymce.util.JSON.serialize, t;\r
+(function() {\r
+       function serialize(o, quote) {\r
+               var i, v, t;\r
+\r
+               quote = quote || '"';\r
 \r
                if (o == null)\r
                        return 'null';\r
@@ -817,7 +863,11 @@ tinymce.create('static tinymce.util.JSON', {
                if (t == 'string') {\r
                        v = '\bb\tt\nn\ff\rr\""\'\'\\\\';\r
 \r
-                       return '"' + o.replace(/([\u0080-\uFFFF\x00-\x1f\"])/g, function(a, b) {\r
+                       return quote + o.replace(/([\u0080-\uFFFF\x00-\x1f\"\'\\])/g, function(a, b) {\r
+                               // Make sure single quotes never get encoded inside double quotes for JSON compatibility\r
+                               if (quote === '"' && a === "'")\r
+                                       return a;\r
+\r
                                i = v.indexOf(b);\r
 \r
                                if (i + 1)\r
@@ -826,13 +876,13 @@ tinymce.create('static tinymce.util.JSON', {
                                a = b.charCodeAt().toString(16);\r
 \r
                                return '\\u' + '0000'.substring(a.length) + a;\r
-                       }) + '"';\r
+                       }) + quote;\r
                }\r
 \r
                if (t == 'object') {\r
                        if (o.hasOwnProperty && o instanceof Array) {\r
                                        for (i=0, v = '['; i<o.length; i++)\r
-                                               v += (i > 0 ? ',' : '') + s(o[i]);\r
+                                               v += (i > 0 ? ',' : '') + serialize(o[i], quote);\r
 \r
                                        return v + ']';\r
                                }\r
@@ -840,24 +890,27 @@ tinymce.create('static tinymce.util.JSON', {
                                v = '{';\r
 \r
                                for (i in o)\r
-                                       v += typeof o[i] != 'function' ? (v.length > 1 ? ',"' : '"') + i + '":' + s(o[i]) : '';\r
+                                       v += typeof o[i] != 'function' ? (v.length > 1 ? ',' + quote : quote) + i + quote +':' + serialize(o[i], quote) : '';\r
 \r
                                return v + '}';\r
                }\r
 \r
                return '' + o;\r
-       },\r
+       };\r
 \r
-       parse : function(s) {\r
-               try {\r
-                       return eval('(' + s + ')');\r
-               } catch (ex) {\r
-                       // Ignore\r
-               }\r
-       }\r
+       tinymce.util.JSON = {\r
+               serialize: serialize,\r
 \r
-       });\r
+               parse: function(s) {\r
+                       try {\r
+                               return eval('(' + s + ')');\r
+                       } catch (ex) {\r
+                               // Ignore\r
+                       }\r
+               }\r
 \r
+               };\r
+})();\r
 tinymce.create('static tinymce.util.XHR', {\r
        send : function(o) {\r
                var x, t, w = window, c = 0;\r
@@ -948,7 +1001,8 @@ tinymce.create('static tinymce.util.XHR', {
                        };\r
 \r
                        o.error = function(ty, x) {\r
-                               ecb.call(o.error_scope || o.scope, ty, x);\r
+                               if (ecb)\r
+                                       ecb.call(o.error_scope || o.scope, ty, x);\r
                        };\r
 \r
                        o.data = JSON.serialize({\r
@@ -971,5861 +1025,6933 @@ tinymce.create('static tinymce.util.XHR', {
        });\r
 }());\r
 (function(tinymce) {\r
-       // Shorten names\r
-       var each = tinymce.each,\r
-               is = tinymce.is,\r
-               isWebKit = tinymce.isWebKit,\r
-               isIE = tinymce.isIE,\r
-               blockRe = /^(H[1-6R]|P|DIV|ADDRESS|PRE|FORM|T(ABLE|BODY|HEAD|FOOT|H|R|D)|LI|OL|UL|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD|DIR|FIELDSET|NOSCRIPT|MENU|ISINDEX|SAMP)$/,\r
-               boolAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'),\r
-               mceAttribs = makeMap('src,href,style,coords,shape'),\r
-               encodedChars = {'&' : '&amp;', '"' : '&quot;', '<' : '&lt;', '>' : '&gt;'},\r
-               encodeCharsRe = /[<>&\"]/g,\r
-               simpleSelectorRe = /^([a-z0-9],?)+$/i,\r
-               tagRegExp = /<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)(\s*\/?)>/g,\r
-               attrRegExp = /(\w+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;\r
-\r
-       function makeMap(str) {\r
-               var map = {}, i;\r
+       var namedEntities, baseEntities, reverseEntities,\r
+               attrsCharsRegExp = /[&\"\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,\r
+               textCharsRegExp = /[<>&\u007E-\uD7FF]|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,\r
+               rawCharsRegExp = /[<>&\"\']/g,\r
+               entityRegExp = /&(#)?([\w]+);/g,\r
+               asciiMap = {\r
+                               128 : "\u20AC", 130 : "\u201A", 131 : "\u0192", 132 : "\u201E", 133 : "\u2026", 134 : "\u2020",\r
+                               135 : "\u2021", 136 : "\u02C6", 137 : "\u2030", 138 : "\u0160", 139 : "\u2039", 140 : "\u0152",\r
+                               142 : "\u017D", 145 : "\u2018", 146 : "\u2019", 147 : "\u201C", 148 : "\u201D", 149 : "\u2022",\r
+                               150 : "\u2013", 151 : "\u2014", 152 : "\u02DC", 153 : "\u2122", 154 : "\u0161", 155 : "\u203A",\r
+                               156 : "\u0153", 158 : "\u017E", 159 : "\u0178"\r
+               };\r
 \r
-               str = str.split(',');\r
-               for (i = str.length; i >= 0; i--)\r
-                       map[str[i]] = 1;\r
+       // Raw entities\r
+       baseEntities = {\r
+               '"' : '&quot;',\r
+               "'" : '&#39;',\r
+               '<' : '&lt;',\r
+               '>' : '&gt;',\r
+               '&' : '&amp;'\r
+       };\r
 \r
-               return map;\r
+       // Reverse lookup table for raw entities\r
+       reverseEntities = {\r
+               '&lt;' : '<',\r
+               '&gt;' : '>',\r
+               '&amp;' : '&',\r
+               '&quot;' : '"',\r
+               '&apos;' : "'"\r
        };\r
 \r
-       tinymce.create('tinymce.dom.DOMUtils', {\r
-               doc : null,\r
-               root : null,\r
-               files : null,\r
-               pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,\r
-               props : {\r
-                       "for" : "htmlFor",\r
-                       "class" : "className",\r
-                       className : "className",\r
-                       checked : "checked",\r
-                       disabled : "disabled",\r
-                       maxlength : "maxLength",\r
-                       readonly : "readOnly",\r
-                       selected : "selected",\r
-                       value : "value",\r
-                       id : "id",\r
-                       name : "name",\r
-                       type : "type"\r
-               },\r
+       // Decodes text by using the browser\r
+       function nativeDecode(text) {\r
+               var elm;\r
 \r
-               DOMUtils : function(d, s) {\r
-                       var t = this, globalStyle;\r
+               elm = document.createElement("div");\r
+               elm.innerHTML = text;\r
 \r
-                       t.doc = d;\r
-                       t.win = window;\r
-                       t.files = {};\r
-                       t.cssFlicker = false;\r
-                       t.counter = 0;\r
-                       t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat"; \r
-                       t.stdMode = d.documentMode === 8;\r
+               return elm.textContent || elm.innerText || text;\r
+       };\r
 \r
-                       t.settings = s = tinymce.extend({\r
-                               keep_values : false,\r
-                               hex_colors : 1,\r
-                               process_html : 1\r
-                       }, s);\r
+       // Build a two way lookup table for the entities\r
+       function buildEntitiesLookup(items, radix) {\r
+               var i, chr, entity, lookup = {};\r
 \r
-                       // Fix IE6SP2 flicker and check it failed for pre SP2\r
-                       if (tinymce.isIE6) {\r
-                               try {\r
-                                       d.execCommand('BackgroundImageCache', false, true);\r
-                               } catch (e) {\r
-                                       t.cssFlicker = true;\r
+               if (items) {\r
+                       items = items.split(',');\r
+                       radix = radix || 10;\r
+\r
+                       // Build entities lookup table\r
+                       for (i = 0; i < items.length; i += 2) {\r
+                               chr = String.fromCharCode(parseInt(items[i], radix));\r
+\r
+                               // Only add non base entities\r
+                               if (!baseEntities[chr]) {\r
+                                       entity = '&' + items[i + 1] + ';';\r
+                                       lookup[chr] = entity;\r
+                                       lookup[entity] = chr;\r
                                }\r
                        }\r
 \r
-                       // Build styles list\r
-                       if (s.valid_styles) {\r
-                               t._styles = {};\r
+                       return lookup;\r
+               }\r
+       };\r
 \r
-                               // Convert styles into a rule list\r
-                               each(s.valid_styles, function(value, key) {\r
-                                       t._styles[key] = tinymce.explode(value);\r
-                               });\r
-                       }\r
+       // Unpack entities lookup where the numbers are in radix 32 to reduce the size\r
+       namedEntities = buildEntitiesLookup(\r
+               '50,nbsp,51,iexcl,52,cent,53,pound,54,curren,55,yen,56,brvbar,57,sect,58,uml,59,copy,' +\r
+               '5a,ordf,5b,laquo,5c,not,5d,shy,5e,reg,5f,macr,5g,deg,5h,plusmn,5i,sup2,5j,sup3,5k,acute,' +\r
+               '5l,micro,5m,para,5n,middot,5o,cedil,5p,sup1,5q,ordm,5r,raquo,5s,frac14,5t,frac12,5u,frac34,' +\r
+               '5v,iquest,60,Agrave,61,Aacute,62,Acirc,63,Atilde,64,Auml,65,Aring,66,AElig,67,Ccedil,' +\r
+               '68,Egrave,69,Eacute,6a,Ecirc,6b,Euml,6c,Igrave,6d,Iacute,6e,Icirc,6f,Iuml,6g,ETH,6h,Ntilde,' +\r
+               '6i,Ograve,6j,Oacute,6k,Ocirc,6l,Otilde,6m,Ouml,6n,times,6o,Oslash,6p,Ugrave,6q,Uacute,' +\r
+               '6r,Ucirc,6s,Uuml,6t,Yacute,6u,THORN,6v,szlig,70,agrave,71,aacute,72,acirc,73,atilde,74,auml,' +\r
+               '75,aring,76,aelig,77,ccedil,78,egrave,79,eacute,7a,ecirc,7b,euml,7c,igrave,7d,iacute,7e,icirc,' +\r
+               '7f,iuml,7g,eth,7h,ntilde,7i,ograve,7j,oacute,7k,ocirc,7l,otilde,7m,ouml,7n,divide,7o,oslash,' +\r
+               '7p,ugrave,7q,uacute,7r,ucirc,7s,uuml,7t,yacute,7u,thorn,7v,yuml,ci,fnof,sh,Alpha,si,Beta,' +\r
+               'sj,Gamma,sk,Delta,sl,Epsilon,sm,Zeta,sn,Eta,so,Theta,sp,Iota,sq,Kappa,sr,Lambda,ss,Mu,' +\r
+               'st,Nu,su,Xi,sv,Omicron,t0,Pi,t1,Rho,t3,Sigma,t4,Tau,t5,Upsilon,t6,Phi,t7,Chi,t8,Psi,' +\r
+               't9,Omega,th,alpha,ti,beta,tj,gamma,tk,delta,tl,epsilon,tm,zeta,tn,eta,to,theta,tp,iota,' +\r
+               'tq,kappa,tr,lambda,ts,mu,tt,nu,tu,xi,tv,omicron,u0,pi,u1,rho,u2,sigmaf,u3,sigma,u4,tau,' +\r
+               'u5,upsilon,u6,phi,u7,chi,u8,psi,u9,omega,uh,thetasym,ui,upsih,um,piv,812,bull,816,hellip,' +\r
+               '81i,prime,81j,Prime,81u,oline,824,frasl,88o,weierp,88h,image,88s,real,892,trade,89l,alefsym,' +\r
+               '8cg,larr,8ch,uarr,8ci,rarr,8cj,darr,8ck,harr,8dl,crarr,8eg,lArr,8eh,uArr,8ei,rArr,8ej,dArr,' +\r
+               '8ek,hArr,8g0,forall,8g2,part,8g3,exist,8g5,empty,8g7,nabla,8g8,isin,8g9,notin,8gb,ni,8gf,prod,' +\r
+               '8gh,sum,8gi,minus,8gn,lowast,8gq,radic,8gt,prop,8gu,infin,8h0,ang,8h7,and,8h8,or,8h9,cap,8ha,cup,' +\r
+               '8hb,int,8hk,there4,8hs,sim,8i5,cong,8i8,asymp,8j0,ne,8j1,equiv,8j4,le,8j5,ge,8k2,sub,8k3,sup,8k4,' +\r
+               'nsub,8k6,sube,8k7,supe,8kl,oplus,8kn,otimes,8l5,perp,8m5,sdot,8o8,lceil,8o9,rceil,8oa,lfloor,8ob,' +\r
+               'rfloor,8p9,lang,8pa,rang,9ea,loz,9j0,spades,9j3,clubs,9j5,hearts,9j6,diams,ai,OElig,aj,oelig,b0,' +\r
+               'Scaron,b1,scaron,bo,Yuml,m6,circ,ms,tilde,802,ensp,803,emsp,809,thinsp,80c,zwnj,80d,zwj,80e,lrm,' +\r
+               '80f,rlm,80j,ndash,80k,mdash,80o,lsquo,80p,rsquo,80q,sbquo,80s,ldquo,80t,rdquo,80u,bdquo,810,dagger,' +\r
+               '811,Dagger,81g,permil,81p,lsaquo,81q,rsaquo,85c,euro'\r
+       , 32);\r
+\r
+       tinymce.html = tinymce.html || {};\r
+\r
+       tinymce.html.Entities = {\r
+               encodeRaw : function(text, attr) {\r
+                       return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {\r
+                               return baseEntities[chr] || chr;\r
+                       });\r
+               },\r
 \r
-                       tinymce.addUnload(t.destroy, t);\r
+               encodeAllRaw : function(text) {\r
+                       return ('' + text).replace(rawCharsRegExp, function(chr) {\r
+                               return baseEntities[chr] || chr;\r
+                       });\r
                },\r
 \r
-               getRoot : function() {\r
-                       var t = this, s = t.settings;\r
+               encodeNumeric : function(text, attr) {\r
+                       return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {\r
+                               // Multi byte sequence convert it to a single entity\r
+                               if (chr.length > 1)\r
+                                       return '&#' + (((chr.charCodeAt(0) - 0xD800) * 0x400) + (chr.charCodeAt(1) - 0xDC00) + 0x10000) + ';';\r
 \r
-                       return (s && t.get(s.root_element)) || t.doc.body;\r
+                               return baseEntities[chr] || '&#' + chr.charCodeAt(0) + ';';\r
+                       });\r
                },\r
 \r
-               getViewPort : function(w) {\r
-                       var d, b;\r
-\r
-                       w = !w ? this.win : w;\r
-                       d = w.document;\r
-                       b = this.boxModel ? d.documentElement : d.body;\r
+               encodeNamed : function(text, attr, entities) {\r
+                       entities = entities || namedEntities;\r
 \r
-                       // Returns viewport size excluding scrollbars\r
-                       return {\r
-                               x : w.pageXOffset || b.scrollLeft,\r
-                               y : w.pageYOffset || b.scrollTop,\r
-                               w : w.innerWidth || b.clientWidth,\r
-                               h : w.innerHeight || b.clientHeight\r
-                       };\r
+                       return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {\r
+                               return baseEntities[chr] || entities[chr] || chr;\r
+                       });\r
                },\r
 \r
-               getRect : function(e) {\r
-                       var p, t = this, sr;\r
+               getEncodeFunc : function(name, entities) {\r
+                       var Entities = tinymce.html.Entities;\r
 \r
-                       e = t.get(e);\r
-                       p = t.getPos(e);\r
-                       sr = t.getSize(e);\r
+                       entities = buildEntitiesLookup(entities) || namedEntities;\r
 \r
-                       return {\r
-                               x : p.x,\r
-                               y : p.y,\r
-                               w : sr.w,\r
-                               h : sr.h\r
+                       function encodeNamedAndNumeric(text, attr) {\r
+                               return text.replace(attr ? attrsCharsRegExp : textCharsRegExp, function(chr) {\r
+                                       return baseEntities[chr] || entities[chr] || '&#' + chr.charCodeAt(0) + ';' || chr;\r
+                               });\r
                        };\r
-               },\r
-\r
-               getSize : function(e) {\r
-                       var t = this, w, h;\r
 \r
-                       e = t.get(e);\r
-                       w = t.getStyle(e, 'width');\r
-                       h = t.getStyle(e, 'height');\r
+                       function encodeCustomNamed(text, attr) {\r
+                               return Entities.encodeNamed(text, attr, entities);\r
+                       };\r
 \r
-                       // Non pixel value, then force offset/clientWidth\r
-                       if (w.indexOf('px') === -1)\r
-                               w = 0;\r
+                       // Replace + with , to be compatible with previous TinyMCE versions\r
+                       name = tinymce.makeMap(name.replace(/\+/g, ','));\r
 \r
-                       // Non pixel value, then force offset/clientWidth\r
-                       if (h.indexOf('px') === -1)\r
-                               h = 0;\r
+                       // Named and numeric encoder\r
+                       if (name.named && name.numeric)\r
+                               return encodeNamedAndNumeric;\r
 \r
-                       return {\r
-                               w : parseInt(w) || e.offsetWidth || e.clientWidth,\r
-                               h : parseInt(h) || e.offsetHeight || e.clientHeight\r
-                       };\r
-               },\r
+                       // Named encoder\r
+                       if (name.named) {\r
+                               // Custom names\r
+                               if (entities)\r
+                                       return encodeCustomNamed;\r
 \r
-               getParent : function(n, f, r) {\r
-                       return this.getParents(n, f, r, false);\r
-               },\r
+                               return Entities.encodeNamed;\r
+                       }\r
 \r
-               getParents : function(n, f, r, c) {\r
-                       var t = this, na, se = t.settings, o = [];\r
+                       // Numeric\r
+                       if (name.numeric)\r
+                               return Entities.encodeNumeric;\r
 \r
-                       n = t.get(n);\r
-                       c = c === undefined;\r
+                       // Raw encoder\r
+                       return Entities.encodeRaw;\r
+               },\r
 \r
-                       if (se.strict_root)\r
-                               r = r || t.getRoot();\r
+               decode : function(text) {\r
+                       return text.replace(entityRegExp, function(all, numeric, value) {\r
+                               if (numeric) {\r
+                                       value = parseInt(value);\r
 \r
-                       // Wrap node name as func\r
-                       if (is(f, 'string')) {\r
-                               na = f;\r
+                                       // Support upper UTF\r
+                                       if (value > 0xFFFF) {\r
+                                               value -= 0x10000;\r
 \r
-                               if (f === '*') {\r
-                                       f = function(n) {return n.nodeType == 1;};\r
-                               } else {\r
-                                       f = function(n) {\r
-                                               return t.is(n, na);\r
-                                       };\r
+                                               return String.fromCharCode(0xD800 + (value >> 10), 0xDC00 + (value & 0x3FF));\r
+                                       } else\r
+                                               return asciiMap[value] || String.fromCharCode(value);\r
                                }\r
-                       }\r
 \r
-                       while (n) {\r
-                               if (n == r || !n.nodeType || n.nodeType === 9)\r
-                                       break;\r
+                               return reverseEntities[all] || namedEntities[all] || nativeDecode(all);\r
+                       });\r
+               }\r
+       };\r
+})(tinymce);\r
 \r
-                               if (!f || f(n)) {\r
-                                       if (c)\r
-                                               o.push(n);\r
-                                       else\r
-                                               return n;\r
-                               }\r
+tinymce.html.Styles = function(settings, schema) {\r
+       var rgbRegExp = /rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)/gi,\r
+               urlOrStrRegExp = /(?:url(?:(?:\(\s*\"([^\"]+)\"\s*\))|(?:\(\s*\'([^\']+)\'\s*\))|(?:\(\s*([^)\s]+)\s*\))))|(?:\'([^\']+)\')|(?:\"([^\"]+)\")/gi,\r
+               styleRegExp = /\s*([^:]+):\s*([^;]+);?/g,\r
+               trimRightRegExp = /\s+$/,\r
+               urlColorRegExp = /rgb/,\r
+               undef, i, encodingLookup = {}, encodingItems;\r
 \r
-                               n = n.parentNode;\r
-                       }\r
+       settings = settings || {};\r
 \r
-                       return c ? o : null;\r
-               },\r
+       encodingItems = '\\" \\\' \\; \\: ; : _'.split(' ');\r
+       for (i = 0; i < encodingItems.length; i++) {\r
+               encodingLookup[encodingItems[i]] = '_' + i;\r
+               encodingLookup['_' + i] = encodingItems[i];\r
+       }\r
 \r
-               get : function(e) {\r
-                       var n;\r
+       function toHex(match, r, g, b) {\r
+               function hex(val) {\r
+                       val = parseInt(val).toString(16);\r
 \r
-                       if (e && this.doc && typeof(e) == 'string') {\r
-                               n = e;\r
-                               e = this.doc.getElementById(e);\r
+                       return val.length > 1 ? val : '0' + val; // 0 -> 00\r
+               };\r
 \r
-                               // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick\r
-                               if (e && e.id !== n)\r
-                                       return this.doc.getElementsByName(n)[1];\r
-                       }\r
+               return '#' + hex(r) + hex(g) + hex(b);\r
+       };\r
 \r
-                       return e;\r
+       return {\r
+               toHex : function(color) {\r
+                       return color.replace(rgbRegExp, toHex);\r
                },\r
 \r
-               getNext : function(node, selector) {\r
-                       return this._findSib(node, selector, 'nextSibling');\r
-               },\r
+               parse : function(css) {\r
+                       var styles = {}, matches, name, value, isEncoded, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope || this;\r
 \r
-               getPrev : function(node, selector) {\r
-                       return this._findSib(node, selector, 'previousSibling');\r
-               },\r
+                       function compress(prefix, suffix) {\r
+                               var top, right, bottom, left;\r
 \r
+                               // Get values and check it it needs compressing\r
+                               top = styles[prefix + '-top' + suffix];\r
+                               if (!top)\r
+                                       return;\r
 \r
-               select : function(pa, s) {\r
-                       var t = this;\r
+                               right = styles[prefix + '-right' + suffix];\r
+                               if (top != right)\r
+                                       return;\r
 \r
-                       return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []);\r
-               },\r
+                               bottom = styles[prefix + '-bottom' + suffix];\r
+                               if (right != bottom)\r
+                                       return;\r
 \r
-               is : function(n, selector) {\r
-                       var i;\r
+                               left = styles[prefix + '-left' + suffix];\r
+                               if (bottom != left)\r
+                                       return;\r
 \r
-                       // If it isn't an array then try to do some simple selectors instead of Sizzle for to boost performance\r
-                       if (n.length === undefined) {\r
-                               // Simple all selector\r
-                               if (selector === '*')\r
-                                       return n.nodeType == 1;\r
+                               // Compress\r
+                               styles[prefix + suffix] = left;\r
+                               delete styles[prefix + '-top' + suffix];\r
+                               delete styles[prefix + '-right' + suffix];\r
+                               delete styles[prefix + '-bottom' + suffix];\r
+                               delete styles[prefix + '-left' + suffix];\r
+                       };\r
 \r
-                               // Simple selector just elements\r
-                               if (simpleSelectorRe.test(selector)) {\r
-                                       selector = selector.toLowerCase().split(/,/);\r
-                                       n = n.nodeName.toLowerCase();\r
+                       function canCompress(key) {\r
+                               var value = styles[key], i;\r
 \r
-                                       for (i = selector.length - 1; i >= 0; i--) {\r
-                                               if (selector[i] == n)\r
-                                                       return true;\r
-                                       }\r
+                               if (!value || value.indexOf(' ') < 0)\r
+                                       return;\r
 \r
-                                       return false;\r
+                               value = value.split(' ');\r
+                               i = value.length;\r
+                               while (i--) {\r
+                                       if (value[i] !== value[0])\r
+                                               return false;\r
                                }\r
-                       }\r
 \r
-                       return tinymce.dom.Sizzle.matches(selector, n.nodeType ? [n] : n).length > 0;\r
-               },\r
+                               styles[key] = value[0];\r
 \r
+                               return true;\r
+                       };\r
 \r
-               add : function(p, n, a, h, c) {\r
-                       var t = this;\r
+                       function compress2(target, a, b, c) {\r
+                               if (!canCompress(a))\r
+                                       return;\r
 \r
-                       return this.run(p, function(p) {\r
-                               var e, k;\r
+                               if (!canCompress(b))\r
+                                       return;\r
 \r
-                               e = is(n, 'string') ? t.doc.createElement(n) : n;\r
-                               t.setAttribs(e, a);\r
+                               if (!canCompress(c))\r
+                                       return;\r
 \r
-                               if (h) {\r
-                                       if (h.nodeType)\r
-                                               e.appendChild(h);\r
-                                       else\r
-                                               t.setHTML(e, h);\r
-                               }\r
+                               // Compress\r
+                               styles[target] = styles[a] + ' ' + styles[b] + ' ' + styles[c];\r
+                               delete styles[a];\r
+                               delete styles[b];\r
+                               delete styles[c];\r
+                       };\r
 \r
-                               return !c ? p.appendChild(e) : e;\r
-                       });\r
-               },\r
+                       // Encodes the specified string by replacing all \" \' ; : with _<num>\r
+                       function encode(str) {\r
+                               isEncoded = true;\r
 \r
-               create : function(n, a, h) {\r
-                       return this.add(this.doc.createElement(n), n, a, h, 1);\r
-               },\r
+                               return encodingLookup[str];\r
+                       };\r
 \r
-               createHTML : function(n, a, h) {\r
-                       var o = '', t = this, k;\r
+                       // Decodes the specified string by replacing all _<num> with it's original value \" \' etc\r
+                       // It will also decode the \" \' if keep_slashes is set to fale or omitted\r
+                       function decode(str, keep_slashes) {\r
+                               if (isEncoded) {\r
+                                       str = str.replace(/_[0-9]/g, function(str) {\r
+                                               return encodingLookup[str];\r
+                                       });\r
+                               }\r
 \r
-                       o += '<' + n;\r
+                               if (!keep_slashes)\r
+                                       str = str.replace(/\\([\'\";:])/g, "$1");\r
 \r
-                       for (k in a) {\r
-                               if (a.hasOwnProperty(k))\r
-                                       o += ' ' + k + '="' + t.encode(a[k]) + '"';\r
+                               return str;\r
                        }\r
 \r
-                       if (tinymce.is(h))\r
-                               return o + '>' + h + '</' + n + '>';\r
+                       if (css) {\r
+                               // Encode \" \' % and ; and : inside strings so they don't interfere with the style parsing\r
+                               css = css.replace(/\\[\"\';:_]/g, encode).replace(/\"[^\"]+\"|\'[^\']+\'/g, function(str) {\r
+                                       return str.replace(/[;:]/g, encode);\r
+                               });\r
 \r
-                       return o + ' />';\r
-               },\r
+                               // Parse styles\r
+                               while (matches = styleRegExp.exec(css)) {\r
+                                       name = matches[1].replace(trimRightRegExp, '').toLowerCase();\r
+                                       value = matches[2].replace(trimRightRegExp, '');\r
 \r
-               remove : function(node, keep_children) {\r
-                       return this.run(node, function(node) {\r
-                               var parent, child;\r
+                                       if (name && value.length > 0) {\r
+                                               // Opera will produce 700 instead of bold in their style values\r
+                                               if (name === 'font-weight' && value === '700')\r
+                                                       value = 'bold';\r
+                                               else if (name === 'color' || name === 'background-color') // Lowercase colors like RED\r
+                                                       value = value.toLowerCase();            \r
 \r
-                               parent = node.parentNode;\r
+                                               // Convert RGB colors to HEX\r
+                                               value = value.replace(rgbRegExp, toHex);\r
 \r
-                               if (!parent)\r
-                                       return null;\r
+                                               // Convert URLs and force them into url('value') format\r
+                                               value = value.replace(urlOrStrRegExp, function(match, url, url2, url3, str, str2) {\r
+                                                       str = str || str2;\r
 \r
-                               if (keep_children) {\r
-                                       while (child = node.firstChild) {\r
-                                               // IE 8 will crash if you don't remove completely empty text nodes\r
-                                               if (!tinymce.isIE || child.nodeType !== 3 || child.nodeValue)\r
-                                                       parent.insertBefore(child, node);\r
-                                               else\r
-                                                       node.removeChild(child);\r
+                                                       if (str) {\r
+                                                               str = decode(str);\r
+\r
+                                                               // Force strings into single quote format\r
+                                                               return "'" + str.replace(/\'/g, "\\'") + "'";\r
+                                                       }\r
+\r
+                                                       url = decode(url || url2 || url3);\r
+\r
+                                                       // Convert the URL to relative/absolute depending on config\r
+                                                       if (urlConverter)\r
+                                                               url = urlConverter.call(urlConverterScope, url, 'style');\r
+\r
+                                                       // Output new URL format\r
+                                                       return "url('" + url.replace(/\'/g, "\\'") + "')";\r
+                                               });\r
+\r
+                                               styles[name] = isEncoded ? decode(value, true) : value;\r
                                        }\r
+\r
+                                       styleRegExp.lastIndex = matches.index + matches[0].length;\r
                                }\r
 \r
-                               return parent.removeChild(node);\r
-                       });\r
+                               // Compress the styles to reduce it's size for example IE will expand styles\r
+                               compress("border", "");\r
+                               compress("border", "-width");\r
+                               compress("border", "-color");\r
+                               compress("border", "-style");\r
+                               compress("padding", "");\r
+                               compress("margin", "");\r
+                               compress2('border', 'border-width', 'border-style', 'border-color');\r
+\r
+                               // Remove pointless border, IE produces these\r
+                               if (styles.border === 'medium none')\r
+                                       delete styles.border;\r
+                       }\r
+\r
+                       return styles;\r
                },\r
 \r
-               setStyle : function(n, na, v) {\r
-                       var t = this;\r
+               serialize : function(styles, element_name) {\r
+                       var css = '', name, value;\r
 \r
-                       return t.run(n, function(e) {\r
-                               var s, i;\r
+                       function serializeStyles(name) {\r
+                               var styleList, i, l, name, value;\r
 \r
-                               s = e.style;\r
+                               styleList = schema.styles[name];\r
+                               if (styleList) {\r
+                                       for (i = 0, l = styleList.length; i < l; i++) {\r
+                                               name = styleList[i];\r
+                                               value = styles[name];\r
 \r
-                               // Camelcase it, if needed\r
-                               na = na.replace(/-(\D)/g, function(a, b){\r
-                                       return b.toUpperCase();\r
-                               });\r
+                                               if (value !== undef && value.length > 0)\r
+                                                       css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';\r
+                                       }\r
+                               }\r
+                       };\r
 \r
-                               // Default px suffix on these\r
-                               if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))\r
-                                       v += 'px';\r
+                       // Serialize styles according to schema\r
+                       if (element_name && schema && schema.styles) {\r
+                               // Serialize global styles and element specific styles\r
+                               serializeStyles('*');\r
+                               serializeStyles(name);\r
+                       } else {\r
+                               // Output the styles in the order they are inside the object\r
+                               for (name in styles) {\r
+                                       value = styles[name];\r
 \r
-                               switch (na) {\r
-                                       case 'opacity':\r
-                                               // IE specific opacity\r
-                                               if (isIE) {\r
-                                                       s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";\r
+                                       if (value !== undef && value.length > 0)\r
+                                               css += (css.length > 0 ? ' ' : '') + name + ': ' + value + ';';\r
+                               }\r
+                       }\r
 \r
-                                                       if (!n.currentStyle || !n.currentStyle.hasLayout)\r
-                                                               s.display = 'inline-block';\r
-                                               }\r
+                       return css;\r
+               }\r
+       };\r
+};\r
 \r
-                                               // Fix for older browsers\r
-                                               s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || '';\r
-                                               break;\r
+(function(tinymce) {\r
+       var transitional = {}, boolAttrMap, blockElementsMap, shortEndedElementsMap, nonEmptyElementsMap,\r
+               whiteSpaceElementsMap, selfClosingElementsMap, makeMap = tinymce.makeMap, each = tinymce.each;\r
 \r
-                                       case 'float':\r
-                                               isIE ? s.styleFloat = v : s.cssFloat = v;\r
-                                               break;\r
-                                       \r
-                                       default:\r
-                                               s[na] = v || '';\r
-                               }\r
+       function split(str, delim) {\r
+               return str.split(delim || ',');\r
+       };\r
 \r
-                               // Force update of the style data\r
-                               if (t.settings.update_styles)\r
-                                       t.setAttrib(e, '_mce_style');\r
-                       });\r
-               },\r
+       function unpack(lookup, data) {\r
+               var key, elements = {};\r
 \r
-               getStyle : function(n, na, c) {\r
-                       n = this.get(n);\r
+               function replace(value) {\r
+                       return value.replace(/[A-Z]+/g, function(key) {\r
+                               return replace(lookup[key]);\r
+                       });\r
+               };\r
 \r
-                       if (!n)\r
-                               return false;\r
+               // Unpack lookup\r
+               for (key in lookup) {\r
+                       if (lookup.hasOwnProperty(key))\r
+                               lookup[key] = replace(lookup[key]);\r
+               }\r
 \r
-                       // Gecko\r
-                       if (this.doc.defaultView && c) {\r
-                               // Remove camelcase\r
-                               na = na.replace(/[A-Z]/g, function(a){\r
-                                       return '-' + a;\r
-                               });\r
+               // Unpack and parse data into object map\r
+               replace(data).replace(/#/g, '#text').replace(/(\w+)\[([^\]]+)\]\[([^\]]*)\]/g, function(str, name, attributes, children) {\r
+                       attributes = split(attributes, '|');\r
 \r
-                               try {\r
-                                       return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);\r
-                               } catch (ex) {\r
-                                       // Old safari might fail\r
-                                       return null;\r
-                               }\r
+                       elements[name] = {\r
+                               attributes : makeMap(attributes),\r
+                               attributesOrder : attributes,\r
+                               children : makeMap(children, '|', {'#comment' : {}})\r
                        }\r
+               });\r
 \r
-                       // Camelcase it, if needed\r
-                       na = na.replace(/-(\D)/g, function(a, b){\r
-                               return b.toUpperCase();\r
-                       });\r
+               return elements;\r
+       };\r
 \r
-                       if (na == 'float')\r
-                               na = isIE ? 'styleFloat' : 'cssFloat';\r
+       // Build a lookup table for block elements both lowercase and uppercase\r
+       blockElementsMap = 'h1,h2,h3,h4,h5,h6,hr,p,div,address,pre,form,table,tbody,thead,tfoot,' + \r
+                                               'th,tr,td,li,ol,ul,caption,blockquote,center,dl,dt,dd,dir,fieldset,' + \r
+                                               'noscript,menu,isindex,samp,header,footer,article,section,hgroup';\r
+       blockElementsMap = makeMap(blockElementsMap, ',', makeMap(blockElementsMap.toUpperCase()));\r
+\r
+       // This is the XHTML 1.0 transitional elements with it's attributes and children packed to reduce it's size\r
+       transitional = unpack({\r
+               Z : 'H|K|N|O|P',\r
+               Y : 'X|form|R|Q',\r
+               ZG : 'E|span|width|align|char|charoff|valign',\r
+               X : 'p|T|div|U|W|isindex|fieldset|table',\r
+               ZF : 'E|align|char|charoff|valign',\r
+               W : 'pre|hr|blockquote|address|center|noframes',\r
+               ZE : 'abbr|axis|headers|scope|rowspan|colspan|align|char|charoff|valign|nowrap|bgcolor|width|height',\r
+               ZD : '[E][S]',\r
+               U : 'ul|ol|dl|menu|dir',\r
+               ZC : 'p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q',\r
+               T : 'h1|h2|h3|h4|h5|h6',\r
+               ZB : 'X|S|Q',\r
+               S : 'R|P',\r
+               ZA : 'a|G|J|M|O|P',\r
+               R : 'a|H|K|N|O',\r
+               Q : 'noscript|P',\r
+               P : 'ins|del|script',\r
+               O : 'input|select|textarea|label|button',\r
+               N : 'M|L',\r
+               M : 'em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym',\r
+               L : 'sub|sup',\r
+               K : 'J|I',\r
+               J : 'tt|i|b|u|s|strike',\r
+               I : 'big|small|font|basefont',\r
+               H : 'G|F',\r
+               G : 'br|span|bdo',\r
+               F : 'object|applet|img|map|iframe',\r
+               E : 'A|B|C',\r
+               D : 'accesskey|tabindex|onfocus|onblur',\r
+               C : 'onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup',\r
+               B : 'lang|xml:lang|dir',\r
+               A : 'id|class|style|title'\r
+       }, 'script[id|charset|type|language|src|defer|xml:space][]' + \r
+               'style[B|id|type|media|title|xml:space][]' + \r
+               'object[E|declare|classid|codebase|data|type|codetype|archive|standby|width|height|usemap|name|tabindex|align|border|hspace|vspace][#|param|Y]' + \r
+               'param[id|name|value|valuetype|type][]' + \r
+               'p[E|align][#|S]' + \r
+               'a[E|D|charset|type|name|href|hreflang|rel|rev|shape|coords|target][#|Z]' + \r
+               'br[A|clear][]' + \r
+               'span[E][#|S]' + \r
+               'bdo[A|C|B][#|S]' + \r
+               'applet[A|codebase|archive|code|object|alt|name|width|height|align|hspace|vspace][#|param|Y]' + \r
+               'h1[E|align][#|S]' + \r
+               'img[E|src|alt|name|longdesc|width|height|usemap|ismap|align|border|hspace|vspace][]' + \r
+               'map[B|C|A|name][X|form|Q|area]' + \r
+               'h2[E|align][#|S]' + \r
+               'iframe[A|longdesc|name|src|frameborder|marginwidth|marginheight|scrolling|align|width|height][#|Y]' + \r
+               'h3[E|align][#|S]' + \r
+               'tt[E][#|S]' + \r
+               'i[E][#|S]' + \r
+               'b[E][#|S]' + \r
+               'u[E][#|S]' + \r
+               's[E][#|S]' + \r
+               'strike[E][#|S]' + \r
+               'big[E][#|S]' + \r
+               'small[E][#|S]' + \r
+               'font[A|B|size|color|face][#|S]' + \r
+               'basefont[id|size|color|face][]' + \r
+               'em[E][#|S]' + \r
+               'strong[E][#|S]' + \r
+               'dfn[E][#|S]' + \r
+               'code[E][#|S]' + \r
+               'q[E|cite][#|S]' + \r
+               'samp[E][#|S]' + \r
+               'kbd[E][#|S]' + \r
+               'var[E][#|S]' + \r
+               'cite[E][#|S]' + \r
+               'abbr[E][#|S]' + \r
+               'acronym[E][#|S]' + \r
+               'sub[E][#|S]' + \r
+               'sup[E][#|S]' + \r
+               'input[E|D|type|name|value|checked|disabled|readonly|size|maxlength|src|alt|usemap|onselect|onchange|accept|align][]' + \r
+               'select[E|name|size|multiple|disabled|tabindex|onfocus|onblur|onchange][optgroup|option]' + \r
+               'optgroup[E|disabled|label][option]' + \r
+               'option[E|selected|disabled|label|value][]' + \r
+               'textarea[E|D|name|rows|cols|disabled|readonly|onselect|onchange][]' + \r
+               'label[E|for|accesskey|onfocus|onblur][#|S]' + \r
+               'button[E|D|name|value|type|disabled][#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]' + \r
+               'h4[E|align][#|S]' + \r
+               'ins[E|cite|datetime][#|Y]' + \r
+               'h5[E|align][#|S]' + \r
+               'del[E|cite|datetime][#|Y]' + \r
+               'h6[E|align][#|S]' + \r
+               'div[E|align][#|Y]' + \r
+               'ul[E|type|compact][li]' + \r
+               'li[E|type|value][#|Y]' + \r
+               'ol[E|type|compact|start][li]' + \r
+               'dl[E|compact][dt|dd]' + \r
+               'dt[E][#|S]' + \r
+               'dd[E][#|Y]' + \r
+               'menu[E|compact][li]' + \r
+               'dir[E|compact][li]' + \r
+               'pre[E|width|xml:space][#|ZA]' + \r
+               'hr[E|align|noshade|size|width][]' + \r
+               'blockquote[E|cite][#|Y]' + \r
+               'address[E][#|S|p]' + \r
+               'center[E][#|Y]' + \r
+               'noframes[E][#|Y]' + \r
+               'isindex[A|B|prompt][]' + \r
+               'fieldset[E][#|legend|Y]' + \r
+               'legend[E|accesskey|align][#|S]' + \r
+               'table[E|summary|width|border|frame|rules|cellspacing|cellpadding|align|bgcolor][caption|col|colgroup|thead|tfoot|tbody|tr]' + \r
+               'caption[E|align][#|S]' + \r
+               'col[ZG][]' + \r
+               'colgroup[ZG][col]' + \r
+               'thead[ZF][tr]' + \r
+               'tr[ZF|bgcolor][th|td]' + \r
+               'th[E|ZE][#|Y]' + \r
+               'form[E|action|method|name|enctype|onsubmit|onreset|accept|accept-charset|target][#|X|R|Q]' + \r
+               'noscript[E][#|Y]' + \r
+               'td[E|ZE][#|Y]' + \r
+               'tfoot[ZF][tr]' + \r
+               'tbody[ZF][tr]' + \r
+               'area[E|D|shape|coords|href|nohref|alt|target][]' + \r
+               'base[id|href|target][]' + \r
+               'body[E|onload|onunload|background|bgcolor|text|link|vlink|alink][#|Y]'\r
+       );\r
 \r
-                       // IE & Opera\r
-                       if (n.currentStyle && c)\r
-                               return n.currentStyle[na];\r
+       boolAttrMap = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected,preload,autoplay,loop,controls');\r
+       shortEndedElementsMap = makeMap('area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed,source');\r
+       nonEmptyElementsMap = tinymce.extend(makeMap('td,th,iframe,video,object'), shortEndedElementsMap);\r
+       whiteSpaceElementsMap = makeMap('pre,script,style');\r
+       selfClosingElementsMap = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');\r
 \r
-                       return n.style[na];\r
-               },\r
+       tinymce.html.Schema = function(settings) {\r
+               var self = this, elements = {}, children = {}, patternElements = [], validStyles;\r
 \r
-               setStyles : function(e, o) {\r
-                       var t = this, s = t.settings, ol;\r
+               settings = settings || {};\r
 \r
-                       ol = s.update_styles;\r
-                       s.update_styles = 0;\r
+               // Allow all elements and attributes if verify_html is set to false\r
+               if (settings.verify_html === false)\r
+                       settings.valid_elements = '*[*]';\r
 \r
-                       each(o, function(v, n) {\r
-                               t.setStyle(e, n, v);\r
-                       });\r
+               // Build styles list\r
+               if (settings.valid_styles) {\r
+                       validStyles = {};\r
 \r
-                       // Update style info\r
-                       s.update_styles = ol;\r
-                       if (s.update_styles)\r
-                               t.setAttrib(e, s.cssText);\r
-               },\r
+                       // Convert styles into a rule list\r
+                       each(settings.valid_styles, function(value, key) {\r
+                               validStyles[key] = tinymce.explode(value);\r
+                       });\r
+               }\r
 \r
-               setAttrib : function(e, n, v) {\r
-                       var t = this;\r
+               // Converts a wildcard expression string to a regexp for example *a will become /.*a/.\r
+               function patternToRegExp(str) {\r
+                       return new RegExp('^' + str.replace(/([?+*])/g, '.$1') + '$');\r
+               };\r
 \r
-                       // Whats the point\r
-                       if (!e || !n)\r
-                               return;\r
+               // Parses the specified valid_elements string and adds to the current rules\r
+               // This function is a bit hard to read since it's heavily optimized for speed\r
+               function addValidElements(valid_elements) {\r
+                       var ei, el, ai, al, yl, matches, element, attr, attrData, elementName, attrName, attrType, attributes, attributesOrder,\r
+                               prefix, outputName, globalAttributes, globalAttributesOrder, transElement, key, childKey, value,\r
+                               elementRuleRegExp = /^([#+-])?([^\[\/]+)(?:\/([^\[]+))?(?:\[([^\]]+)\])?$/,\r
+                               attrRuleRegExp = /^([!\-])?(\w+::\w+|[^=:<]+)?(?:([=:<])(.*))?$/,\r
+                               hasPatternsRegExp = /[*?+]/;\r
+\r
+                       if (valid_elements) {\r
+                               // Split valid elements into an array with rules\r
+                               valid_elements = split(valid_elements);\r
+\r
+                               if (elements['@']) {\r
+                                       globalAttributes = elements['@'].attributes;\r
+                                       globalAttributesOrder = elements['@'].attributesOrder;\r
+                               }\r
+\r
+                               // Loop all rules\r
+                               for (ei = 0, el = valid_elements.length; ei < el; ei++) {\r
+                                       // Parse element rule\r
+                                       matches = elementRuleRegExp.exec(valid_elements[ei]);\r
+                                       if (matches) {\r
+                                               // Setup local names for matches\r
+                                               prefix = matches[1];\r
+                                               elementName = matches[2];\r
+                                               outputName = matches[3];\r
+                                               attrData = matches[4];\r
+\r
+                                               // Create new attributes and attributesOrder\r
+                                               attributes = {};\r
+                                               attributesOrder = [];\r
+\r
+                                               // Create the new element\r
+                                               element = {\r
+                                                       attributes : attributes,\r
+                                                       attributesOrder : attributesOrder\r
+                                               };\r
 \r
-                       // Strict XML mode\r
-                       if (t.settings.strict)\r
-                               n = n.toLowerCase();\r
+                                               // Padd empty elements prefix\r
+                                               if (prefix === '#')\r
+                                                       element.paddEmpty = true;\r
 \r
-                       return this.run(e, function(e) {\r
-                               var s = t.settings;\r
+                                               // Remove empty elements prefix\r
+                                               if (prefix === '-')\r
+                                                       element.removeEmpty = true;\r
 \r
-                               switch (n) {\r
-                                       case "style":\r
-                                               if (!is(v, 'string')) {\r
-                                                       each(v, function(v, n) {\r
-                                                               t.setStyle(e, n, v);\r
-                                                       });\r
+                                               // Copy attributes from global rule into current rule\r
+                                               if (globalAttributes) {\r
+                                                       for (key in globalAttributes)\r
+                                                               attributes[key] = globalAttributes[key];\r
 \r
-                                                       return;\r
+                                                       attributesOrder.push.apply(attributesOrder, globalAttributesOrder);\r
                                                }\r
 \r
-                                               // No mce_style for elements with these since they might get resized by the user\r
-                                               if (s.keep_values) {\r
-                                                       if (v && !t._isRes(v))\r
-                                                               e.setAttribute('_mce_style', v, 2);\r
-                                                       else\r
-                                                               e.removeAttribute('_mce_style', 2);\r
-                                               }\r
+                                               // Attributes defined\r
+                                               if (attrData) {\r
+                                                       attrData = split(attrData, '|');\r
+                                                       for (ai = 0, al = attrData.length; ai < al; ai++) {\r
+                                                               matches = attrRuleRegExp.exec(attrData[ai]);\r
+                                                               if (matches) {\r
+                                                                       attr = {};\r
+                                                                       attrType = matches[1];\r
+                                                                       attrName = matches[2].replace(/::/g, ':');\r
+                                                                       prefix = matches[3];\r
+                                                                       value = matches[4];\r
+\r
+                                                                       // Required\r
+                                                                       if (attrType === '!') {\r
+                                                                               element.attributesRequired = element.attributesRequired || [];\r
+                                                                               element.attributesRequired.push(attrName);\r
+                                                                               attr.required = true;\r
+                                                                       }\r
 \r
-                                               e.style.cssText = v;\r
-                                               break;\r
+                                                                       // Denied from global\r
+                                                                       if (attrType === '-') {\r
+                                                                               delete attributes[attrName];\r
+                                                                               attributesOrder.splice(tinymce.inArray(attributesOrder, attrName), 1);\r
+                                                                               continue;\r
+                                                                       }\r
 \r
-                                       case "class":\r
-                                               e.className = v || ''; // Fix IE null bug\r
-                                               break;\r
+                                                                       // Default value\r
+                                                                       if (prefix) {\r
+                                                                               // Default value\r
+                                                                               if (prefix === '=') {\r
+                                                                                       element.attributesDefault = element.attributesDefault || [];\r
+                                                                                       element.attributesDefault.push({name: attrName, value: value});\r
+                                                                                       attr.defaultValue = value;\r
+                                                                               }\r
 \r
-                                       case "src":\r
-                                       case "href":\r
-                                               if (s.keep_values) {\r
-                                                       if (s.url_converter)\r
-                                                               v = s.url_converter.call(s.url_converter_scope || t, v, n, e);\r
+                                                                               // Forced value\r
+                                                                               if (prefix === ':') {\r
+                                                                                       element.attributesForced = element.attributesForced || [];\r
+                                                                                       element.attributesForced.push({name: attrName, value: value});\r
+                                                                                       attr.forcedValue = value;\r
+                                                                               }\r
+\r
+                                                                               // Required values\r
+                                                                               if (prefix === '<')\r
+                                                                                       attr.validValues = makeMap(value, '?');\r
+                                                                       }\r
+\r
+                                                                       // Check for attribute patterns\r
+                                                                       if (hasPatternsRegExp.test(attrName)) {\r
+                                                                               element.attributePatterns = element.attributePatterns || [];\r
+                                                                               attr.pattern = patternToRegExp(attrName);\r
+                                                                               element.attributePatterns.push(attr);\r
+                                                                       } else {\r
+                                                                               // Add attribute to order list if it doesn't already exist\r
+                                                                               if (!attributes[attrName])\r
+                                                                                       attributesOrder.push(attrName);\r
 \r
-                                                       t.setAttrib(e, '_mce_' + n, v, 2);\r
+                                                                               attributes[attrName] = attr;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
                                                }\r
 \r
-                                               break;\r
-                                       \r
-                                       case "shape":\r
-                                               e.setAttribute('_mce_style', v);\r
-                                               break;\r
-                               }\r
+                                               // Global rule, store away these for later usage\r
+                                               if (!globalAttributes && elementName == '@') {\r
+                                                       globalAttributes = attributes;\r
+                                                       globalAttributesOrder = attributesOrder;\r
+                                               }\r
 \r
-                               if (is(v) && v !== null && v.length !== 0)\r
-                                       e.setAttribute(n, '' + v, 2);\r
-                               else\r
-                                       e.removeAttribute(n, 2);\r
-                       });\r
-               },\r
+                                               // Handle substitute elements such as b/strong\r
+                                               if (outputName) {\r
+                                                       element.outputName = elementName;\r
+                                                       elements[outputName] = element;\r
+                                               }\r
 \r
-               setAttribs : function(e, o) {\r
-                       var t = this;\r
+                                               // Add pattern or exact element\r
+                                               if (hasPatternsRegExp.test(elementName)) {\r
+                                                       element.pattern = patternToRegExp(elementName);\r
+                                                       patternElements.push(element);\r
+                                               } else\r
+                                                       elements[elementName] = element;\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
 \r
-                       return this.run(e, function(e) {\r
-                               each(o, function(v, n) {\r
-                                       t.setAttrib(e, n, v);\r
-                               });\r
-                       });\r
-               },\r
+               function setValidElements(valid_elements) {\r
+                       elements = {};\r
+                       patternElements = [];\r
 \r
-               getAttrib : function(e, n, dv) {\r
-                       var v, t = this;\r
+                       addValidElements(valid_elements);\r
 \r
-                       e = t.get(e);\r
+                       each(transitional, function(element, name) {\r
+                               children[name] = element.children;\r
+                       });\r
+               };\r
 \r
-                       if (!e || e.nodeType !== 1)\r
-                               return false;\r
+               // Adds custom non HTML elements to the schema\r
+               function addCustomElements(custom_elements) {\r
+                       var customElementRegExp = /^(~)?(.+)$/;\r
 \r
-                       if (!is(dv))\r
-                               dv = '';\r
+                       if (custom_elements) {\r
+                               each(split(custom_elements), function(rule) {\r
+                                       var matches = customElementRegExp.exec(rule),\r
+                                               cloneName = matches[1] === '~' ? 'span' : 'div',\r
+                                               name = matches[2];\r
 \r
-                       // Try the mce variant for these\r
-                       if (/^(src|href|style|coords|shape)$/.test(n)) {\r
-                               v = e.getAttribute("_mce_" + n);\r
+                                       children[name] = children[cloneName];\r
 \r
-                               if (v)\r
-                                       return v;\r
+                                       // Add custom elements at span/div positions\r
+                                       each(children, function(element, child) {\r
+                                               if (element[cloneName])\r
+                                                       element[name] = element[cloneName];\r
+                                       });\r
+                               });\r
                        }\r
+               };\r
 \r
-                       if (isIE && t.props[n]) {\r
-                               v = e[t.props[n]];\r
-                               v = v && v.nodeValue ? v.nodeValue : v;\r
-                       }\r
+               // Adds valid children to the schema object\r
+               function addValidChildren(valid_children) {\r
+                       var childRuleRegExp = /^([+\-]?)(\w+)\[([^\]]+)\]$/;\r
 \r
-                       if (!v)\r
-                               v = e.getAttribute(n, 2);\r
+                       if (valid_children) {\r
+                               each(split(valid_children), function(rule) {\r
+                                       var matches = childRuleRegExp.exec(rule), parent, prefix;\r
 \r
-                       // Check boolean attribs\r
-                       if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) {\r
-                               if (e[t.props[n]] === true && v === '')\r
-                                       return n;\r
+                                       if (matches) {\r
+                                               prefix = matches[1];\r
 \r
-                               return v ? n : '';\r
-                       }\r
+                                               // Add/remove items from default\r
+                                               if (prefix)\r
+                                                       parent = children[matches[2]];\r
+                                               else\r
+                                                       parent = children[matches[2]] = {'#comment' : {}};\r
 \r
-                       // Inner input elements will override attributes on form elements\r
-                       if (e.nodeName === "FORM" && e.getAttributeNode(n))\r
-                               return e.getAttributeNode(n).nodeValue;\r
+                                               parent = children[matches[2]];\r
 \r
-                       if (n === 'style') {\r
-                               v = v || e.style.cssText;\r
-\r
-                               if (v) {\r
-                                       v = t.serializeStyle(t.parseStyle(v), e.nodeName);\r
-\r
-                                       if (t.settings.keep_values && !t._isRes(v))\r
-                                               e.setAttribute('_mce_style', v);\r
-                               }\r
+                                               each(split(matches[3], '|'), function(child) {\r
+                                                       if (prefix === '-')\r
+                                                               delete parent[child];\r
+                                                       else\r
+                                                               parent[child] = {};\r
+                                               });\r
+                                       }\r
+                               });\r
                        }\r
+               }\r
 \r
-                       // Remove Apple and WebKit stuff\r
-                       if (isWebKit && n === "class" && v)\r
-                               v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');\r
+               if (!settings.valid_elements) {\r
+                       // No valid elements defined then clone the elements from the transitional spec\r
+                       each(transitional, function(element, name) {\r
+                               elements[name] = {\r
+                                       attributes : element.attributes,\r
+                                       attributesOrder : element.attributesOrder\r
+                               };\r
 \r
-                       // Handle IE issues\r
-                       if (isIE) {\r
-                               switch (n) {\r
-                                       case 'rowspan':\r
-                                       case 'colspan':\r
-                                               // IE returns 1 as default value\r
-                                               if (v === 1)\r
-                                                       v = '';\r
+                               children[name] = element.children;\r
+                       });\r
 \r
-                                               break;\r
+                       // Switch these\r
+                       each(split('strong/b,em/i'), function(item) {\r
+                               item = split(item, '/');\r
+                               elements[item[1]].outputName = item[0];\r
+                       });\r
 \r
-                                       case 'size':\r
-                                               // IE returns +0 as default value for size\r
-                                               if (v === '+0' || v === 20 || v === 0)\r
-                                                       v = '';\r
+                       // Add default alt attribute for images\r
+                       elements.img.attributesDefault = [{name: 'alt', value: ''}];\r
 \r
-                                               break;\r
+                       // Remove these if they are empty by default\r
+                       each(split('ol,ul,li,sub,sup,blockquote,tr,div,span,font,a,table,tbody'), function(name) {\r
+                               elements[name].removeEmpty = true;\r
+                       });\r
 \r
-                                       case 'width':\r
-                                       case 'height':\r
-                                       case 'vspace':\r
-                                       case 'checked':\r
-                                       case 'disabled':\r
-                                       case 'readonly':\r
-                                               if (v === 0)\r
-                                                       v = '';\r
+                       // Padd these by default\r
+                       each(split('p,h1,h2,h3,h4,h5,h6,th,td,pre,div,address,caption'), function(name) {\r
+                               elements[name].paddEmpty = true;\r
+                       });\r
+               } else\r
+                       setValidElements(settings.valid_elements);\r
 \r
-                                               break;\r
+               addCustomElements(settings.custom_elements);\r
+               addValidChildren(settings.valid_children);\r
+               addValidElements(settings.extended_valid_elements);\r
 \r
-                                       case 'hspace':\r
-                                               // IE returns -1 as default value\r
-                                               if (v === -1)\r
-                                                       v = '';\r
+               // Todo: Remove this when we fix list handling to be valid\r
+               addValidChildren('+ol[ul|ol],+ul[ul|ol]');\r
 \r
-                                               break;\r
+               // Delete invalid elements\r
+               if (settings.invalid_elements) {\r
+                       tinymce.each(tinymce.explode(settings.invalid_elements), function(item) {\r
+                               if (elements[item])\r
+                                       delete elements[item];\r
+                       });\r
+               }\r
 \r
-                                       case 'maxlength':\r
-                                       case 'tabindex':\r
-                                               // IE returns default value\r
-                                               if (v === 32768 || v === 2147483647 || v === '32768')\r
-                                                       v = '';\r
+               self.children = children;\r
 \r
-                                               break;\r
+               self.styles = validStyles;\r
 \r
-                                       case 'multiple':\r
-                                       case 'compact':\r
-                                       case 'noshade':\r
-                                       case 'nowrap':\r
-                                               if (v === 65535)\r
-                                                       return n;\r
+               self.getBoolAttrs = function() {\r
+                       return boolAttrMap;\r
+               };\r
 \r
-                                               return dv;\r
+               self.getBlockElements = function() {\r
+                       return blockElementsMap;\r
+               };\r
 \r
-                                       case 'shape':\r
-                                               v = v.toLowerCase();\r
-                                               break;\r
+               self.getShortEndedElements = function() {\r
+                       return shortEndedElementsMap;\r
+               };\r
 \r
-                                       default:\r
-                                               // IE has odd anonymous function for event attributes\r
-                                               if (n.indexOf('on') === 0 && v)\r
-                                                       v = ('' + v).replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1');\r
-                               }\r
-                       }\r
+               self.getSelfClosingElements = function() {\r
+                       return selfClosingElementsMap;\r
+               };\r
 \r
-                       return (v !== undefined && v !== null && v !== '') ? '' + v : dv;\r
-               },\r
+               self.getNonEmptyElements = function() {\r
+                       return nonEmptyElementsMap;\r
+               };\r
 \r
-               getPos : function(n, ro) {\r
-                       var t = this, x = 0, y = 0, e, d = t.doc, r;\r
+               self.getWhiteSpaceElements = function() {\r
+                       return whiteSpaceElementsMap;\r
+               };\r
 \r
-                       n = t.get(n);\r
-                       ro = ro || d.body;\r
+               self.isValidChild = function(name, child) {\r
+                       var parent = children[name];\r
 \r
-                       if (n) {\r
-                               // Use getBoundingClientRect on IE, Opera has it but it's not perfect\r
-                               if (isIE && !t.stdMode) {\r
-                                       n = n.getBoundingClientRect();\r
-                                       e = t.boxModel ? d.documentElement : d.body;\r
-                                       x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border\r
-                                       x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;\r
-                                       n.top += t.win.self != t.win.top ? 2 : 0; // IE adds some strange extra cord if used in a frameset\r
+                       return !!(parent && parent[child]);\r
+               };\r
 \r
-                                       return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
-                               }\r
+               self.getElementRule = function(name) {\r
+                       var element = elements[name], i;\r
 \r
-                               r = n;\r
-                               while (r && r != ro && r.nodeType) {\r
-                                       x += r.offsetLeft || 0;\r
-                                       y += r.offsetTop || 0;\r
-                                       r = r.offsetParent;\r
-                               }\r
+                       // Exact match found\r
+                       if (element)\r
+                               return element;\r
 \r
-                               r = n.parentNode;\r
-                               while (r && r != ro && r.nodeType) {\r
-                                       x -= r.scrollLeft || 0;\r
-                                       y -= r.scrollTop || 0;\r
-                                       r = r.parentNode;\r
-                               }\r
+                       // No exact match then try the patterns\r
+                       i = patternElements.length;\r
+                       while (i--) {\r
+                               element = patternElements[i];\r
+\r
+                               if (element.pattern.test(name))\r
+                                       return element;\r
                        }\r
+               };\r
 \r
-                       return {x : x, y : y};\r
-               },\r
+               self.addValidElements = addValidElements;\r
 \r
-               parseStyle : function(st) {\r
-                       var t = this, s = t.settings, o = {};\r
+               self.setValidElements = setValidElements;\r
 \r
-                       if (!st)\r
-                               return o;\r
+               self.addCustomElements = addCustomElements;\r
 \r
-                       function compress(p, s, ot) {\r
-                               var t, r, b, l;\r
+               self.addValidChildren = addValidChildren;\r
+       };\r
 \r
-                               // Get values and check it it needs compressing\r
-                               t = o[p + '-top' + s];\r
-                               if (!t)\r
-                                       return;\r
+       // Expose boolMap and blockElementMap as static properties for usage in DOMUtils\r
+       tinymce.html.Schema.boolAttrMap = boolAttrMap;\r
+       tinymce.html.Schema.blockElementsMap = blockElementsMap;\r
+})(tinymce);\r
 \r
-                               r = o[p + '-right' + s];\r
-                               if (t != r)\r
-                                       return;\r
+(function(tinymce) {\r
+       tinymce.html.SaxParser = function(settings, schema) {\r
+               var self = this, noop = function() {};\r
 \r
-                               b = o[p + '-bottom' + s];\r
-                               if (r != b)\r
-                                       return;\r
+               settings = settings || {};\r
+               self.schema = schema = schema || new tinymce.html.Schema();\r
 \r
-                               l = o[p + '-left' + s];\r
-                               if (b != l)\r
-                                       return;\r
+               if (settings.fix_self_closing !== false)\r
+                       settings.fix_self_closing = true;\r
 \r
-                               // Compress\r
-                               o[ot] = l;\r
-                               delete o[p + '-top' + s];\r
-                               delete o[p + '-right' + s];\r
-                               delete o[p + '-bottom' + s];\r
-                               delete o[p + '-left' + s];\r
-                       };\r
+               // Add handler functions from settings and setup default handlers\r
+               tinymce.each('comment cdata text start end pi doctype'.split(' '), function(name) {\r
+                       if (name)\r
+                               self[name] = settings[name] || noop;\r
+               });\r
 \r
-                       function compress2(ta, a, b, c) {\r
-                               var t;\r
+               self.parse = function(html) {\r
+                       var self = this, matches, index = 0, value, endRegExp, stack = [], attrList, i, text, name,\r
+                               shortEndedElements, fillAttrsMap, isShortEnded, validate, elementRule, isValidElement, attr, attribsValue,\r
+                               validAttributesMap, validAttributePatterns, attributesRequired, attributesDefault, attributesForced, selfClosing,\r
+                               tokenRegExp, attrRegExp, specialElements, attrValue, idCount = 0, decode = tinymce.html.Entities.decode, fixSelfClosing;\r
 \r
-                               t = o[a];\r
-                               if (!t)\r
-                                       return;\r
+                       function processEndTag(name) {\r
+                               var pos, i;\r
 \r
-                               t = o[b];\r
-                               if (!t)\r
-                                       return;\r
+                               // Find position of parent of the same type\r
+                               pos = stack.length;\r
+                               while (pos--) {\r
+                                       if (stack[pos].name === name)\r
+                                               break;                                          \r
+                               }\r
 \r
-                               t = o[c];\r
-                               if (!t)\r
-                                       return;\r
+                               // Found parent\r
+                               if (pos >= 0) {\r
+                                       // Close all the open elements\r
+                                       for (i = stack.length - 1; i >= pos; i--) {\r
+                                               name = stack[i];\r
 \r
-                               // Compress\r
-                               o[ta] = o[a] + ' ' + o[b] + ' ' + o[c];\r
-                               delete o[a];\r
-                               delete o[b];\r
-                               delete o[c];\r
+                                               if (name.valid)\r
+                                                       self.end(name.name);\r
+                                       }\r
+\r
+                                       // Remove the open elements from the stack\r
+                                       stack.length = pos;\r
+                               }\r
                        };\r
 \r
-                       st = st.replace(/&(#?[a-z0-9]+);/g, '&$1_MCE_SEMI_'); // Protect entities\r
+                       // Precompile RegExps and map objects\r
+                       tokenRegExp = new RegExp('<(?:' +\r
+                               '(?:!--([\\w\\W]*?)-->)|' + // Comment\r
+                               '(?:!\\[CDATA\\[([\\w\\W]*?)\\]\\]>)|' + // CDATA\r
+                               '(?:!DOCTYPE([\\w\\W]*?)>)|' + // DOCTYPE\r
+                               '(?:\\?([^\\s\\/<>]+) ?([\\w\\W]*?)[?/]>)|' + // PI\r
+                               '(?:\\/([^>]+)>)|' + // End element\r
+                               '(?:([^\\s\\/<>]+)\\s*((?:[^"\'>]+(?:(?:"[^"]*")|(?:\'[^\']*\')|[^>]*))*)>)' + // Start element\r
+                       ')', 'g');\r
+\r
+                       attrRegExp = /([\w:\-]+)(?:\s*=\s*(?:(?:\"((?:\\.|[^\"])*)\")|(?:\'((?:\\.|[^\'])*)\')|([^>\s]+)))?/g;\r
+                       specialElements = {\r
+                               'script' : /<\/script[^>]*>/gi,\r
+                               'style' : /<\/style[^>]*>/gi,\r
+                               'noscript' : /<\/noscript[^>]*>/gi\r
+                       };\r
 \r
-                       each(st.split(';'), function(v) {\r
-                               var sv, ur = [];\r
+                       // Setup lookup tables for empty elements and boolean attributes\r
+                       shortEndedElements = schema.getShortEndedElements();\r
+                       selfClosing = schema.getSelfClosingElements();\r
+                       fillAttrsMap = schema.getBoolAttrs();\r
+                       validate = settings.validate;\r
+                       fixSelfClosing = settings.fix_self_closing;\r
+\r
+                       while (matches = tokenRegExp.exec(html)) {\r
+                               // Text\r
+                               if (index < matches.index)\r
+                                       self.text(decode(html.substr(index, matches.index - index)));\r
+\r
+                               if (value = matches[6]) { // End element\r
+                                       processEndTag(value.toLowerCase());\r
+                               } else if (value = matches[7]) { // Start element\r
+                                       value = value.toLowerCase();\r
+                                       isShortEnded = value in shortEndedElements;\r
+\r
+                                       // Is self closing tag for example an <li> after an open <li>\r
+                                       if (fixSelfClosing && selfClosing[value] && stack.length > 0 && stack[stack.length - 1].name === value)\r
+                                               processEndTag(value);\r
+\r
+                                       // Validate element\r
+                                       if (!validate || (elementRule = schema.getElementRule(value))) {\r
+                                               isValidElement = true;\r
+\r
+                                               // Grab attributes map and patters when validation is enabled\r
+                                               if (validate) {\r
+                                                       validAttributesMap = elementRule.attributes;\r
+                                                       validAttributePatterns = elementRule.attributePatterns;\r
+                                               }\r
 \r
-                               if (v) {\r
-                                       v = v.replace(/_MCE_SEMI_/g, ';'); // Restore entities\r
-                                       v = v.replace(/url\([^\)]+\)/g, function(v) {ur.push(v);return 'url(' + ur.length + ')';});\r
-                                       v = v.split(':');\r
-                                       sv = tinymce.trim(v[1]);\r
-                                       sv = sv.replace(/url\(([^\)]+)\)/g, function(a, b) {return ur[parseInt(b) - 1];});\r
-\r
-                                       sv = sv.replace(/rgb\([^\)]+\)/g, function(v) {\r
-                                               return t.toHex(v);\r
-                                       });\r
+                                               // Parse attributes\r
+                                               if (attribsValue = matches[8]) {\r
+                                                       attrList = [];\r
+                                                       attrList.map = {};\r
 \r
-                                       if (s.url_converter) {\r
-                                               sv = sv.replace(/url\([\'\"]?([^\)\'\"]+)[\'\"]?\)/g, function(x, c) {\r
-                                                       return 'url(' + s.url_converter.call(s.url_converter_scope || t, t.decode(c), 'style', null) + ')';\r
-                                               });\r
-                                       }\r
+                                                       attribsValue.replace(attrRegExp, function(match, name, value, val2, val3) {\r
+                                                               var attrRule, i;\r
 \r
-                                       o[tinymce.trim(v[0]).toLowerCase()] = sv;\r
-                               }\r
-                       });\r
+                                                               name = name.toLowerCase();\r
+                                                               value = name in fillAttrsMap ? name : decode(value || val2 || val3 || ''); // Handle boolean attribute than value attribute\r
 \r
-                       compress("border", "", "border");\r
-                       compress("border", "-width", "border-width");\r
-                       compress("border", "-color", "border-color");\r
-                       compress("border", "-style", "border-style");\r
-                       compress("padding", "", "padding");\r
-                       compress("margin", "", "margin");\r
-                       compress2('border', 'border-width', 'border-style', 'border-color');\r
+                                                               // Validate name and value\r
+                                                               if (validate && name.indexOf('data-') !== 0) {\r
+                                                                       attrRule = validAttributesMap[name];\r
 \r
-                       if (isIE) {\r
-                               // Remove pointless border\r
-                               if (o.border == 'medium none')\r
-                                       o.border = '';\r
-                       }\r
+                                                                       // Find rule by pattern matching\r
+                                                                       if (!attrRule && validAttributePatterns) {\r
+                                                                               i = validAttributePatterns.length;\r
+                                                                               while (i--) {\r
+                                                                                       attrRule = validAttributePatterns[i];\r
+                                                                                       if (attrRule.pattern.test(name))\r
+                                                                                               break;\r
+                                                                               }\r
 \r
-                       return o;\r
-               },\r
+                                                                               // No rule matched\r
+                                                                               if (i === -1)\r
+                                                                                       attrRule = null;\r
+                                                                       }\r
 \r
-               serializeStyle : function(o, name) {\r
-                       var t = this, s = '';\r
+                                                                       // No attribute rule found\r
+                                                                       if (!attrRule)\r
+                                                                               return;\r
 \r
-                       function add(v, k) {\r
-                               if (k && v) {\r
-                                       // Remove browser specific styles like -moz- or -webkit-\r
-                                       if (k.indexOf('-') === 0)\r
-                                               return;\r
+                                                                       // Validate value\r
+                                                                       if (attrRule.validValues && !(value in attrRule.validValues))\r
+                                                                               return;\r
+                                                               }\r
 \r
-                                       switch (k) {\r
-                                               case 'font-weight':\r
-                                                       // Opera will output bold as 700\r
-                                                       if (v == 700)\r
-                                                               v = 'bold';\r
+                                                               // Add attribute to list and map\r
+                                                               attrList.map[name] = value;\r
+                                                               attrList.push({\r
+                                                                       name: name,\r
+                                                                       value: value\r
+                                                               });\r
+                                                       });\r
+                                               } else {\r
+                                                       attrList = [];\r
+                                                       attrList.map = {};\r
+                                               }\r
 \r
-                                                       break;\r
+                                               // Process attributes if validation is enabled\r
+                                               if (validate) {\r
+                                                       attributesRequired = elementRule.attributesRequired;\r
+                                                       attributesDefault = elementRule.attributesDefault;\r
+                                                       attributesForced = elementRule.attributesForced;\r
+\r
+                                                       // Handle forced attributes\r
+                                                       if (attributesForced) {\r
+                                                               i = attributesForced.length;\r
+                                                               while (i--) {\r
+                                                                       attr = attributesForced[i];\r
+                                                                       name = attr.name;\r
+                                                                       attrValue = attr.value;\r
+\r
+                                                                       if (attrValue === '{$uid}')\r
+                                                                               attrValue = 'mce_' + idCount++;\r
+\r
+                                                                       attrList.map[name] = attrValue;\r
+                                                                       attrList.push({name: name, value: attrValue});\r
+                                                               }\r
+                                                       }\r
 \r
-                                               case 'color':\r
-                                               case 'background-color':\r
-                                                       v = v.toLowerCase();\r
-                                                       break;\r
-                                       }\r
+                                                       // Handle default attributes\r
+                                                       if (attributesDefault) {\r
+                                                               i = attributesDefault.length;\r
+                                                               while (i--) {\r
+                                                                       attr = attributesDefault[i];\r
+                                                                       name = attr.name;\r
 \r
-                                       s += (s ? ' ' : '') + k + ': ' + v + ';';\r
-                               }\r
-                       };\r
+                                                                       if (!(name in attrList.map)) {\r
+                                                                               attrValue = attr.value;\r
 \r
-                       // Validate style output\r
-                       if (name && t._styles) {\r
-                               each(t._styles['*'], function(name) {\r
-                                       add(o[name], name);\r
-                               });\r
+                                                                               if (attrValue === '{$uid}')\r
+                                                                                       attrValue = 'mce_' + idCount++;\r
 \r
-                               each(t._styles[name.toLowerCase()], function(name) {\r
-                                       add(o[name], name);\r
-                               });\r
-                       } else\r
-                               each(o, add);\r
+                                                                               attrList.map[name] = attrValue;\r
+                                                                               attrList.push({name: name, value: attrValue});\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
 \r
-                       return s;\r
-               },\r
+                                                       // Handle required attributes\r
+                                                       if (attributesRequired) {\r
+                                                               i = attributesRequired.length;\r
+                                                               while (i--) {\r
+                                                                       if (attributesRequired[i] in attrList.map)\r
+                                                                               break;\r
+                                                               }\r
 \r
-               loadCSS : function(u) {\r
-                       var t = this, d = t.doc, head;\r
+                                                               // None of the required attributes where found\r
+                                                               if (i === -1)\r
+                                                                       isValidElement = false;\r
+                                                       }\r
 \r
-                       if (!u)\r
-                               u = '';\r
+                                                       // Invalidate element if it's marked as bogus\r
+                                                       if (attrList.map['data-mce-bogus'])\r
+                                                               isValidElement = false;\r
+                                               }\r
 \r
-                       head = t.select('head')[0];\r
+                                               if (isValidElement)\r
+                                                       self.start(value, attrList, isShortEnded);\r
+                                       } else\r
+                                               isValidElement = false;\r
 \r
-                       each(u.split(','), function(u) {\r
-                               var link;\r
+                                       // Treat script, noscript and style a bit different since they may include code that looks like elements\r
+                                       if (endRegExp = specialElements[value]) {\r
+                                               endRegExp.lastIndex = index = matches.index + matches[0].length;\r
 \r
-                               if (t.files[u])\r
-                                       return;\r
+                                               if (matches = endRegExp.exec(html)) {\r
+                                                       if (isValidElement)\r
+                                                               text = html.substr(index, matches.index - index);\r
 \r
-                               t.files[u] = true;\r
-                               link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)});\r
+                                                       index = matches.index + matches[0].length;\r
+                                               } else {\r
+                                                       text = html.substr(index);\r
+                                                       index = html.length;\r
+                                               }\r
 \r
-                               // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug\r
-                               // This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading\r
-                               // It's ugly but it seems to work fine.\r
-                               if (isIE && d.documentMode) {\r
-                                       link.onload = function() {\r
-                                               d.recalc();\r
-                                               link.onload = null;\r
-                                       };\r
+                                               if (isValidElement && text.length > 0)\r
+                                                       self.text(text, true);\r
+\r
+                                               if (isValidElement)\r
+                                                       self.end(value);\r
+\r
+                                               tokenRegExp.lastIndex = index;\r
+                                               continue;\r
+                                       }\r
+\r
+                                       // Push value on to stack\r
+                                       if (!isShortEnded) {\r
+                                               if (!attribsValue || attribsValue.indexOf('/') != attribsValue.length - 1)\r
+                                                       stack.push({name: value, valid: isValidElement});\r
+                                               else if (isValidElement)\r
+                                                       self.end(value);\r
+                                       }\r
+                               } else if (value = matches[1]) { // Comment\r
+                                       self.comment(value);\r
+                               } else if (value = matches[2]) { // CDATA\r
+                                       self.cdata(value);\r
+                               } else if (value = matches[3]) { // DOCTYPE\r
+                                       self.doctype(value);\r
+                               } else if (value = matches[4]) { // PI\r
+                                       self.pi(value, matches[5]);\r
                                }\r
 \r
-                               head.appendChild(link);\r
-                       });\r
-               },\r
+                               index = matches.index + matches[0].length;\r
+                       }\r
 \r
-               addClass : function(e, c) {\r
-                       return this.run(e, function(e) {\r
-                               var o;\r
+                       // Text\r
+                       if (index < html.length)\r
+                               self.text(decode(html.substr(index)));\r
 \r
-                               if (!c)\r
-                                       return 0;\r
+                       // Close any open elements\r
+                       for (i = stack.length - 1; i >= 0; i--) {\r
+                               value = stack[i];\r
 \r
-                               if (this.hasClass(e, c))\r
-                                       return e.className;\r
+                               if (value.valid)\r
+                                       self.end(value.name);\r
+                       }\r
+               };\r
+       }\r
+})(tinymce);\r
 \r
-                               o = this.removeClass(e, c);\r
+(function(tinymce) {\r
+       var whiteSpaceRegExp = /^[ \t\r\n]*$/, typeLookup = {\r
+               '#text' : 3,\r
+               '#comment' : 8,\r
+               '#cdata' : 4,\r
+               '#pi' : 7,\r
+               '#doctype' : 10,\r
+               '#document-fragment' : 11\r
+       };\r
 \r
-                               return e.className = (o != '' ? (o + ' ') : '') + c;\r
-                       });\r
-               },\r
+       // Walks the tree left/right\r
+       function walk(node, root_node, prev) {\r
+               var sibling, parent, startName = prev ? 'lastChild' : 'firstChild', siblingName = prev ? 'prev' : 'next';\r
 \r
-               removeClass : function(e, c) {\r
-                       var t = this, re;\r
+               // Walk into nodes if it has a start\r
+               if (node[startName])\r
+                       return node[startName];\r
 \r
-                       return t.run(e, function(e) {\r
-                               var v;\r
+               // Return the sibling if it has one\r
+               if (node !== root_node) {\r
+                       sibling = node[siblingName];\r
 \r
-                               if (t.hasClass(e, c)) {\r
-                                       if (!re)\r
-                                               re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");\r
+                       if (sibling)\r
+                               return sibling;\r
 \r
-                                       v = e.className.replace(re, ' ');\r
-                                       v = tinymce.trim(v != ' ' ? v : '');\r
+                       // Walk up the parents to look for siblings\r
+                       for (parent = node.parent; parent && parent !== root_node; parent = parent.parent) {\r
+                               sibling = parent[siblingName];\r
 \r
-                                       e.className = v;\r
+                               if (sibling)\r
+                                       return sibling;\r
+                       }\r
+               }\r
+       };\r
 \r
-                                       // Empty class attr\r
-                                       if (!v) {\r
-                                               e.removeAttribute('class');\r
-                                               e.removeAttribute('className');\r
-                                       }\r
+       function Node(name, type) {\r
+               this.name = name;\r
+               this.type = type;\r
 \r
-                                       return v;\r
-                               }\r
+               if (type === 1) {\r
+                       this.attributes = [];\r
+                       this.attributes.map = {};\r
+               }\r
+       }\r
 \r
-                               return e.className;\r
-                       });\r
-               },\r
+       tinymce.extend(Node.prototype, {\r
+               replace : function(node) {\r
+                       var self = this;\r
 \r
-               hasClass : function(n, c) {\r
-                       n = this.get(n);\r
+                       if (node.parent)\r
+                               node.remove();\r
 \r
-                       if (!n || !c)\r
-                               return false;\r
+                       self.insert(node, self);\r
+                       self.remove();\r
 \r
-                       return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;\r
+                       return self;\r
                },\r
 \r
-               show : function(e) {\r
-                       return this.setStyle(e, 'display', 'block');\r
-               },\r
+               attr : function(name, value) {\r
+                       var self = this, attrs, i, undef;\r
 \r
-               hide : function(e) {\r
-                       return this.setStyle(e, 'display', 'none');\r
-               },\r
-\r
-               isHidden : function(e) {\r
-                       e = this.get(e);\r
-\r
-                       return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
-               },\r
-\r
-               uniqueId : function(p) {\r
-                       return (!p ? 'mce_' : p) + (this.counter++);\r
-               },\r
-\r
-               setHTML : function(e, h) {\r
-                       var t = this;\r
-\r
-                       return this.run(e, function(e) {\r
-                               var x, i, nl, n, p, x;\r
+                       if (typeof name !== "string") {\r
+                               for (i in name)\r
+                                       self.attr(i, name[i]);\r
 \r
-                               h = t.processHTML(h);\r
+                               return self;\r
+                       }\r
 \r
-                               if (isIE) {\r
-                                       function set() {\r
-                                               // Remove all child nodes\r
-                                               while (e.firstChild)\r
-                                                       e.firstChild.removeNode();\r
+                       if (attrs = self.attributes) {\r
+                               if (value !== undef) {\r
+                                       // Remove attribute\r
+                                       if (value === null) {\r
+                                               if (name in attrs.map) {\r
+                                                       delete attrs.map[name];\r
 \r
-                                               try {\r
-                                                       // IE will remove comments from the beginning\r
-                                                       // unless you padd the contents with something\r
-                                                       e.innerHTML = '<br />' + h;\r
-                                                       e.removeChild(e.firstChild);\r
-                                               } catch (ex) {\r
-                                                       // 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\r
-                                                       // This seems to fix this problem\r
-\r
-                                                       // Create new div with HTML contents and a BR infront to keep comments\r
-                                                       x = t.create('div');\r
-                                                       x.innerHTML = '<br />' + h;\r
-\r
-                                                       // Add all children from div to target\r
-                                                       each (x.childNodes, function(n, i) {\r
-                                                               // Skip br element\r
-                                                               if (i)\r
-                                                                       e.appendChild(n);\r
-                                                       });\r
+                                                       i = attrs.length;\r
+                                                       while (i--) {\r
+                                                               if (attrs[i].name === name) {\r
+                                                                       attrs = attrs.splice(i, 1);\r
+                                                                       return self;\r
+                                                               }\r
+                                                       }\r
                                                }\r
-                                       };\r
-\r
-                                       // IE has a serious bug when it comes to paragraphs it can produce an invalid\r
-                                       // DOM tree if contents like this <p><ul><li>Item 1</li></ul></p> is inserted\r
-                                       // It seems to be that IE doesn't like a root block element placed inside another root block element\r
-                                       if (t.settings.fix_ie_paragraphs)\r
-                                               h = h.replace(/<p><\/p>|<p([^>]+)><\/p>|<p[^\/+]\/>/gi, '<p$1 _mce_keep="true">&nbsp;</p>');\r
 \r
-                                       set();\r
-\r
-                                       if (t.settings.fix_ie_paragraphs) {\r
-                                               // Check for odd paragraphs this is a sign of a broken DOM\r
-                                               nl = e.getElementsByTagName("p");\r
-                                               for (i = nl.length - 1, x = 0; i >= 0; i--) {\r
-                                                       n = nl[i];\r
-\r
-                                                       if (!n.hasChildNodes()) {\r
-                                                               if (!n._mce_keep) {\r
-                                                                       x = 1; // Is broken\r
-                                                                       break;\r
-                                                               }\r
+                                               return self;\r
+                                       }\r
 \r
-                                                               n.removeAttribute('_mce_keep');\r
+                                       // Set attribute\r
+                                       if (name in attrs.map) {\r
+                                               // Set attribute\r
+                                               i = attrs.length;\r
+                                               while (i--) {\r
+                                                       if (attrs[i].name === name) {\r
+                                                               attrs[i].value = value;\r
+                                                               break;\r
                                                        }\r
                                                }\r
-                                       }\r
+                                       } else\r
+                                               attrs.push({name: name, value: value});\r
 \r
-                                       // Time to fix the madness IE left us\r
-                                       if (x) {\r
-                                               // So if we replace the p elements with divs and mark them and then replace them back to paragraphs\r
-                                               // after we use innerHTML we can fix the DOM tree\r
-                                               h = h.replace(/<p ([^>]+)>|<p>/ig, '<div $1 _mce_tmp="1">');\r
-                                               h = h.replace(/<\/p>/gi, '</div>');\r
+                                       attrs.map[name] = value;\r
 \r
-                                               // Set the new HTML with DIVs\r
-                                               set();\r
+                                       return self;\r
+                               } else {\r
+                                       return attrs.map[name];\r
+                               }\r
+                       }\r
+               },\r
 \r
-                                               // Replace all DIV elements with the _mce_tmp attibute back to paragraphs\r
-                                               // This is needed since IE has a annoying bug see above for details\r
-                                               // This is a slow process but it has to be done. :(\r
-                                               if (t.settings.fix_ie_paragraphs) {\r
-                                                       nl = e.getElementsByTagName("DIV");\r
-                                                       for (i = nl.length - 1; i >= 0; i--) {\r
-                                                               n = nl[i];\r
+               clone : function() {\r
+                       var self = this, clone = new Node(self.name, self.type), i, l, selfAttrs, selfAttr, cloneAttrs;\r
 \r
-                                                               // Is it a temp div\r
-                                                               if (n._mce_tmp) {\r
-                                                                       // Create new paragraph\r
-                                                                       p = t.doc.createElement('p');\r
+                       // Clone element attributes\r
+                       if (selfAttrs = self.attributes) {\r
+                               cloneAttrs = [];\r
+                               cloneAttrs.map = {};\r
 \r
-                                                                       // Copy all attributes\r
-                                                                       n.cloneNode(false).outerHTML.replace(/([a-z0-9\-_]+)=/gi, function(a, b) {\r
-                                                                               var v;\r
+                               for (i = 0, l = selfAttrs.length; i < l; i++) {\r
+                                       selfAttr = selfAttrs[i];\r
 \r
-                                                                               if (b !== '_mce_tmp') {\r
-                                                                                       v = n.getAttribute(b);\r
+                                       // Clone everything except id\r
+                                       if (selfAttr.name !== 'id') {\r
+                                               cloneAttrs[cloneAttrs.length] = {name: selfAttr.name, value: selfAttr.value};\r
+                                               cloneAttrs.map[selfAttr.name] = selfAttr.value;\r
+                                       }\r
+                               }\r
 \r
-                                                                                       if (!v && b === 'class')\r
-                                                                                               v = n.className;\r
+                               clone.attributes = cloneAttrs;\r
+                       }\r
 \r
-                                                                                       p.setAttribute(b, v);\r
-                                                                               }\r
-                                                                       });\r
+                       clone.value = self.value;\r
+                       clone.shortEnded = self.shortEnded;\r
 \r
-                                                                       // Append all children to new paragraph\r
-                                                                       for (x = 0; x<n.childNodes.length; x++)\r
-                                                                               p.appendChild(n.childNodes[x].cloneNode(true));\r
+                       return clone;\r
+               },\r
 \r
-                                                                       // Replace div with new paragraph\r
-                                                                       n.swapNode(p);\r
-                                                               }\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                               } else\r
-                                       e.innerHTML = h;\r
+               wrap : function(wrapper) {\r
+                       var self = this;\r
 \r
-                               return h;\r
-                       });\r
-               },\r
+                       self.parent.insert(wrapper, self);\r
+                       wrapper.append(self);\r
 \r
-               processHTML : function(h) {\r
-                       var t = this, s = t.settings, codeBlocks = [];\r
+                       return self;\r
+               },\r
 \r
-                       if (!s.process_html)\r
-                               return h;\r
+               unwrap : function() {\r
+                       var self = this, node, next;\r
 \r
-                       if (isIE) {\r
-                               h = h.replace(/&apos;/g, '&#39;'); // IE can't handle apos\r
-                               h = h.replace(/\s+(disabled|checked|readonly|selected)\s*=\s*[\"\']?(false|0)[\"\']?/gi, ''); // IE doesn't handle default values correct\r
+                       for (node = self.firstChild; node; ) {\r
+                               next = node.next;\r
+                               self.insert(node, self, true);\r
+                               node = next;\r
                        }\r
 \r
-                       // Fix some issues\r
-                       h = h.replace(/<a( )([^>]+)\/>|<a\/>/gi, '<a$1$2></a>'); // Force open\r
+                       self.remove();\r
+               },\r
 \r
-                       // Store away src and href in _mce_src and mce_href since browsers mess them up\r
-                       if (s.keep_values) {\r
-                               // Wrap scripts and styles in comments for serialization purposes\r
-                               if (/<script|noscript|style/i.test(h)) {\r
-                                       function trim(s) {\r
-                                               // Remove prefix and suffix code for element\r
-                                               s = s.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n');\r
-                                               s = s.replace(/^[\r\n]*|[\r\n]*$/g, '');\r
-                                               s = s.replace(/^\s*(\/\/\s*<!--|\/\/\s*<!\[CDATA\[|<!--|<!\[CDATA\[)[\r\n]*/g, '');\r
-                                               s = s.replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->|\]\]-->)\s*$/g, '');\r
+               remove : function() {\r
+                       var self = this, parent = self.parent, next = self.next, prev = self.prev;\r
 \r
-                                               return s;\r
-                                       };\r
+                       if (parent) {\r
+                               if (parent.firstChild === self) {\r
+                                       parent.firstChild = next;\r
 \r
-                                       // Wrap the script contents in CDATA and keep them from executing\r
-                                       h = h.replace(/<script([^>]+|)>([\s\S]*?)<\/script>/gi, function(v, attribs, text) {\r
-                                               // Force type attribute\r
-                                               if (!attribs)\r
-                                                       attribs = ' type="text/javascript"';\r
+                                       if (next)\r
+                                               next.prev = null;\r
+                               } else {\r
+                                       prev.next = next;\r
+                               }\r
 \r
-                                               // Convert the src attribute of the scripts\r
-                                               attribs = attribs.replace(/src=\"([^\"]+)\"?/i, function(a, url) {\r
-                                                       if (s.url_converter)\r
-                                                               url = t.encode(s.url_converter.call(s.url_converter_scope || t, t.decode(url), 'src', 'script'));\r
+                               if (parent.lastChild === self) {\r
+                                       parent.lastChild = prev;\r
 \r
-                                                       return '_mce_src="' + url + '"';\r
-                                               });\r
+                                       if (prev)\r
+                                               prev.next = null;\r
+                               } else {\r
+                                       next.prev = prev;\r
+                               }\r
 \r
-                                               // Wrap text contents\r
-                                               if (tinymce.trim(text)) {\r
-                                                       codeBlocks.push(trim(text));\r
-                                                       text = '<!--\nMCE_SCRIPT:' + (codeBlocks.length - 1) + '\n// -->';\r
-                                               }\r
+                               self.parent = self.next = self.prev = null;\r
+                       }\r
 \r
-                                               return '<mce:script' + attribs + '>' + text + '</mce:script>';\r
-                                       });\r
+                       return self;\r
+               },\r
 \r
-                                       // Wrap style elements\r
-                                       h = h.replace(/<style([^>]+|)>([\s\S]*?)<\/style>/gi, function(v, attribs, text) {\r
-                                               // Wrap text contents\r
-                                               if (text) {\r
-                                                       codeBlocks.push(trim(text));\r
-                                                       text = '<!--\nMCE_SCRIPT:' + (codeBlocks.length - 1) + '\n-->';\r
-                                               }\r
+               append : function(node) {\r
+                       var self = this, last;\r
 \r
-                                               return '<mce:style' + attribs + '>' + text + '</mce:style><style ' + attribs + ' _mce_bogus="1">' + text + '</style>';\r
-                                       });\r
+                       if (node.parent)\r
+                               node.remove();\r
 \r
-                                       // Wrap noscript elements\r
-                                       h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {\r
-                                               return '<mce:noscript' + attribs + '><!--' + t.encode(text).replace(/--/g, '&#45;&#45;') + '--></mce:noscript>';\r
-                                       });\r
-                               }\r
+                       last = self.lastChild;\r
+                       if (last) {\r
+                               last.next = node;\r
+                               node.prev = last;\r
+                               self.lastChild = node;\r
+                       } else\r
+                               self.lastChild = self.firstChild = node;\r
 \r
-                               h = h.replace(/<!\[CDATA\[([\s\S]+)\]\]>/g, '<!--[CDATA[$1]]-->');\r
+                       node.parent = self;\r
 \r
-                               // This function processes the attributes in the HTML string to force boolean\r
-                               // attributes to the attr="attr" format and convert style, src and href to _mce_ versions\r
-                               function processTags(html) {\r
-                                       return html.replace(tagRegExp, function(match, elm_name, attrs, end) {\r
-                                               return '<' + elm_name + attrs.replace(attrRegExp, function(match, name, value, val2, val3) {\r
-                                                       var mceValue;\r
+                       return node;\r
+               },\r
 \r
-                                                       name = name.toLowerCase();\r
-                                                       value = value || val2 || val3 || "";\r
+               insert : function(node, ref_node, before) {\r
+                       var parent;\r
 \r
-                                                       // Treat boolean attributes\r
-                                                       if (boolAttrs[name]) {\r
-                                                               // false or 0 is treated as a missing attribute\r
-                                                               if (value === 'false' || value === '0')\r
-                                                                       return;\r
+                       if (node.parent)\r
+                               node.remove();\r
 \r
-                                                               return name + '="' + name + '"';\r
-                                                       }\r
+                       parent = ref_node.parent || this;\r
 \r
-                                                       // Is attribute one that needs special treatment\r
-                                                       if (mceAttribs[name] && attrs.indexOf('_mce_' + name) == -1) {\r
-                                                               mceValue = t.decode(value);\r
+                       if (before) {\r
+                               if (ref_node === parent.firstChild)\r
+                                       parent.firstChild = node;\r
+                               else\r
+                                       ref_node.prev.next = node;\r
 \r
-                                                               // Convert URLs to relative/absolute ones\r
-                                                               if (s.url_converter && (name == "src" || name == "href"))\r
-                                                                       mceValue = s.url_converter.call(s.url_converter_scope || t, mceValue, name, elm_name);\r
+                               node.prev = ref_node.prev;\r
+                               node.next = ref_node;\r
+                               ref_node.prev = node;\r
+                       } else {\r
+                               if (ref_node === parent.lastChild)\r
+                                       parent.lastChild = node;\r
+                               else\r
+                                       ref_node.next.prev = node;\r
 \r
-                                                               // Process styles lowercases them and compresses them\r
-                                                               if (name == 'style')\r
-                                                                       mceValue = t.serializeStyle(t.parseStyle(mceValue), name);\r
+                               node.next = ref_node.next;\r
+                               node.prev = ref_node;\r
+                               ref_node.next = node;\r
+                       }\r
 \r
-                                                               return name + '="' + value + '"' + ' _mce_' + name + '="' + t.encode(mceValue) + '"';\r
-                                                       }\r
+                       node.parent = parent;\r
 \r
-                                                       return match;\r
-                                               }) + end + '>';\r
-                                       });\r
-                               };\r
+                       return node;\r
+               },\r
 \r
-                               h = processTags(h);\r
+               getAll : function(name) {\r
+                       var self = this, node, collection = [];\r
 \r
-                               // Restore script blocks\r
-                               h = h.replace(/MCE_SCRIPT:([0-9]+)/g, function(val, idx) {\r
-                                       return codeBlocks[idx];\r
-                               });\r
+                       for (node = self.firstChild; node; node = walk(node, self)) {\r
+                               if (node.name === name)\r
+                                       collection.push(node);\r
                        }\r
 \r
-                       return h;\r
+                       return collection;\r
                },\r
 \r
-               getOuterHTML : function(e) {\r
-                       var d;\r
+               empty : function() {\r
+                       var self = this, nodes, i, node;\r
 \r
-                       e = this.get(e);\r
+                       // Remove all children\r
+                       if (self.firstChild) {\r
+                               nodes = [];\r
 \r
-                       if (!e)\r
-                               return null;\r
+                               // Collect the children\r
+                               for (node = self.firstChild; node; node = walk(node, self))\r
+                                       nodes.push(node);\r
 \r
-                       if (e.outerHTML !== undefined)\r
-                               return e.outerHTML;\r
+                               // Remove the children\r
+                               i = nodes.length;\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       node.parent = node.firstChild = node.lastChild = node.next = node.prev = null;\r
+                               }\r
+                       }\r
 \r
-                       d = (e.ownerDocument || this.doc).createElement("body");\r
-                       d.appendChild(e.cloneNode(true));\r
+                       self.firstChild = self.lastChild = null;\r
 \r
-                       return d.innerHTML;\r
+                       return self;\r
                },\r
 \r
-               setOuterHTML : function(e, h, d) {\r
-                       var t = this;\r
-\r
-                       function setHTML(e, h, d) {\r
-                               var n, tp;\r
+               isEmpty : function(elements) {\r
+                       var self = this, node = self.firstChild, i, name;\r
 \r
-                               tp = d.createElement("body");\r
-                               tp.innerHTML = h;\r
+                       if (node) {\r
+                               do {\r
+                                       if (node.type === 1) {\r
+                                               // Ignore bogus elements\r
+                                               if (node.attributes.map['data-mce-bogus'])\r
+                                                       continue;\r
 \r
-                               n = tp.lastChild;\r
-                               while (n) {\r
-                                       t.insertAfter(n.cloneNode(true), e);\r
-                                       n = n.previousSibling;\r
-                               }\r
+                                               // Keep empty elements like <img />\r
+                                               if (elements[node.name])\r
+                                                       return false;\r
 \r
-                               t.remove(e);\r
-                       };\r
+                                               // Keep elements with data attributes or name attribute like <a name="1"></a>\r
+                                               i = node.attributes.length;\r
+                                               while (i--) {\r
+                                                       name = node.attributes[i].name;\r
+                                                       if (name === "name" || name.indexOf('data-') === 0)\r
+                                                               return false;\r
+                                               }\r
+                                       }\r
 \r
-                       return this.run(e, function(e) {\r
-                               e = t.get(e);\r
+                                       // Keep non whitespace text nodes\r
+                                       if ((node.type === 3 && !whiteSpaceRegExp.test(node.value)))\r
+                                               return false;\r
+                               } while (node = walk(node, self));\r
+                       }\r
 \r
-                               // Only set HTML on elements\r
-                               if (e.nodeType == 1) {\r
-                                       d = d || e.ownerDocument || t.doc;\r
+                       return true;\r
+               }\r
+       });\r
 \r
-                                       if (isIE) {\r
-                                               try {\r
-                                                       // Try outerHTML for IE it sometimes produces an unknown runtime error\r
-                                                       if (isIE && e.nodeType == 1)\r
-                                                               e.outerHTML = h;\r
-                                                       else\r
-                                                               setHTML(e, h, d);\r
-                                               } catch (ex) {\r
-                                                       // Fix for unknown runtime error\r
-                                                       setHTML(e, h, d);\r
-                                               }\r
-                                       } else\r
-                                               setHTML(e, h, d);\r
-                               }\r
-                       });\r
-               },\r
+       tinymce.extend(Node, {\r
+               create : function(name, attrs) {\r
+                       var node, attrName;\r
 \r
-               decode : function(s) {\r
-                       var e, n, v;\r
+                       // Create node\r
+                       node = new Node(name, typeLookup[name] || 1);\r
 \r
-                       // Look for entities to decode\r
-                       if (/&[\w#]+;/.test(s)) {\r
-                               // Decode the entities using a div element not super efficient but less code\r
-                               e = this.doc.createElement("div");\r
-                               e.innerHTML = s;\r
-                               n = e.firstChild;\r
-                               v = '';\r
+                       // Add attributes if needed\r
+                       if (attrs) {\r
+                               for (attrName in attrs)\r
+                                       node.attr(attrName, attrs[attrName]);\r
+                       }\r
 \r
-                               if (n) {\r
-                                       do {\r
-                                               v += n.nodeValue;\r
-                                       } while (n = n.nextSibling);\r
-                               }\r
+                       return node;\r
+               }\r
+       });\r
 \r
-                               return v || s;\r
-                       }\r
+       tinymce.html.Node = Node;\r
+})(tinymce);\r
 \r
-                       return s;\r
-               },\r
+(function(tinymce) {\r
+       var Node = tinymce.html.Node;\r
 \r
-               encode : function(str) {\r
-                       return ('' + str).replace(encodeCharsRe, function(chr) {\r
-                               return encodedChars[chr];\r
-                       });\r
-               },\r
+       tinymce.html.DomParser = function(settings, schema) {\r
+               var self = this, nodeFilters = {}, attributeFilters = [], matchedNodes = {}, matchedAttributes = {};\r
 \r
-               insertAfter : function(node, reference_node) {\r
-                       reference_node = this.get(reference_node);\r
+               settings = settings || {};\r
+               settings.validate = "validate" in settings ? settings.validate : true;\r
+               settings.root_name = settings.root_name || 'body';\r
+               self.schema = schema = schema || new tinymce.html.Schema();\r
 \r
-                       return this.run(node, function(node) {\r
-                               var parent, nextSibling;\r
+               function fixInvalidChildren(nodes) {\r
+                       var ni, node, parent, parents, newParent, currentNode, tempNode, childNode, i,\r
+                               childClone, nonEmptyElements, nonSplitableElements, sibling, nextNode;\r
 \r
-                               parent = reference_node.parentNode;\r
-                               nextSibling = reference_node.nextSibling;\r
+                       nonSplitableElements = tinymce.makeMap('tr,td,th,tbody,thead,tfoot,table');\r
+                       nonEmptyElements = schema.getNonEmptyElements();\r
 \r
-                               if (nextSibling)\r
-                                       parent.insertBefore(node, nextSibling);\r
-                               else\r
-                                       parent.appendChild(node);\r
+                       for (ni = 0; ni < nodes.length; ni++) {\r
+                               node = nodes[ni];\r
 \r
-                               return node;\r
-                       });\r
-               },\r
+                               // Already removed\r
+                               if (!node.parent)\r
+                                       continue;\r
 \r
-               isBlock : function(n) {\r
-                       if (n.nodeType && n.nodeType !== 1)\r
-                               return false;\r
+                               // Get list of all parent nodes until we find a valid parent to stick the child into\r
+                               parents = [node];\r
+                               for (parent = node.parent; parent && !schema.isValidChild(parent.name, node.name) && !nonSplitableElements[parent.name]; parent = parent.parent)\r
+                                       parents.push(parent);\r
 \r
-                       n = n.nodeName || n;\r
+                               // Found a suitable parent\r
+                               if (parent && parents.length > 1) {\r
+                                       // Reverse the array since it makes looping easier\r
+                                       parents.reverse();\r
 \r
-                       return blockRe.test(n);\r
-               },\r
+                                       // Clone the related parent and insert that after the moved node\r
+                                       newParent = currentNode = self.filterNode(parents[0].clone());\r
 \r
-               replace : function(n, o, k) {\r
-                       var t = this;\r
+                                       // Start cloning and moving children on the left side of the target node\r
+                                       for (i = 0; i < parents.length - 1; i++) {\r
+                                               if (schema.isValidChild(currentNode.name, parents[i].name)) {\r
+                                                       tempNode = self.filterNode(parents[i].clone());\r
+                                                       currentNode.append(tempNode);\r
+                                               } else\r
+                                                       tempNode = currentNode;\r
 \r
-                       if (is(o, 'array'))\r
-                               n = n.cloneNode(true);\r
+                                               for (childNode = parents[i].firstChild; childNode && childNode != parents[i + 1]; ) {\r
+                                                       nextNode = childNode.next;\r
+                                                       tempNode.append(childNode);\r
+                                                       childNode = nextNode;\r
+                                               }\r
 \r
-                       return t.run(o, function(o) {\r
-                               if (k) {\r
-                                       each(tinymce.grep(o.childNodes), function(c) {\r
-                                               n.appendChild(c);\r
-                                       });\r
-                               }\r
+                                               currentNode = tempNode;\r
+                                       }\r
 \r
-                               return o.parentNode.replaceChild(n, o);\r
-                       });\r
-               },\r
+                                       if (!newParent.isEmpty(nonEmptyElements)) {\r
+                                               parent.insert(newParent, parents[0], true);\r
+                                               parent.insert(node, newParent);\r
+                                       } else {\r
+                                               parent.insert(node, parents[0], true);\r
+                                       }\r
 \r
-               rename : function(elm, name) {\r
-                       var t = this, newElm;\r
+                                       // Check if the element is empty by looking through it's contents and special treatment for <p><br /></p>\r
+                                       parent = parents[0];\r
+                                       if (parent.isEmpty(nonEmptyElements) || parent.firstChild === parent.lastChild && parent.firstChild.name === 'br') {\r
+                                               parent.empty().remove();\r
+                                       }\r
+                               } else if (node.parent) {\r
+                                       // If it's an LI try to find a UL/OL for it or wrap it\r
+                                       if (node.name === 'li') {\r
+                                               sibling = node.prev;\r
+                                               if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {\r
+                                                       sibling.append(node);\r
+                                                       continue;\r
+                                               }\r
 \r
-                       if (elm.nodeName != name.toUpperCase()) {\r
-                               // Rename block element\r
-                               newElm = t.create(name);\r
+                                               sibling = node.next;\r
+                                               if (sibling && (sibling.name === 'ul' || sibling.name === 'ul')) {\r
+                                                       sibling.insert(node, sibling.firstChild, true);\r
+                                                       continue;\r
+                                               }\r
 \r
-                               // Copy attribs to new block\r
-                               each(t.getAttribs(elm), function(attr_node) {\r
-                                       t.setAttrib(newElm, attr_node.nodeName, t.getAttrib(elm, attr_node.nodeName));\r
-                               });\r
+                                               node.wrap(self.filterNode(new Node('ul', 1)));\r
+                                               continue;\r
+                                       }\r
 \r
-                               // Replace block\r
-                               t.replace(newElm, elm, 1);\r
+                                       // Try wrapping the element in a DIV\r
+                                       if (schema.isValidChild(node.parent.name, 'div') && schema.isValidChild('div', node.name)) {\r
+                                               node.wrap(self.filterNode(new Node('div', 1)));\r
+                                       } else {\r
+                                               // We failed wrapping it, then remove or unwrap it\r
+                                               if (node.name === 'style' || node.name === 'script')\r
+                                                       node.empty().remove();\r
+                                               else\r
+                                                       node.unwrap();\r
+                                       }\r
+                               }\r
                        }\r
+               };\r
 \r
-                       return newElm || elm;\r
-               },\r
+               self.filterNode = function(node) {\r
+                       var i, name, list;\r
 \r
-               findCommonAncestor : function(a, b) {\r
-                       var ps = a, pe;\r
+                       // Run element filters\r
+                       if (name in nodeFilters) {\r
+                               list = matchedNodes[name];\r
 \r
-                       while (ps) {\r
-                               pe = b;\r
+                               if (list)\r
+                                       list.push(node);\r
+                               else\r
+                                       matchedNodes[name] = [node];\r
+                       }\r
 \r
-                               while (pe && ps != pe)\r
-                                       pe = pe.parentNode;\r
+                       // Run attribute filters\r
+                       i = attributeFilters.length;\r
+                       while (i--) {\r
+                               name = attributeFilters[i].name;\r
 \r
-                               if (ps == pe)\r
-                                       break;\r
+                               if (name in node.attributes.map) {\r
+                                       list = matchedAttributes[name];\r
 \r
-                               ps = ps.parentNode;\r
+                                       if (list)\r
+                                               list.push(node);\r
+                                       else\r
+                                               matchedAttributes[name] = [node];\r
+                               }\r
                        }\r
 \r
-                       if (!ps && a.ownerDocument)\r
-                               return a.ownerDocument.documentElement;\r
+                       return node;\r
+               };\r
 \r
-                       return ps;\r
-               },\r
+               self.addNodeFilter = function(name, callback) {\r
+                       tinymce.each(tinymce.explode(name), function(name) {\r
+                               var list = nodeFilters[name];\r
 \r
-               toHex : function(s) {\r
-                       var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);\r
+                               if (!list)\r
+                                       nodeFilters[name] = list = [];\r
 \r
-                       function hex(s) {\r
-                               s = parseInt(s).toString(16);\r
+                               list.push(callback);\r
+                       });\r
+               };\r
 \r
-                               return s.length > 1 ? s : '0' + s; // 0 -> 00\r
-                       };\r
+               self.addAttributeFilter = function(name, callback) {\r
+                       tinymce.each(tinymce.explode(name), function(name) {\r
+                               var i;\r
 \r
-                       if (c) {\r
-                               s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]);\r
+                               for (i = 0; i < attributeFilters.length; i++) {\r
+                                       if (attributeFilters[i].name === name) {\r
+                                               attributeFilters[i].callbacks.push(callback);\r
+                                               return;\r
+                                       }\r
+                               }\r
 \r
-                               return s;\r
-                       }\r
+                               attributeFilters.push({name: name, callbacks: [callback]});\r
+                       });\r
+               };\r
 \r
-                       return s;\r
-               },\r
+               self.parse = function(html, args) {\r
+                       var parser, rootNode, node, nodes, i, l, fi, fl, list, name, validate,\r
+                               blockElements, startWhiteSpaceRegExp, invalidChildren = [],\r
+                               endWhiteSpaceRegExp, allWhiteSpaceRegExp, whiteSpaceElements, children, nonEmptyElements;\r
 \r
-               getClasses : function() {\r
-                       var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov;\r
+                       args = args || {};\r
+                       matchedNodes = {};\r
+                       matchedAttributes = {};\r
+                       blockElements = tinymce.extend(tinymce.makeMap('script,style,head,html,body,title,meta,param'), schema.getBlockElements());\r
+                       nonEmptyElements = schema.getNonEmptyElements();\r
+                       children = schema.children;\r
+                       validate = settings.validate;\r
 \r
-                       if (t.classes)\r
-                               return t.classes;\r
+                       whiteSpaceElements = schema.getWhiteSpaceElements();\r
+                       startWhiteSpaceRegExp = /^[ \t\r\n]+/;\r
+                       endWhiteSpaceRegExp = /[ \t\r\n]+$/;\r
+                       allWhiteSpaceRegExp = /[ \t\r\n]+/g;\r
 \r
-                       function addClasses(s) {\r
-                               // IE style imports\r
-                               each(s.imports, function(r) {\r
-                                       addClasses(r);\r
-                               });\r
+                       function createNode(name, type) {\r
+                               var node = new Node(name, type), list;\r
 \r
-                               each(s.cssRules || s.rules, function(r) {\r
-                                       // Real type or fake it on IE\r
-                                       switch (r.type || 1) {\r
-                                               // Rule\r
-                                               case 1:\r
-                                                       if (r.selectorText) {\r
-                                                               each(r.selectorText.split(','), function(v) {\r
-                                                                       v = v.replace(/^\s*|\s*$|^\s\./g, "");\r
+                               if (name in nodeFilters) {\r
+                                       list = matchedNodes[name];\r
 \r
-                                                                       // Is internal or it doesn't contain a class\r
-                                                                       if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v))\r
-                                                                               return;\r
+                                       if (list)\r
+                                               list.push(node);\r
+                                       else\r
+                                               matchedNodes[name] = [node];\r
+                               }\r
 \r
-                                                                       // Remove everything but class name\r
-                                                                       ov = v;\r
-                                                                       v = v.replace(/.*\.([a-z0-9_\-]+).*/i, '$1');\r
+                               return node;\r
+                       };\r
 \r
-                                                                       // Filter classes\r
-                                                                       if (f && !(v = f(v, ov)))\r
-                                                                               return;\r
+                       function removeWhitespaceBefore(node) {\r
+                               var textNode, textVal, sibling;\r
 \r
-                                                                       if (!lo[v]) {\r
-                                                                               cl.push({'class' : v});\r
-                                                                               lo[v] = 1;\r
-                                                                       }\r
-                                                               });\r
-                                                       }\r
-                                                       break;\r
+                               for (textNode = node.prev; textNode && textNode.type === 3; ) {\r
+                                       textVal = textNode.value.replace(endWhiteSpaceRegExp, '');\r
 \r
-                                               // Import\r
-                                               case 3:\r
-                                                       addClasses(r.styleSheet);\r
-                                                       break;\r
+                                       if (textVal.length > 0) {\r
+                                               textNode.value = textVal;\r
+                                               textNode = textNode.prev;\r
+                                       } else {\r
+                                               sibling = textNode.prev;\r
+                                               textNode.remove();\r
+                                               textNode = sibling;\r
                                        }\r
-                               });\r
+                               }\r
                        };\r
 \r
-                       try {\r
-                               each(t.doc.styleSheets, addClasses);\r
-                       } catch (ex) {\r
-                               // Ignore\r
-                       }\r
+                       parser = new tinymce.html.SaxParser({\r
+                               validate : validate,\r
+                               fix_self_closing : !validate, // Let the DOM parser handle <li> in <li> or <p> in <p> for better results\r
 \r
-                       if (cl.length > 0)\r
-                               t.classes = cl;\r
+                               cdata: function(text) {\r
+                                       node.append(createNode('#cdata', 4)).value = text;\r
+                               },\r
 \r
-                       return cl;\r
-               },\r
+                               text: function(text, raw) {\r
+                                       var textNode;\r
 \r
-               run : function(e, f, s) {\r
-                       var t = this, o;\r
+                                       // Trim all redundant whitespace on non white space elements\r
+                                       if (!whiteSpaceElements[node.name]) {\r
+                                               text = text.replace(allWhiteSpaceRegExp, ' ');\r
 \r
-                       if (t.doc && typeof(e) === 'string')\r
-                               e = t.get(e);\r
+                                               if (node.lastChild && blockElements[node.lastChild.name])\r
+                                                       text = text.replace(startWhiteSpaceRegExp, '');\r
+                                       }\r
 \r
-                       if (!e)\r
-                               return false;\r
+                                       // Do we need to create the node\r
+                                       if (text.length !== 0) {\r
+                                               textNode = createNode('#text', 3);\r
+                                               textNode.raw = !!raw;\r
+                                               node.append(textNode).value = text;\r
+                                       }\r
+                               },\r
 \r
-                       s = s || this;\r
-                       if (!e.nodeType && (e.length || e.length === 0)) {\r
-                               o = [];\r
+                               comment: function(text) {\r
+                                       node.append(createNode('#comment', 8)).value = text;\r
+                               },\r
 \r
-                               each(e, function(e, i) {\r
-                                       if (e) {\r
-                                               if (typeof(e) == 'string')\r
-                                                       e = t.doc.getElementById(e);\r
+                               pi: function(name, text) {\r
+                                       node.append(createNode(name, 7)).value = text;\r
+                                       removeWhitespaceBefore(node);\r
+                               },\r
 \r
-                                               o.push(f.call(s, e, i));\r
-                                       }\r
-                               });\r
+                               doctype: function(text) {\r
+                                       var newNode;\r
+               \r
+                                       newNode = node.append(createNode('#doctype', 10));\r
+                                       newNode.value = text;\r
+                                       removeWhitespaceBefore(node);\r
+                               },\r
 \r
-                               return o;\r
-                       }\r
+                               start: function(name, attrs, empty) {\r
+                                       var newNode, attrFiltersLen, elementRule, textNode, attrName, text, sibling, parent;\r
 \r
-                       return f.call(s, e);\r
-               },\r
+                                       elementRule = validate ? schema.getElementRule(name) : {};\r
+                                       if (elementRule) {\r
+                                               newNode = createNode(elementRule.outputName || name, 1);\r
+                                               newNode.attributes = attrs;\r
+                                               newNode.shortEnded = empty;\r
 \r
-               getAttribs : function(n) {\r
-                       var o;\r
+                                               node.append(newNode);\r
 \r
-                       n = this.get(n);\r
+                                               // Check if node is valid child of the parent node is the child is\r
+                                               // unknown we don't collect it since it's probably a custom element\r
+                                               parent = children[node.name];\r
+                                               if (parent && children[newNode.name] && !parent[newNode.name])\r
+                                                       invalidChildren.push(newNode);\r
 \r
-                       if (!n)\r
-                               return [];\r
+                                               attrFiltersLen = attributeFilters.length;\r
+                                               while (attrFiltersLen--) {\r
+                                                       attrName = attributeFilters[attrFiltersLen].name;\r
 \r
-                       if (isIE) {\r
-                               o = [];\r
+                                                       if (attrName in attrs.map) {\r
+                                                               list = matchedAttributes[attrName];\r
 \r
-                               // Object will throw exception in IE\r
-                               if (n.nodeName == 'OBJECT')\r
-                                       return n.attributes;\r
+                                                               if (list)\r
+                                                                       list.push(newNode);\r
+                                                               else\r
+                                                                       matchedAttributes[attrName] = [newNode];\r
+                                                       }\r
+                                               }\r
 \r
-                               // IE doesn't keep the selected attribute if you clone option elements\r
-                               if (n.nodeName === 'OPTION' && this.getAttrib(n, 'selected'))\r
-                                       o.push({specified : 1, nodeName : 'selected'});\r
+                                               // Trim whitespace before block\r
+                                               if (blockElements[name])\r
+                                                       removeWhitespaceBefore(newNode);\r
 \r
-                               // It's crazy that this is faster in IE but it's because it returns all attributes all the time\r
-                               n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) {\r
-                                       o.push({specified : 1, nodeName : a});\r
-                               });\r
+                                               // Change current node if the element wasn't empty i.e not <br /> or <img />\r
+                                               if (!empty)\r
+                                                       node = newNode;\r
+                                       }\r
+                               },\r
 \r
-                               return o;\r
-                       }\r
+                               end: function(name) {\r
+                                       var textNode, elementRule, text, sibling, tempNode;\r
 \r
-                       return n.attributes;\r
-               },\r
+                                       elementRule = validate ? schema.getElementRule(name) : {};\r
+                                       if (elementRule) {\r
+                                               if (blockElements[name]) {\r
+                                                       if (!whiteSpaceElements[node.name]) {\r
+                                                               // Trim whitespace at beginning of block\r
+                                                               for (textNode = node.firstChild; textNode && textNode.type === 3; ) {\r
+                                                                       text = textNode.value.replace(startWhiteSpaceRegExp, '');\r
 \r
-               destroy : function(s) {\r
-                       var t = this;\r
+                                                                       if (text.length > 0) {\r
+                                                                               textNode.value = text;\r
+                                                                               textNode = textNode.next;\r
+                                                                       } else {\r
+                                                                               sibling = textNode.next;\r
+                                                                               textNode.remove();\r
+                                                                               textNode = sibling;\r
+                                                                       }\r
+                                                               }\r
 \r
-                       if (t.events)\r
-                               t.events.destroy();\r
+                                                               // Trim whitespace at end of block\r
+                                                               for (textNode = node.lastChild; textNode && textNode.type === 3; ) {\r
+                                                                       text = textNode.value.replace(endWhiteSpaceRegExp, '');\r
 \r
-                       t.win = t.doc = t.root = t.events = null;\r
+                                                                       if (text.length > 0) {\r
+                                                                               textNode.value = text;\r
+                                                                               textNode = textNode.prev;\r
+                                                                       } else {\r
+                                                                               sibling = textNode.prev;\r
+                                                                               textNode.remove();\r
+                                                                               textNode = sibling;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
 \r
-                       // Manual destroy then remove unload handler\r
-                       if (!s)\r
-                               tinymce.removeUnload(t.destroy);\r
-               },\r
+                                                       // Trim start white space\r
+                                                       textNode = node.prev;\r
+                                                       if (textNode && textNode.type === 3) {\r
+                                                               text = textNode.value.replace(startWhiteSpaceRegExp, '');\r
 \r
-               createRng : function() {\r
-                       var d = this.doc;\r
+                                                               if (text.length > 0)\r
+                                                                       textNode.value = text;\r
+                                                               else\r
+                                                                       textNode.remove();\r
+                                                       }\r
+                                               }\r
 \r
-                       return d.createRange ? d.createRange() : new tinymce.dom.Range(this);\r
-               },\r
+                                               // Handle empty nodes\r
+                                               if (elementRule.removeEmpty || elementRule.paddEmpty) {\r
+                                                       if (node.isEmpty(nonEmptyElements)) {\r
+                                                               if (elementRule.paddEmpty)\r
+                                                                       node.empty().append(new Node('#text', '3')).value = '\u00a0';\r
+                                                               else {\r
+                                                                       // Leave nodes that have a name like <a name="name">\r
+                                                                       if (!node.attributes.map.name) {\r
+                                                                               tempNode = node.parent;\r
+                                                                               node.empty().remove();\r
+                                                                               node = tempNode;\r
+                                                                               return;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
 \r
-               nodeIndex : function(node, normalized) {\r
-                       var idx = 0, lastNodeType, lastNode, nodeType;\r
+                                               node = node.parent;\r
+                                       }\r
+                               }\r
+                       }, schema);\r
 \r
-                       if (node) {\r
-                               for (lastNodeType = node.nodeType, node = node.previousSibling, lastNode = node; node; node = node.previousSibling) {\r
-                                       nodeType = node.nodeType;\r
+                       rootNode = node = new Node(settings.root_name, 11);\r
 \r
-                                       // Normalize text nodes\r
-                                       if (normalized && nodeType == 3) {\r
-                                               if (nodeType == lastNodeType || !node.nodeValue.length)\r
-                                                       continue;\r
-                                       }\r
+                       parser.parse(html);\r
 \r
-                                       idx++;\r
-                                       lastNodeType = nodeType;\r
+                       if (validate)\r
+                               fixInvalidChildren(invalidChildren);\r
+\r
+                       // Run node filters\r
+                       for (name in matchedNodes) {\r
+                               list = nodeFilters[name];\r
+                               nodes = matchedNodes[name];\r
+\r
+                               // Remove already removed children\r
+                               fi = nodes.length;\r
+                               while (fi--) {\r
+                                       if (!nodes[fi].parent)\r
+                                               nodes.splice(fi, 1);\r
                                }\r
+\r
+                               for (i = 0, l = list.length; i < l; i++)\r
+                                       list[i](nodes, name, args);\r
                        }\r
 \r
-                       return idx;\r
-               },\r
+                       // Run attribute filters\r
+                       for (i = 0, l = attributeFilters.length; i < l; i++) {\r
+                               list = attributeFilters[i];\r
 \r
-               split : function(pe, e, re) {\r
-                       var t = this, r = t.createRng(), bef, aft, pa;\r
+                               if (list.name in matchedAttributes) {\r
+                                       nodes = matchedAttributes[list.name];\r
 \r
-                       // W3C valid browsers tend to leave empty nodes to the left/right side of the contents, this makes sense\r
-                       // but we don't want that in our code since it serves no purpose for the end user\r
-                       // For example if this is chopped:\r
-                       //   <p>text 1<span><b>CHOP</b></span>text 2</p>\r
-                       // would produce:\r
-                       //   <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p>\r
-                       // this function will then trim of empty edges and produce:\r
-                       //   <p>text 1</p><b>CHOP</b><p>text 2</p>\r
-                       function trim(node) {\r
-                               var i, children = node.childNodes;\r
+                                       // Remove already removed children\r
+                                       fi = nodes.length;\r
+                                       while (fi--) {\r
+                                               if (!nodes[fi].parent)\r
+                                                       nodes.splice(fi, 1);\r
+                                       }\r
 \r
-                               if (node.nodeType == 1 && node.getAttribute('_mce_type') == 'bookmark')\r
-                                       return;\r
+                                       for (fi = 0, fl = list.callbacks.length; fi < fl; fi++)\r
+                                               list.callbacks[fi](nodes, list.name, args);\r
+                               }\r
+                       }\r
 \r
-                               for (i = children.length - 1; i >= 0; i--)\r
-                                       trim(children[i]);\r
+                       return rootNode;\r
+               };\r
 \r
-                               if (node.nodeType != 9) {\r
-                                       // Keep non whitespace text nodes\r
-                                       if (node.nodeType == 3 && node.nodeValue.length > 0)\r
-                                               return;\r
+               // Remove <br> at end of block elements Gecko and WebKit injects BR elements to\r
+               // make it possible to place the caret inside empty blocks. This logic tries to remove\r
+               // these elements and keep br elements that where intended to be there intact\r
+               if (settings.remove_trailing_brs) {\r
+                       self.addNodeFilter('br', function(nodes, name) {\r
+                               var i, l = nodes.length, node, blockElements = schema.getBlockElements(),\r
+                                       nonEmptyElements = schema.getNonEmptyElements(), parent, prev, prevName;\r
+\r
+                               // Must loop forwards since it will otherwise remove all brs in <p>a<br><br><br></p>\r
+                               for (i = 0; i < l; i++) {\r
+                                       node = nodes[i];\r
+                                       parent = node.parent;\r
+\r
+                                       if (blockElements[node.parent.name] && node === parent.lastChild) {\r
+                                               // Loop all nodes to the right of the current node and check for other BR elements\r
+                                               // excluding bookmarks since they are invisible\r
+                                               prev = node.prev;\r
+                                               while (prev) {\r
+                                                       prevName = prev.name;\r
+\r
+                                                       // Ignore bookmarks\r
+                                                       if (prevName !== "span" || prev.attr('data-mce-type') !== 'bookmark') {\r
+                                                               // Found a non BR element\r
+                                                               if (prevName !== "br")\r
+                                                                       break;\r
+       \r
+                                                               // Found another br it's a <br><br> structure then don't remove anything\r
+                                                               if (prevName === 'br') {\r
+                                                                       node = null;\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
 \r
-                                       if (node.nodeType == 1) {\r
-                                               // If the only child is a bookmark then move it up\r
-                                               children = node.childNodes;\r
-                                               if (children.length == 1 && children[0] && children[0].nodeType == 1 && children[0].getAttribute('_mce_type') == 'bookmark')\r
-                                                       node.parentNode.insertBefore(children[0], node);\r
+                                                       prev = prev.prev;\r
+                                               }\r
 \r
-                                               // Keep non empty elements or img, hr etc\r
-                                               if (children.length || /^(br|hr|input|img)$/i.test(node.nodeName))\r
-                                                       return;\r
-                                       }\r
+                                               if (node) {\r
+                                                       node.remove();\r
 \r
-                                       t.remove(node);\r
+                                                       // Is the parent to be considered empty after we removed the BR\r
+                                                       if (parent.isEmpty(nonEmptyElements)) {\r
+                                                               elementRule = schema.getElementRule(parent.name);\r
+\r
+                                                               // Remove or padd the element depending on schema rule\r
+                                                               if (elementRule.removeEmpty)\r
+                                                                       parent.remove();\r
+                                                               else if (elementRule.paddEmpty) \r
+                                                                       parent.empty().append(new tinymce.html.Node('#text', 3)).value = '\u00a0';\r
+                                                       }\r
+                                               }\r
+                                       }\r
                                }\r
+                       });\r
+               }\r
+       }\r
+})(tinymce);\r
 \r
-                               return node;\r
-                       };\r
+tinymce.html.Writer = function(settings) {\r
+       var html = [], indent, indentBefore, indentAfter, encode, htmlOutput;\r
 \r
-                       if (pe && e) {\r
-                               // Get before chunk\r
-                               r.setStart(pe.parentNode, t.nodeIndex(pe));\r
-                               r.setEnd(e.parentNode, t.nodeIndex(e));\r
-                               bef = r.extractContents();\r
+       settings = settings || {};\r
+       indent = settings.indent;\r
+       indentBefore = tinymce.makeMap(settings.indent_before || '');\r
+       indentAfter = tinymce.makeMap(settings.indent_after || '');\r
+       encode = tinymce.html.Entities.getEncodeFunc(settings.entity_encoding || 'raw', settings.entities);\r
+       htmlOutput = settings.element_format == "html";\r
 \r
-                               // Get after chunk\r
-                               r = t.createRng();\r
-                               r.setStart(e.parentNode, t.nodeIndex(e) + 1);\r
-                               r.setEnd(pe.parentNode, t.nodeIndex(pe) + 1);\r
-                               aft = r.extractContents();\r
+       return {\r
+               start: function(name, attrs, empty) {\r
+                       var i, l, attr, value;\r
 \r
-                               // Insert before chunk\r
-                               pa = pe.parentNode;\r
-                               pa.insertBefore(trim(bef), pe);\r
+                       if (indent && indentBefore[name] && html.length > 0) {\r
+                               value = html[html.length - 1];\r
 \r
-                               // Insert middle chunk\r
-                               if (re)\r
-                                       pa.replaceChild(re, e);\r
-                               else\r
-                                       pa.insertBefore(e, pe);\r
+                               if (value.length > 0 && value !== '\n')\r
+                                       html.push('\n');\r
+                       }\r
 \r
-                               // Insert after chunk\r
-                               pa.insertBefore(trim(aft), pe);\r
-                               t.remove(pe);\r
+                       html.push('<', name);\r
 \r
-                               return re || e;\r
+                       if (attrs) {\r
+                               for (i = 0, l = attrs.length; i < l; i++) {\r
+                                       attr = attrs[i];\r
+                                       html.push(' ', attr.name, '="', encode(attr.value, true), '"');\r
+                               }\r
                        }\r
-               },\r
 \r
-               bind : function(target, name, func, scope) {\r
-                       var t = this;\r
+                       if (!empty || htmlOutput)\r
+                               html[html.length] = '>';\r
+                       else\r
+                               html[html.length] = ' />';\r
 \r
-                       if (!t.events)\r
-                               t.events = new tinymce.dom.EventUtils();\r
+                       if (empty && indent && indentAfter[name] && html.length > 0) {\r
+                               value = html[html.length - 1];\r
 \r
-                       return t.events.add(target, name, func, scope || this);\r
+                               if (value.length > 0 && value !== '\n')\r
+                                       html.push('\n');\r
+                       }\r
                },\r
 \r
-               unbind : function(target, name, func) {\r
-                       var t = this;\r
-\r
-                       if (!t.events)\r
-                               t.events = new tinymce.dom.EventUtils();\r
+               end: function(name) {\r
+                       var value;\r
 \r
-                       return t.events.remove(target, name, func);\r
-               },\r
+                       /*if (indent && indentBefore[name] && html.length > 0) {\r
+                               value = html[html.length - 1];\r
 \r
+                               if (value.length > 0 && value !== '\n')\r
+                                       html.push('\n');\r
+                       }*/\r
 \r
-               _findSib : function(node, selector, name) {\r
-                       var t = this, f = selector;\r
+                       html.push('</', name, '>');\r
 \r
-                       if (node) {\r
-                               // If expression make a function of it using is\r
-                               if (is(f, 'string')) {\r
-                                       f = function(node) {\r
-                                               return t.is(node, selector);\r
-                                       };\r
-                               }\r
+                       if (indent && indentAfter[name] && html.length > 0) {\r
+                               value = html[html.length - 1];\r
 \r
-                               // Loop all siblings\r
-                               for (node = node[name]; node; node = node[name]) {\r
-                                       if (f(node))\r
-                                               return node;\r
-                               }\r
+                               if (value.length > 0 && value !== '\n')\r
+                                       html.push('\n');\r
                        }\r
+               },\r
 \r
-                       return null;\r
+               text: function(text, raw) {\r
+                       if (text.length > 0)\r
+                               html[html.length] = raw ? text : encode(text);\r
                },\r
 \r
-               _isRes : function(c) {\r
-                       // Is live resizble element\r
-                       return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c);\r
-               }\r
+               cdata: function(text) {\r
+                       html.push('<![CDATA[', text, ']]>');\r
+               },\r
 \r
-               /*\r
-               walk : function(n, f, s) {\r
-                       var d = this.doc, w;\r
+               comment: function(text) {\r
+                       html.push('<!--', text, '-->');\r
+               },\r
 \r
-                       if (d.createTreeWalker) {\r
-                               w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
+               pi: function(name, text) {\r
+                       if (text)\r
+                               html.push('<?', name, ' ', text, '?>');\r
+                       else\r
+                               html.push('<?', name, '?>');\r
 \r
-                               while ((n = w.nextNode()) != null)\r
-                                       f.call(s || this, n);\r
-                       } else\r
-                               tinymce.walk(n, f, 'childNodes', s);\r
-               }\r
-               */\r
-\r
-               /*\r
-               toRGB : function(s) {\r
-                       var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s);\r
+                       if (indent)\r
+                               html.push('\n');\r
+               },\r
 \r
-                       if (c) {\r
-                               // #FFF -> #FFFFFF\r
-                               if (!is(c[3]))\r
-                                       c[3] = c[2] = c[1];\r
+               doctype: function(text) {\r
+                       html.push('<!DOCTYPE', text, '>', indent ? '\n' : '');\r
+               },\r
 \r
-                               return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")";\r
-                       }\r
+               reset: function() {\r
+                       html.length = 0;\r
+               },\r
 \r
-                       return s;\r
+               getContent: function() {\r
+                       return html.join('').replace(/\n$/, '');\r
                }\r
-               */\r
-       });\r
-\r
-       tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});\r
-})(tinymce);\r
-\r
-(function(ns) {\r
-       // Range constructor\r
-       function Range(dom) {\r
-               var t = this,\r
-                       doc = dom.doc,\r
-                       EXTRACT = 0,\r
-                       CLONE = 1,\r
-                       DELETE = 2,\r
-                       TRUE = true,\r
-                       FALSE = false,\r
-                       START_OFFSET = 'startOffset',\r
-                       START_CONTAINER = 'startContainer',\r
-                       END_CONTAINER = 'endContainer',\r
-                       END_OFFSET = 'endOffset',\r
-                       extend = tinymce.extend,\r
-                       nodeIndex = dom.nodeIndex;\r
-\r
-               extend(t, {\r
-                       // Inital states\r
-                       startContainer : doc,\r
-                       startOffset : 0,\r
-                       endContainer : doc,\r
-                       endOffset : 0,\r
-                       collapsed : TRUE,\r
-                       commonAncestorContainer : doc,\r
+       };\r
+};\r
 \r
-                       // Range constants\r
-                       START_TO_START : 0,\r
-                       START_TO_END : 1,\r
-                       END_TO_END : 2,\r
-                       END_TO_START : 3,\r
+(function(tinymce) {\r
+       tinymce.html.Serializer = function(settings, schema) {\r
+               var self = this, writer = new tinymce.html.Writer(settings);\r
 \r
-                       // Public methods\r
-                       setStart : setStart,\r
-                       setEnd : setEnd,\r
-                       setStartBefore : setStartBefore,\r
-                       setStartAfter : setStartAfter,\r
-                       setEndBefore : setEndBefore,\r
-                       setEndAfter : setEndAfter,\r
-                       collapse : collapse,\r
-                       selectNode : selectNode,\r
-                       selectNodeContents : selectNodeContents,\r
-                       compareBoundaryPoints : compareBoundaryPoints,\r
-                       deleteContents : deleteContents,\r
-                       extractContents : extractContents,\r
-                       cloneContents : cloneContents,\r
-                       insertNode : insertNode,\r
-                       surroundContents : surroundContents,\r
-                       cloneRange : cloneRange\r
-               });\r
+               settings = settings || {};\r
+               settings.validate = "validate" in settings ? settings.validate : true;\r
 \r
-               function setStart(n, o) {\r
-                       _setEndPoint(TRUE, n, o);\r
-               };\r
+               self.schema = schema = schema || new tinymce.html.Schema();\r
+               self.writer = writer;\r
 \r
-               function setEnd(n, o) {\r
-                       _setEndPoint(FALSE, n, o);\r
-               };\r
+               self.serialize = function(node) {\r
+                       var handlers, validate;\r
 \r
-               function setStartBefore(n) {\r
-                       setStart(n.parentNode, nodeIndex(n));\r
-               };\r
+                       validate = settings.validate;\r
 \r
-               function setStartAfter(n) {\r
-                       setStart(n.parentNode, nodeIndex(n) + 1);\r
-               };\r
+                       handlers = {\r
+                               // #text\r
+                               3: function(node, raw) {\r
+                                       writer.text(node.value, node.raw);\r
+                               },\r
 \r
-               function setEndBefore(n) {\r
-                       setEnd(n.parentNode, nodeIndex(n));\r
-               };\r
+                               // #comment\r
+                               8: function(node) {\r
+                                       writer.comment(node.value);\r
+                               },\r
 \r
-               function setEndAfter(n) {\r
-                       setEnd(n.parentNode, nodeIndex(n) + 1);\r
-               };\r
+                               // Processing instruction\r
+                               7: function(node) {\r
+                                       writer.pi(node.name, node.value);\r
+                               },\r
 \r
-               function collapse(ts) {\r
-                       if (ts) {\r
-                               t[END_CONTAINER] = t[START_CONTAINER];\r
-                               t[END_OFFSET] = t[START_OFFSET];\r
-                       } else {\r
-                               t[START_CONTAINER] = t[END_CONTAINER];\r
-                               t[START_OFFSET] = t[END_OFFSET];\r
-                       }\r
+                               // Doctype\r
+                               10: function(node) {\r
+                                       writer.doctype(node.value);\r
+                               },\r
 \r
-                       t.collapsed = TRUE;\r
-               };\r
+                               // CDATA\r
+                               4: function(node) {\r
+                                       writer.cdata(node.value);\r
+                               },\r
 \r
-               function selectNode(n) {\r
-                       setStartBefore(n);\r
-                       setEndAfter(n);\r
-               };\r
+                               // Document fragment\r
+                               11: function(node) {\r
+                                       if ((node = node.firstChild)) {\r
+                                               do {\r
+                                                       walk(node);\r
+                                               } while (node = node.next);\r
+                                       }\r
+                               }\r
+                       };\r
 \r
-               function selectNodeContents(n) {\r
-                       setStart(n, 0);\r
-                       setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length);\r
-               };\r
+                       writer.reset();\r
 \r
-               function compareBoundaryPoints(h, r) {\r
-                       var sc = t[START_CONTAINER], so = t[START_OFFSET], ec = t[END_CONTAINER], eo = t[END_OFFSET];\r
+                       function walk(node) {\r
+                               var handler = handlers[node.type], name, isEmpty, attrs, attrName, attrValue, sortedAttrs, i, l, elementRule;\r
 \r
-                       // Check START_TO_START\r
-                       if (h === 0)\r
-                               return _compareBoundaryPoints(sc, so, sc, so);\r
+                               if (!handler) {\r
+                                       name = node.name;\r
+                                       isEmpty = node.shortEnded;\r
+                                       attrs = node.attributes;\r
 \r
-                       // Check START_TO_END\r
-                       if (h === 1)\r
-                               return _compareBoundaryPoints(sc, so, ec, eo);\r
+                                       // Sort attributes\r
+                                       if (validate && attrs && attrs.length > 1) {\r
+                                               sortedAttrs = [];\r
+                                               sortedAttrs.map = {};\r
 \r
-                       // Check END_TO_END\r
-                       if (h === 2)\r
-                               return _compareBoundaryPoints(ec, eo, ec, eo);\r
+                                               elementRule = schema.getElementRule(node.name);\r
+                                               for (i = 0, l = elementRule.attributesOrder.length; i < l; i++) {\r
+                                                       attrName = elementRule.attributesOrder[i];\r
 \r
-                       // Check END_TO_START\r
-                       if (h === 3)\r
-                               return _compareBoundaryPoints(ec, eo, sc, so);\r
-               };\r
+                                                       if (attrName in attrs.map) {\r
+                                                               attrValue = attrs.map[attrName];\r
+                                                               sortedAttrs.map[attrName] = attrValue;\r
+                                                               sortedAttrs.push({name: attrName, value: attrValue});\r
+                                                       }\r
+                                               }\r
 \r
-               function deleteContents() {\r
-                       _traverse(DELETE);\r
-               };\r
+                                               for (i = 0, l = attrs.length; i < l; i++) {\r
+                                                       attrName = attrs[i].name;\r
 \r
-               function extractContents() {\r
-                       return _traverse(EXTRACT);\r
-               };\r
+                                                       if (!(attrName in sortedAttrs.map)) {\r
+                                                               attrValue = attrs.map[attrName];\r
+                                                               sortedAttrs.map[attrName] = attrValue;\r
+                                                               sortedAttrs.push({name: attrName, value: attrValue});\r
+                                                       }\r
+                                               }\r
 \r
-               function cloneContents() {\r
-                       return _traverse(CLONE);\r
-               };\r
+                                               attrs = sortedAttrs;\r
+                                       }\r
 \r
-               function insertNode(n) {\r
-                       var startContainer = this[START_CONTAINER],\r
-                               startOffset = this[START_OFFSET], nn, o;\r
+                                       writer.start(node.name, attrs, isEmpty);\r
 \r
-                       // Node is TEXT_NODE or CDATA\r
-                       if ((startContainer.nodeType === 3 || startContainer.nodeType === 4) && startContainer.nodeValue) {\r
-                               if (!startOffset) {\r
-                                       // At the start of text\r
-                                       startContainer.parentNode.insertBefore(n, startContainer);\r
-                               } else if (startOffset >= startContainer.nodeValue.length) {\r
-                                       // At the end of text\r
-                                       dom.insertAfter(n, startContainer);\r
-                               } else {\r
-                                       // Middle, need to split\r
-                                       nn = startContainer.splitText(startOffset);\r
-                                       startContainer.parentNode.insertBefore(n, nn);\r
-                               }\r
-                       } else {\r
-                               // Insert element node\r
-                               if (startContainer.childNodes.length > 0)\r
-                                       o = startContainer.childNodes[startOffset];\r
+                                       if (!isEmpty) {\r
+                                               if ((node = node.firstChild)) {\r
+                                                       do {\r
+                                                               walk(node);\r
+                                                       } while (node = node.next);\r
+                                               }\r
 \r
-                               if (o)\r
-                                       startContainer.insertBefore(n, o);\r
-                               else\r
-                                       startContainer.appendChild(n);\r
+                                               writer.end(name);\r
+                                       }\r
+                               else\r
+                                       handler(node);\r
                        }\r
-               };\r
 \r
-               function surroundContents(n) {\r
-                       var f = t.extractContents();\r
+                       // Serialize element and treat all non elements as fragments\r
+                       if (node.type == 1 && !settings.inner)\r
+                               walk(node);\r
+                       else\r
+                               handlers[11](node);\r
 \r
-                       t.insertNode(n);\r
-                       n.appendChild(f);\r
-                       t.selectNode(n);\r
+                       return writer.getContent();\r
                };\r
+       }\r
+})(tinymce);\r
 \r
-               function cloneRange() {\r
-                       return extend(new Range(dom), {\r
-                               startContainer : t[START_CONTAINER],\r
-                               startOffset : t[START_OFFSET],\r
-                               endContainer : t[END_CONTAINER],\r
-                               endOffset : t[END_OFFSET],\r
-                               collapsed : t.collapsed,\r
-                               commonAncestorContainer : t.commonAncestorContainer\r
-                       });\r
-               };\r
+(function(tinymce) {\r
+       // Shorten names\r
+       var each = tinymce.each,\r
+               is = tinymce.is,\r
+               isWebKit = tinymce.isWebKit,\r
+               isIE = tinymce.isIE,\r
+               Entities = tinymce.html.Entities,\r
+               simpleSelectorRe = /^([a-z0-9],?)+$/i,\r
+               blockElementsMap = tinymce.html.Schema.blockElementsMap,\r
+               whiteSpaceRegExp = /^[ \t\r\n]*$/;\r
 \r
-               // Private methods\r
+       tinymce.create('tinymce.dom.DOMUtils', {\r
+               doc : null,\r
+               root : null,\r
+               files : null,\r
+               pixelStyles : /^(top|left|bottom|right|width|height|borderWidth)$/,\r
+               props : {\r
+                       "for" : "htmlFor",\r
+                       "class" : "className",\r
+                       className : "className",\r
+                       checked : "checked",\r
+                       disabled : "disabled",\r
+                       maxlength : "maxLength",\r
+                       readonly : "readOnly",\r
+                       selected : "selected",\r
+                       value : "value",\r
+                       id : "id",\r
+                       name : "name",\r
+                       type : "type"\r
+               },\r
 \r
-               function _getSelectedNode(container, offset) {\r
-                       var child;\r
+               DOMUtils : function(d, s) {\r
+                       var t = this, globalStyle;\r
 \r
-                       if (container.nodeType == 3 /* TEXT_NODE */)\r
-                               return container;\r
+                       t.doc = d;\r
+                       t.win = window;\r
+                       t.files = {};\r
+                       t.cssFlicker = false;\r
+                       t.counter = 0;\r
+                       t.stdMode = !tinymce.isIE || d.documentMode >= 8;\r
+                       t.boxModel = !tinymce.isIE || d.compatMode == "CSS1Compat" || t.stdMode;\r
+                       t.hasOuterHTML = "outerHTML" in d.createElement("a");\r
 \r
-                       if (offset < 0)\r
-                               return container;\r
+                       t.settings = s = tinymce.extend({\r
+                               keep_values : false,\r
+                               hex_colors : 1\r
+                       }, s);\r
+                       \r
+                       t.schema = s.schema;\r
+                       t.styles = new tinymce.html.Styles({\r
+                               url_converter : s.url_converter,\r
+                               url_converter_scope : s.url_converter_scope\r
+                       }, s.schema);\r
 \r
-                       child = container.firstChild;\r
-                       while (child && offset > 0) {\r
-                               --offset;\r
-                               child = child.nextSibling;\r
+                       // Fix IE6SP2 flicker and check it failed for pre SP2\r
+                       if (tinymce.isIE6) {\r
+                               try {\r
+                                       d.execCommand('BackgroundImageCache', false, true);\r
+                               } catch (e) {\r
+                                       t.cssFlicker = true;\r
+                               }\r
                        }\r
 \r
-                       if (child)\r
-                               return child;\r
+                       if (isIE) {\r
+                               // Add missing HTML 4/5 elements to IE\r
+                               ('abbr article aside audio canvas ' +\r
+                               'details figcaption figure footer ' +\r
+                               'header hgroup mark menu meter nav ' +\r
+                               'output progress section summary ' +\r
+                               'time video').replace(/\w+/g, function(name) {\r
+                                       d.createElement(name);\r
+                               });\r
+                       }\r
 \r
-                       return container;\r
-               };\r
+                       tinymce.addUnload(t.destroy, t);\r
+               },\r
 \r
-               function _isCollapsed() {\r
-                       return (t[START_CONTAINER] == t[END_CONTAINER] && t[START_OFFSET] == t[END_OFFSET]);\r
-               };\r
-\r
-               function _compareBoundaryPoints(containerA, offsetA, containerB, offsetB) {\r
-                       var c, offsetC, n, cmnRoot, childA, childB;\r
-\r
-                       // In the first case the boundary-points have the same container. A is before B\r
-                       // if its offset is less than the offset of B, A is equal to B if its offset is\r
-                       // equal to the offset of B, and A is after B if its offset is greater than the\r
-                       // offset of B.\r
-                       if (containerA == containerB) {\r
-                               if (offsetA == offsetB)\r
-                                       return 0; // equal\r
+               getRoot : function() {\r
+                       var t = this, s = t.settings;\r
 \r
-                               if (offsetA < offsetB)\r
-                                       return -1; // before\r
+                       return (s && t.get(s.root_element)) || t.doc.body;\r
+               },\r
 \r
-                               return 1; // after\r
-                       }\r
+               getViewPort : function(w) {\r
+                       var d, b;\r
 \r
-                       // In the second case a child node C of the container of A is an ancestor\r
-                       // container of B. In this case, A is before B if the offset of A is less than or\r
-                       // equal to the index of the child node C and A is after B otherwise.\r
-                       c = containerB;\r
-                       while (c && c.parentNode != containerA)\r
-                               c = c.parentNode;\r
+                       w = !w ? this.win : w;\r
+                       d = w.document;\r
+                       b = this.boxModel ? d.documentElement : d.body;\r
 \r
-                       if (c) {\r
-                               offsetC = 0;\r
-                               n = containerA.firstChild;\r
+                       // Returns viewport size excluding scrollbars\r
+                       return {\r
+                               x : w.pageXOffset || b.scrollLeft,\r
+                               y : w.pageYOffset || b.scrollTop,\r
+                               w : w.innerWidth || b.clientWidth,\r
+                               h : w.innerHeight || b.clientHeight\r
+                       };\r
+               },\r
 \r
-                               while (n != c && offsetC < offsetA) {\r
-                                       offsetC++;\r
-                                       n = n.nextSibling;\r
-                               }\r
+               getRect : function(e) {\r
+                       var p, t = this, sr;\r
 \r
-                               if (offsetA <= offsetC)\r
-                                       return -1; // before\r
+                       e = t.get(e);\r
+                       p = t.getPos(e);\r
+                       sr = t.getSize(e);\r
 \r
-                               return 1; // after\r
-                       }\r
+                       return {\r
+                               x : p.x,\r
+                               y : p.y,\r
+                               w : sr.w,\r
+                               h : sr.h\r
+                       };\r
+               },\r
 \r
-                       // In the third case a child node C of the container of B is an ancestor container\r
-                       // of A. In this case, A is before B if the index of the child node C is less than\r
-                       // the offset of B and A is after B otherwise.\r
-                       c = containerA;\r
-                       while (c && c.parentNode != containerB) {\r
-                               c = c.parentNode;\r
-                       }\r
+               getSize : function(e) {\r
+                       var t = this, w, h;\r
 \r
-                       if (c) {\r
-                               offsetC = 0;\r
-                               n = containerB.firstChild;\r
+                       e = t.get(e);\r
+                       w = t.getStyle(e, 'width');\r
+                       h = t.getStyle(e, 'height');\r
 \r
-                               while (n != c && offsetC < offsetB) {\r
-                                       offsetC++;\r
-                                       n = n.nextSibling;\r
-                               }\r
+                       // Non pixel value, then force offset/clientWidth\r
+                       if (w.indexOf('px') === -1)\r
+                               w = 0;\r
 \r
-                               if (offsetC < offsetB)\r
-                                       return -1; // before\r
+                       // Non pixel value, then force offset/clientWidth\r
+                       if (h.indexOf('px') === -1)\r
+                               h = 0;\r
 \r
-                               return 1; // after\r
-                       }\r
+                       return {\r
+                               w : parseInt(w) || e.offsetWidth || e.clientWidth,\r
+                               h : parseInt(h) || e.offsetHeight || e.clientHeight\r
+                       };\r
+               },\r
 \r
-                       // In the fourth case, none of three other cases hold: the containers of A and B\r
-                       // are siblings or descendants of sibling nodes. In this case, A is before B if\r
-                       // the container of A is before the container of B in a pre-order traversal of the\r
-                       // Ranges' context tree and A is after B otherwise.\r
-                       cmnRoot = dom.findCommonAncestor(containerA, containerB);\r
-                       childA = containerA;\r
+               getParent : function(n, f, r) {\r
+                       return this.getParents(n, f, r, false);\r
+               },\r
 \r
-                       while (childA && childA.parentNode != cmnRoot)\r
-                               childA = childA.parentNode;\r
+               getParents : function(n, f, r, c) {\r
+                       var t = this, na, se = t.settings, o = [];\r
 \r
-                       if (!childA)\r
-                               childA = cmnRoot;\r
+                       n = t.get(n);\r
+                       c = c === undefined;\r
 \r
-                       childB = containerB;\r
-                       while (childB && childB.parentNode != cmnRoot)\r
-                               childB = childB.parentNode;\r
+                       if (se.strict_root)\r
+                               r = r || t.getRoot();\r
 \r
-                       if (!childB)\r
-                               childB = cmnRoot;\r
+                       // Wrap node name as func\r
+                       if (is(f, 'string')) {\r
+                               na = f;\r
 \r
-                       if (childA == childB)\r
-                               return 0; // equal\r
+                               if (f === '*') {\r
+                                       f = function(n) {return n.nodeType == 1;};\r
+                               } else {\r
+                                       f = function(n) {\r
+                                               return t.is(n, na);\r
+                                       };\r
+                               }\r
+                       }\r
 \r
-                       n = cmnRoot.firstChild;\r
                        while (n) {\r
-                               if (n == childA)\r
-                                       return -1; // before\r
+                               if (n == r || !n.nodeType || n.nodeType === 9)\r
+                                       break;\r
 \r
-                               if (n == childB)\r
-                                       return 1; // after\r
+                               if (!f || f(n)) {\r
+                                       if (c)\r
+                                               o.push(n);\r
+                                       else\r
+                                               return n;\r
+                               }\r
 \r
-                               n = n.nextSibling;\r
+                               n = n.parentNode;\r
                        }\r
-               };\r
-\r
-               function _setEndPoint(st, n, o) {\r
-                       var ec, sc;\r
 \r
-                       if (st) {\r
-                               t[START_CONTAINER] = n;\r
-                               t[START_OFFSET] = o;\r
-                       } else {\r
-                               t[END_CONTAINER] = n;\r
-                               t[END_OFFSET] = o;\r
-                       }\r
+                       return c ? o : null;\r
+               },\r
 \r
-                       // If one boundary-point of a Range is set to have a root container\r
-                       // other than the current one for the Range, the Range is collapsed to\r
-                       // the new position. This enforces the restriction that both boundary-\r
-                       // points of a Range must have the same root container.\r
-                       ec = t[END_CONTAINER];\r
-                       while (ec.parentNode)\r
-                               ec = ec.parentNode;\r
+               get : function(e) {\r
+                       var n;\r
 \r
-                       sc = t[START_CONTAINER];\r
-                       while (sc.parentNode)\r
-                               sc = sc.parentNode;\r
+                       if (e && this.doc && typeof(e) == 'string') {\r
+                               n = e;\r
+                               e = this.doc.getElementById(e);\r
 \r
-                       if (sc == ec) {\r
-                               // The start position of a Range is guaranteed to never be after the\r
-                               // end position. To enforce this restriction, if the start is set to\r
-                               // be at a position after the end, the Range is collapsed to that\r
-                               // position.\r
-                               if (_compareBoundaryPoints(t[START_CONTAINER], t[START_OFFSET], t[END_CONTAINER], t[END_OFFSET]) > 0)\r
-                                       t.collapse(st);\r
-                       } else\r
-                               t.collapse(st);\r
+                               // IE and Opera returns meta elements when they match the specified input ID, but getElementsByName seems to do the trick\r
+                               if (e && e.id !== n)\r
+                                       return this.doc.getElementsByName(n)[1];\r
+                       }\r
 \r
-                       t.collapsed = _isCollapsed();\r
-                       t.commonAncestorContainer = dom.findCommonAncestor(t[START_CONTAINER], t[END_CONTAINER]);\r
-               };\r
+                       return e;\r
+               },\r
 \r
-               function _traverse(how) {\r
-                       var c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep;\r
+               getNext : function(node, selector) {\r
+                       return this._findSib(node, selector, 'nextSibling');\r
+               },\r
 \r
-                       if (t[START_CONTAINER] == t[END_CONTAINER])\r
-                               return _traverseSameContainer(how);\r
+               getPrev : function(node, selector) {\r
+                       return this._findSib(node, selector, 'previousSibling');\r
+               },\r
 \r
-                       for (c = t[END_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) {\r
-                               if (p == t[START_CONTAINER])\r
-                                       return _traverseCommonStartContainer(c, how);\r
 \r
-                               ++endContainerDepth;\r
-                       }\r
+               select : function(pa, s) {\r
+                       var t = this;\r
 \r
-                       for (c = t[START_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) {\r
-                               if (p == t[END_CONTAINER])\r
-                                       return _traverseCommonEndContainer(c, how);\r
+                       return tinymce.dom.Sizzle(pa, t.get(s) || t.get(t.settings.root_element) || t.doc, []);\r
+               },\r
 \r
-                               ++startContainerDepth;\r
-                       }\r
+               is : function(n, selector) {\r
+                       var i;\r
 \r
-                       depthDiff = startContainerDepth - endContainerDepth;\r
+                       // If it isn't an array then try to do some simple selectors instead of Sizzle for to boost performance\r
+                       if (n.length === undefined) {\r
+                               // Simple all selector\r
+                               if (selector === '*')\r
+                                       return n.nodeType == 1;\r
 \r
-                       startNode = t[START_CONTAINER];\r
-                       while (depthDiff > 0) {\r
-                               startNode = startNode.parentNode;\r
-                               depthDiff--;\r
-                       }\r
+                               // Simple selector just elements\r
+                               if (simpleSelectorRe.test(selector)) {\r
+                                       selector = selector.toLowerCase().split(/,/);\r
+                                       n = n.nodeName.toLowerCase();\r
 \r
-                       endNode = t[END_CONTAINER];\r
-                       while (depthDiff < 0) {\r
-                               endNode = endNode.parentNode;\r
-                               depthDiff++;\r
-                       }\r
+                                       for (i = selector.length - 1; i >= 0; i--) {\r
+                                               if (selector[i] == n)\r
+                                                       return true;\r
+                                       }\r
 \r
-                       // ascend the ancestor hierarchy until we have a common parent.\r
-                       for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) {\r
-                               startNode = sp;\r
-                               endNode = ep;\r
+                                       return false;\r
+                               }\r
                        }\r
 \r
-                       return _traverseCommonAncestors(startNode, endNode, how);\r
-               };\r
+                       return tinymce.dom.Sizzle.matches(selector, n.nodeType ? [n] : n).length > 0;\r
+               },\r
 \r
-                function _traverseSameContainer(how) {\r
-                       var frag, s, sub, n, cnt, sibling, xferNode;\r
 \r
-                       if (how != DELETE)\r
-                               frag = doc.createDocumentFragment();\r
-\r
-                       // If selection is empty, just return the fragment\r
-                       if (t[START_OFFSET] == t[END_OFFSET])\r
-                               return frag;\r
+               add : function(p, n, a, h, c) {\r
+                       var t = this;\r
 \r
-                       // Text node needs special case handling\r
-                       if (t[START_CONTAINER].nodeType == 3 /* TEXT_NODE */) {\r
-                               // get the substring\r
-                               s = t[START_CONTAINER].nodeValue;\r
-                               sub = s.substring(t[START_OFFSET], t[END_OFFSET]);\r
+                       return this.run(p, function(p) {\r
+                               var e, k;\r
 \r
-                               // set the original text node to its new value\r
-                               if (how != CLONE) {\r
-                                       t[START_CONTAINER].deleteData(t[START_OFFSET], t[END_OFFSET] - t[START_OFFSET]);\r
+                               e = is(n, 'string') ? t.doc.createElement(n) : n;\r
+                               t.setAttribs(e, a);\r
 \r
-                                       // Nothing is partially selected, so collapse to start point\r
-                                       t.collapse(TRUE);\r
+                               if (h) {\r
+                                       if (h.nodeType)\r
+                                               e.appendChild(h);\r
+                                       else\r
+                                               t.setHTML(e, h);\r
                                }\r
 \r
-                               if (how == DELETE)\r
-                                       return;\r
-\r
-                               frag.appendChild(doc.createTextNode(sub));\r
-                               return frag;\r
-                       }\r
+                               return !c ? p.appendChild(e) : e;\r
+                       });\r
+               },\r
 \r
-                       // Copy nodes between the start/end offsets.\r
-                       n = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]);\r
-                       cnt = t[END_OFFSET] - t[START_OFFSET];\r
+               create : function(n, a, h) {\r
+                       return this.add(this.doc.createElement(n), n, a, h, 1);\r
+               },\r
 \r
-                       while (cnt > 0) {\r
-                               sibling = n.nextSibling;\r
-                               xferNode = _traverseFullySelected(n, how);\r
+               createHTML : function(n, a, h) {\r
+                       var o = '', t = this, k;\r
 \r
-                               if (frag)\r
-                                       frag.appendChild( xferNode );\r
+                       o += '<' + n;\r
 \r
-                               --cnt;\r
-                               n = sibling;\r
+                       for (k in a) {\r
+                               if (a.hasOwnProperty(k))\r
+                                       o += ' ' + k + '="' + t.encode(a[k]) + '"';\r
                        }\r
 \r
-                       // Nothing is partially selected, so collapse to start point\r
-                       if (how != CLONE)\r
-                               t.collapse(TRUE);\r
-\r
-                       return frag;\r
-               };\r
-\r
-               function _traverseCommonStartContainer(endAncestor, how) {\r
-                       var frag, n, endIdx, cnt, sibling, xferNode;\r
-\r
-                       if (how != DELETE)\r
-                               frag = doc.createDocumentFragment();\r
+                       // A call to tinymce.is doesn't work for some odd reason on IE9 possible bug inside their JS runtime\r
+                       if (typeof(h) != "undefined")\r
+                               return o + '>' + h + '</' + n + '>';\r
 \r
-                       n = _traverseRightBoundary(endAncestor, how);\r
+                       return o + ' />';\r
+               },\r
 \r
-                       if (frag)\r
-                               frag.appendChild(n);\r
+               remove : function(node, keep_children) {\r
+                       return this.run(node, function(node) {\r
+                               var child, parent = node.parentNode;\r
 \r
-                       endIdx = nodeIndex(endAncestor);\r
-                       cnt = endIdx - t[START_OFFSET];\r
+                               if (!parent)\r
+                                       return null;\r
 \r
-                       if (cnt <= 0) {\r
-                               // Collapse to just before the endAncestor, which\r
-                               // is partially selected.\r
-                               if (how != CLONE) {\r
-                                       t.setEndBefore(endAncestor);\r
-                                       t.collapse(FALSE);\r
+                               if (keep_children) {\r
+                                       while (child = node.firstChild) {\r
+                                               // IE 8 will crash if you don't remove completely empty text nodes\r
+                                               if (!tinymce.isIE || child.nodeType !== 3 || child.nodeValue)\r
+                                                       parent.insertBefore(child, node);\r
+                                               else\r
+                                                       node.removeChild(child);\r
+                                       }\r
                                }\r
 \r
-                               return frag;\r
-                       }\r
+                               return parent.removeChild(node);\r
+                       });\r
+               },\r
 \r
-                       n = endAncestor.previousSibling;\r
-                       while (cnt > 0) {\r
-                               sibling = n.previousSibling;\r
-                               xferNode = _traverseFullySelected(n, how);\r
+               setStyle : function(n, na, v) {\r
+                       var t = this;\r
 \r
-                               if (frag)\r
-                                       frag.insertBefore(xferNode, frag.firstChild);\r
+                       return t.run(n, function(e) {\r
+                               var s, i;\r
 \r
-                               --cnt;\r
-                               n = sibling;\r
-                       }\r
+                               s = e.style;\r
 \r
-                       // Collapse to just before the endAncestor, which\r
-                       // is partially selected.\r
-                       if (how != CLONE) {\r
-                               t.setEndBefore(endAncestor);\r
-                               t.collapse(FALSE);\r
-                       }\r
+                               // Camelcase it, if needed\r
+                               na = na.replace(/-(\D)/g, function(a, b){\r
+                                       return b.toUpperCase();\r
+                               });\r
 \r
-                       return frag;\r
-               };\r
+                               // Default px suffix on these\r
+                               if (t.pixelStyles.test(na) && (tinymce.is(v, 'number') || /^[\-0-9\.]+$/.test(v)))\r
+                                       v += 'px';\r
 \r
-               function _traverseCommonEndContainer(startAncestor, how) {\r
-                       var frag, startIdx, n, cnt, sibling, xferNode;\r
+                               switch (na) {\r
+                                       case 'opacity':\r
+                                               // IE specific opacity\r
+                                               if (isIE) {\r
+                                                       s.filter = v === '' ? '' : "alpha(opacity=" + (v * 100) + ")";\r
 \r
-                       if (how != DELETE)\r
-                               frag = doc.createDocumentFragment();\r
+                                                       if (!n.currentStyle || !n.currentStyle.hasLayout)\r
+                                                               s.display = 'inline-block';\r
+                                               }\r
 \r
-                       n = _traverseLeftBoundary(startAncestor, how);\r
-                       if (frag)\r
-                               frag.appendChild(n);\r
+                                               // Fix for older browsers\r
+                                               s[na] = s['-moz-opacity'] = s['-khtml-opacity'] = v || '';\r
+                                               break;\r
 \r
-                       startIdx = nodeIndex(startAncestor);\r
-                       ++startIdx;  // Because we already traversed it....\r
+                                       case 'float':\r
+                                               isIE ? s.styleFloat = v : s.cssFloat = v;\r
+                                               break;\r
+                                       \r
+                                       default:\r
+                                               s[na] = v || '';\r
+                               }\r
 \r
-                       cnt = t[END_OFFSET] - startIdx;\r
-                       n = startAncestor.nextSibling;\r
-                       while (cnt > 0) {\r
-                               sibling = n.nextSibling;\r
-                               xferNode = _traverseFullySelected(n, how);\r
+                               // Force update of the style data\r
+                               if (t.settings.update_styles)\r
+                                       t.setAttrib(e, 'data-mce-style');\r
+                       });\r
+               },\r
 \r
-                               if (frag)\r
-                                       frag.appendChild(xferNode);\r
+               getStyle : function(n, na, c) {\r
+                       n = this.get(n);\r
 \r
-                               --cnt;\r
-                               n = sibling;\r
-                       }\r
+                       if (!n)\r
+                               return;\r
 \r
-                       if (how != CLONE) {\r
-                               t.setStartAfter(startAncestor);\r
-                               t.collapse(TRUE);\r
+                       // Gecko\r
+                       if (this.doc.defaultView && c) {\r
+                               // Remove camelcase\r
+                               na = na.replace(/[A-Z]/g, function(a){\r
+                                       return '-' + a;\r
+                               });\r
+\r
+                               try {\r
+                                       return this.doc.defaultView.getComputedStyle(n, null).getPropertyValue(na);\r
+                               } catch (ex) {\r
+                                       // Old safari might fail\r
+                                       return null;\r
+                               }\r
                        }\r
 \r
-                       return frag;\r
-               };\r
+                       // Camelcase it, if needed\r
+                       na = na.replace(/-(\D)/g, function(a, b){\r
+                               return b.toUpperCase();\r
+                       });\r
 \r
-               function _traverseCommonAncestors(startAncestor, endAncestor, how) {\r
-                       var n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling;\r
+                       if (na == 'float')\r
+                               na = isIE ? 'styleFloat' : 'cssFloat';\r
 \r
-                       if (how != DELETE)\r
-                               frag = doc.createDocumentFragment();\r
+                       // IE & Opera\r
+                       if (n.currentStyle && c)\r
+                               return n.currentStyle[na];\r
 \r
-                       n = _traverseLeftBoundary(startAncestor, how);\r
-                       if (frag)\r
-                               frag.appendChild(n);\r
+                       return n.style ? n.style[na] : undefined;\r
+               },\r
 \r
-                       commonParent = startAncestor.parentNode;\r
-                       startOffset = nodeIndex(startAncestor);\r
-                       endOffset = nodeIndex(endAncestor);\r
-                       ++startOffset;\r
+               setStyles : function(e, o) {\r
+                       var t = this, s = t.settings, ol;\r
 \r
-                       cnt = endOffset - startOffset;\r
-                       sibling = startAncestor.nextSibling;\r
+                       ol = s.update_styles;\r
+                       s.update_styles = 0;\r
 \r
-                       while (cnt > 0) {\r
-                               nextSibling = sibling.nextSibling;\r
-                               n = _traverseFullySelected(sibling, how);\r
+                       each(o, function(v, n) {\r
+                               t.setStyle(e, n, v);\r
+                       });\r
 \r
-                               if (frag)\r
-                                       frag.appendChild(n);\r
+                       // Update style info\r
+                       s.update_styles = ol;\r
+                       if (s.update_styles)\r
+                               t.setAttrib(e, s.cssText);\r
+               },\r
 \r
-                               sibling = nextSibling;\r
-                               --cnt;\r
-                       }\r
+               removeAllAttribs: function(e) {\r
+                       return this.run(e, function(e) {\r
+                               var i, attrs = e.attributes;\r
+                               for (i = attrs.length - 1; i >= 0; i--) {\r
+                                       e.removeAttributeNode(attrs.item(i));\r
+                               }\r
+                       });\r
+               },\r
 \r
-                       n = _traverseRightBoundary(endAncestor, how);\r
+               setAttrib : function(e, n, v) {\r
+                       var t = this;\r
 \r
-                       if (frag)\r
-                               frag.appendChild(n);\r
+                       // Whats the point\r
+                       if (!e || !n)\r
+                               return;\r
 \r
-                       if (how != CLONE) {\r
-                               t.setStartAfter(startAncestor);\r
-                               t.collapse(TRUE);\r
-                       }\r
+                       // Strict XML mode\r
+                       if (t.settings.strict)\r
+                               n = n.toLowerCase();\r
 \r
-                       return frag;\r
-               };\r
+                       return this.run(e, function(e) {\r
+                               var s = t.settings;\r
 \r
-               function _traverseRightBoundary(root, how) {\r
-                       var next = _getSelectedNode(t[END_CONTAINER], t[END_OFFSET] - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent, isFullySelected = next != t[END_CONTAINER];\r
+                               switch (n) {\r
+                                       case "style":\r
+                                               if (!is(v, 'string')) {\r
+                                                       each(v, function(v, n) {\r
+                                                               t.setStyle(e, n, v);\r
+                                                       });\r
 \r
-                       if (next == root)\r
-                               return _traverseNode(next, isFullySelected, FALSE, how);\r
+                                                       return;\r
+                                               }\r
 \r
-                       parent = next.parentNode;\r
-                       clonedParent = _traverseNode(parent, FALSE, FALSE, how);\r
+                                               // No mce_style for elements with these since they might get resized by the user\r
+                                               if (s.keep_values) {\r
+                                                       if (v && !t._isRes(v))\r
+                                                               e.setAttribute('data-mce-style', v, 2);\r
+                                                       else\r
+                                                               e.removeAttribute('data-mce-style', 2);\r
+                                               }\r
 \r
-                       while (parent) {\r
-                               while (next) {\r
-                                       prevSibling = next.previousSibling;\r
-                                       clonedChild = _traverseNode(next, isFullySelected, FALSE, how);\r
+                                               e.style.cssText = v;\r
+                                               break;\r
 \r
-                                       if (how != DELETE)\r
-                                               clonedParent.insertBefore(clonedChild, clonedParent.firstChild);\r
+                                       case "class":\r
+                                               e.className = v || ''; // Fix IE null bug\r
+                                               break;\r
 \r
-                                       isFullySelected = TRUE;\r
-                                       next = prevSibling;\r
-                               }\r
+                                       case "src":\r
+                                       case "href":\r
+                                               if (s.keep_values) {\r
+                                                       if (s.url_converter)\r
+                                                               v = s.url_converter.call(s.url_converter_scope || t, v, n, e);\r
 \r
-                               if (parent == root)\r
-                                       return clonedParent;\r
+                                                       t.setAttrib(e, 'data-mce-' + n, v, 2);\r
+                                               }\r
 \r
-                               next = parent.previousSibling;\r
-                               parent = parent.parentNode;\r
+                                               break;\r
 \r
-                               clonedGrandParent = _traverseNode(parent, FALSE, FALSE, how);\r
+                                       case "shape":\r
+                                               e.setAttribute('data-mce-style', v);\r
+                                               break;\r
+                               }\r
 \r
-                               if (how != DELETE)\r
-                                       clonedGrandParent.appendChild(clonedParent);\r
+                               if (is(v) && v !== null && v.length !== 0)\r
+                                       e.setAttribute(n, '' + v, 2);\r
+                               else\r
+                                       e.removeAttribute(n, 2);\r
+                       });\r
+               },\r
 \r
-                               clonedParent = clonedGrandParent;\r
-                       }\r
-               };\r
+               setAttribs : function(e, o) {\r
+                       var t = this;\r
 \r
-               function _traverseLeftBoundary(root, how) {\r
-                       var next = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]), isFullySelected = next != t[START_CONTAINER], parent, clonedParent, nextSibling, clonedChild, clonedGrandParent;\r
+                       return this.run(e, function(e) {\r
+                               each(o, function(v, n) {\r
+                                       t.setAttrib(e, n, v);\r
+                               });\r
+                       });\r
+               },\r
 \r
-                       if (next == root)\r
-                               return _traverseNode(next, isFullySelected, TRUE, how);\r
+               getAttrib : function(e, n, dv) {\r
+                       var v, t = this;\r
 \r
-                       parent = next.parentNode;\r
-                       clonedParent = _traverseNode(parent, FALSE, TRUE, how);\r
+                       e = t.get(e);\r
 \r
-                       while (parent) {\r
-                               while (next) {\r
-                                       nextSibling = next.nextSibling;\r
-                                       clonedChild = _traverseNode(next, isFullySelected, TRUE, how);\r
+                       if (!e || e.nodeType !== 1)\r
+                               return false;\r
 \r
-                                       if (how != DELETE)\r
-                                               clonedParent.appendChild(clonedChild);\r
+                       if (!is(dv))\r
+                               dv = '';\r
 \r
-                                       isFullySelected = TRUE;\r
-                                       next = nextSibling;\r
-                               }\r
+                       // Try the mce variant for these\r
+                       if (/^(src|href|style|coords|shape)$/.test(n)) {\r
+                               v = e.getAttribute("data-mce-" + n);\r
 \r
-                               if (parent == root)\r
-                                       return clonedParent;\r
+                               if (v)\r
+                                       return v;\r
+                       }\r
 \r
-                               next = parent.nextSibling;\r
-                               parent = parent.parentNode;\r
+                       if (isIE && t.props[n]) {\r
+                               v = e[t.props[n]];\r
+                               v = v && v.nodeValue ? v.nodeValue : v;\r
+                       }\r
 \r
-                               clonedGrandParent = _traverseNode(parent, FALSE, TRUE, how);\r
+                       if (!v)\r
+                               v = e.getAttribute(n, 2);\r
 \r
-                               if (how != DELETE)\r
-                                       clonedGrandParent.appendChild(clonedParent);\r
+                       // Check boolean attribs\r
+                       if (/^(checked|compact|declare|defer|disabled|ismap|multiple|nohref|noshade|nowrap|readonly|selected)$/.test(n)) {\r
+                               if (e[t.props[n]] === true && v === '')\r
+                                       return n;\r
 \r
-                               clonedParent = clonedGrandParent;\r
+                               return v ? n : '';\r
                        }\r
-               };\r
 \r
-               function _traverseNode(n, isFullySelected, isLeft, how) {\r
-                       var txtValue, newNodeValue, oldNodeValue, offset, newNode;\r
+                       // Inner input elements will override attributes on form elements\r
+                       if (e.nodeName === "FORM" && e.getAttributeNode(n))\r
+                               return e.getAttributeNode(n).nodeValue;\r
 \r
-                       if (isFullySelected)\r
-                               return _traverseFullySelected(n, how);\r
+                       if (n === 'style') {\r
+                               v = v || e.style.cssText;\r
 \r
-                       if (n.nodeType == 3 /* TEXT_NODE */) {\r
-                               txtValue = n.nodeValue;\r
+                               if (v) {\r
+                                       v = t.serializeStyle(t.parseStyle(v), e.nodeName);\r
 \r
-                               if (isLeft) {\r
-                                       offset = t[START_OFFSET];\r
-                                       newNodeValue = txtValue.substring(offset);\r
-                                       oldNodeValue = txtValue.substring(0, offset);\r
-                               } else {\r
-                                       offset = t[END_OFFSET];\r
-                                       newNodeValue = txtValue.substring(0, offset);\r
-                                       oldNodeValue = txtValue.substring(offset);\r
+                                       if (t.settings.keep_values && !t._isRes(v))\r
+                                               e.setAttribute('data-mce-style', v);\r
                                }\r
+                       }\r
 \r
-                               if (how != CLONE)\r
-                                       n.nodeValue = oldNodeValue;\r
+                       // Remove Apple and WebKit stuff\r
+                       if (isWebKit && n === "class" && v)\r
+                               v = v.replace(/(apple|webkit)\-[a-z\-]+/gi, '');\r
 \r
-                               if (how == DELETE)\r
-                                       return;\r
+                       // Handle IE issues\r
+                       if (isIE) {\r
+                               switch (n) {\r
+                                       case 'rowspan':\r
+                                       case 'colspan':\r
+                                               // IE returns 1 as default value\r
+                                               if (v === 1)\r
+                                                       v = '';\r
 \r
-                               newNode = n.cloneNode(FALSE);\r
-                               newNode.nodeValue = newNodeValue;\r
+                                               break;\r
 \r
-                               return newNode;\r
-                       }\r
+                                       case 'size':\r
+                                               // IE returns +0 as default value for size\r
+                                               if (v === '+0' || v === 20 || v === 0)\r
+                                                       v = '';\r
 \r
-                       if (how == DELETE)\r
-                               return;\r
+                                               break;\r
 \r
-                       return n.cloneNode(FALSE);\r
-               };\r
+                                       case 'width':\r
+                                       case 'height':\r
+                                       case 'vspace':\r
+                                       case 'checked':\r
+                                       case 'disabled':\r
+                                       case 'readonly':\r
+                                               if (v === 0)\r
+                                                       v = '';\r
 \r
-               function _traverseFullySelected(n, how) {\r
-                       if (how != DELETE)\r
-                               return how == CLONE ? n.cloneNode(TRUE) : n;\r
+                                               break;\r
 \r
-                       n.parentNode.removeChild(n);\r
-               };\r
-       };\r
+                                       case 'hspace':\r
+                                               // IE returns -1 as default value\r
+                                               if (v === -1)\r
+                                                       v = '';\r
 \r
-       ns.Range = Range;\r
-})(tinymce.dom);\r
+                                               break;\r
 \r
-(function() {\r
-       function Selection(selection) {\r
-               var t = this, invisibleChar = '\uFEFF', range, lastIERng, dom = selection.dom, TRUE = true, FALSE = false;\r
+                                       case 'maxlength':\r
+                                       case 'tabindex':\r
+                                               // IE returns default value\r
+                                               if (v === 32768 || v === 2147483647 || v === '32768')\r
+                                                       v = '';\r
 \r
-               // Returns a W3C DOM compatible range object by using the IE Range API\r
-               function getRange() {\r
-                       var ieRange = selection.getRng(), domRange = dom.createRng(), element, collapsed;\r
+                                               break;\r
 \r
-                       // If selection is outside the current document just return an empty range\r
-                       element = ieRange.item ? ieRange.item(0) : ieRange.parentElement();\r
-                       if (element.ownerDocument != dom.doc)\r
-                               return domRange;\r
+                                       case 'multiple':\r
+                                       case 'compact':\r
+                                       case 'noshade':\r
+                                       case 'nowrap':\r
+                                               if (v === 65535)\r
+                                                       return n;\r
 \r
-                       // Handle control selection or text selection of a image\r
-                       if (ieRange.item || !element.hasChildNodes()) {\r
-                               domRange.setStart(element.parentNode, dom.nodeIndex(element));\r
-                               domRange.setEnd(domRange.startContainer, domRange.startOffset + 1);\r
+                                               return dv;\r
 \r
-                               return domRange;\r
+                                       case 'shape':\r
+                                               v = v.toLowerCase();\r
+                                               break;\r
+\r
+                                       default:\r
+                                               // IE has odd anonymous function for event attributes\r
+                                               if (n.indexOf('on') === 0 && v)\r
+                                                       v = tinymce._replace(/^function\s+\w+\(\)\s+\{\s+(.*)\s+\}$/, '$1', '' + v);\r
+                               }\r
                        }\r
 \r
-                       collapsed = selection.isCollapsed();\r
+                       return (v !== undefined && v !== null && v !== '') ? '' + v : dv;\r
+               },\r
 \r
-                       function findEndPoint(start) {\r
-                               var marker, container, offset, nodes, startIndex = 0, endIndex, index, parent, checkRng, position;\r
+               getPos : function(n, ro) {\r
+                       var t = this, x = 0, y = 0, e, d = t.doc, r;\r
 \r
-                               // Setup temp range and collapse it\r
-                               checkRng = ieRange.duplicate();\r
-                               checkRng.collapse(start);\r
+                       n = t.get(n);\r
+                       ro = ro || d.body;\r
 \r
-                               // Create marker and insert it at the end of the endpoints parent\r
-                               marker = dom.create('a');\r
-                               parent = checkRng.parentElement();\r
+                       if (n) {\r
+                               // Use getBoundingClientRect on IE, Opera has it but it's not perfect\r
+                               if (isIE && !t.stdMode) {\r
+                                       n = n.getBoundingClientRect();\r
+                                       e = t.boxModel ? d.documentElement : d.body;\r
+                                       x = t.getStyle(t.select('html')[0], 'borderWidth'); // Remove border\r
+                                       x = (x == 'medium' || t.boxModel && !t.isIE6) && 2 || x;\r
 \r
-                               // If parent doesn't have any children then set the container to that parent and the index to 0\r
-                               if (!parent.hasChildNodes()) {\r
-                                       domRange[start ? 'setStart' : 'setEnd'](parent, 0);\r
-                                       return;\r
+                                       return {x : n.left + e.scrollLeft - x, y : n.top + e.scrollTop - x};\r
                                }\r
 \r
-                               parent.appendChild(marker);\r
-                               checkRng.moveToElementText(marker);\r
-                               position = ieRange.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', checkRng);\r
-                               if (position > 0) {\r
-                                       // The position is after the end of the parent element.\r
-                                       // This is the case where IE puts the caret to the left edge of a table.\r
-                                       domRange[start ? 'setStartAfter' : 'setEndAfter'](parent);\r
-                                       dom.remove(marker);\r
-                                       return;\r
+                               r = n;\r
+                               while (r && r != ro && r.nodeType) {\r
+                                       x += r.offsetLeft || 0;\r
+                                       y += r.offsetTop || 0;\r
+                                       r = r.offsetParent;\r
                                }\r
 \r
-                               // Setup node list and endIndex\r
-                               nodes = tinymce.grep(parent.childNodes);\r
-                               endIndex = nodes.length - 1;\r
-                               // Perform a binary search for the position\r
-                               while (startIndex <= endIndex) {\r
-                                       index = Math.floor((startIndex + endIndex) / 2);\r
-\r
-                                       // Insert marker and check it's position relative to the selection\r
-                                       parent.insertBefore(marker, nodes[index]);\r
-                                       checkRng.moveToElementText(marker);\r
-                                       position = ieRange.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', checkRng);\r
-                                       if (position > 0) {\r
-                                               // Marker is to the right\r
-                                               startIndex = index + 1;\r
-                                       } else if (position < 0) {\r
-                                               // Marker is to the left\r
-                                               endIndex = index - 1;\r
-                                       } else {\r
-                                               // Maker is where we are\r
-                                               found = true;\r
-                                               break;\r
-                                       }\r
+                               r = n.parentNode;\r
+                               while (r && r != ro && r.nodeType) {\r
+                                       x -= r.scrollLeft || 0;\r
+                                       y -= r.scrollTop || 0;\r
+                                       r = r.parentNode;\r
                                }\r
+                       }\r
 \r
-                               // Setup container\r
-                               container = position > 0 || index == 0 ? marker.nextSibling : marker.previousSibling;\r
+                       return {x : x, y : y};\r
+               },\r
 \r
-                               // Handle element selection\r
-                               if (container.nodeType == 1) {\r
-                                       dom.remove(marker);\r
+               parseStyle : function(st) {\r
+                       return this.styles.parse(st);\r
+               },\r
 \r
-                                       // Find offset and container\r
-                                       offset = dom.nodeIndex(container);\r
-                                       container = container.parentNode;\r
+               serializeStyle : function(o, name) {\r
+                       return this.styles.serialize(o, name);\r
+               },\r
 \r
-                                       // Move the offset if we are setting the end or the position is after an element\r
-                                       if (!start || index > 0)\r
-                                               offset++;\r
-                               } else {\r
-                                       // Calculate offset within text node\r
-                                       if (position > 0 || index == 0) {\r
-                                               checkRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', ieRange);\r
-                                               offset = checkRng.text.length;\r
-                                       } else {\r
-                                               checkRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', ieRange);\r
-                                               offset = container.nodeValue.length - checkRng.text.length;\r
-                                       }\r
+               loadCSS : function(u) {\r
+                       var t = this, d = t.doc, head;\r
 \r
-                                       dom.remove(marker);\r
-                               }\r
+                       if (!u)\r
+                               u = '';\r
 \r
-                               domRange[start ? 'setStart' : 'setEnd'](container, offset);\r
-                       };\r
+                       head = t.select('head')[0];\r
 \r
-                       // Find start point\r
-                       findEndPoint(true);\r
+                       each(u.split(','), function(u) {\r
+                               var link;\r
 \r
-                       // Find end point if needed\r
-                       if (!collapsed)\r
-                               findEndPoint();\r
+                               if (t.files[u])\r
+                                       return;\r
 \r
-                       return domRange;\r
-               };\r
+                               t.files[u] = true;\r
+                               link = t.create('link', {rel : 'stylesheet', href : tinymce._addVer(u)});\r
 \r
-               this.addRange = function(rng) {\r
-                       var ieRng, ieRng2, doc = selection.dom.doc, body = doc.body, startPos, endPos, sc, so, ec, eo, marker, lastIndex, skipStart, skipEnd;\r
+                               // IE 8 has a bug where dynamically loading stylesheets would produce a 1 item remaining bug\r
+                               // This fix seems to resolve that issue by realcing the document ones a stylesheet finishes loading\r
+                               // It's ugly but it seems to work fine.\r
+                               if (isIE && d.documentMode && d.recalc) {\r
+                                       link.onload = function() {\r
+                                               if (d.recalc)\r
+                                                       d.recalc();\r
 \r
-                       this.destroy();\r
+                                               link.onload = null;\r
+                                       };\r
+                               }\r
 \r
-                       // Setup some shorter versions\r
-                       sc = rng.startContainer;\r
-                       so = rng.startOffset;\r
-                       ec = rng.endContainer;\r
-                       eo = rng.endOffset;\r
-                       ieRng = body.createTextRange();\r
+                               head.appendChild(link);\r
+                       });\r
+               },\r
 \r
-                       // If document selection move caret to first node in document\r
-                       if (sc == doc || ec == doc) {\r
-                               ieRng = body.createTextRange();\r
-                               ieRng.collapse();\r
-                               ieRng.select();\r
-                               return;\r
-                       }\r
+               addClass : function(e, c) {\r
+                       return this.run(e, function(e) {\r
+                               var o;\r
 \r
-                       // If child index resolve it\r
-                       if (sc.nodeType == 1 && sc.hasChildNodes()) {\r
-                               lastIndex = sc.childNodes.length - 1;\r
+                               if (!c)\r
+                                       return 0;\r
 \r
-                               // Index is higher that the child count then we need to jump over the start container\r
-                               if (so > lastIndex) {\r
-                                       skipStart = 1;\r
-                                       sc = sc.childNodes[lastIndex];\r
-                               } else\r
-                                       sc = sc.childNodes[so];\r
+                               if (this.hasClass(e, c))\r
+                                       return e.className;\r
 \r
-                               // Child was text node then move offset to start of it\r
-                               if (sc.nodeType == 3)\r
-                                       so = 0;\r
-                       }\r
+                               o = this.removeClass(e, c);\r
 \r
-                       // If child index resolve it\r
-                       if (ec.nodeType == 1 && ec.hasChildNodes()) {\r
-                               lastIndex = ec.childNodes.length - 1;\r
+                               return e.className = (o != '' ? (o + ' ') : '') + c;\r
+                       });\r
+               },\r
 \r
-                               if (eo == 0) {\r
-                                       skipEnd = 1;\r
-                                       ec = ec.childNodes[0];\r
-                               } else {\r
-                                       ec = ec.childNodes[Math.min(lastIndex, eo - 1)];\r
+               removeClass : function(e, c) {\r
+                       var t = this, re;\r
 \r
-                                       // Child was text node then move offset to end of text node\r
-                                       if (ec.nodeType == 3)\r
-                                               eo = ec.nodeValue.length;\r
-                               }\r
-                       }\r
+                       return t.run(e, function(e) {\r
+                               var v;\r
 \r
-                       // Single element selection\r
-                       if (sc == ec && sc.nodeType == 1) {\r
-                               // Make control selection for some elements\r
-                               if (/^(IMG|TABLE)$/.test(sc.nodeName) && so != eo) {\r
-                                       ieRng = body.createControlRange();\r
-                                       ieRng.addElement(sc);\r
-                               } else {\r
-                                       ieRng = body.createTextRange();\r
+                               if (t.hasClass(e, c)) {\r
+                                       if (!re)\r
+                                               re = new RegExp("(^|\\s+)" + c + "(\\s+|$)", "g");\r
 \r
-                                       // Padd empty elements with invisible character\r
-                                       if (!sc.hasChildNodes() && sc.canHaveHTML)\r
-                                               sc.innerHTML = invisibleChar;\r
+                                       v = e.className.replace(re, ' ');\r
+                                       v = tinymce.trim(v != ' ' ? v : '');\r
 \r
-                                       // Select element contents\r
-                                       ieRng.moveToElementText(sc);\r
+                                       e.className = v;\r
 \r
-                                       // If it's only containing a padding remove it so the caret remains\r
-                                       if (sc.innerHTML == invisibleChar) {\r
-                                               ieRng.collapse(TRUE);\r
-                                               sc.removeChild(sc.firstChild);\r
+                                       // Empty class attr\r
+                                       if (!v) {\r
+                                               e.removeAttribute('class');\r
+                                               e.removeAttribute('className');\r
                                        }\r
+\r
+                                       return v;\r
                                }\r
 \r
-                               if (so == eo)\r
-                                       ieRng.collapse(eo <= rng.endContainer.childNodes.length - 1);\r
+                               return e.className;\r
+                       });\r
+               },\r
 \r
-                               ieRng.select();\r
-                               ieRng.scrollIntoView();\r
-                               return;\r
-                       }\r
+               hasClass : function(n, c) {\r
+                       n = this.get(n);\r
 \r
-                       // Create range and marker\r
-                       ieRng = body.createTextRange();\r
-                       marker = doc.createElement('span');\r
-                       marker.innerHTML = ' ';\r
-\r
-                       // Set start of range to startContainer/startOffset\r
-                       if (sc.nodeType == 3) {\r
-                               // Insert marker after/before startContainer\r
-                               if (skipStart)\r
-                                       dom.insertAfter(marker, sc);\r
-                               else\r
-                                       sc.parentNode.insertBefore(marker, sc);\r
+                       if (!n || !c)\r
+                               return false;\r
 \r
-                               // Select marker the caret to offset position\r
-                               ieRng.moveToElementText(marker);\r
-                               marker.parentNode.removeChild(marker);\r
+                       return (' ' + n.className + ' ').indexOf(' ' + c + ' ') !== -1;\r
+               },\r
 \r
-                               // Move if we need to, moving it 0 characters actually moves it!\r
-                               if (so > 0)\r
-                                       ieRng.move('character', so);\r
-                       } else {\r
-                               ieRng.moveToElementText(sc);\r
+               show : function(e) {\r
+                       return this.setStyle(e, 'display', 'block');\r
+               },\r
 \r
-                               if (skipStart)\r
-                                       ieRng.collapse(FALSE);\r
-                       }\r
+               hide : function(e) {\r
+                       return this.setStyle(e, 'display', 'none');\r
+               },\r
 \r
-                       // If same text container then we can do a more simple move\r
-                       if (sc == ec && sc.nodeType == 3) {\r
-                               try {\r
-                                       ieRng.moveEnd('character', eo - so);\r
-                                       ieRng.select();\r
-                                       ieRng.scrollIntoView();\r
-                               } catch (ex) {\r
-                                       // Some times a Runtime error of the 800a025e type gets thrown\r
-                                       // especially when the caret is placed before a table.\r
-                                       // This is a somewhat strange location for the caret.\r
-                                       // TODO: Find a better solution for this would possible require a rewrite of the setRng method\r
-                               }\r
+               isHidden : function(e) {\r
+                       e = this.get(e);\r
 \r
-                               return;\r
-                       }\r
+                       return !e || e.style.display == 'none' || this.getStyle(e, 'display') == 'none';\r
+               },\r
 \r
-                       // Set end of range to endContainer/endOffset\r
-                       ieRng2 = body.createTextRange();\r
-                       if (ec.nodeType == 3) {\r
-                               // Insert marker after/before startContainer\r
-                               ec.parentNode.insertBefore(marker, ec);\r
+               uniqueId : function(p) {\r
+                       return (!p ? 'mce_' : p) + (this.counter++);\r
+               },\r
 \r
-                               // Move selection to end marker and move caret to end offset\r
-                               ieRng2.moveToElementText(marker);\r
-                               marker.parentNode.removeChild(marker);\r
-                               ieRng2.move('character', eo);\r
-                               ieRng.setEndPoint('EndToStart', ieRng2);\r
-                       } else {\r
-                               ieRng2.moveToElementText(ec);\r
-                               ieRng2.collapse(!!skipEnd);\r
-                               ieRng.setEndPoint('EndToEnd', ieRng2);\r
-                       }\r
+               setHTML : function(element, html) {\r
+                       var self = this;\r
 \r
-                       ieRng.select();\r
-                       ieRng.scrollIntoView();\r
-               };\r
+                       return self.run(element, function(element) {\r
+                               if (isIE) {\r
+                                       // Remove all child nodes, IE keeps empty text nodes in DOM\r
+                                       while (element.firstChild)\r
+                                               element.removeChild(element.firstChild);\r
 \r
-               this.getRangeAt = function() {\r
-                       // Setup new range if the cache is empty\r
-                       if (!range || !tinymce.dom.RangeUtils.compareRanges(lastIERng, selection.getRng())) {\r
-                               range = getRange();\r
+                                       try {\r
+                                               // IE will remove comments from the beginning\r
+                                               // unless you padd the contents with something\r
+                                               element.innerHTML = '<br />' + html;\r
+                                               element.removeChild(element.firstChild);\r
+                                       } catch (ex) {\r
+                                               // 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\r
+                                               // This seems to fix this problem\r
+\r
+                                               // Create new div with HTML contents and a BR infront to keep comments\r
+                                               element = self.create('div');\r
+                                               element.innerHTML = '<br />' + html;\r
+\r
+                                               // Add all children from div to target\r
+                                               each (element.childNodes, function(node, i) {\r
+                                                       // Skip br element\r
+                                                       if (i)\r
+                                                               element.appendChild(node);\r
+                                               });\r
+                                       }\r
+                               } else\r
+                                       element.innerHTML = html;\r
 \r
-                               // Store away text range for next call\r
-                               lastIERng = selection.getRng();\r
-                       }\r
+                               return html;\r
+                       });\r
+               },\r
 \r
-                       // IE will say that the range is equal then produce an invalid argument exception\r
-                       // if you perform specific operations in a keyup event. For example Ctrl+Del.\r
-                       // This hack will invalidate the range cache if the exception occurs\r
-                       try {\r
-                               range.startContainer.nextSibling;\r
-                       } catch (ex) {\r
-                               range = getRange();\r
-                               lastIERng = null;\r
-                       }\r
+               getOuterHTML : function(elm) {\r
+                       var doc, self = this;\r
 \r
-                       // Return cached range\r
-                       return range;\r
-               };\r
+                       elm = self.get(elm);\r
 \r
-               this.destroy = function() {\r
-                       // Destroy cached range and last IE range to avoid memory leaks\r
-                       lastIERng = range = null;\r
-               };\r
+                       if (!elm)\r
+                               return null;\r
 \r
-               // IE has an issue where you can't select/move the caret by clicking outside the body if the document is in standards mode\r
-               if (selection.dom.boxModel) {\r
-                       (function() {\r
-                               var doc = dom.doc, body = doc.body, started, startRng;\r
+                       if (elm.nodeType === 1 && self.hasOuterHTML)\r
+                               return elm.outerHTML;\r
 \r
-                               // Make HTML element unselectable since we are going to handle selection by hand\r
-                               doc.documentElement.unselectable = TRUE;\r
+                       doc = (elm.ownerDocument || self.doc).createElement("body");\r
+                       doc.appendChild(elm.cloneNode(true));\r
 \r
-                               // Return range from point or null if it failed\r
-                               function rngFromPoint(x, y) {\r
-                                       var rng = body.createTextRange();\r
+                       return doc.innerHTML;\r
+               },\r
 \r
-                                       try {\r
-                                               rng.moveToPoint(x, y);\r
-                                       } catch (ex) {\r
-                                               // IE sometimes throws and exception, so lets just ignore it\r
-                                               rng = null;\r
-                                       }\r
+               setOuterHTML : function(e, h, d) {\r
+                       var t = this;\r
 \r
-                                       return rng;\r
-                               };\r
+                       function setHTML(e, h, d) {\r
+                               var n, tp;\r
+\r
+                               tp = d.createElement("body");\r
+                               tp.innerHTML = h;\r
 \r
-                               // Fires while the selection is changing\r
-                               function selectionChange(e) {\r
-                                       var pointRng;\r
+                               n = tp.lastChild;\r
+                               while (n) {\r
+                                       t.insertAfter(n.cloneNode(true), e);\r
+                                       n = n.previousSibling;\r
+                               }\r
 \r
-                                       // Check if the button is down or not\r
-                                       if (e.button) {\r
-                                               // Create range from mouse position\r
-                                               pointRng = rngFromPoint(e.x, e.y);\r
+                               t.remove(e);\r
+                       };\r
 \r
-                                               if (pointRng) {\r
-                                                       // Check if pointRange is before/after selection then change the endPoint\r
-                                                       if (pointRng.compareEndPoints('StartToStart', startRng) > 0)\r
-                                                               pointRng.setEndPoint('StartToStart', startRng);\r
-                                                       else\r
-                                                               pointRng.setEndPoint('EndToEnd', startRng);\r
+                       return this.run(e, function(e) {\r
+                               e = t.get(e);\r
 \r
-                                                       pointRng.select();\r
+                               // Only set HTML on elements\r
+                               if (e.nodeType == 1) {\r
+                                       d = d || e.ownerDocument || t.doc;\r
+\r
+                                       if (isIE) {\r
+                                               try {\r
+                                                       // Try outerHTML for IE it sometimes produces an unknown runtime error\r
+                                                       if (isIE && e.nodeType == 1)\r
+                                                               e.outerHTML = h;\r
+                                                       else\r
+                                                               setHTML(e, h, d);\r
+                                               } catch (ex) {\r
+                                                       // Fix for unknown runtime error\r
+                                                       setHTML(e, h, d);\r
                                                }\r
                                        } else\r
-                                               endSelection();\r
+                                               setHTML(e, h, d);\r
                                }\r
+                       });\r
+               },\r
 \r
-                               // Removes listeners\r
-                               function endSelection() {\r
-                                       dom.unbind(doc, 'mouseup', endSelection);\r
-                                       dom.unbind(doc, 'mousemove', selectionChange);\r
-                                       started = 0;\r
-                               };\r
+               decode : Entities.decode,\r
 \r
-                               // Detect when user selects outside BODY\r
-                               dom.bind(doc, 'mousedown', function(e) {\r
-                                       if (e.target.nodeName === 'HTML') {\r
-                                               if (started)\r
-                                                       endSelection();\r
+               encode : Entities.encodeAllRaw,\r
 \r
-                                               started = 1;\r
+               insertAfter : function(node, reference_node) {\r
+                       reference_node = this.get(reference_node);\r
 \r
-                                               // Setup start position\r
-                                               startRng = rngFromPoint(e.x, e.y);\r
-                                               if (startRng) {\r
-                                                       // Listen for selection change events\r
-                                                       dom.bind(doc, 'mouseup', endSelection);\r
-                                                       dom.bind(doc, 'mousemove', selectionChange);\r
+                       return this.run(node, function(node) {\r
+                               var parent, nextSibling;\r
 \r
-                                                       startRng.select();\r
-                                               }\r
-                                       }\r
-                               });\r
-                       })();\r
-               }\r
-       };\r
+                               parent = reference_node.parentNode;\r
+                               nextSibling = reference_node.nextSibling;\r
 \r
-       // Expose the selection object\r
-       tinymce.dom.TridentSelection = Selection;\r
-})();\r
+                               if (nextSibling)\r
+                                       parent.insertBefore(node, nextSibling);\r
+                               else\r
+                                       parent.appendChild(node);\r
 \r
+                               return node;\r
+                       });\r
+               },\r
 \r
-/*\r
- * Sizzle CSS Selector Engine - v1.0\r
- *  Copyright 2009, The Dojo Foundation\r
- *  Released under the MIT, BSD, and GPL Licenses.\r
- *  More information: http://sizzlejs.com/\r
- */\r
-(function(){\r
+               isBlock : function(node) {\r
+                       var type = node.nodeType;\r
 \r
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,\r
-       done = 0,\r
-       toString = Object.prototype.toString,\r
-       hasDuplicate = false,\r
-       baseHasDuplicate = true;\r
+                       // If it's a node then check the type and use the nodeName\r
+                       if (type)\r
+                               return !!(type === 1 && blockElementsMap[node.nodeName]);\r
 \r
-// Here we check if the JavaScript engine is using some sort of\r
-// optimization where it does not always call our comparision\r
-// function. If that is the case, discard the hasDuplicate value.\r
-//   Thus far that includes Google Chrome.\r
-[0, 0].sort(function(){\r
-       baseHasDuplicate = false;\r
-       return 0;\r
-});\r
+                       return !!blockElementsMap[node];\r
+               },\r
 \r
-var Sizzle = function(selector, context, results, seed) {\r
-       results = results || [];\r
-       context = context || document;\r
+               replace : function(n, o, k) {\r
+                       var t = this;\r
 \r
-       var origContext = context;\r
+                       if (is(o, 'array'))\r
+                               n = n.cloneNode(true);\r
 \r
-       if ( context.nodeType !== 1 && context.nodeType !== 9 ) {\r
-               return [];\r
-       }\r
-       \r
-       if ( !selector || typeof selector !== "string" ) {\r
-               return results;\r
-       }\r
+                       return t.run(o, function(o) {\r
+                               if (k) {\r
+                                       each(tinymce.grep(o.childNodes), function(c) {\r
+                                               n.appendChild(c);\r
+                                       });\r
+                               }\r
 \r
-       var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),\r
-               soFar = selector, ret, cur, pop, i;\r
-       \r
-       // Reset the position of the chunker regexp (start from head)\r
-       do {\r
-               chunker.exec("");\r
-               m = chunker.exec(soFar);\r
+                               return o.parentNode.replaceChild(n, o);\r
+                       });\r
+               },\r
 \r
-               if ( m ) {\r
-                       soFar = m[3];\r
-               \r
-                       parts.push( m[1] );\r
-               \r
-                       if ( m[2] ) {\r
-                               extra = m[3];\r
-                               break;\r
-                       }\r
-               }\r
-       } while ( m );\r
+               rename : function(elm, name) {\r
+                       var t = this, newElm;\r
 \r
-       if ( parts.length > 1 && origPOS.exec( selector ) ) {\r
-               if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {\r
-                       set = posProcess( parts[0] + parts[1], context );\r
-               } else {\r
-                       set = Expr.relative[ parts[0] ] ?\r
-                               [ context ] :\r
-                               Sizzle( parts.shift(), context );\r
+                       if (elm.nodeName != name.toUpperCase()) {\r
+                               // Rename block element\r
+                               newElm = t.create(name);\r
 \r
-                       while ( parts.length ) {\r
-                               selector = parts.shift();\r
+                               // Copy attribs to new block\r
+                               each(t.getAttribs(elm), function(attr_node) {\r
+                                       t.setAttrib(newElm, attr_node.nodeName, t.getAttrib(elm, attr_node.nodeName));\r
+                               });\r
 \r
-                               if ( Expr.relative[ selector ] ) {\r
-                                       selector += parts.shift();\r
-                               }\r
-                               \r
-                               set = posProcess( selector, set );\r
+                               // Replace block\r
+                               t.replace(newElm, elm, 1);\r
                        }\r
-               }\r
-       } else {\r
-               // Take a shortcut and set the context if the root selector is an ID\r
-               // (but not if it'll be faster if the inner selector is an ID)\r
-               if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&\r
-                               Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {\r
-                       ret = Sizzle.find( parts.shift(), context, contextXML );\r
-                       context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];\r
-               }\r
 \r
-               if ( context ) {\r
-                       ret = seed ?\r
-                               { expr: parts.pop(), set: makeArray(seed) } :\r
-                               Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );\r
-                       set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;\r
+                       return newElm || elm;\r
+               },\r
 \r
-                       if ( parts.length > 0 ) {\r
-                               checkSet = makeArray(set);\r
-                       } else {\r
-                               prune = false;\r
-                       }\r
+               findCommonAncestor : function(a, b) {\r
+                       var ps = a, pe;\r
 \r
-                       while ( parts.length ) {\r
-                               cur = parts.pop();\r
-                               pop = cur;\r
+                       while (ps) {\r
+                               pe = b;\r
 \r
-                               if ( !Expr.relative[ cur ] ) {\r
-                                       cur = "";\r
-                               } else {\r
-                                       pop = parts.pop();\r
-                               }\r
+                               while (pe && ps != pe)\r
+                                       pe = pe.parentNode;\r
 \r
-                               if ( pop == null ) {\r
-                                       pop = context;\r
-                               }\r
+                               if (ps == pe)\r
+                                       break;\r
 \r
-                               Expr.relative[ cur ]( checkSet, pop, contextXML );\r
+                               ps = ps.parentNode;\r
                        }\r
-               } else {\r
-                       checkSet = parts = [];\r
-               }\r
-       }\r
 \r
-       if ( !checkSet ) {\r
-               checkSet = set;\r
-       }\r
+                       if (!ps && a.ownerDocument)\r
+                               return a.ownerDocument.documentElement;\r
 \r
-       if ( !checkSet ) {\r
-               Sizzle.error( cur || selector );\r
-       }\r
+                       return ps;\r
+               },\r
 \r
-       if ( toString.call(checkSet) === "[object Array]" ) {\r
-               if ( !prune ) {\r
-                       results.push.apply( results, checkSet );\r
-               } else if ( context && context.nodeType === 1 ) {\r
-                       for ( i = 0; checkSet[i] != null; i++ ) {\r
-                               if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {\r
-                                       results.push( set[i] );\r
-                               }\r
-                       }\r
-               } else {\r
-                       for ( i = 0; checkSet[i] != null; i++ ) {\r
-                               if ( checkSet[i] && checkSet[i].nodeType === 1 ) {\r
-                                       results.push( set[i] );\r
-                               }\r
-                       }\r
-               }\r
-       } else {\r
-               makeArray( checkSet, results );\r
-       }\r
+               toHex : function(s) {\r
+                       var c = /^\s*rgb\s*?\(\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?,\s*?([0-9]+)\s*?\)\s*$/i.exec(s);\r
 \r
-       if ( extra ) {\r
-               Sizzle( extra, origContext, results, seed );\r
-               Sizzle.uniqueSort( results );\r
-       }\r
+                       function hex(s) {\r
+                               s = parseInt(s).toString(16);\r
 \r
-       return results;\r
-};\r
+                               return s.length > 1 ? s : '0' + s; // 0 -> 00\r
+                       };\r
 \r
-Sizzle.uniqueSort = function(results){\r
-       if ( sortOrder ) {\r
-               hasDuplicate = baseHasDuplicate;\r
-               results.sort(sortOrder);\r
+                       if (c) {\r
+                               s = '#' + hex(c[1]) + hex(c[2]) + hex(c[3]);\r
 \r
-               if ( hasDuplicate ) {\r
-                       for ( var i = 1; i < results.length; i++ ) {\r
-                               if ( results[i] === results[i-1] ) {\r
-                                       results.splice(i--, 1);\r
-                               }\r
+                               return s;\r
                        }\r
-               }\r
-       }\r
 \r
-       return results;\r
-};\r
+                       return s;\r
+               },\r
 \r
-Sizzle.matches = function(expr, set){\r
-       return Sizzle(expr, null, null, set);\r
-};\r
+               getClasses : function() {\r
+                       var t = this, cl = [], i, lo = {}, f = t.settings.class_filter, ov;\r
 \r
-Sizzle.find = function(expr, context, isXML){\r
-       var set;\r
+                       if (t.classes)\r
+                               return t.classes;\r
 \r
-       if ( !expr ) {\r
-               return [];\r
-       }\r
+                       function addClasses(s) {\r
+                               // IE style imports\r
+                               each(s.imports, function(r) {\r
+                                       addClasses(r);\r
+                               });\r
 \r
-       for ( var i = 0, l = Expr.order.length; i < l; i++ ) {\r
-               var type = Expr.order[i], match;\r
-               \r
-               if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {\r
-                       var left = match[1];\r
-                       match.splice(1,1);\r
+                               each(s.cssRules || s.rules, function(r) {\r
+                                       // Real type or fake it on IE\r
+                                       switch (r.type || 1) {\r
+                                               // Rule\r
+                                               case 1:\r
+                                                       if (r.selectorText) {\r
+                                                               each(r.selectorText.split(','), function(v) {\r
+                                                                       v = v.replace(/^\s*|\s*$|^\s\./g, "");\r
 \r
-                       if ( left.substr( left.length - 1 ) !== "\\" ) {\r
-                               match[1] = (match[1] || "").replace(/\\/g, "");\r
-                               set = Expr.find[ type ]( match, context, isXML );\r
-                               if ( set != null ) {\r
-                                       expr = expr.replace( Expr.match[ type ], "" );\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
+                                                                       // Is internal or it doesn't contain a class\r
+                                                                       if (/\.mce/.test(v) || !/\.[\w\-]+$/.test(v))\r
+                                                                               return;\r
 \r
-       if ( !set ) {\r
-               set = context.getElementsByTagName("*");\r
-       }\r
+                                                                       // Remove everything but class name\r
+                                                                       ov = v;\r
+                                                                       v = tinymce._replace(/.*\.([a-z0-9_\-]+).*/i, '$1', v);\r
 \r
-       return {set: set, expr: expr};\r
-};\r
+                                                                       // Filter classes\r
+                                                                       if (f && !(v = f(v, ov)))\r
+                                                                               return;\r
 \r
-Sizzle.filter = function(expr, set, inplace, not){\r
-       var old = expr, result = [], curLoop = set, match, anyFound,\r
-               isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);\r
-\r
-       while ( expr && set.length ) {\r
-               for ( var type in Expr.filter ) {\r
-                       if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {\r
-                               var filter = Expr.filter[ type ], found, item, left = match[1];\r
-                               anyFound = false;\r
+                                                                       if (!lo[v]) {\r
+                                                                               cl.push({'class' : v});\r
+                                                                               lo[v] = 1;\r
+                                                                       }\r
+                                                               });\r
+                                                       }\r
+                                                       break;\r
 \r
-                               match.splice(1,1);\r
+                                               // Import\r
+                                               case 3:\r
+                                                       addClasses(r.styleSheet);\r
+                                                       break;\r
+                                       }\r
+                               });\r
+                       };\r
 \r
-                               if ( left.substr( left.length - 1 ) === "\\" ) {\r
-                                       continue;\r
-                               }\r
+                       try {\r
+                               each(t.doc.styleSheets, addClasses);\r
+                       } catch (ex) {\r
+                               // Ignore\r
+                       }\r
 \r
-                               if ( curLoop === result ) {\r
-                                       result = [];\r
-                               }\r
+                       if (cl.length > 0)\r
+                               t.classes = cl;\r
 \r
-                               if ( Expr.preFilter[ type ] ) {\r
-                                       match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );\r
+                       return cl;\r
+               },\r
 \r
-                                       if ( !match ) {\r
-                                               anyFound = found = true;\r
-                                       } else if ( match === true ) {\r
-                                               continue;\r
-                                       }\r
-                               }\r
+               run : function(e, f, s) {\r
+                       var t = this, o;\r
 \r
-                               if ( match ) {\r
-                                       for ( var i = 0; (item = curLoop[i]) != null; i++ ) {\r
-                                               if ( item ) {\r
-                                                       found = filter( item, match, i, curLoop );\r
-                                                       var pass = not ^ !!found;\r
+                       if (t.doc && typeof(e) === 'string')\r
+                               e = t.get(e);\r
 \r
-                                                       if ( inplace && found != null ) {\r
-                                                               if ( pass ) {\r
-                                                                       anyFound = true;\r
-                                                               } else {\r
-                                                                       curLoop[i] = false;\r
-                                                               }\r
-                                                       } else if ( pass ) {\r
-                                                               result.push( item );\r
-                                                               anyFound = true;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                               }\r
+                       if (!e)\r
+                               return false;\r
 \r
-                               if ( found !== undefined ) {\r
-                                       if ( !inplace ) {\r
-                                               curLoop = result;\r
-                                       }\r
+                       s = s || this;\r
+                       if (!e.nodeType && (e.length || e.length === 0)) {\r
+                               o = [];\r
 \r
-                                       expr = expr.replace( Expr.match[ type ], "" );\r
+                               each(e, function(e, i) {\r
+                                       if (e) {\r
+                                               if (typeof(e) == 'string')\r
+                                                       e = t.doc.getElementById(e);\r
 \r
-                                       if ( !anyFound ) {\r
-                                               return [];\r
+                                               o.push(f.call(s, e, i));\r
                                        }\r
+                               });\r
 \r
-                                       break;\r
-                               }\r
+                               return o;\r
                        }\r
-               }\r
 \r
-               // Improper expression\r
-               if ( expr === old ) {\r
-                       if ( anyFound == null ) {\r
-                               Sizzle.error( expr );\r
-                       } else {\r
-                               break;\r
-                       }\r
-               }\r
+                       return f.call(s, e);\r
+               },\r
 \r
-               old = expr;\r
-       }\r
+               getAttribs : function(n) {\r
+                       var o;\r
 \r
-       return curLoop;\r
-};\r
+                       n = this.get(n);\r
 \r
-Sizzle.error = function( msg ) {\r
-       throw "Syntax error, unrecognized expression: " + msg;\r
-};\r
+                       if (!n)\r
+                               return [];\r
 \r
-var Expr = Sizzle.selectors = {\r
-       order: [ "ID", "NAME", "TAG" ],\r
-       match: {\r
-               ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,\r
-               CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,\r
-               NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,\r
-               ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,\r
-               TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,\r
-               CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,\r
-               POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,\r
-               PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/\r
-       },\r
-       leftMatch: {},\r
-       attrMap: {\r
-               "class": "className",\r
-               "for": "htmlFor"\r
-       },\r
-       attrHandle: {\r
-               href: function(elem){\r
-                       return elem.getAttribute("href");\r
-               }\r
-       },\r
-       relative: {\r
-               "+": function(checkSet, part){\r
-                       var isPartStr = typeof part === "string",\r
-                               isTag = isPartStr && !/\W/.test(part),\r
-                               isPartStrNotTag = isPartStr && !isTag;\r
+                       if (isIE) {\r
+                               o = [];\r
 \r
-                       if ( isTag ) {\r
-                               part = part.toLowerCase();\r
-                       }\r
+                               // Object will throw exception in IE\r
+                               if (n.nodeName == 'OBJECT')\r
+                                       return n.attributes;\r
 \r
-                       for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {\r
-                               if ( (elem = checkSet[i]) ) {\r
-                                       while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}\r
+                               // IE doesn't keep the selected attribute if you clone option elements\r
+                               if (n.nodeName === 'OPTION' && this.getAttrib(n, 'selected'))\r
+                                       o.push({specified : 1, nodeName : 'selected'});\r
 \r
-                                       checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?\r
-                                               elem || false :\r
-                                               elem === part;\r
-                               }\r
-                       }\r
+                               // It's crazy that this is faster in IE but it's because it returns all attributes all the time\r
+                               n.cloneNode(false).outerHTML.replace(/<\/?[\w:\-]+ ?|=[\"][^\"]+\"|=\'[^\']+\'|=[\w\-]+|>/gi, '').replace(/[\w:\-]+/gi, function(a) {\r
+                                       o.push({specified : 1, nodeName : a});\r
+                               });\r
 \r
-                       if ( isPartStrNotTag ) {\r
-                               Sizzle.filter( part, checkSet, true );\r
+                               return o;\r
                        }\r
+\r
+                       return n.attributes;\r
                },\r
-               ">": function(checkSet, part){\r
-                       var isPartStr = typeof part === "string",\r
-                               elem, i = 0, l = checkSet.length;\r
 \r
-                       if ( isPartStr && !/\W/.test(part) ) {\r
-                               part = part.toLowerCase();\r
+               isEmpty : function(node, elements) {\r
+                       var self = this, i, attributes, type, walker, name;\r
 \r
-                               for ( ; i < l; i++ ) {\r
-                                       elem = checkSet[i];\r
-                                       if ( elem ) {\r
-                                               var parent = elem.parentNode;\r
-                                               checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;\r
-                                       }\r
-                               }\r
-                       } else {\r
-                               for ( ; i < l; i++ ) {\r
-                                       elem = checkSet[i];\r
-                                       if ( elem ) {\r
-                                               checkSet[i] = isPartStr ?\r
-                                                       elem.parentNode :\r
-                                                       elem.parentNode === part;\r
+                       node = node.firstChild;\r
+                       if (node) {\r
+                               walker = new tinymce.dom.TreeWalker(node);\r
+                               elements = elements || self.schema ? self.schema.getNonEmptyElements() : null;\r
+\r
+                               do {\r
+                                       type = node.nodeType;\r
+\r
+                                       if (type === 1) {\r
+                                               // Ignore bogus elements\r
+                                               if (node.getAttribute('data-mce-bogus'))\r
+                                                       continue;\r
+\r
+                                               // Keep empty elements like <img />\r
+                                               if (elements && elements[node.nodeName.toLowerCase()])\r
+                                                       return false;\r
+\r
+                                               // Keep elements with data attributes or name attribute like <a name="1"></a>\r
+                                               attributes = self.getAttribs(node);\r
+                                               i = node.attributes.length;\r
+                                               while (i--) {\r
+                                                       name = node.attributes[i].nodeName;\r
+                                                       if (name === "name" || name.indexOf('data-') === 0)\r
+                                                               return false;\r
+                                               }\r
                                        }\r
-                               }\r
 \r
-                               if ( isPartStr ) {\r
-                                       Sizzle.filter( part, checkSet, true );\r
-                               }\r
+                                       // Keep non whitespace text nodes\r
+                                       if ((type === 3 && !whiteSpaceRegExp.test(node.nodeValue)))\r
+                                               return false;\r
+                               } while (node = walker.next());\r
                        }\r
+\r
+                       return true;\r
                },\r
-               "": function(checkSet, part, isXML){\r
-                       var doneName = done++, checkFn = dirCheck, nodeCheck;\r
 \r
-                       if ( typeof part === "string" && !/\W/.test(part) ) {\r
-                               part = part.toLowerCase();\r
-                               nodeCheck = part;\r
-                               checkFn = dirNodeCheck;\r
-                       }\r
+               destroy : function(s) {\r
+                       var t = this;\r
 \r
-                       checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);\r
-               },\r
-               "~": function(checkSet, part, isXML){\r
-                       var doneName = done++, checkFn = dirCheck, nodeCheck;\r
+                       if (t.events)\r
+                               t.events.destroy();\r
 \r
-                       if ( typeof part === "string" && !/\W/.test(part) ) {\r
-                               part = part.toLowerCase();\r
-                               nodeCheck = part;\r
-                               checkFn = dirNodeCheck;\r
-                       }\r
+                       t.win = t.doc = t.root = t.events = null;\r
 \r
-                       checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);\r
-               }\r
-       },\r
-       find: {\r
-               ID: function(match, context, isXML){\r
-                       if ( typeof context.getElementById !== "undefined" && !isXML ) {\r
-                               var m = context.getElementById(match[1]);\r
-                               return m ? [m] : [];\r
-                       }\r
+                       // Manual destroy then remove unload handler\r
+                       if (!s)\r
+                               tinymce.removeUnload(t.destroy);\r
                },\r
-               NAME: function(match, context){\r
-                       if ( typeof context.getElementsByName !== "undefined" ) {\r
-                               var ret = [], results = context.getElementsByName(match[1]);\r
 \r
-                               for ( var i = 0, l = results.length; i < l; i++ ) {\r
-                                       if ( results[i].getAttribute("name") === match[1] ) {\r
-                                               ret.push( results[i] );\r
-                                       }\r
-                               }\r
+               createRng : function() {\r
+                       var d = this.doc;\r
 \r
-                               return ret.length === 0 ? null : ret;\r
-                       }\r
+                       return d.createRange ? d.createRange() : new tinymce.dom.Range(this);\r
                },\r
-               TAG: function(match, context){\r
-                       return context.getElementsByTagName(match[1]);\r
-               }\r
-       },\r
-       preFilter: {\r
-               CLASS: function(match, curLoop, inplace, result, not, isXML){\r
-                       match = " " + match[1].replace(/\\/g, "") + " ";\r
 \r
-                       if ( isXML ) {\r
-                               return match;\r
-                       }\r
+               nodeIndex : function(node, normalized) {\r
+                       var idx = 0, lastNodeType, lastNode, nodeType, nodeValueExists;\r
 \r
-                       for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {\r
-                               if ( elem ) {\r
-                                       if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {\r
-                                               if ( !inplace ) {\r
-                                                       result.push( elem );\r
-                                               }\r
-                                       } else if ( inplace ) {\r
-                                               curLoop[i] = false;\r
+                       if (node) {\r
+                               for (lastNodeType = node.nodeType, node = node.previousSibling, lastNode = node; node; node = node.previousSibling) {\r
+                                       nodeType = node.nodeType;\r
+\r
+                                       // Normalize text nodes\r
+                                       if (normalized && nodeType == 3) {\r
+                                               // ensure that text nodes that have been removed are handled correctly in Internet Explorer.\r
+                                               // (the nodeValue attribute will not exist, and will error here).\r
+                                               nodeValueExists = false;\r
+                                               try {nodeValueExists = node.nodeValue.length} catch (c) {}\r
+                                               if (nodeType == lastNodeType || !nodeValueExists)\r
+                                                       continue;\r
                                        }\r
+                                       idx++;\r
+                                       lastNodeType = nodeType;\r
                                }\r
                        }\r
 \r
-                       return false;\r
-               },\r
-               ID: function(match){\r
-                       return match[1].replace(/\\/g, "");\r
-               },\r
-               TAG: function(match, curLoop){\r
-                       return match[1].toLowerCase();\r
+                       return idx;\r
                },\r
-               CHILD: function(match){\r
-                       if ( match[1] === "nth" ) {\r
-                               // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'\r
-                               var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(\r
-                                       match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||\r
-                                       !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);\r
 \r
-                               // calculate the numbers (first)n+(last) including if they are negative\r
-                               match[2] = (test[1] + (test[2] || 1)) - 0;\r
-                               match[3] = test[3] - 0;\r
-                       }\r
+               split : function(pe, e, re) {\r
+                       var t = this, r = t.createRng(), bef, aft, pa;\r
 \r
-                       // TODO: Move to normal caching system\r
-                       match[0] = done++;\r
+                       // W3C valid browsers tend to leave empty nodes to the left/right side of the contents, this makes sense\r
+                       // but we don't want that in our code since it serves no purpose for the end user\r
+                       // For example if this is chopped:\r
+                       //   <p>text 1<span><b>CHOP</b></span>text 2</p>\r
+                       // would produce:\r
+                       //   <p>text 1<span></span></p><b>CHOP</b><p><span></span>text 2</p>\r
+                       // this function will then trim of empty edges and produce:\r
+                       //   <p>text 1</p><b>CHOP</b><p>text 2</p>\r
+                       function trim(node) {\r
+                               var i, children = node.childNodes, type = node.nodeType;\r
 \r
-                       return match;\r
-               },\r
-               ATTR: function(match, curLoop, inplace, result, not, isXML){\r
-                       var name = match[1].replace(/\\/g, "");\r
-                       \r
-                       if ( !isXML && Expr.attrMap[name] ) {\r
-                               match[1] = Expr.attrMap[name];\r
-                       }\r
+                               if (type == 1 && node.getAttribute('data-mce-type') == 'bookmark')\r
+                                       return;\r
 \r
-                       if ( match[2] === "~=" ) {\r
-                               match[4] = " " + match[4] + " ";\r
-                       }\r
+                               for (i = children.length - 1; i >= 0; i--)\r
+                                       trim(children[i]);\r
 \r
-                       return match;\r
-               },\r
-               PSEUDO: function(match, curLoop, inplace, result, not){\r
-                       if ( match[1] === "not" ) {\r
-                               // If we're dealing with a complex expression, or a simple one\r
-                               if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {\r
-                                       match[3] = Sizzle(match[3], null, null, curLoop);\r
-                               } else {\r
-                                       var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);\r
-                                       if ( !inplace ) {\r
-                                               result.push.apply( result, ret );\r
+                               if (type != 9) {\r
+                                       // Keep non whitespace text nodes\r
+                                       if (type == 3 && node.nodeValue.length > 0) {\r
+                                               // If parent element isn't a block or there isn't any useful contents for example "<p>   </p>"\r
+                                               if (!t.isBlock(node.parentNode) || tinymce.trim(node.nodeValue).length > 0)\r
+                                                       return;\r
+                                       } else if (type == 1) {\r
+                                               // If the only child is a bookmark then move it up\r
+                                               children = node.childNodes;\r
+                                               if (children.length == 1 && children[0] && children[0].nodeType == 1 && children[0].getAttribute('data-mce-type') == 'bookmark')\r
+                                                       node.parentNode.insertBefore(children[0], node);\r
+\r
+                                               // Keep non empty elements or img, hr etc\r
+                                               if (children.length || /^(br|hr|input|img)$/i.test(node.nodeName))\r
+                                                       return;\r
                                        }\r
-                                       return false;\r
+\r
+                                       t.remove(node);\r
                                }\r
-                       } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {\r
-                               return true;\r
+\r
+                               return node;\r
+                       };\r
+\r
+                       if (pe && e) {\r
+                               // Get before chunk\r
+                               r.setStart(pe.parentNode, t.nodeIndex(pe));\r
+                               r.setEnd(e.parentNode, t.nodeIndex(e));\r
+                               bef = r.extractContents();\r
+\r
+                               // Get after chunk\r
+                               r = t.createRng();\r
+                               r.setStart(e.parentNode, t.nodeIndex(e) + 1);\r
+                               r.setEnd(pe.parentNode, t.nodeIndex(pe) + 1);\r
+                               aft = r.extractContents();\r
+\r
+                               // Insert before chunk\r
+                               pa = pe.parentNode;\r
+                               pa.insertBefore(trim(bef), pe);\r
+\r
+                               // Insert middle chunk\r
+                               if (re)\r
+                                       pa.replaceChild(re, e);\r
+                               else\r
+                                       pa.insertBefore(e, pe);\r
+\r
+                               // Insert after chunk\r
+                               pa.insertBefore(trim(aft), pe);\r
+                               t.remove(pe);\r
+\r
+                               return re || e;\r
                        }\r
-                       \r
-                       return match;\r
-               },\r
-               POS: function(match){\r
-                       match.unshift( true );\r
-                       return match;\r
-               }\r
-       },\r
-       filters: {\r
-               enabled: function(elem){\r
-                       return elem.disabled === false && elem.type !== "hidden";\r
-               },\r
-               disabled: function(elem){\r
-                       return elem.disabled === true;\r
-               },\r
-               checked: function(elem){\r
-                       return elem.checked === true;\r
-               },\r
-               selected: function(elem){\r
-                       // Accessing this property makes selected-by-default\r
-                       // options in Safari work properly\r
-                       elem.parentNode.selectedIndex;\r
-                       return elem.selected === true;\r
-               },\r
-               parent: function(elem){\r
-                       return !!elem.firstChild;\r
-               },\r
-               empty: function(elem){\r
-                       return !elem.firstChild;\r
-               },\r
-               has: function(elem, i, match){\r
-                       return !!Sizzle( match[3], elem ).length;\r
-               },\r
-               header: function(elem){\r
-                       return (/h\d/i).test( elem.nodeName );\r
-               },\r
-               text: function(elem){\r
-                       return "text" === elem.type;\r
-               },\r
-               radio: function(elem){\r
-                       return "radio" === elem.type;\r
-               },\r
-               checkbox: function(elem){\r
-                       return "checkbox" === elem.type;\r
-               },\r
-               file: function(elem){\r
-                       return "file" === elem.type;\r
-               },\r
-               password: function(elem){\r
-                       return "password" === elem.type;\r
-               },\r
-               submit: function(elem){\r
-                       return "submit" === elem.type;\r
-               },\r
-               image: function(elem){\r
-                       return "image" === elem.type;\r
-               },\r
-               reset: function(elem){\r
-                       return "reset" === elem.type;\r
-               },\r
-               button: function(elem){\r
-                       return "button" === elem.type || elem.nodeName.toLowerCase() === "button";\r
-               },\r
-               input: function(elem){\r
-                       return (/input|select|textarea|button/i).test(elem.nodeName);\r
-               }\r
-       },\r
-       setFilters: {\r
-               first: function(elem, i){\r
-                       return i === 0;\r
-               },\r
-               last: function(elem, i, match, array){\r
-                       return i === array.length - 1;\r
-               },\r
-               even: function(elem, i){\r
-                       return i % 2 === 0;\r
-               },\r
-               odd: function(elem, i){\r
-                       return i % 2 === 1;\r
-               },\r
-               lt: function(elem, i, match){\r
-                       return i < match[3] - 0;\r
                },\r
-               gt: function(elem, i, match){\r
-                       return i > match[3] - 0;\r
+\r
+               bind : function(target, name, func, scope) {\r
+                       var t = this;\r
+\r
+                       if (!t.events)\r
+                               t.events = new tinymce.dom.EventUtils();\r
+\r
+                       return t.events.add(target, name, func, scope || this);\r
                },\r
-               nth: function(elem, i, match){\r
-                       return match[3] - 0 === i;\r
+\r
+               unbind : function(target, name, func) {\r
+                       var t = this;\r
+\r
+                       if (!t.events)\r
+                               t.events = new tinymce.dom.EventUtils();\r
+\r
+                       return t.events.remove(target, name, func);\r
                },\r
-               eq: function(elem, i, match){\r
-                       return match[3] - 0 === i;\r
-               }\r
-       },\r
-       filter: {\r
-               PSEUDO: function(elem, match, i, array){\r
-                       var name = match[1], filter = Expr.filters[ name ];\r
 \r
-                       if ( filter ) {\r
-                               return filter( elem, i, match, array );\r
-                       } else if ( name === "contains" ) {\r
-                               return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;\r
-                       } else if ( name === "not" ) {\r
-                               var not = match[3];\r
 \r
-                               for ( var j = 0, l = not.length; j < l; j++ ) {\r
-                                       if ( not[j] === elem ) {\r
-                                               return false;\r
-                                       }\r
+               _findSib : function(node, selector, name) {\r
+                       var t = this, f = selector;\r
+\r
+                       if (node) {\r
+                               // If expression make a function of it using is\r
+                               if (is(f, 'string')) {\r
+                                       f = function(node) {\r
+                                               return t.is(node, selector);\r
+                                       };\r
                                }\r
 \r
-                               return true;\r
-                       } else {\r
-                               Sizzle.error( "Syntax error, unrecognized expression: " + name );\r
-                       }\r
-               },\r
-               CHILD: function(elem, match){\r
-                       var type = match[1], node = elem;\r
-                       switch (type) {\r
-                               case 'only':\r
-                               case 'first':\r
-                                       while ( (node = node.previousSibling) )  {\r
-                                               if ( node.nodeType === 1 ) { \r
-                                                       return false; \r
-                                               }\r
-                                       }\r
-                                       if ( type === "first" ) { \r
-                                               return true; \r
-                                       }\r
-                                       node = elem;\r
-                               case 'last':\r
-                                       while ( (node = node.nextSibling) )      {\r
-                                               if ( node.nodeType === 1 ) { \r
-                                                       return false; \r
-                                               }\r
-                                       }\r
-                                       return true;\r
-                               case 'nth':\r
-                                       var first = match[2], last = match[3];\r
+                               // Loop all siblings\r
+                               for (node = node[name]; node; node = node[name]) {\r
+                                       if (f(node))\r
+                                               return node;\r
+                               }\r
+                       }\r
+\r
+                       return null;\r
+               },\r
+\r
+               _isRes : function(c) {\r
+                       // Is live resizble element\r
+                       return /^(top|left|bottom|right|width|height)/i.test(c) || /;\s*(top|left|bottom|right|width|height)/i.test(c);\r
+               }\r
+\r
+               /*\r
+               walk : function(n, f, s) {\r
+                       var d = this.doc, w;\r
+\r
+                       if (d.createTreeWalker) {\r
+                               w = d.createTreeWalker(n, NodeFilter.SHOW_TEXT, null, false);\r
+\r
+                               while ((n = w.nextNode()) != null)\r
+                                       f.call(s || this, n);\r
+                       } else\r
+                               tinymce.walk(n, f, 'childNodes', s);\r
+               }\r
+               */\r
+\r
+               /*\r
+               toRGB : function(s) {\r
+                       var c = /^\s*?#([0-9A-F]{2})([0-9A-F]{1,2})([0-9A-F]{2})?\s*?$/.exec(s);\r
+\r
+                       if (c) {\r
+                               // #FFF -> #FFFFFF\r
+                               if (!is(c[3]))\r
+                                       c[3] = c[2] = c[1];\r
+\r
+                               return "rgb(" + parseInt(c[1], 16) + "," + parseInt(c[2], 16) + "," + parseInt(c[3], 16) + ")";\r
+                       }\r
+\r
+                       return s;\r
+               }\r
+               */\r
+       });\r
+\r
+       tinymce.DOM = new tinymce.dom.DOMUtils(document, {process_html : 0});\r
+})(tinymce);\r
+\r
+(function(ns) {\r
+       // Range constructor\r
+       function Range(dom) {\r
+               var t = this,\r
+                       doc = dom.doc,\r
+                       EXTRACT = 0,\r
+                       CLONE = 1,\r
+                       DELETE = 2,\r
+                       TRUE = true,\r
+                       FALSE = false,\r
+                       START_OFFSET = 'startOffset',\r
+                       START_CONTAINER = 'startContainer',\r
+                       END_CONTAINER = 'endContainer',\r
+                       END_OFFSET = 'endOffset',\r
+                       extend = tinymce.extend,\r
+                       nodeIndex = dom.nodeIndex;\r
+\r
+               extend(t, {\r
+                       // Inital states\r
+                       startContainer : doc,\r
+                       startOffset : 0,\r
+                       endContainer : doc,\r
+                       endOffset : 0,\r
+                       collapsed : TRUE,\r
+                       commonAncestorContainer : doc,\r
+\r
+                       // Range constants\r
+                       START_TO_START : 0,\r
+                       START_TO_END : 1,\r
+                       END_TO_END : 2,\r
+                       END_TO_START : 3,\r
+\r
+                       // Public methods\r
+                       setStart : setStart,\r
+                       setEnd : setEnd,\r
+                       setStartBefore : setStartBefore,\r
+                       setStartAfter : setStartAfter,\r
+                       setEndBefore : setEndBefore,\r
+                       setEndAfter : setEndAfter,\r
+                       collapse : collapse,\r
+                       selectNode : selectNode,\r
+                       selectNodeContents : selectNodeContents,\r
+                       compareBoundaryPoints : compareBoundaryPoints,\r
+                       deleteContents : deleteContents,\r
+                       extractContents : extractContents,\r
+                       cloneContents : cloneContents,\r
+                       insertNode : insertNode,\r
+                       surroundContents : surroundContents,\r
+                       cloneRange : cloneRange\r
+               });\r
+\r
+               function setStart(n, o) {\r
+                       _setEndPoint(TRUE, n, o);\r
+               };\r
+\r
+               function setEnd(n, o) {\r
+                       _setEndPoint(FALSE, n, o);\r
+               };\r
+\r
+               function setStartBefore(n) {\r
+                       setStart(n.parentNode, nodeIndex(n));\r
+               };\r
+\r
+               function setStartAfter(n) {\r
+                       setStart(n.parentNode, nodeIndex(n) + 1);\r
+               };\r
+\r
+               function setEndBefore(n) {\r
+                       setEnd(n.parentNode, nodeIndex(n));\r
+               };\r
+\r
+               function setEndAfter(n) {\r
+                       setEnd(n.parentNode, nodeIndex(n) + 1);\r
+               };\r
+\r
+               function collapse(ts) {\r
+                       if (ts) {\r
+                               t[END_CONTAINER] = t[START_CONTAINER];\r
+                               t[END_OFFSET] = t[START_OFFSET];\r
+                       } else {\r
+                               t[START_CONTAINER] = t[END_CONTAINER];\r
+                               t[START_OFFSET] = t[END_OFFSET];\r
+                       }\r
+\r
+                       t.collapsed = TRUE;\r
+               };\r
+\r
+               function selectNode(n) {\r
+                       setStartBefore(n);\r
+                       setEndAfter(n);\r
+               };\r
+\r
+               function selectNodeContents(n) {\r
+                       setStart(n, 0);\r
+                       setEnd(n, n.nodeType === 1 ? n.childNodes.length : n.nodeValue.length);\r
+               };\r
+\r
+               function compareBoundaryPoints(h, r) {\r
+                       var sc = t[START_CONTAINER], so = t[START_OFFSET], ec = t[END_CONTAINER], eo = t[END_OFFSET],\r
+                       rsc = r.startContainer, rso = r.startOffset, rec = r.endContainer, reo = r.endOffset;\r
+\r
+                       // Check START_TO_START\r
+                       if (h === 0)\r
+                               return _compareBoundaryPoints(sc, so, rsc, rso);\r
+       \r
+                       // Check START_TO_END\r
+                       if (h === 1)\r
+                               return _compareBoundaryPoints(ec, eo, rsc, rso);\r
+       \r
+                       // Check END_TO_END\r
+                       if (h === 2)\r
+                               return _compareBoundaryPoints(ec, eo, rec, reo);\r
+       \r
+                       // Check END_TO_START\r
+                       if (h === 3) \r
+                               return _compareBoundaryPoints(sc, so, rec, reo);\r
+               };\r
+\r
+               function deleteContents() {\r
+                       _traverse(DELETE);\r
+               };\r
+\r
+               function extractContents() {\r
+                       return _traverse(EXTRACT);\r
+               };\r
+\r
+               function cloneContents() {\r
+                       return _traverse(CLONE);\r
+               };\r
+\r
+               function insertNode(n) {\r
+                       var startContainer = this[START_CONTAINER],\r
+                               startOffset = this[START_OFFSET], nn, o;\r
+\r
+                       // Node is TEXT_NODE or CDATA\r
+                       if ((startContainer.nodeType === 3 || startContainer.nodeType === 4) && startContainer.nodeValue) {\r
+                               if (!startOffset) {\r
+                                       // At the start of text\r
+                                       startContainer.parentNode.insertBefore(n, startContainer);\r
+                               } else if (startOffset >= startContainer.nodeValue.length) {\r
+                                       // At the end of text\r
+                                       dom.insertAfter(n, startContainer);\r
+                               } else {\r
+                                       // Middle, need to split\r
+                                       nn = startContainer.splitText(startOffset);\r
+                                       startContainer.parentNode.insertBefore(n, nn);\r
+                               }\r
+                       } else {\r
+                               // Insert element node\r
+                               if (startContainer.childNodes.length > 0)\r
+                                       o = startContainer.childNodes[startOffset];\r
+\r
+                               if (o)\r
+                                       startContainer.insertBefore(n, o);\r
+                               else\r
+                                       startContainer.appendChild(n);\r
+                       }\r
+               };\r
+\r
+               function surroundContents(n) {\r
+                       var f = t.extractContents();\r
+\r
+                       t.insertNode(n);\r
+                       n.appendChild(f);\r
+                       t.selectNode(n);\r
+               };\r
+\r
+               function cloneRange() {\r
+                       return extend(new Range(dom), {\r
+                               startContainer : t[START_CONTAINER],\r
+                               startOffset : t[START_OFFSET],\r
+                               endContainer : t[END_CONTAINER],\r
+                               endOffset : t[END_OFFSET],\r
+                               collapsed : t.collapsed,\r
+                               commonAncestorContainer : t.commonAncestorContainer\r
+                       });\r
+               };\r
+\r
+               // Private methods\r
+\r
+               function _getSelectedNode(container, offset) {\r
+                       var child;\r
+\r
+                       if (container.nodeType == 3 /* TEXT_NODE */)\r
+                               return container;\r
+\r
+                       if (offset < 0)\r
+                               return container;\r
+\r
+                       child = container.firstChild;\r
+                       while (child && offset > 0) {\r
+                               --offset;\r
+                               child = child.nextSibling;\r
+                       }\r
+\r
+                       if (child)\r
+                               return child;\r
+\r
+                       return container;\r
+               };\r
+\r
+               function _isCollapsed() {\r
+                       return (t[START_CONTAINER] == t[END_CONTAINER] && t[START_OFFSET] == t[END_OFFSET]);\r
+               };\r
+\r
+               function _compareBoundaryPoints(containerA, offsetA, containerB, offsetB) {\r
+                       var c, offsetC, n, cmnRoot, childA, childB;\r
+                       \r
+                       // In the first case the boundary-points have the same container. A is before B\r
+                       // if its offset is less than the offset of B, A is equal to B if its offset is\r
+                       // equal to the offset of B, and A is after B if its offset is greater than the\r
+                       // offset of B.\r
+                       if (containerA == containerB) {\r
+                               if (offsetA == offsetB)\r
+                                       return 0; // equal\r
+\r
+                               if (offsetA < offsetB)\r
+                                       return -1; // before\r
+\r
+                               return 1; // after\r
+                       }\r
+\r
+                       // In the second case a child node C of the container of A is an ancestor\r
+                       // container of B. In this case, A is before B if the offset of A is less than or\r
+                       // equal to the index of the child node C and A is after B otherwise.\r
+                       c = containerB;\r
+                       while (c && c.parentNode != containerA)\r
+                               c = c.parentNode;\r
+\r
+                       if (c) {\r
+                               offsetC = 0;\r
+                               n = containerA.firstChild;\r
+\r
+                               while (n != c && offsetC < offsetA) {\r
+                                       offsetC++;\r
+                                       n = n.nextSibling;\r
+                               }\r
+\r
+                               if (offsetA <= offsetC)\r
+                                       return -1; // before\r
+\r
+                               return 1; // after\r
+                       }\r
+\r
+                       // In the third case a child node C of the container of B is an ancestor container\r
+                       // of A. In this case, A is before B if the index of the child node C is less than\r
+                       // the offset of B and A is after B otherwise.\r
+                       c = containerA;\r
+                       while (c && c.parentNode != containerB) {\r
+                               c = c.parentNode;\r
+                       }\r
+\r
+                       if (c) {\r
+                               offsetC = 0;\r
+                               n = containerB.firstChild;\r
+\r
+                               while (n != c && offsetC < offsetB) {\r
+                                       offsetC++;\r
+                                       n = n.nextSibling;\r
+                               }\r
+\r
+                               if (offsetC < offsetB)\r
+                                       return -1; // before\r
+\r
+                               return 1; // after\r
+                       }\r
+\r
+                       // In the fourth case, none of three other cases hold: the containers of A and B\r
+                       // are siblings or descendants of sibling nodes. In this case, A is before B if\r
+                       // the container of A is before the container of B in a pre-order traversal of the\r
+                       // Ranges' context tree and A is after B otherwise.\r
+                       cmnRoot = dom.findCommonAncestor(containerA, containerB);\r
+                       childA = containerA;\r
+\r
+                       while (childA && childA.parentNode != cmnRoot)\r
+                               childA = childA.parentNode;\r
+\r
+                       if (!childA)\r
+                               childA = cmnRoot;\r
+\r
+                       childB = containerB;\r
+                       while (childB && childB.parentNode != cmnRoot)\r
+                               childB = childB.parentNode;\r
+\r
+                       if (!childB)\r
+                               childB = cmnRoot;\r
+\r
+                       if (childA == childB)\r
+                               return 0; // equal\r
+\r
+                       n = cmnRoot.firstChild;\r
+                       while (n) {\r
+                               if (n == childA)\r
+                                       return -1; // before\r
+\r
+                               if (n == childB)\r
+                                       return 1; // after\r
+\r
+                               n = n.nextSibling;\r
+                       }\r
+               };\r
+\r
+               function _setEndPoint(st, n, o) {\r
+                       var ec, sc;\r
+\r
+                       if (st) {\r
+                               t[START_CONTAINER] = n;\r
+                               t[START_OFFSET] = o;\r
+                       } else {\r
+                               t[END_CONTAINER] = n;\r
+                               t[END_OFFSET] = o;\r
+                       }\r
+\r
+                       // If one boundary-point of a Range is set to have a root container\r
+                       // other than the current one for the Range, the Range is collapsed to\r
+                       // the new position. This enforces the restriction that both boundary-\r
+                       // points of a Range must have the same root container.\r
+                       ec = t[END_CONTAINER];\r
+                       while (ec.parentNode)\r
+                               ec = ec.parentNode;\r
+\r
+                       sc = t[START_CONTAINER];\r
+                       while (sc.parentNode)\r
+                               sc = sc.parentNode;\r
+\r
+                       if (sc == ec) {\r
+                               // The start position of a Range is guaranteed to never be after the\r
+                               // end position. To enforce this restriction, if the start is set to\r
+                               // be at a position after the end, the Range is collapsed to that\r
+                               // position.\r
+                               if (_compareBoundaryPoints(t[START_CONTAINER], t[START_OFFSET], t[END_CONTAINER], t[END_OFFSET]) > 0)\r
+                                       t.collapse(st);\r
+                       } else\r
+                               t.collapse(st);\r
+\r
+                       t.collapsed = _isCollapsed();\r
+                       t.commonAncestorContainer = dom.findCommonAncestor(t[START_CONTAINER], t[END_CONTAINER]);\r
+               };\r
+\r
+               function _traverse(how) {\r
+                       var c, endContainerDepth = 0, startContainerDepth = 0, p, depthDiff, startNode, endNode, sp, ep;\r
+\r
+                       if (t[START_CONTAINER] == t[END_CONTAINER])\r
+                               return _traverseSameContainer(how);\r
+\r
+                       for (c = t[END_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) {\r
+                               if (p == t[START_CONTAINER])\r
+                                       return _traverseCommonStartContainer(c, how);\r
+\r
+                               ++endContainerDepth;\r
+                       }\r
+\r
+                       for (c = t[START_CONTAINER], p = c.parentNode; p; c = p, p = p.parentNode) {\r
+                               if (p == t[END_CONTAINER])\r
+                                       return _traverseCommonEndContainer(c, how);\r
+\r
+                               ++startContainerDepth;\r
+                       }\r
+\r
+                       depthDiff = startContainerDepth - endContainerDepth;\r
+\r
+                       startNode = t[START_CONTAINER];\r
+                       while (depthDiff > 0) {\r
+                               startNode = startNode.parentNode;\r
+                               depthDiff--;\r
+                       }\r
+\r
+                       endNode = t[END_CONTAINER];\r
+                       while (depthDiff < 0) {\r
+                               endNode = endNode.parentNode;\r
+                               depthDiff++;\r
+                       }\r
+\r
+                       // ascend the ancestor hierarchy until we have a common parent.\r
+                       for (sp = startNode.parentNode, ep = endNode.parentNode; sp != ep; sp = sp.parentNode, ep = ep.parentNode) {\r
+                               startNode = sp;\r
+                               endNode = ep;\r
+                       }\r
+\r
+                       return _traverseCommonAncestors(startNode, endNode, how);\r
+               };\r
+\r
+                function _traverseSameContainer(how) {\r
+                       var frag, s, sub, n, cnt, sibling, xferNode;\r
+\r
+                       if (how != DELETE)\r
+                               frag = doc.createDocumentFragment();\r
+\r
+                       // If selection is empty, just return the fragment\r
+                       if (t[START_OFFSET] == t[END_OFFSET])\r
+                               return frag;\r
+\r
+                       // Text node needs special case handling\r
+                       if (t[START_CONTAINER].nodeType == 3 /* TEXT_NODE */) {\r
+                               // get the substring\r
+                               s = t[START_CONTAINER].nodeValue;\r
+                               sub = s.substring(t[START_OFFSET], t[END_OFFSET]);\r
+\r
+                               // set the original text node to its new value\r
+                               if (how != CLONE) {\r
+                                       t[START_CONTAINER].deleteData(t[START_OFFSET], t[END_OFFSET] - t[START_OFFSET]);\r
+\r
+                                       // Nothing is partially selected, so collapse to start point\r
+                                       t.collapse(TRUE);\r
+                               }\r
+\r
+                               if (how == DELETE)\r
+                                       return;\r
+\r
+                               frag.appendChild(doc.createTextNode(sub));\r
+                               return frag;\r
+                       }\r
+\r
+                       // Copy nodes between the start/end offsets.\r
+                       n = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]);\r
+                       cnt = t[END_OFFSET] - t[START_OFFSET];\r
+\r
+                       while (cnt > 0) {\r
+                               sibling = n.nextSibling;\r
+                               xferNode = _traverseFullySelected(n, how);\r
+\r
+                               if (frag)\r
+                                       frag.appendChild( xferNode );\r
+\r
+                               --cnt;\r
+                               n = sibling;\r
+                       }\r
+\r
+                       // Nothing is partially selected, so collapse to start point\r
+                       if (how != CLONE)\r
+                               t.collapse(TRUE);\r
+\r
+                       return frag;\r
+               };\r
+\r
+               function _traverseCommonStartContainer(endAncestor, how) {\r
+                       var frag, n, endIdx, cnt, sibling, xferNode;\r
+\r
+                       if (how != DELETE)\r
+                               frag = doc.createDocumentFragment();\r
+\r
+                       n = _traverseRightBoundary(endAncestor, how);\r
+\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       endIdx = nodeIndex(endAncestor);\r
+                       cnt = endIdx - t[START_OFFSET];\r
+\r
+                       if (cnt <= 0) {\r
+                               // Collapse to just before the endAncestor, which\r
+                               // is partially selected.\r
+                               if (how != CLONE) {\r
+                                       t.setEndBefore(endAncestor);\r
+                                       t.collapse(FALSE);\r
+                               }\r
+\r
+                               return frag;\r
+                       }\r
+\r
+                       n = endAncestor.previousSibling;\r
+                       while (cnt > 0) {\r
+                               sibling = n.previousSibling;\r
+                               xferNode = _traverseFullySelected(n, how);\r
+\r
+                               if (frag)\r
+                                       frag.insertBefore(xferNode, frag.firstChild);\r
+\r
+                               --cnt;\r
+                               n = sibling;\r
+                       }\r
+\r
+                       // Collapse to just before the endAncestor, which\r
+                       // is partially selected.\r
+                       if (how != CLONE) {\r
+                               t.setEndBefore(endAncestor);\r
+                               t.collapse(FALSE);\r
+                       }\r
+\r
+                       return frag;\r
+               };\r
+\r
+               function _traverseCommonEndContainer(startAncestor, how) {\r
+                       var frag, startIdx, n, cnt, sibling, xferNode;\r
+\r
+                       if (how != DELETE)\r
+                               frag = doc.createDocumentFragment();\r
+\r
+                       n = _traverseLeftBoundary(startAncestor, how);\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       startIdx = nodeIndex(startAncestor);\r
+                       ++startIdx; // Because we already traversed it\r
+\r
+                       cnt = t[END_OFFSET] - startIdx;\r
+                       n = startAncestor.nextSibling;\r
+                       while (cnt > 0) {\r
+                               sibling = n.nextSibling;\r
+                               xferNode = _traverseFullySelected(n, how);\r
+\r
+                               if (frag)\r
+                                       frag.appendChild(xferNode);\r
+\r
+                               --cnt;\r
+                               n = sibling;\r
+                       }\r
+\r
+                       if (how != CLONE) {\r
+                               t.setStartAfter(startAncestor);\r
+                               t.collapse(TRUE);\r
+                       }\r
+\r
+                       return frag;\r
+               };\r
+\r
+               function _traverseCommonAncestors(startAncestor, endAncestor, how) {\r
+                       var n, frag, commonParent, startOffset, endOffset, cnt, sibling, nextSibling;\r
+\r
+                       if (how != DELETE)\r
+                               frag = doc.createDocumentFragment();\r
+\r
+                       n = _traverseLeftBoundary(startAncestor, how);\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       commonParent = startAncestor.parentNode;\r
+                       startOffset = nodeIndex(startAncestor);\r
+                       endOffset = nodeIndex(endAncestor);\r
+                       ++startOffset;\r
+\r
+                       cnt = endOffset - startOffset;\r
+                       sibling = startAncestor.nextSibling;\r
+\r
+                       while (cnt > 0) {\r
+                               nextSibling = sibling.nextSibling;\r
+                               n = _traverseFullySelected(sibling, how);\r
+\r
+                               if (frag)\r
+                                       frag.appendChild(n);\r
+\r
+                               sibling = nextSibling;\r
+                               --cnt;\r
+                       }\r
+\r
+                       n = _traverseRightBoundary(endAncestor, how);\r
+\r
+                       if (frag)\r
+                               frag.appendChild(n);\r
+\r
+                       if (how != CLONE) {\r
+                               t.setStartAfter(startAncestor);\r
+                               t.collapse(TRUE);\r
+                       }\r
+\r
+                       return frag;\r
+               };\r
+\r
+               function _traverseRightBoundary(root, how) {\r
+                       var next = _getSelectedNode(t[END_CONTAINER], t[END_OFFSET] - 1), parent, clonedParent, prevSibling, clonedChild, clonedGrandParent, isFullySelected = next != t[END_CONTAINER];\r
+\r
+                       if (next == root)\r
+                               return _traverseNode(next, isFullySelected, FALSE, how);\r
+\r
+                       parent = next.parentNode;\r
+                       clonedParent = _traverseNode(parent, FALSE, FALSE, how);\r
+\r
+                       while (parent) {\r
+                               while (next) {\r
+                                       prevSibling = next.previousSibling;\r
+                                       clonedChild = _traverseNode(next, isFullySelected, FALSE, how);\r
+\r
+                                       if (how != DELETE)\r
+                                               clonedParent.insertBefore(clonedChild, clonedParent.firstChild);\r
+\r
+                                       isFullySelected = TRUE;\r
+                                       next = prevSibling;\r
+                               }\r
 \r
-                                       if ( first === 1 && last === 0 ) {\r
-                                               return true;\r
-                                       }\r
-                                       \r
-                                       var doneName = match[0],\r
-                                               parent = elem.parentNode;\r
-       \r
-                                       if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {\r
-                                               var count = 0;\r
-                                               for ( node = parent.firstChild; node; node = node.nextSibling ) {\r
-                                                       if ( node.nodeType === 1 ) {\r
-                                                               node.nodeIndex = ++count;\r
-                                                       }\r
-                                               } \r
-                                               parent.sizcache = doneName;\r
-                                       }\r
-                                       \r
-                                       var diff = elem.nodeIndex - last;\r
-                                       if ( first === 0 ) {\r
-                                               return diff === 0;\r
-                                       } else {\r
-                                               return ( diff % first === 0 && diff / first >= 0 );\r
-                                       }\r
+                               if (parent == root)\r
+                                       return clonedParent;\r
+\r
+                               next = parent.previousSibling;\r
+                               parent = parent.parentNode;\r
+\r
+                               clonedGrandParent = _traverseNode(parent, FALSE, FALSE, how);\r
+\r
+                               if (how != DELETE)\r
+                                       clonedGrandParent.appendChild(clonedParent);\r
+\r
+                               clonedParent = clonedGrandParent;\r
                        }\r
-               },\r
-               ID: function(elem, match){\r
-                       return elem.nodeType === 1 && elem.getAttribute("id") === match;\r
-               },\r
-               TAG: function(elem, match){\r
-                       return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;\r
-               },\r
-               CLASS: function(elem, match){\r
-                       return (" " + (elem.className || elem.getAttribute("class")) + " ")\r
-                               .indexOf( match ) > -1;\r
-               },\r
-               ATTR: function(elem, match){\r
-                       var name = match[1],\r
-                               result = Expr.attrHandle[ name ] ?\r
-                                       Expr.attrHandle[ name ]( elem ) :\r
-                                       elem[ name ] != null ?\r
-                                               elem[ name ] :\r
-                                               elem.getAttribute( name ),\r
-                               value = result + "",\r
-                               type = match[2],\r
-                               check = match[4];\r
+               };\r
 \r
-                       return result == null ?\r
-                               type === "!=" :\r
-                               type === "=" ?\r
-                               value === check :\r
-                               type === "*=" ?\r
-                               value.indexOf(check) >= 0 :\r
-                               type === "~=" ?\r
-                               (" " + value + " ").indexOf(check) >= 0 :\r
-                               !check ?\r
-                               value && result !== false :\r
-                               type === "!=" ?\r
-                               value !== check :\r
-                               type === "^=" ?\r
-                               value.indexOf(check) === 0 :\r
-                               type === "$=" ?\r
-                               value.substr(value.length - check.length) === check :\r
-                               type === "|=" ?\r
-                               value === check || value.substr(0, check.length + 1) === check + "-" :\r
-                               false;\r
-               },\r
-               POS: function(elem, match, i, array){\r
-                       var name = match[2], filter = Expr.setFilters[ name ];\r
+               function _traverseLeftBoundary(root, how) {\r
+                       var next = _getSelectedNode(t[START_CONTAINER], t[START_OFFSET]), isFullySelected = next != t[START_CONTAINER], parent, clonedParent, nextSibling, clonedChild, clonedGrandParent;\r
 \r
-                       if ( filter ) {\r
-                               return filter( elem, i, match, array );\r
+                       if (next == root)\r
+                               return _traverseNode(next, isFullySelected, TRUE, how);\r
+\r
+                       parent = next.parentNode;\r
+                       clonedParent = _traverseNode(parent, FALSE, TRUE, how);\r
+\r
+                       while (parent) {\r
+                               while (next) {\r
+                                       nextSibling = next.nextSibling;\r
+                                       clonedChild = _traverseNode(next, isFullySelected, TRUE, how);\r
+\r
+                                       if (how != DELETE)\r
+                                               clonedParent.appendChild(clonedChild);\r
+\r
+                                       isFullySelected = TRUE;\r
+                                       next = nextSibling;\r
+                               }\r
+\r
+                               if (parent == root)\r
+                                       return clonedParent;\r
+\r
+                               next = parent.nextSibling;\r
+                               parent = parent.parentNode;\r
+\r
+                               clonedGrandParent = _traverseNode(parent, FALSE, TRUE, how);\r
+\r
+                               if (how != DELETE)\r
+                                       clonedGrandParent.appendChild(clonedParent);\r
+\r
+                               clonedParent = clonedGrandParent;\r
                        }\r
-               }\r
-       }\r
-};\r
+               };\r
 \r
-var origPOS = Expr.match.POS,\r
-       fescape = function(all, num){\r
-               return "\\" + (num - 0 + 1);\r
+               function _traverseNode(n, isFullySelected, isLeft, how) {\r
+                       var txtValue, newNodeValue, oldNodeValue, offset, newNode;\r
+\r
+                       if (isFullySelected)\r
+                               return _traverseFullySelected(n, how);\r
+\r
+                       if (n.nodeType == 3 /* TEXT_NODE */) {\r
+                               txtValue = n.nodeValue;\r
+\r
+                               if (isLeft) {\r
+                                       offset = t[START_OFFSET];\r
+                                       newNodeValue = txtValue.substring(offset);\r
+                                       oldNodeValue = txtValue.substring(0, offset);\r
+                               } else {\r
+                                       offset = t[END_OFFSET];\r
+                                       newNodeValue = txtValue.substring(0, offset);\r
+                                       oldNodeValue = txtValue.substring(offset);\r
+                               }\r
+\r
+                               if (how != CLONE)\r
+                                       n.nodeValue = oldNodeValue;\r
+\r
+                               if (how == DELETE)\r
+                                       return;\r
+\r
+                               newNode = n.cloneNode(FALSE);\r
+                               newNode.nodeValue = newNodeValue;\r
+\r
+                               return newNode;\r
+                       }\r
+\r
+                       if (how == DELETE)\r
+                               return;\r
+\r
+                       return n.cloneNode(FALSE);\r
+               };\r
+\r
+               function _traverseFullySelected(n, how) {\r
+                       if (how != DELETE)\r
+                               return how == CLONE ? n.cloneNode(TRUE) : n;\r
+\r
+                       n.parentNode.removeChild(n);\r
+               };\r
        };\r
 \r
-for ( var type in Expr.match ) {\r
-       Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );\r
-       Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );\r
-}\r
+       ns.Range = Range;\r
+})(tinymce.dom);\r
 \r
-var makeArray = function(array, results) {\r
-       array = Array.prototype.slice.call( array, 0 );\r
+(function() {\r
+       function Selection(selection) {\r
+               var t = this, invisibleChar = '\uFEFF', range, lastIERng, dom = selection.dom, TRUE = true, FALSE = false;\r
 \r
-       if ( results ) {\r
-               results.push.apply( results, array );\r
-               return results;\r
-       }\r
-       \r
-       return array;\r
-};\r
+               // Returns a W3C DOM compatible range object by using the IE Range API\r
+               function getRange() {\r
+                       var ieRange = selection.getRng(), domRange = dom.createRng(), element, collapsed;\r
 \r
-// Perform a simple check to determine if the browser is capable of\r
-// converting a NodeList to an array using builtin methods.\r
-// Also verifies that the returned array holds DOM nodes\r
-// (which is not the case in the Blackberry browser)\r
-try {\r
-       Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;\r
+                       // If selection is outside the current document just return an empty range\r
+                       element = ieRange.item ? ieRange.item(0) : ieRange.parentElement();\r
+                       if (element.ownerDocument != dom.doc)\r
+                               return domRange;\r
+\r
+                       collapsed = selection.isCollapsed();\r
+\r
+                       // Handle control selection or text selection of a image\r
+                       if (ieRange.item || !element.hasChildNodes()) {\r
+                               if (collapsed) {\r
+                                       domRange.setStart(element, 0);\r
+                                       domRange.setEnd(element, 0);\r
+                               } else {\r
+                                       domRange.setStart(element.parentNode, dom.nodeIndex(element));\r
+                                       domRange.setEnd(domRange.startContainer, domRange.startOffset + 1);\r
+                               }\r
+\r
+                               return domRange;\r
+                       }\r
+\r
+                       function findEndPoint(start) {\r
+                               var marker, container, offset, nodes, startIndex = 0, endIndex, index, parent, checkRng, position;\r
+\r
+                               // Setup temp range and collapse it\r
+                               checkRng = ieRange.duplicate();\r
+                               checkRng.collapse(start);\r
+\r
+                               // Create marker and insert it at the end of the endpoints parent\r
+                               marker = dom.create('a');\r
+                               parent = checkRng.parentElement();\r
+\r
+                               // If parent doesn't have any children then set the container to that parent and the index to 0\r
+                               if (!parent.hasChildNodes()) {\r
+                                       domRange[start ? 'setStart' : 'setEnd'](parent, 0);\r
+                                       return;\r
+                               }\r
+\r
+                               parent.appendChild(marker);\r
+                               checkRng.moveToElementText(marker);\r
+                               position = ieRange.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', checkRng);\r
+                               if (position > 0) {\r
+                                       // The position is after the end of the parent element.\r
+                                       // This is the case where IE puts the caret to the left edge of a table.\r
+                                       domRange[start ? 'setStartAfter' : 'setEndAfter'](parent);\r
+                                       dom.remove(marker);\r
+                                       return;\r
+                               }\r
+\r
+                               // Setup node list and endIndex\r
+                               nodes = tinymce.grep(parent.childNodes);\r
+                               endIndex = nodes.length - 1;\r
+                               // Perform a binary search for the position\r
+                               while (startIndex <= endIndex) {\r
+                                       index = Math.floor((startIndex + endIndex) / 2);\r
+\r
+                                       // Insert marker and check it's position relative to the selection\r
+                                       parent.insertBefore(marker, nodes[index]);\r
+                                       checkRng.moveToElementText(marker);\r
+                                       position = ieRange.compareEndPoints(start ? 'StartToStart' : 'EndToEnd', checkRng);\r
+                                       if (position > 0) {\r
+                                               // Marker is to the right\r
+                                               startIndex = index + 1;\r
+                                       } else if (position < 0) {\r
+                                               // Marker is to the left\r
+                                               endIndex = index - 1;\r
+                                       } else {\r
+                                               // Maker is where we are\r
+                                               found = true;\r
+                                               break;\r
+                                       }\r
+                               }\r
 \r
-// Provide a fallback method if it does not work\r
-} catch(e){\r
-       makeArray = function(array, results) {\r
-               var ret = results || [], i = 0;\r
+                               // Setup container\r
+                               container = position > 0 || index == 0 ? marker.nextSibling : marker.previousSibling;\r
 \r
-               if ( toString.call(array) === "[object Array]" ) {\r
-                       Array.prototype.push.apply( ret, array );\r
-               } else {\r
-                       if ( typeof array.length === "number" ) {\r
-                               for ( var l = array.length; i < l; i++ ) {\r
-                                       ret.push( array[i] );\r
-                               }\r
-                       } else {\r
-                               for ( ; array[i]; i++ ) {\r
-                                       ret.push( array[i] );\r
-                               }\r
-                       }\r
-               }\r
+                               // Handle element selection\r
+                               if (container.nodeType == 1) {\r
+                                       dom.remove(marker);\r
 \r
-               return ret;\r
-       };\r
-}\r
+                                       // Find offset and container\r
+                                       offset = dom.nodeIndex(container);\r
+                                       container = container.parentNode;\r
 \r
-var sortOrder;\r
+                                       // Move the offset if we are setting the end or the position is after an element\r
+                                       if (!start || index > 0)\r
+                                               offset++;\r
+                               } else {\r
+                                       // Calculate offset within text node\r
+                                       if (position > 0 || index == 0) {\r
+                                               checkRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', ieRange);\r
+                                               offset = checkRng.text.length;\r
+                                       } else {\r
+                                               checkRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', ieRange);\r
+                                               offset = container.nodeValue.length - checkRng.text.length;\r
+                                       }\r
 \r
-if ( document.documentElement.compareDocumentPosition ) {\r
-       sortOrder = function( a, b ) {\r
-               if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {\r
-                       if ( a == b ) {\r
-                               hasDuplicate = true;\r
-                       }\r
-                       return a.compareDocumentPosition ? -1 : 1;\r
-               }\r
+                                       dom.remove(marker);\r
+                               }\r
 \r
-               var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;\r
-               if ( ret === 0 ) {\r
-                       hasDuplicate = true;\r
-               }\r
-               return ret;\r
-       };\r
-} else if ( "sourceIndex" in document.documentElement ) {\r
-       sortOrder = function( a, b ) {\r
-               if ( !a.sourceIndex || !b.sourceIndex ) {\r
-                       if ( a == b ) {\r
-                               hasDuplicate = true;\r
-                       }\r
-                       return a.sourceIndex ? -1 : 1;\r
-               }\r
+                               domRange[start ? 'setStart' : 'setEnd'](container, offset);\r
+                       };\r
 \r
-               var ret = a.sourceIndex - b.sourceIndex;\r
-               if ( ret === 0 ) {\r
-                       hasDuplicate = true;\r
-               }\r
-               return ret;\r
-       };\r
-} else if ( document.createRange ) {\r
-       sortOrder = function( a, b ) {\r
-               if ( !a.ownerDocument || !b.ownerDocument ) {\r
-                       if ( a == b ) {\r
-                               hasDuplicate = true;\r
-                       }\r
-                       return a.ownerDocument ? -1 : 1;\r
-               }\r
+                       // Find start point\r
+                       findEndPoint(true);\r
 \r
-               var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();\r
-               aRange.setStart(a, 0);\r
-               aRange.setEnd(a, 0);\r
-               bRange.setStart(b, 0);\r
-               bRange.setEnd(b, 0);\r
-               var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);\r
-               if ( ret === 0 ) {\r
-                       hasDuplicate = true;\r
-               }\r
-               return ret;\r
-       };\r
-}\r
+                       // Find end point if needed\r
+                       if (!collapsed)\r
+                               findEndPoint();\r
 \r
-// Utility function for retreiving the text value of an array of DOM nodes\r
-Sizzle.getText = function( elems ) {\r
-       var ret = "", elem;\r
+                       return domRange;\r
+               };\r
 \r
-       for ( var i = 0; elems[i]; i++ ) {\r
-               elem = elems[i];\r
+               this.addRange = function(rng) {\r
+                       var ieRng, ctrlRng, startContainer, startOffset, endContainer, endOffset, doc = selection.dom.doc, body = doc.body;\r
 \r
-               // Get the text from text nodes and CDATA nodes\r
-               if ( elem.nodeType === 3 || elem.nodeType === 4 ) {\r
-                       ret += elem.nodeValue;\r
+                       function setEndPoint(start) {\r
+                               var container, offset, marker, tmpRng, nodes;\r
 \r
-               // Traverse everything else, except comment nodes\r
-               } else if ( elem.nodeType !== 8 ) {\r
-                       ret += Sizzle.getText( elem.childNodes );\r
-               }\r
-       }\r
+                               marker = dom.create('a');\r
+                               container = start ? startContainer : endContainer;\r
+                               offset = start ? startOffset : endOffset;\r
+                               tmpRng = ieRng.duplicate();\r
 \r
-       return ret;\r
-};\r
+                               if (container == doc || container == doc.documentElement) {\r
+                                       container = body;\r
+                                       offset = 0;\r
+                               }\r
 \r
-// Check to see if the browser returns elements by name when\r
-// querying by getElementById (and provide a workaround)\r
-(function(){\r
-       // We're going to inject a fake input element with a specified name\r
-       var form = document.createElement("div"),\r
-               id = "script" + (new Date()).getTime();\r
-       form.innerHTML = "<a name='" + id + "'/>";\r
+                               if (container.nodeType == 3) {\r
+                                       container.parentNode.insertBefore(marker, container);\r
+                                       tmpRng.moveToElementText(marker);\r
+                                       tmpRng.moveStart('character', offset);\r
+                                       dom.remove(marker);\r
+                                       ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng);\r
+                               } else {\r
+                                       nodes = container.childNodes;\r
 \r
-       // Inject it into the root element, check its status, and remove it quickly\r
-       var root = document.documentElement;\r
-       root.insertBefore( form, root.firstChild );\r
+                                       if (nodes.length) {\r
+                                               if (offset >= nodes.length) {\r
+                                                       dom.insertAfter(marker, nodes[nodes.length - 1]);\r
+                                               } else {\r
+                                                       container.insertBefore(marker, nodes[offset]);\r
+                                               }\r
 \r
-       // The workaround has to do additional checks after a getElementById\r
-       // Which slows things down for other browsers (hence the branching)\r
-       if ( document.getElementById( id ) ) {\r
-               Expr.find.ID = function(match, context, isXML){\r
-                       if ( typeof context.getElementById !== "undefined" && !isXML ) {\r
-                               var m = context.getElementById(match[1]);\r
-                               return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];\r
+                                               tmpRng.moveToElementText(marker);\r
+                                       } else {\r
+                                               // Empty node selection for example <div>|</div>\r
+                                               marker = doc.createTextNode(invisibleChar);\r
+                                               container.appendChild(marker);\r
+                                               tmpRng.moveToElementText(marker.parentNode);\r
+                                               tmpRng.collapse(TRUE);\r
+                                       }\r
+\r
+                                       ieRng.setEndPoint(start ? 'StartToStart' : 'EndToEnd', tmpRng);\r
+                                       dom.remove(marker);\r
+                               }\r
                        }\r
-               };\r
 \r
-               Expr.filter.ID = function(elem, match){\r
-                       var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");\r
-                       return elem.nodeType === 1 && node && node.nodeValue === match;\r
-               };\r
-       }\r
+                       // Destroy cached range\r
+                       this.destroy();\r
 \r
-       root.removeChild( form );\r
-       root = form = null; // release memory in IE\r
-})();\r
+                       // Setup some shorter versions\r
+                       startContainer = rng.startContainer;\r
+                       startOffset = rng.startOffset;\r
+                       endContainer = rng.endContainer;\r
+                       endOffset = rng.endOffset;\r
+                       ieRng = body.createTextRange();\r
 \r
-(function(){\r
-       // Check to see if the browser returns only elements\r
-       // when doing getElementsByTagName("*")\r
+                       // If single element selection then try making a control selection out of it\r
+                       if (startContainer == endContainer && startContainer.nodeType == 1 && startOffset == endOffset - 1) {\r
+                               if (startOffset == endOffset - 1) {\r
+                                       try {\r
+                                               ctrlRng = body.createControlRange();\r
+                                               ctrlRng.addElement(startContainer.childNodes[startOffset]);\r
+                                               ctrlRng.select();\r
+                                               return;\r
+                                       } catch (ex) {\r
+                                               // Ignore\r
+                                       }\r
+                               }\r
+                       }\r
 \r
-       // Create a fake element\r
-       var div = document.createElement("div");\r
-       div.appendChild( document.createComment("") );\r
+                       // Set start/end point of selection\r
+                       setEndPoint(true);\r
+                       setEndPoint();\r
 \r
-       // Make sure no comments are found\r
-       if ( div.getElementsByTagName("*").length > 0 ) {\r
-               Expr.find.TAG = function(match, context){\r
-                       var results = context.getElementsByTagName(match[1]);\r
+                       // Select the new range and scroll it into view\r
+                       ieRng.select();\r
+               };\r
 \r
-                       // Filter out possible comments\r
-                       if ( match[1] === "*" ) {\r
-                               var tmp = [];\r
+               this.getRangeAt = function() {\r
+                       // Setup new range if the cache is empty\r
+                       if (!range || !tinymce.dom.RangeUtils.compareRanges(lastIERng, selection.getRng())) {\r
+                               range = getRange();\r
 \r
-                               for ( var i = 0; results[i]; i++ ) {\r
-                                       if ( results[i].nodeType === 1 ) {\r
-                                               tmp.push( results[i] );\r
-                                       }\r
-                               }\r
+                               // Store away text range for next call\r
+                               lastIERng = selection.getRng();\r
+                       }\r
 \r
-                               results = tmp;\r
+                       // IE will say that the range is equal then produce an invalid argument exception\r
+                       // if you perform specific operations in a keyup event. For example Ctrl+Del.\r
+                       // This hack will invalidate the range cache if the exception occurs\r
+                       try {\r
+                               range.startContainer.nextSibling;\r
+                       } catch (ex) {\r
+                               range = getRange();\r
+                               lastIERng = null;\r
                        }\r
 \r
-                       return results;\r
+                       // Return cached range\r
+                       return range;\r
                };\r
-       }\r
 \r
-       // Check to see if an attribute returns normalized href attributes\r
-       div.innerHTML = "<a href='#'></a>";\r
-       if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&\r
-                       div.firstChild.getAttribute("href") !== "#" ) {\r
-               Expr.attrHandle.href = function(elem){\r
-                       return elem.getAttribute("href", 2);\r
+               this.destroy = function() {\r
+                       // Destroy cached range and last IE range to avoid memory leaks\r
+                       lastIERng = range = null;\r
                };\r
-       }\r
+       };\r
 \r
-       div = null; // release memory in IE\r
+       // Expose the selection object\r
+       tinymce.dom.TridentSelection = Selection;\r
 })();\r
 \r
-if ( document.querySelectorAll ) {\r
-       (function(){\r
-               var oldSizzle = Sizzle, div = document.createElement("div");\r
-               div.innerHTML = "<p class='TEST'></p>";\r
-\r
-               // Safari can't handle uppercase or unicode characters when\r
-               // in quirks mode.\r
-               if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {\r
-                       return;\r
-               }\r
-       \r
-               Sizzle = function(query, context, extra, seed){\r
-                       context = context || document;\r
 \r
-                       // Only use querySelectorAll on non-XML documents\r
-                       // (ID selectors don't work in non-HTML documents)\r
-                       if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) {\r
-                               try {\r
-                                       return makeArray( context.querySelectorAll(query), extra );\r
-                               } catch(e){}\r
-                       }\r
-               \r
-                       return oldSizzle(query, context, extra, seed);\r
-               };\r
+/*\r
+ * Sizzle CSS Selector Engine - v1.0\r
+ *  Copyright 2009, The Dojo Foundation\r
+ *  Released under the MIT, BSD, and GPL Licenses.\r
+ *  More information: http://sizzlejs.com/\r
+ */\r
+(function(){\r
 \r
-               for ( var prop in oldSizzle ) {\r
-                       Sizzle[ prop ] = oldSizzle[ prop ];\r
-               }\r
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,\r
+       done = 0,\r
+       toString = Object.prototype.toString,\r
+       hasDuplicate = false,\r
+       baseHasDuplicate = true;\r
 \r
-               div = null; // release memory in IE\r
-       })();\r
-}\r
+// Here we check if the JavaScript engine is using some sort of\r
+// optimization where it does not always call our comparision\r
+// function. If that is the case, discard the hasDuplicate value.\r
+//   Thus far that includes Google Chrome.\r
+[0, 0].sort(function(){\r
+       baseHasDuplicate = false;\r
+       return 0;\r
+});\r
 \r
-(function(){\r
-       var div = document.createElement("div");\r
+var Sizzle = function(selector, context, results, seed) {\r
+       results = results || [];\r
+       context = context || document;\r
 \r
-       div.innerHTML = "<div class='test e'></div><div class='test'></div>";\r
+       var origContext = context;\r
 \r
-       // Opera can't find a second classname (in 9.6)\r
-       // Also, make sure that getElementsByClassName actually exists\r
-       if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {\r
-               return;\r
+       if ( context.nodeType !== 1 && context.nodeType !== 9 ) {\r
+               return [];\r
        }\r
-\r
-       // Safari caches class attributes, doesn't catch changes (in 3.2)\r
-       div.lastChild.className = "e";\r
-\r
-       if ( div.getElementsByClassName("e").length === 1 ) {\r
-               return;\r
+       \r
+       if ( !selector || typeof selector !== "string" ) {\r
+               return results;\r
        }\r
+\r
+       var parts = [], m, set, checkSet, extra, prune = true, contextXML = Sizzle.isXML(context),\r
+               soFar = selector, ret, cur, pop, i;\r
        \r
-       Expr.order.splice(1, 0, "CLASS");\r
-       Expr.find.CLASS = function(match, context, isXML) {\r
-               if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {\r
-                       return context.getElementsByClassName(match[1]);\r
-               }\r
-       };\r
+       // Reset the position of the chunker regexp (start from head)\r
+       do {\r
+               chunker.exec("");\r
+               m = chunker.exec(soFar);\r
 \r
-       div = null; // release memory in IE\r
-})();\r
+               if ( m ) {\r
+                       soFar = m[3];\r
+               \r
+                       parts.push( m[1] );\r
+               \r
+                       if ( m[2] ) {\r
+                               extra = m[3];\r
+                               break;\r
+                       }\r
+               }\r
+       } while ( m );\r
 \r
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\r
-       for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
-               var elem = checkSet[i];\r
-               if ( elem ) {\r
-                       elem = elem[dir];\r
-                       var match = false;\r
+       if ( parts.length > 1 && origPOS.exec( selector ) ) {\r
+               if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {\r
+                       set = posProcess( parts[0] + parts[1], context );\r
+               } else {\r
+                       set = Expr.relative[ parts[0] ] ?\r
+                               [ context ] :\r
+                               Sizzle( parts.shift(), context );\r
 \r
-                       while ( elem ) {\r
-                               if ( elem.sizcache === doneName ) {\r
-                                       match = checkSet[elem.sizset];\r
-                                       break;\r
-                               }\r
+                       while ( parts.length ) {\r
+                               selector = parts.shift();\r
 \r
-                               if ( elem.nodeType === 1 && !isXML ){\r
-                                       elem.sizcache = doneName;\r
-                                       elem.sizset = i;\r
+                               if ( Expr.relative[ selector ] ) {\r
+                                       selector += parts.shift();\r
                                }\r
+                               \r
+                               set = posProcess( selector, set );\r
+                       }\r
+               }\r
+       } else {\r
+               // Take a shortcut and set the context if the root selector is an ID\r
+               // (but not if it'll be faster if the inner selector is an ID)\r
+               if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&\r
+                               Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {\r
+                       ret = Sizzle.find( parts.shift(), context, contextXML );\r
+                       context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];\r
+               }\r
 \r
-                               if ( elem.nodeName.toLowerCase() === cur ) {\r
-                                       match = elem;\r
-                                       break;\r
-                               }\r
+               if ( context ) {\r
+                       ret = seed ?\r
+                               { expr: parts.pop(), set: makeArray(seed) } :\r
+                               Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );\r
+                       set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;\r
 \r
-                               elem = elem[dir];\r
+                       if ( parts.length > 0 ) {\r
+                               checkSet = makeArray(set);\r
+                       } else {\r
+                               prune = false;\r
                        }\r
 \r
-                       checkSet[i] = match;\r
-               }\r
-       }\r
-}\r
-\r
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\r
-       for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
-               var elem = checkSet[i];\r
-               if ( elem ) {\r
-                       elem = elem[dir];\r
-                       var match = false;\r
+                       while ( parts.length ) {\r
+                               cur = parts.pop();\r
+                               pop = cur;\r
 \r
-                       while ( elem ) {\r
-                               if ( elem.sizcache === doneName ) {\r
-                                       match = checkSet[elem.sizset];\r
-                                       break;\r
+                               if ( !Expr.relative[ cur ] ) {\r
+                                       cur = "";\r
+                               } else {\r
+                                       pop = parts.pop();\r
                                }\r
 \r
-                               if ( elem.nodeType === 1 ) {\r
-                                       if ( !isXML ) {\r
-                                               elem.sizcache = doneName;\r
-                                               elem.sizset = i;\r
-                                       }\r
-                                       if ( typeof cur !== "string" ) {\r
-                                               if ( elem === cur ) {\r
-                                                       match = true;\r
-                                                       break;\r
-                                               }\r
-\r
-                                       } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {\r
-                                               match = elem;\r
-                                               break;\r
-                                       }\r
+                               if ( pop == null ) {\r
+                                       pop = context;\r
                                }\r
 \r
-                               elem = elem[dir];\r
+                               Expr.relative[ cur ]( checkSet, pop, contextXML );\r
                        }\r
-\r
-                       checkSet[i] = match;\r
+               } else {\r
+                       checkSet = parts = [];\r
                }\r
        }\r
-}\r
-\r
-Sizzle.contains = document.compareDocumentPosition ? function(a, b){\r
-       return !!(a.compareDocumentPosition(b) & 16);\r
-} : function(a, b){\r
-       return a !== b && (a.contains ? a.contains(b) : true);\r
-};\r
-\r
-Sizzle.isXML = function(elem){\r
-       // documentElement is verified for cases where it doesn't yet exist\r
-       // (such as loading iframes in IE - #4833) \r
-       var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;\r
-       return documentElement ? documentElement.nodeName !== "HTML" : false;\r
-};\r
 \r
-var posProcess = function(selector, context){\r
-       var tmpSet = [], later = "", match,\r
-               root = context.nodeType ? [context] : context;\r
+       if ( !checkSet ) {\r
+               checkSet = set;\r
+       }\r
 \r
-       // Position selectors must be done after the filter\r
-       // And so must :not(positional) so we move all PSEUDOs to the end\r
-       while ( (match = Expr.match.PSEUDO.exec( selector )) ) {\r
-               later += match[0];\r
-               selector = selector.replace( Expr.match.PSEUDO, "" );\r
+       if ( !checkSet ) {\r
+               Sizzle.error( cur || selector );\r
        }\r
 \r
-       selector = Expr.relative[selector] ? selector + "*" : selector;\r
+       if ( toString.call(checkSet) === "[object Array]" ) {\r
+               if ( !prune ) {\r
+                       results.push.apply( results, checkSet );\r
+               } else if ( context && context.nodeType === 1 ) {\r
+                       for ( i = 0; checkSet[i] != null; i++ ) {\r
+                               if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {\r
+                                       results.push( set[i] );\r
+                               }\r
+                       }\r
+               } else {\r
+                       for ( i = 0; checkSet[i] != null; i++ ) {\r
+                               if ( checkSet[i] && checkSet[i].nodeType === 1 ) {\r
+                                       results.push( set[i] );\r
+                               }\r
+                       }\r
+               }\r
+       } else {\r
+               makeArray( checkSet, results );\r
+       }\r
 \r
-       for ( var i = 0, l = root.length; i < l; i++ ) {\r
-               Sizzle( selector, root[i], tmpSet );\r
+       if ( extra ) {\r
+               Sizzle( extra, origContext, results, seed );\r
+               Sizzle.uniqueSort( results );\r
        }\r
 \r
-       return Sizzle.filter( later, tmpSet );\r
+       return results;\r
 };\r
 \r
-// EXPOSE\r
+Sizzle.uniqueSort = function(results){\r
+       if ( sortOrder ) {\r
+               hasDuplicate = baseHasDuplicate;\r
+               results.sort(sortOrder);\r
 \r
-window.tinymce.dom.Sizzle = Sizzle;\r
+               if ( hasDuplicate ) {\r
+                       for ( var i = 1; i < results.length; i++ ) {\r
+                               if ( results[i] === results[i-1] ) {\r
+                                       results.splice(i--, 1);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
 \r
-})();\r
+       return results;\r
+};\r
 \r
+Sizzle.matches = function(expr, set){\r
+       return Sizzle(expr, null, null, set);\r
+};\r
 \r
-(function(tinymce) {\r
-       // Shorten names\r
-       var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
+Sizzle.find = function(expr, context, isXML){\r
+       var set;\r
 \r
-       tinymce.create('tinymce.dom.EventUtils', {\r
-               EventUtils : function() {\r
-                       this.inits = [];\r
-                       this.events = [];\r
-               },\r
+       if ( !expr ) {\r
+               return [];\r
+       }\r
 \r
-               add : function(o, n, f, s) {\r
-                       var cb, t = this, el = t.events, r;\r
+       for ( var i = 0, l = Expr.order.length; i < l; i++ ) {\r
+               var type = Expr.order[i], match;\r
+               \r
+               if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {\r
+                       var left = match[1];\r
+                       match.splice(1,1);\r
 \r
-                       if (n instanceof Array) {\r
-                               r = [];\r
+                       if ( left.substr( left.length - 1 ) !== "\\" ) {\r
+                               match[1] = (match[1] || "").replace(/\\/g, "");\r
+                               set = Expr.find[ type ]( match, context, isXML );\r
+                               if ( set != null ) {\r
+                                       expr = expr.replace( Expr.match[ type ], "" );\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
 \r
-                               each(n, function(n) {\r
-                                       r.push(t.add(o, n, f, s));\r
-                               });\r
+       if ( !set ) {\r
+               set = context.getElementsByTagName("*");\r
+       }\r
 \r
-                               return r;\r
-                       }\r
+       return {set: set, expr: expr};\r
+};\r
 \r
-                       // Handle array\r
-                       if (o && o.hasOwnProperty && o instanceof Array) {\r
-                               r = [];\r
+Sizzle.filter = function(expr, set, inplace, not){\r
+       var old = expr, result = [], curLoop = set, match, anyFound,\r
+               isXMLFilter = set && set[0] && Sizzle.isXML(set[0]);\r
 \r
-                               each(o, function(o) {\r
-                                       o = DOM.get(o);\r
-                                       r.push(t.add(o, n, f, s));\r
-                               });\r
+       while ( expr && set.length ) {\r
+               for ( var type in Expr.filter ) {\r
+                       if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {\r
+                               var filter = Expr.filter[ type ], found, item, left = match[1];\r
+                               anyFound = false;\r
 \r
-                               return r;\r
-                       }\r
+                               match.splice(1,1);\r
 \r
-                       o = DOM.get(o);\r
+                               if ( left.substr( left.length - 1 ) === "\\" ) {\r
+                                       continue;\r
+                               }\r
 \r
-                       if (!o)\r
-                               return;\r
+                               if ( curLoop === result ) {\r
+                                       result = [];\r
+                               }\r
 \r
-                       // Setup event callback\r
-                       cb = function(e) {\r
-                               // Is all events disabled\r
-                               if (t.disabled)\r
-                                       return;\r
+                               if ( Expr.preFilter[ type ] ) {\r
+                                       match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );\r
 \r
-                               e = e || window.event;\r
+                                       if ( !match ) {\r
+                                               anyFound = found = true;\r
+                                       } else if ( match === true ) {\r
+                                               continue;\r
+                                       }\r
+                               }\r
 \r
-                               // Patch in target, preventDefault and stopPropagation in IE it's W3C valid\r
-                               if (e && isIE) {\r
-                                       if (!e.target)\r
-                                               e.target = e.srcElement;\r
+                               if ( match ) {\r
+                                       for ( var i = 0; (item = curLoop[i]) != null; i++ ) {\r
+                                               if ( item ) {\r
+                                                       found = filter( item, match, i, curLoop );\r
+                                                       var pass = not ^ !!found;\r
 \r
-                                       // Patch in preventDefault, stopPropagation methods for W3C compatibility\r
-                                       tinymce.extend(e, t._stoppers);\r
+                                                       if ( inplace && found != null ) {\r
+                                                               if ( pass ) {\r
+                                                                       anyFound = true;\r
+                                                               } else {\r
+                                                                       curLoop[i] = false;\r
+                                                               }\r
+                                                       } else if ( pass ) {\r
+                                                               result.push( item );\r
+                                                               anyFound = true;\r
+                                                       }\r
+                                               }\r
+                                       }\r
                                }\r
 \r
-                               if (!s)\r
-                                       return f(e);\r
+                               if ( found !== undefined ) {\r
+                                       if ( !inplace ) {\r
+                                               curLoop = result;\r
+                                       }\r
 \r
-                               return f.call(s, e);\r
-                       };\r
+                                       expr = expr.replace( Expr.match[ type ], "" );\r
 \r
-                       if (n == 'unload') {\r
-                               tinymce.unloads.unshift({func : cb});\r
-                               return cb;\r
-                       }\r
+                                       if ( !anyFound ) {\r
+                                               return [];\r
+                                       }\r
 \r
-                       if (n == 'init') {\r
-                               if (t.domLoaded)\r
-                                       cb();\r
-                               else\r
-                                       t.inits.push(cb);\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
 \r
-                               return cb;\r
+               // Improper expression\r
+               if ( expr === old ) {\r
+                       if ( anyFound == null ) {\r
+                               Sizzle.error( expr );\r
+                       } else {\r
+                               break;\r
                        }\r
+               }\r
 \r
-                       // Store away listener reference\r
-                       el.push({\r
-                               obj : o,\r
-                               name : n,\r
-                               func : f,\r
-                               cfunc : cb,\r
-                               scope : s\r
-                       });\r
+               old = expr;\r
+       }\r
 \r
-                       t._add(o, n, cb);\r
+       return curLoop;\r
+};\r
 \r
-                       return f;\r
-               },\r
+Sizzle.error = function( msg ) {\r
+       throw "Syntax error, unrecognized expression: " + msg;\r
+};\r
 \r
-               remove : function(o, n, f) {\r
-                       var t = this, a = t.events, s = false, r;\r
+var Expr = Sizzle.selectors = {\r
+       order: [ "ID", "NAME", "TAG" ],\r
+       match: {\r
+               ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,\r
+               CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,\r
+               NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,\r
+               ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,\r
+               TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,\r
+               CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,\r
+               POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,\r
+               PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/\r
+       },\r
+       leftMatch: {},\r
+       attrMap: {\r
+               "class": "className",\r
+               "for": "htmlFor"\r
+       },\r
+       attrHandle: {\r
+               href: function(elem){\r
+                       return elem.getAttribute("href");\r
+               }\r
+       },\r
+       relative: {\r
+               "+": function(checkSet, part){\r
+                       var isPartStr = typeof part === "string",\r
+                               isTag = isPartStr && !/\W/.test(part),\r
+                               isPartStrNotTag = isPartStr && !isTag;\r
 \r
-                       // Handle array\r
-                       if (o && o.hasOwnProperty && o instanceof Array) {\r
-                               r = [];\r
+                       if ( isTag ) {\r
+                               part = part.toLowerCase();\r
+                       }\r
 \r
-                               each(o, function(o) {\r
-                                       o = DOM.get(o);\r
-                                       r.push(t.remove(o, n, f));\r
-                               });\r
+                       for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {\r
+                               if ( (elem = checkSet[i]) ) {\r
+                                       while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}\r
 \r
-                               return r;\r
+                                       checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?\r
+                                               elem || false :\r
+                                               elem === part;\r
+                               }\r
                        }\r
 \r
-                       o = DOM.get(o);\r
+                       if ( isPartStrNotTag ) {\r
+                               Sizzle.filter( part, checkSet, true );\r
+                       }\r
+               },\r
+               ">": function(checkSet, part){\r
+                       var isPartStr = typeof part === "string",\r
+                               elem, i = 0, l = checkSet.length;\r
 \r
-                       each(a, function(e, i) {\r
-                               if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {\r
-                                       a.splice(i, 1);\r
-                                       t._remove(o, n, e.cfunc);\r
-                                       s = true;\r
-                                       return false;\r
+                       if ( isPartStr && !/\W/.test(part) ) {\r
+                               part = part.toLowerCase();\r
+\r
+                               for ( ; i < l; i++ ) {\r
+                                       elem = checkSet[i];\r
+                                       if ( elem ) {\r
+                                               var parent = elem.parentNode;\r
+                                               checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               for ( ; i < l; i++ ) {\r
+                                       elem = checkSet[i];\r
+                                       if ( elem ) {\r
+                                               checkSet[i] = isPartStr ?\r
+                                                       elem.parentNode :\r
+                                                       elem.parentNode === part;\r
+                                       }\r
                                }\r
-                       });\r
 \r
-                       return s;\r
+                               if ( isPartStr ) {\r
+                                       Sizzle.filter( part, checkSet, true );\r
+                               }\r
+                       }\r
                },\r
+               "": function(checkSet, part, isXML){\r
+                       var doneName = done++, checkFn = dirCheck, nodeCheck;\r
 \r
-               clear : function(o) {\r
-                       var t = this, a = t.events, i, e;\r
+                       if ( typeof part === "string" && !/\W/.test(part) ) {\r
+                               part = part.toLowerCase();\r
+                               nodeCheck = part;\r
+                               checkFn = dirNodeCheck;\r
+                       }\r
 \r
-                       if (o) {\r
-                               o = DOM.get(o);\r
+                       checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);\r
+               },\r
+               "~": function(checkSet, part, isXML){\r
+                       var doneName = done++, checkFn = dirCheck, nodeCheck;\r
 \r
-                               for (i = a.length - 1; i >= 0; i--) {\r
-                                       e = a[i];\r
+                       if ( typeof part === "string" && !/\W/.test(part) ) {\r
+                               part = part.toLowerCase();\r
+                               nodeCheck = part;\r
+                               checkFn = dirNodeCheck;\r
+                       }\r
 \r
-                                       if (e.obj === o) {\r
-                                               t._remove(e.obj, e.name, e.cfunc);\r
-                                               e.obj = e.cfunc = null;\r
-                                               a.splice(i, 1);\r
+                       checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);\r
+               }\r
+       },\r
+       find: {\r
+               ID: function(match, context, isXML){\r
+                       if ( typeof context.getElementById !== "undefined" && !isXML ) {\r
+                               var m = context.getElementById(match[1]);\r
+                               return m ? [m] : [];\r
+                       }\r
+               },\r
+               NAME: function(match, context){\r
+                       if ( typeof context.getElementsByName !== "undefined" ) {\r
+                               var ret = [], results = context.getElementsByName(match[1]);\r
+\r
+                               for ( var i = 0, l = results.length; i < l; i++ ) {\r
+                                       if ( results[i].getAttribute("name") === match[1] ) {\r
+                                               ret.push( results[i] );\r
                                        }\r
                                }\r
-                       }\r
-               },\r
-\r
-               cancel : function(e) {\r
-                       if (!e)\r
-                               return false;\r
-\r
-                       this.stop(e);\r
 \r
-                       return this.prevent(e);\r
+                               return ret.length === 0 ? null : ret;\r
+                       }\r
                },\r
+               TAG: function(match, context){\r
+                       return context.getElementsByTagName(match[1]);\r
+               }\r
+       },\r
+       preFilter: {\r
+               CLASS: function(match, curLoop, inplace, result, not, isXML){\r
+                       match = " " + match[1].replace(/\\/g, "") + " ";\r
 \r
-               stop : function(e) {\r
-                       if (e.stopPropagation)\r
-                               e.stopPropagation();\r
-                       else\r
-                               e.cancelBubble = true;\r
-\r
-                       return false;\r
-               },\r
+                       if ( isXML ) {\r
+                               return match;\r
+                       }\r
 \r
-               prevent : function(e) {\r
-                       if (e.preventDefault)\r
-                               e.preventDefault();\r
-                       else\r
-                               e.returnValue = false;\r
+                       for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {\r
+                               if ( elem ) {\r
+                                       if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {\r
+                                               if ( !inplace ) {\r
+                                                       result.push( elem );\r
+                                               }\r
+                                       } else if ( inplace ) {\r
+                                               curLoop[i] = false;\r
+                                       }\r
+                               }\r
+                       }\r
 \r
                        return false;\r
                },\r
-\r
-               destroy : function() {\r
-                       var t = this;\r
-\r
-                       each(t.events, function(e, i) {\r
-                               t._remove(e.obj, e.name, e.cfunc);\r
-                               e.obj = e.cfunc = null;\r
-                       });\r
-\r
-                       t.events = [];\r
-                       t = null;\r
+               ID: function(match){\r
+                       return match[1].replace(/\\/g, "");\r
                },\r
-\r
-               _add : function(o, n, f) {\r
-                       if (o.attachEvent)\r
-                               o.attachEvent('on' + n, f);\r
-                       else if (o.addEventListener)\r
-                               o.addEventListener(n, f, false);\r
-                       else\r
-                               o['on' + n] = f;\r
+               TAG: function(match, curLoop){\r
+                       return match[1].toLowerCase();\r
                },\r
+               CHILD: function(match){\r
+                       if ( match[1] === "nth" ) {\r
+                               // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'\r
+                               var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(\r
+                                       match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||\r
+                                       !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);\r
 \r
-               _remove : function(o, n, f) {\r
-                       if (o) {\r
-                               try {\r
-                                       if (o.detachEvent)\r
-                                               o.detachEvent('on' + n, f);\r
-                                       else if (o.removeEventListener)\r
-                                               o.removeEventListener(n, f, false);\r
-                                       else\r
-                                               o['on' + n] = null;\r
-                               } catch (ex) {\r
-                                       // Might fail with permission denined on IE so we just ignore that\r
-                               }\r
+                               // calculate the numbers (first)n+(last) including if they are negative\r
+                               match[2] = (test[1] + (test[2] || 1)) - 0;\r
+                               match[3] = test[3] - 0;\r
                        }\r
-               },\r
-\r
-               _pageInit : function(win) {\r
-                       var t = this;\r
 \r
-                       // Keep it from running more than once\r
-                       if (t.domLoaded)\r
-                               return;\r
-\r
-                       t.domLoaded = true;\r
-\r
-                       each(t.inits, function(c) {\r
-                               c();\r
-                       });\r
+                       // TODO: Move to normal caching system\r
+                       match[0] = done++;\r
 \r
-                       t.inits = [];\r
+                       return match;\r
                },\r
+               ATTR: function(match, curLoop, inplace, result, not, isXML){\r
+                       var name = match[1].replace(/\\/g, "");\r
+                       \r
+                       if ( !isXML && Expr.attrMap[name] ) {\r
+                               match[1] = Expr.attrMap[name];\r
+                       }\r
 \r
-               _wait : function(win) {\r
-                       var t = this, doc = win.document;\r
-\r
-                       // No need since the document is already loaded\r
-                       if (win.tinyMCE_GZ && tinyMCE_GZ.loaded) {\r
-                               t.domLoaded = 1;\r
-                               return;\r
+                       if ( match[2] === "~=" ) {\r
+                               match[4] = " " + match[4] + " ";\r
                        }\r
 \r
-                       // Use IE method\r
-                       if (doc.attachEvent) {\r
-                               doc.attachEvent("onreadystatechange", function() {\r
-                                       if (doc.readyState === "complete") {\r
-                                               doc.detachEvent("onreadystatechange", arguments.callee);\r
-                                               t._pageInit(win);\r
+                       return match;\r
+               },\r
+               PSEUDO: function(match, curLoop, inplace, result, not){\r
+                       if ( match[1] === "not" ) {\r
+                               // If we're dealing with a complex expression, or a simple one\r
+                               if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {\r
+                                       match[3] = Sizzle(match[3], null, null, curLoop);\r
+                               } else {\r
+                                       var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);\r
+                                       if ( !inplace ) {\r
+                                               result.push.apply( result, ret );\r
                                        }\r
-                               });\r
-\r
-                               if (doc.documentElement.doScroll && win == win.top) {\r
-                                       (function() {\r
-                                               if (t.domLoaded)\r
-                                                       return;\r
+                                       return false;\r
+                               }\r
+                       } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {\r
+                               return true;\r
+                       }\r
+                       \r
+                       return match;\r
+               },\r
+               POS: function(match){\r
+                       match.unshift( true );\r
+                       return match;\r
+               }\r
+       },\r
+       filters: {\r
+               enabled: function(elem){\r
+                       return elem.disabled === false && elem.type !== "hidden";\r
+               },\r
+               disabled: function(elem){\r
+                       return elem.disabled === true;\r
+               },\r
+               checked: function(elem){\r
+                       return elem.checked === true;\r
+               },\r
+               selected: function(elem){\r
+                       // Accessing this property makes selected-by-default\r
+                       // options in Safari work properly\r
+                       elem.parentNode.selectedIndex;\r
+                       return elem.selected === true;\r
+               },\r
+               parent: function(elem){\r
+                       return !!elem.firstChild;\r
+               },\r
+               empty: function(elem){\r
+                       return !elem.firstChild;\r
+               },\r
+               has: function(elem, i, match){\r
+                       return !!Sizzle( match[3], elem ).length;\r
+               },\r
+               header: function(elem){\r
+                       return (/h\d/i).test( elem.nodeName );\r
+               },\r
+               text: function(elem){\r
+                       return "text" === elem.type;\r
+               },\r
+               radio: function(elem){\r
+                       return "radio" === elem.type;\r
+               },\r
+               checkbox: function(elem){\r
+                       return "checkbox" === elem.type;\r
+               },\r
+               file: function(elem){\r
+                       return "file" === elem.type;\r
+               },\r
+               password: function(elem){\r
+                       return "password" === elem.type;\r
+               },\r
+               submit: function(elem){\r
+                       return "submit" === elem.type;\r
+               },\r
+               image: function(elem){\r
+                       return "image" === elem.type;\r
+               },\r
+               reset: function(elem){\r
+                       return "reset" === elem.type;\r
+               },\r
+               button: function(elem){\r
+                       return "button" === elem.type || elem.nodeName.toLowerCase() === "button";\r
+               },\r
+               input: function(elem){\r
+                       return (/input|select|textarea|button/i).test(elem.nodeName);\r
+               }\r
+       },\r
+       setFilters: {\r
+               first: function(elem, i){\r
+                       return i === 0;\r
+               },\r
+               last: function(elem, i, match, array){\r
+                       return i === array.length - 1;\r
+               },\r
+               even: function(elem, i){\r
+                       return i % 2 === 0;\r
+               },\r
+               odd: function(elem, i){\r
+                       return i % 2 === 1;\r
+               },\r
+               lt: function(elem, i, match){\r
+                       return i < match[3] - 0;\r
+               },\r
+               gt: function(elem, i, match){\r
+                       return i > match[3] - 0;\r
+               },\r
+               nth: function(elem, i, match){\r
+                       return match[3] - 0 === i;\r
+               },\r
+               eq: function(elem, i, match){\r
+                       return match[3] - 0 === i;\r
+               }\r
+       },\r
+       filter: {\r
+               PSEUDO: function(elem, match, i, array){\r
+                       var name = match[1], filter = Expr.filters[ name ];\r
 \r
-                                               try {\r
-                                                       // If IE is used, use the trick by Diego Perini\r
-                                                       // http://javascript.nwbox.com/IEContentLoaded/\r
-                                                       doc.documentElement.doScroll("left");\r
-                                               } catch (ex) {\r
-                                                       setTimeout(arguments.callee, 0);\r
-                                                       return;\r
-                                               }\r
+                       if ( filter ) {\r
+                               return filter( elem, i, match, array );\r
+                       } else if ( name === "contains" ) {\r
+                               return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;\r
+                       } else if ( name === "not" ) {\r
+                               var not = match[3];\r
 \r
-                                               t._pageInit(win);\r
-                                       })();\r
+                               for ( var j = 0, l = not.length; j < l; j++ ) {\r
+                                       if ( not[j] === elem ) {\r
+                                               return false;\r
+                                       }\r
                                }\r
-                       } else if (doc.addEventListener) {\r
-                               t._add(win, 'DOMContentLoaded', function() {\r
-                                       t._pageInit(win);\r
-                               });\r
+\r
+                               return true;\r
+                       } else {\r
+                               Sizzle.error( "Syntax error, unrecognized expression: " + name );\r
                        }\r
+               },\r
+               CHILD: function(elem, match){\r
+                       var type = match[1], node = elem;\r
+                       switch (type) {\r
+                               case 'only':\r
+                               case 'first':\r
+                                       while ( (node = node.previousSibling) )  {\r
+                                               if ( node.nodeType === 1 ) { \r
+                                                       return false; \r
+                                               }\r
+                                       }\r
+                                       if ( type === "first" ) { \r
+                                               return true; \r
+                                       }\r
+                                       node = elem;\r
+                               case 'last':\r
+                                       while ( (node = node.nextSibling) )      {\r
+                                               if ( node.nodeType === 1 ) { \r
+                                                       return false; \r
+                                               }\r
+                                       }\r
+                                       return true;\r
+                               case 'nth':\r
+                                       var first = match[2], last = match[3];\r
 \r
-                       t._add(win, 'load', function() {\r
-                               t._pageInit(win);\r
-                       });\r
+                                       if ( first === 1 && last === 0 ) {\r
+                                               return true;\r
+                                       }\r
+                                       \r
+                                       var doneName = match[0],\r
+                                               parent = elem.parentNode;\r
+       \r
+                                       if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {\r
+                                               var count = 0;\r
+                                               for ( node = parent.firstChild; node; node = node.nextSibling ) {\r
+                                                       if ( node.nodeType === 1 ) {\r
+                                                               node.nodeIndex = ++count;\r
+                                                       }\r
+                                               } \r
+                                               parent.sizcache = doneName;\r
+                                       }\r
+                                       \r
+                                       var diff = elem.nodeIndex - last;\r
+                                       if ( first === 0 ) {\r
+                                               return diff === 0;\r
+                                       } else {\r
+                                               return ( diff % first === 0 && diff / first >= 0 );\r
+                                       }\r
+                       }\r
+               },\r
+               ID: function(elem, match){\r
+                       return elem.nodeType === 1 && elem.getAttribute("id") === match;\r
+               },\r
+               TAG: function(elem, match){\r
+                       return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;\r
+               },\r
+               CLASS: function(elem, match){\r
+                       return (" " + (elem.className || elem.getAttribute("class")) + " ")\r
+                               .indexOf( match ) > -1;\r
                },\r
+               ATTR: function(elem, match){\r
+                       var name = match[1],\r
+                               result = Expr.attrHandle[ name ] ?\r
+                                       Expr.attrHandle[ name ]( elem ) :\r
+                                       elem[ name ] != null ?\r
+                                               elem[ name ] :\r
+                                               elem.getAttribute( name ),\r
+                               value = result + "",\r
+                               type = match[2],\r
+                               check = match[4];\r
 \r
-               _stoppers : {\r
-                       preventDefault :  function() {\r
-                               this.returnValue = false;\r
-                       },\r
+                       return result == null ?\r
+                               type === "!=" :\r
+                               type === "=" ?\r
+                               value === check :\r
+                               type === "*=" ?\r
+                               value.indexOf(check) >= 0 :\r
+                               type === "~=" ?\r
+                               (" " + value + " ").indexOf(check) >= 0 :\r
+                               !check ?\r
+                               value && result !== false :\r
+                               type === "!=" ?\r
+                               value !== check :\r
+                               type === "^=" ?\r
+                               value.indexOf(check) === 0 :\r
+                               type === "$=" ?\r
+                               value.substr(value.length - check.length) === check :\r
+                               type === "|=" ?\r
+                               value === check || value.substr(0, check.length + 1) === check + "-" :\r
+                               false;\r
+               },\r
+               POS: function(elem, match, i, array){\r
+                       var name = match[2], filter = Expr.setFilters[ name ];\r
 \r
-                       stopPropagation : function() {\r
-                               this.cancelBubble = true;\r
+                       if ( filter ) {\r
+                               return filter( elem, i, match, array );\r
                        }\r
                }\r
-       });\r
-\r
-       Event = tinymce.dom.Event = new tinymce.dom.EventUtils();\r
-\r
-       // Dispatch DOM content loaded event for IE and Safari\r
-       Event._wait(window);\r
-\r
-       tinymce.addUnload(function() {\r
-               Event.destroy();\r
-       });\r
-})(tinymce);\r
+       }\r
+};\r
 \r
-(function(tinymce) {\r
-       tinymce.dom.Element = function(id, settings) {\r
-               var t = this, dom, el;\r
+var origPOS = Expr.match.POS,\r
+       fescape = function(all, num){\r
+               return "\\" + (num - 0 + 1);\r
+       };\r
 \r
-               t.settings = settings = settings || {};\r
-               t.id = id;\r
-               t.dom = dom = settings.dom || tinymce.DOM;\r
+for ( var type in Expr.match ) {\r
+       Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );\r
+       Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );\r
+}\r
 \r
-               // Only IE leaks DOM references, this is a lot faster\r
-               if (!tinymce.isIE)\r
-                       el = dom.get(t.id);\r
+var makeArray = function(array, results) {\r
+       array = Array.prototype.slice.call( array, 0 );\r
 \r
-               tinymce.each(\r
-                               ('getPos,getRect,getParent,add,setStyle,getStyle,setStyles,' + \r
-                               'setAttrib,setAttribs,getAttrib,addClass,removeClass,' + \r
-                               'hasClass,getOuterHTML,setOuterHTML,remove,show,hide,' + \r
-                               'isHidden,setHTML,get').split(/,/)\r
-                       , function(k) {\r
-                               t[k] = function() {\r
-                                       var a = [id], i;\r
+       if ( results ) {\r
+               results.push.apply( results, array );\r
+               return results;\r
+       }\r
+       \r
+       return array;\r
+};\r
 \r
-                                       for (i = 0; i < arguments.length; i++)\r
-                                               a.push(arguments[i]);\r
+// Perform a simple check to determine if the browser is capable of\r
+// converting a NodeList to an array using builtin methods.\r
+// Also verifies that the returned array holds DOM nodes\r
+// (which is not the case in the Blackberry browser)\r
+try {\r
+       Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;\r
 \r
-                                       a = dom[k].apply(dom, a);\r
-                                       t.update(k);\r
+// Provide a fallback method if it does not work\r
+} catch(e){\r
+       makeArray = function(array, results) {\r
+               var ret = results || [], i = 0;\r
 \r
-                                       return a;\r
-                               };\r
-               });\r
+               if ( toString.call(array) === "[object Array]" ) {\r
+                       Array.prototype.push.apply( ret, array );\r
+               } else {\r
+                       if ( typeof array.length === "number" ) {\r
+                               for ( var l = array.length; i < l; i++ ) {\r
+                                       ret.push( array[i] );\r
+                               }\r
+                       } else {\r
+                               for ( ; array[i]; i++ ) {\r
+                                       ret.push( array[i] );\r
+                               }\r
+                       }\r
+               }\r
 \r
-               tinymce.extend(t, {\r
-                       on : function(n, f, s) {\r
-                               return tinymce.dom.Event.add(t.id, n, f, s);\r
-                       },\r
+               return ret;\r
+       };\r
+}\r
 \r
-                       getXY : function() {\r
-                               return {\r
-                                       x : parseInt(t.getStyle('left')),\r
-                                       y : parseInt(t.getStyle('top'))\r
-                               };\r
-                       },\r
+var sortOrder;\r
 \r
-                       getSize : function() {\r
-                               var n = dom.get(t.id);\r
+if ( document.documentElement.compareDocumentPosition ) {\r
+       sortOrder = function( a, b ) {\r
+               if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {\r
+                       if ( a == b ) {\r
+                               hasDuplicate = true;\r
+                       }\r
+                       return a.compareDocumentPosition ? -1 : 1;\r
+               }\r
 \r
-                               return {\r
-                                       w : parseInt(t.getStyle('width') || n.clientWidth),\r
-                                       h : parseInt(t.getStyle('height') || n.clientHeight)\r
-                               };\r
-                       },\r
+               var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;\r
+               if ( ret === 0 ) {\r
+                       hasDuplicate = true;\r
+               }\r
+               return ret;\r
+       };\r
+} else if ( "sourceIndex" in document.documentElement ) {\r
+       sortOrder = function( a, b ) {\r
+               if ( !a.sourceIndex || !b.sourceIndex ) {\r
+                       if ( a == b ) {\r
+                               hasDuplicate = true;\r
+                       }\r
+                       return a.sourceIndex ? -1 : 1;\r
+               }\r
 \r
-                       moveTo : function(x, y) {\r
-                               t.setStyles({left : x, top : y});\r
-                       },\r
+               var ret = a.sourceIndex - b.sourceIndex;\r
+               if ( ret === 0 ) {\r
+                       hasDuplicate = true;\r
+               }\r
+               return ret;\r
+       };\r
+} else if ( document.createRange ) {\r
+       sortOrder = function( a, b ) {\r
+               if ( !a.ownerDocument || !b.ownerDocument ) {\r
+                       if ( a == b ) {\r
+                               hasDuplicate = true;\r
+                       }\r
+                       return a.ownerDocument ? -1 : 1;\r
+               }\r
 \r
-                       moveBy : function(x, y) {\r
-                               var p = t.getXY();\r
+               var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();\r
+               aRange.setStart(a, 0);\r
+               aRange.setEnd(a, 0);\r
+               bRange.setStart(b, 0);\r
+               bRange.setEnd(b, 0);\r
+               var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);\r
+               if ( ret === 0 ) {\r
+                       hasDuplicate = true;\r
+               }\r
+               return ret;\r
+       };\r
+}\r
 \r
-                               t.moveTo(p.x + x, p.y + y);\r
-                       },\r
+// Utility function for retreiving the text value of an array of DOM nodes\r
+Sizzle.getText = function( elems ) {\r
+       var ret = "", elem;\r
 \r
-                       resizeTo : function(w, h) {\r
-                               t.setStyles({width : w, height : h});\r
-                       },\r
+       for ( var i = 0; elems[i]; i++ ) {\r
+               elem = elems[i];\r
 \r
-                       resizeBy : function(w, h) {\r
-                               var s = t.getSize();\r
+               // Get the text from text nodes and CDATA nodes\r
+               if ( elem.nodeType === 3 || elem.nodeType === 4 ) {\r
+                       ret += elem.nodeValue;\r
 \r
-                               t.resizeTo(s.w + w, s.h + h);\r
-                       },\r
+               // Traverse everything else, except comment nodes\r
+               } else if ( elem.nodeType !== 8 ) {\r
+                       ret += Sizzle.getText( elem.childNodes );\r
+               }\r
+       }\r
 \r
-                       update : function(k) {\r
-                               var b;\r
+       return ret;\r
+};\r
 \r
-                               if (tinymce.isIE6 && settings.blocker) {\r
-                                       k = k || '';\r
+// Check to see if the browser returns elements by name when\r
+// querying by getElementById (and provide a workaround)\r
+(function(){\r
+       // We're going to inject a fake input element with a specified name\r
+       var form = document.createElement("div"),\r
+               id = "script" + (new Date()).getTime();\r
+       form.innerHTML = "<a name='" + id + "'/>";\r
 \r
-                                       // Ignore getters\r
-                                       if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0)\r
-                                               return;\r
+       // Inject it into the root element, check its status, and remove it quickly\r
+       var root = document.documentElement;\r
+       root.insertBefore( form, root.firstChild );\r
 \r
-                                       // Remove blocker on remove\r
-                                       if (k == 'remove') {\r
-                                               dom.remove(t.blocker);\r
-                                               return;\r
-                                       }\r
+       // The workaround has to do additional checks after a getElementById\r
+       // Which slows things down for other browsers (hence the branching)\r
+       if ( document.getElementById( id ) ) {\r
+               Expr.find.ID = function(match, context, isXML){\r
+                       if ( typeof context.getElementById !== "undefined" && !isXML ) {\r
+                               var m = context.getElementById(match[1]);\r
+                               return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];\r
+                       }\r
+               };\r
 \r
-                                       if (!t.blocker) {\r
-                                               t.blocker = dom.uniqueId();\r
-                                               b = dom.add(settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'});\r
-                                               dom.setStyle(b, 'opacity', 0);\r
-                                       } else\r
-                                               b = dom.get(t.blocker);\r
+               Expr.filter.ID = function(elem, match){\r
+                       var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");\r
+                       return elem.nodeType === 1 && node && node.nodeValue === match;\r
+               };\r
+       }\r
 \r
-                                       dom.setStyles(b, {\r
-                                               left : t.getStyle('left', 1),\r
-                                               top : t.getStyle('top', 1),\r
-                                               width : t.getStyle('width', 1),\r
-                                               height : t.getStyle('height', 1),\r
-                                               display : t.getStyle('display', 1),\r
-                                               zIndex : parseInt(t.getStyle('zIndex', 1) || 0) - 1\r
-                                       });\r
-                               }\r
-                       }\r
-               });\r
-       };\r
-})(tinymce);\r
+       root.removeChild( form );\r
+       root = form = null; // release memory in IE\r
+})();\r
 \r
-(function(tinymce) {\r
-       function trimNl(s) {\r
-               return s.replace(/[\n\r]+/g, '');\r
-       };\r
+(function(){\r
+       // Check to see if the browser returns only elements\r
+       // when doing getElementsByTagName("*")\r
 \r
-       // Shorten names\r
-       var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;\r
+       // Create a fake element\r
+       var div = document.createElement("div");\r
+       div.appendChild( document.createComment("") );\r
 \r
-       tinymce.create('tinymce.dom.Selection', {\r
-               Selection : function(dom, win, serializer) {\r
-                       var t = this;\r
+       // Make sure no comments are found\r
+       if ( div.getElementsByTagName("*").length > 0 ) {\r
+               Expr.find.TAG = function(match, context){\r
+                       var results = context.getElementsByTagName(match[1]);\r
 \r
-                       t.dom = dom;\r
-                       t.win = win;\r
-                       t.serializer = serializer;\r
+                       // Filter out possible comments\r
+                       if ( match[1] === "*" ) {\r
+                               var tmp = [];\r
 \r
-                       // Add events\r
-                       each([\r
-                               'onBeforeSetContent',\r
-                               'onBeforeGetContent',\r
-                               'onSetContent',\r
-                               'onGetContent'\r
-                       ], function(e) {\r
-                               t[e] = new tinymce.util.Dispatcher(t);\r
-                       });\r
+                               for ( var i = 0; results[i]; i++ ) {\r
+                                       if ( results[i].nodeType === 1 ) {\r
+                                               tmp.push( results[i] );\r
+                                       }\r
+                               }\r
 \r
-                       // No W3C Range support\r
-                       if (!t.win.getSelection)\r
-                               t.tridentSel = new tinymce.dom.TridentSelection(t);\r
+                               results = tmp;\r
+                       }\r
 \r
-                       // Prevent leaks\r
-                       tinymce.addUnload(t.destroy, t);\r
-               },\r
+                       return results;\r
+               };\r
+       }\r
 \r
-               getContent : function(s) {\r
-                       var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;\r
+       // Check to see if an attribute returns normalized href attributes\r
+       div.innerHTML = "<a href='#'></a>";\r
+       if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&\r
+                       div.firstChild.getAttribute("href") !== "#" ) {\r
+               Expr.attrHandle.href = function(elem){\r
+                       return elem.getAttribute("href", 2);\r
+               };\r
+       }\r
 \r
-                       s = s || {};\r
-                       wb = wa = '';\r
-                       s.get = true;\r
-                       s.format = s.format || 'html';\r
-                       t.onBeforeGetContent.dispatch(t, s);\r
+       div = null; // release memory in IE\r
+})();\r
 \r
-                       if (s.format == 'text')\r
-                               return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));\r
+if ( document.querySelectorAll ) {\r
+       (function(){\r
+               var oldSizzle = Sizzle, div = document.createElement("div");\r
+               div.innerHTML = "<p class='TEST'></p>";\r
 \r
-                       if (r.cloneContents) {\r
-                               n = r.cloneContents();\r
+               // Safari can't handle uppercase or unicode characters when\r
+               // in quirks mode.\r
+               if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {\r
+                       return;\r
+               }\r
+       \r
+               Sizzle = function(query, context, extra, seed){\r
+                       context = context || document;\r
 \r
-                               if (n)\r
-                                       e.appendChild(n);\r
-                       } else if (is(r.item) || is(r.htmlText))\r
-                               e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;\r
-                       else\r
-                               e.innerHTML = r.toString();\r
+                       // Only use querySelectorAll on non-XML documents\r
+                       // (ID selectors don't work in non-HTML documents)\r
+                       if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) {\r
+                               try {\r
+                                       return makeArray( context.querySelectorAll(query), extra );\r
+                               } catch(e){}\r
+                       }\r
+               \r
+                       return oldSizzle(query, context, extra, seed);\r
+               };\r
 \r
-                       // Keep whitespace before and after\r
-                       if (/^\s/.test(e.innerHTML))\r
-                               wb = ' ';\r
+               for ( var prop in oldSizzle ) {\r
+                       Sizzle[ prop ] = oldSizzle[ prop ];\r
+               }\r
 \r
-                       if (/\s+$/.test(e.innerHTML))\r
-                               wa = ' ';\r
+               div = null; // release memory in IE\r
+       })();\r
+}\r
 \r
-                       s.getInner = true;\r
+(function(){\r
+       var div = document.createElement("div");\r
 \r
-                       s.content = t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
-                       t.onGetContent.dispatch(t, s);\r
+       div.innerHTML = "<div class='test e'></div><div class='test'></div>";\r
 \r
-                       return s.content;\r
-               },\r
+       // Opera can't find a second classname (in 9.6)\r
+       // Also, make sure that getElementsByClassName actually exists\r
+       if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {\r
+               return;\r
+       }\r
 \r
-               setContent : function(h, s) {\r
-                       var t = this, r = t.getRng(), c, d = t.win.document;\r
+       // Safari caches class attributes, doesn't catch changes (in 3.2)\r
+       div.lastChild.className = "e";\r
+\r
+       if ( div.getElementsByClassName("e").length === 1 ) {\r
+               return;\r
+       }\r
+       \r
+       Expr.order.splice(1, 0, "CLASS");\r
+       Expr.find.CLASS = function(match, context, isXML) {\r
+               if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {\r
+                       return context.getElementsByClassName(match[1]);\r
+               }\r
+       };\r
 \r
-                       s = s || {format : 'html'};\r
-                       s.set = true;\r
-                       h = s.content = t.dom.processHTML(h);\r
+       div = null; // release memory in IE\r
+})();\r
 \r
-                       // Dispatch before set content event\r
-                       t.onBeforeSetContent.dispatch(t, s);\r
-                       h = s.content;\r
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\r
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
+               var elem = checkSet[i];\r
+               if ( elem ) {\r
+                       elem = elem[dir];\r
+                       var match = false;\r
 \r
-                       if (r.insertNode) {\r
-                               // Make caret marker since insertNode places the caret in the beginning of text after insert\r
-                               h += '<span id="__caret">_</span>';\r
+                       while ( elem ) {\r
+                               if ( elem.sizcache === doneName ) {\r
+                                       match = checkSet[elem.sizset];\r
+                                       break;\r
+                               }\r
 \r
-                               // Delete and insert new node\r
-                               \r
-                               if (r.startContainer == d && r.endContainer ==  d) {\r
-                                       // WebKit will fail if the body is empty since the range is then invalid and it can't insert contents\r
-                                       d.body.innerHTML = h;\r
-                               } else {\r
-                                       r.deleteContents();\r
-                                       if (d.body.childNodes.length == 0) {\r
-                                               d.body.innerHTML = h;\r
-                                       } else {\r
-                                               r.insertNode(r.createContextualFragment(h));\r
-                                       }\r
+                               if ( elem.nodeType === 1 && !isXML ){\r
+                                       elem.sizcache = doneName;\r
+                                       elem.sizset = i;\r
                                }\r
 \r
-                               // Move to caret marker\r
-                               c = t.dom.get('__caret');\r
-                               // Make sure we wrap it compleatly, Opera fails with a simple select call\r
-                               r = d.createRange();\r
-                               r.setStartBefore(c);\r
-                               r.setEndBefore(c);\r
-                               t.setRng(r);\r
-\r
-                               // Remove the caret position\r
-                               t.dom.remove('__caret');\r
-                       } else {\r
-                               if (r.item) {\r
-                                       // Delete content and get caret text selection\r
-                                       d.execCommand('Delete', false, null);\r
-                                       r = t.getRng();\r
+                               if ( elem.nodeName.toLowerCase() === cur ) {\r
+                                       match = elem;\r
+                                       break;\r
                                }\r
 \r
-                               r.pasteHTML(h);\r
+                               elem = elem[dir];\r
                        }\r
 \r
-                       // Dispatch set content event\r
-                       t.onSetContent.dispatch(t, s);\r
-               },\r
+                       checkSet[i] = match;\r
+               }\r
+       }\r
+}\r
 \r
-               getStart : function() {\r
-                       var rng = this.getRng(), startElement, parentElement, checkRng, node;\r
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {\r
+       for ( var i = 0, l = checkSet.length; i < l; i++ ) {\r
+               var elem = checkSet[i];\r
+               if ( elem ) {\r
+                       elem = elem[dir];\r
+                       var match = false;\r
 \r
-                       if (rng.duplicate || rng.item) {\r
-                               // Control selection, return first item\r
-                               if (rng.item)\r
-                                       return rng.item(0);\r
+                       while ( elem ) {\r
+                               if ( elem.sizcache === doneName ) {\r
+                                       match = checkSet[elem.sizset];\r
+                                       break;\r
+                               }\r
 \r
-                               // Get start element\r
-                               checkRng = rng.duplicate();\r
-                               checkRng.collapse(1);\r
-                               startElement = checkRng.parentElement();\r
+                               if ( elem.nodeType === 1 ) {\r
+                                       if ( !isXML ) {\r
+                                               elem.sizcache = doneName;\r
+                                               elem.sizset = i;\r
+                                       }\r
+                                       if ( typeof cur !== "string" ) {\r
+                                               if ( elem === cur ) {\r
+                                                       match = true;\r
+                                                       break;\r
+                                               }\r
 \r
-                               // Check if range parent is inside the start element, then return the inner parent element\r
-                               // This will fix issues when a single element is selected, IE would otherwise return the wrong start element\r
-                               parentElement = node = rng.parentElement();\r
-                               while (node = node.parentNode) {\r
-                                       if (node == startElement) {\r
-                                               startElement = parentElement;\r
+                                       } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {\r
+                                               match = elem;\r
                                                break;\r
                                        }\r
                                }\r
 \r
-                               // If start element is body element try to move to the first child if it exists\r
-                               if (startElement && startElement.nodeName == 'BODY')\r
-                                       return startElement.firstChild || startElement;\r
-\r
-                               return startElement;\r
-                       } else {\r
-                               startElement = rng.startContainer;\r
-\r
-                               if (startElement.nodeType == 1 && startElement.hasChildNodes())\r
-                                       startElement = startElement.childNodes[Math.min(startElement.childNodes.length - 1, rng.startOffset)];\r
-\r
-                               if (startElement && startElement.nodeType == 3)\r
-                                       return startElement.parentNode;\r
-\r
-                               return startElement;\r
+                               elem = elem[dir];\r
                        }\r
-               },\r
-\r
-               getEnd : function() {\r
-                       var t = this, r = t.getRng(), e, eo;\r
-\r
-                       if (r.duplicate || r.item) {\r
-                               if (r.item)\r
-                                       return r.item(0);\r
-\r
-                               r = r.duplicate();\r
-                               r.collapse(0);\r
-                               e = r.parentElement();\r
 \r
-                               if (e && e.nodeName == 'BODY')\r
-                                       return e.lastChild || e;\r
+                       checkSet[i] = match;\r
+               }\r
+       }\r
+}\r
 \r
-                               return e;\r
-                       } else {\r
-                               e = r.endContainer;\r
-                               eo = r.endOffset;\r
+Sizzle.contains = document.compareDocumentPosition ? function(a, b){\r
+       return !!(a.compareDocumentPosition(b) & 16);\r
+} : function(a, b){\r
+       return a !== b && (a.contains ? a.contains(b) : true);\r
+};\r
 \r
-                               if (e.nodeType == 1 && e.hasChildNodes())\r
-                                       e = e.childNodes[eo > 0 ? eo - 1 : eo];\r
+Sizzle.isXML = function(elem){\r
+       // documentElement is verified for cases where it doesn't yet exist\r
+       // (such as loading iframes in IE - #4833) \r
+       var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;\r
+       return documentElement ? documentElement.nodeName !== "HTML" : false;\r
+};\r
 \r
-                               if (e && e.nodeType == 3)\r
-                                       return e.parentNode;\r
+var posProcess = function(selector, context){\r
+       var tmpSet = [], later = "", match,\r
+               root = context.nodeType ? [context] : context;\r
 \r
-                               return e;\r
-                       }\r
-               },\r
+       // Position selectors must be done after the filter\r
+       // And so must :not(positional) so we move all PSEUDOs to the end\r
+       while ( (match = Expr.match.PSEUDO.exec( selector )) ) {\r
+               later += match[0];\r
+               selector = selector.replace( Expr.match.PSEUDO, "" );\r
+       }\r
 \r
-               getBookmark : function(type, normalized) {\r
-                       var t = this, dom = t.dom, rng, rng2, id, collapsed, name, element, index, chr = '\uFEFF', styles;\r
+       selector = Expr.relative[selector] ? selector + "*" : selector;\r
 \r
-                       function findIndex(name, element) {\r
-                               var index = 0;\r
+       for ( var i = 0, l = root.length; i < l; i++ ) {\r
+               Sizzle( selector, root[i], tmpSet );\r
+       }\r
 \r
-                               each(dom.select(name), function(node, i) {\r
-                                       if (node == element)\r
-                                               index = i;\r
-                               });\r
+       return Sizzle.filter( later, tmpSet );\r
+};\r
 \r
-                               return index;\r
-                       };\r
+// EXPOSE\r
 \r
-                       if (type == 2) {\r
-                               function getLocation() {\r
-                                       var rng = t.getRng(true), root = dom.getRoot(), bookmark = {};\r
+window.tinymce.dom.Sizzle = Sizzle;\r
 \r
-                                       function getPoint(rng, start) {\r
-                                               var container = rng[start ? 'startContainer' : 'endContainer'],\r
-                                                       offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;\r
+})();\r
 \r
-                                               if (container.nodeType == 3) {\r
-                                                       if (normalized) {\r
-                                                               for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling)\r
-                                                                       offset += node.nodeValue.length;\r
-                                                       }\r
 \r
-                                                       point.push(offset);\r
-                                               } else {\r
-                                                       childNodes = container.childNodes;\r
+(function(tinymce) {\r
+       // Shorten names\r
+       var each = tinymce.each, DOM = tinymce.DOM, isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, Event;\r
 \r
-                                                       if (offset >= childNodes.length && childNodes.length) {\r
-                                                               after = 1;\r
-                                                               offset = Math.max(0, childNodes.length - 1);\r
-                                                       }\r
+       tinymce.create('tinymce.dom.EventUtils', {\r
+               EventUtils : function() {\r
+                       this.inits = [];\r
+                       this.events = [];\r
+               },\r
 \r
-                                                       point.push(t.dom.nodeIndex(childNodes[offset], normalized) + after);\r
-                                               }\r
+               add : function(o, n, f, s) {\r
+                       var cb, t = this, el = t.events, r;\r
 \r
-                                               for (; container && container != root; container = container.parentNode)\r
-                                                       point.push(t.dom.nodeIndex(container, normalized));\r
+                       if (n instanceof Array) {\r
+                               r = [];\r
 \r
-                                               return point;\r
-                                       };\r
+                               each(n, function(n) {\r
+                                       r.push(t.add(o, n, f, s));\r
+                               });\r
 \r
-                                       bookmark.start = getPoint(rng, true);\r
+                               return r;\r
+                       }\r
 \r
-                                       if (!t.isCollapsed())\r
-                                               bookmark.end = getPoint(rng);\r
+                       // Handle array\r
+                       if (o && o.hasOwnProperty && o instanceof Array) {\r
+                               r = [];\r
 \r
-                                       return bookmark;\r
-                               };\r
+                               each(o, function(o) {\r
+                                       o = DOM.get(o);\r
+                                       r.push(t.add(o, n, f, s));\r
+                               });\r
 \r
-                               return getLocation();\r
+                               return r;\r
                        }\r
 \r
-                       // Handle simple range\r
-                       if (type)\r
-                               return {rng : t.getRng()};\r
+                       o = DOM.get(o);\r
 \r
-                       rng = t.getRng();\r
-                       id = dom.uniqueId();\r
-                       collapsed = tinyMCE.activeEditor.selection.isCollapsed();\r
-                       styles = 'overflow:hidden;line-height:0px';\r
+                       if (!o)\r
+                               return;\r
 \r
-                       // Explorer method\r
-                       if (rng.duplicate || rng.item) {\r
-                               // Text selection\r
-                               if (!rng.item) {\r
-                                       rng2 = rng.duplicate();\r
+                       // Setup event callback\r
+                       cb = function(e) {\r
+                               // Is all events disabled\r
+                               if (t.disabled)\r
+                                       return;\r
 \r
-                                       // Insert start marker\r
-                                       rng.collapse();\r
-                                       rng.pasteHTML('<span _mce_type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');\r
+                               e = e || window.event;\r
 \r
-                                       // Insert end marker\r
-                                       if (!collapsed) {\r
-                                               rng2.collapse(false);\r
-                                               rng2.pasteHTML('<span _mce_type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');\r
-                                       }\r
-                               } else {\r
-                                       // Control selection\r
-                                       element = rng.item(0);\r
-                                       name = element.nodeName;\r
+                               // Patch in target, preventDefault and stopPropagation in IE it's W3C valid\r
+                               if (e && isIE) {\r
+                                       if (!e.target)\r
+                                               e.target = e.srcElement;\r
 \r
-                                       return {name : name, index : findIndex(name, element)};\r
+                                       // Patch in preventDefault, stopPropagation methods for W3C compatibility\r
+                                       tinymce.extend(e, t._stoppers);\r
                                }\r
-                       } else {\r
-                               element = t.getNode();\r
-                               name = element.nodeName;\r
-                               if (name == 'IMG')\r
-                                       return {name : name, index : findIndex(name, element)};\r
 \r
-                               // W3C method\r
-                               rng2 = rng.cloneRange();\r
+                               if (!s)\r
+                                       return f(e);\r
 \r
-                               // Insert end marker\r
-                               if (!collapsed) {\r
-                                       rng2.collapse(false);\r
-                                       rng2.insertNode(dom.create('span', {_mce_type : "bookmark", id : id + '_end', style : styles}, chr));\r
-                               }\r
+                               return f.call(s, e);\r
+                       };\r
 \r
-                               rng.collapse(true);\r
-                               rng.insertNode(dom.create('span', {_mce_type : "bookmark", id : id + '_start', style : styles}, chr));\r
+                       if (n == 'unload') {\r
+                               tinymce.unloads.unshift({func : cb});\r
+                               return cb;\r
+                       }\r
+\r
+                       if (n == 'init') {\r
+                               if (t.domLoaded)\r
+                                       cb();\r
+                               else\r
+                                       t.inits.push(cb);\r
+\r
+                               return cb;\r
                        }\r
 \r
-                       t.moveToBookmark({id : id, keep : 1});\r
+                       // Store away listener reference\r
+                       el.push({\r
+                               obj : o,\r
+                               name : n,\r
+                               func : f,\r
+                               cfunc : cb,\r
+                               scope : s\r
+                       });\r
+\r
+                       t._add(o, n, cb);\r
 \r
-                       return {id : id};\r
+                       return f;\r
                },\r
 \r
-               moveToBookmark : function(bookmark) {\r
-                       var t = this, dom = t.dom, marker1, marker2, rng, root, startContainer, endContainer, startOffset, endOffset;\r
+               remove : function(o, n, f) {\r
+                       var t = this, a = t.events, s = false, r;\r
 \r
-                       // Clear selection cache\r
-                       if (t.tridentSel)\r
-                               t.tridentSel.destroy();\r
+                       // Handle array\r
+                       if (o && o.hasOwnProperty && o instanceof Array) {\r
+                               r = [];\r
 \r
-                       if (bookmark) {\r
-                               if (bookmark.start) {\r
-                                       rng = dom.createRng();\r
-                                       root = dom.getRoot();\r
+                               each(o, function(o) {\r
+                                       o = DOM.get(o);\r
+                                       r.push(t.remove(o, n, f));\r
+                               });\r
 \r
-                                       function setEndPoint(start) {\r
-                                               var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;\r
+                               return r;\r
+                       }\r
 \r
-                                               if (point) {\r
-                                                       // Find container node\r
-                                                       for (node = root, i = point.length - 1; i >= 1; i--) {\r
-                                                               children = node.childNodes;\r
+                       o = DOM.get(o);\r
 \r
-                                                               if (children.length)\r
-                                                                       node = children[point[i]];\r
-                                                       }\r
+                       each(a, function(e, i) {\r
+                               if (e.obj == o && e.name == n && (!f || (e.func == f || e.cfunc == f))) {\r
+                                       a.splice(i, 1);\r
+                                       t._remove(o, n, e.cfunc);\r
+                                       s = true;\r
+                                       return false;\r
+                               }\r
+                       });\r
 \r
-                                                       // Set offset within container node\r
-                                                       if (start)\r
-                                                               rng.setStart(node, point[0]);\r
-                                                       else\r
-                                                               rng.setEnd(node, point[0]);\r
-                                               }\r
-                                       };\r
+                       return s;\r
+               },\r
 \r
-                                       setEndPoint(true);\r
-                                       setEndPoint();\r
+               clear : function(o) {\r
+                       var t = this, a = t.events, i, e;\r
 \r
-                                       t.setRng(rng);\r
-                               } else if (bookmark.id) {\r
-                                       function restoreEndPoint(suffix) {\r
-                                               var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;\r
+                       if (o) {\r
+                               o = DOM.get(o);\r
 \r
-                                               if (marker) {\r
-                                                       node = marker.parentNode;\r
+                               for (i = a.length - 1; i >= 0; i--) {\r
+                                       e = a[i];\r
 \r
-                                                       if (suffix == 'start') {\r
-                                                               if (!keep) {\r
-                                                                       idx = dom.nodeIndex(marker);\r
-                                                               } else {\r
-                                                                       node = marker.firstChild;\r
-                                                                       idx = 1;\r
-                                                               }\r
+                                       if (e.obj === o) {\r
+                                               t._remove(e.obj, e.name, e.cfunc);\r
+                                               e.obj = e.cfunc = null;\r
+                                               a.splice(i, 1);\r
+                                       }\r
+                               }\r
+                       }\r
+               },\r
 \r
-                                                               startContainer = endContainer = node;\r
-                                                               startOffset = endOffset = idx;\r
-                                                       } else {\r
-                                                               if (!keep) {\r
-                                                                       idx = dom.nodeIndex(marker);\r
-                                                               } else {\r
-                                                                       node = marker.firstChild;\r
-                                                                       idx = 1;\r
-                                                               }\r
+               cancel : function(e) {\r
+                       if (!e)\r
+                               return false;\r
 \r
-                                                               endContainer = node;\r
-                                                               endOffset = idx;\r
-                                                       }\r
+                       this.stop(e);\r
 \r
-                                                       if (!keep) {\r
-                                                               prev = marker.previousSibling;\r
-                                                               next = marker.nextSibling;\r
+                       return this.prevent(e);\r
+               },\r
 \r
-                                                               // Remove all marker text nodes\r
-                                                               each(tinymce.grep(marker.childNodes), function(node) {\r
-                                                                       if (node.nodeType == 3)\r
-                                                                               node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');\r
-                                                               });\r
+               stop : function(e) {\r
+                       if (e.stopPropagation)\r
+                               e.stopPropagation();\r
+                       else\r
+                               e.cancelBubble = true;\r
 \r
-                                                               // Remove marker but keep children if for example contents where inserted into the marker\r
-                                                               // Also remove duplicated instances of the marker for example by a split operation or by WebKit auto split on paste feature\r
-                                                               while (marker = dom.get(bookmark.id + '_' + suffix))\r
-                                                                       dom.remove(marker, 1);\r
+                       return false;\r
+               },\r
 \r
-                                                               // If siblings are text nodes then merge them\r
-                                                               if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3) {\r
-                                                                       idx = prev.nodeValue.length;\r
-                                                                       prev.appendData(next.nodeValue);\r
-                                                                       dom.remove(next);\r
+               prevent : function(e) {\r
+                       if (e.preventDefault)\r
+                               e.preventDefault();\r
+                       else\r
+                               e.returnValue = false;\r
 \r
-                                                                       if (suffix == 'start') {\r
-                                                                               startContainer = endContainer = prev;\r
-                                                                               startOffset = endOffset = idx;\r
-                                                                       } else {\r
-                                                                               endContainer = prev;\r
-                                                                               endOffset = idx;\r
-                                                                       }\r
-                                                               }\r
-                                                       }\r
-                                               }\r
-                                       };\r
+                       return false;\r
+               },\r
 \r
-                                       function addBogus(node) {\r
-                                               // Adds a bogus BR element for empty block elements\r
-                                               // on non IE browsers just to have a place to put the caret\r
-                                               if (!isIE && dom.isBlock(node) && !node.innerHTML)\r
-                                                       node.innerHTML = '<br _mce_bogus="1" />';\r
+               destroy : function() {\r
+                       var t = this;\r
 \r
-                                               return node;\r
-                                       };\r
+                       each(t.events, function(e, i) {\r
+                               t._remove(e.obj, e.name, e.cfunc);\r
+                               e.obj = e.cfunc = null;\r
+                       });\r
 \r
-                                       // Restore start/end points\r
-                                       restoreEndPoint('start');\r
-                                       restoreEndPoint('end');\r
+                       t.events = [];\r
+                       t = null;\r
+               },\r
 \r
-                                       rng = dom.createRng();\r
-                                       rng.setStart(addBogus(startContainer), startOffset);\r
-                                       rng.setEnd(addBogus(endContainer), endOffset);\r
-                                       t.setRng(rng);\r
-                               } else if (bookmark.name) {\r
-                                       t.select(dom.select(bookmark.name)[bookmark.index]);\r
-                               } else if (bookmark.rng)\r
-                                       t.setRng(bookmark.rng);\r
-                       }\r
+               _add : function(o, n, f) {\r
+                       if (o.attachEvent)\r
+                               o.attachEvent('on' + n, f);\r
+                       else if (o.addEventListener)\r
+                               o.addEventListener(n, f, false);\r
+                       else\r
+                               o['on' + n] = f;\r
                },\r
 \r
-               select : function(node, content) {\r
-                       var t = this, dom = t.dom, rng = dom.createRng(), idx;\r
+               _remove : function(o, n, f) {\r
+                       if (o) {\r
+                               try {\r
+                                       if (o.detachEvent)\r
+                                               o.detachEvent('on' + n, f);\r
+                                       else if (o.removeEventListener)\r
+                                               o.removeEventListener(n, f, false);\r
+                                       else\r
+                                               o['on' + n] = null;\r
+                               } catch (ex) {\r
+                                       // Might fail with permission denined on IE so we just ignore that\r
+                               }\r
+                       }\r
+               },\r
 \r
-                       idx = dom.nodeIndex(node);\r
-                       rng.setStart(node.parentNode, idx);\r
-                       rng.setEnd(node.parentNode, idx + 1);\r
+               _pageInit : function(win) {\r
+                       var t = this;\r
 \r
-                       // Find first/last text node or BR element\r
-                       if (content) {\r
-                               function setPoint(node, start) {\r
-                                       var walker = new tinymce.dom.TreeWalker(node, node);\r
+                       // Keep it from running more than once\r
+                       if (t.domLoaded)\r
+                               return;\r
 \r
-                                       do {\r
-                                               // Text node\r
-                                               if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length != 0) {\r
-                                                       if (start)\r
-                                                               rng.setStart(node, 0);\r
-                                                       else\r
-                                                               rng.setEnd(node, node.nodeValue.length);\r
+                       t.domLoaded = true;\r
 \r
-                                                       return;\r
-                                               }\r
+                       each(t.inits, function(c) {\r
+                               c();\r
+                       });\r
 \r
-                                               // BR element\r
-                                               if (node.nodeName == 'BR') {\r
-                                                       if (start)\r
-                                                               rng.setStartBefore(node);\r
-                                                       else\r
-                                                               rng.setEndBefore(node);\r
+                       t.inits = [];\r
+               },\r
 \r
-                                                       return;\r
-                                               }\r
-                                       } while (node = (start ? walker.next() : walker.prev()));\r
-                               };\r
+               _wait : function(win) {\r
+                       var t = this, doc = win.document;\r
 \r
-                               setPoint(node, 1);\r
-                               setPoint(node);\r
+                       // No need since the document is already loaded\r
+                       if (win.tinyMCE_GZ && tinyMCE_GZ.loaded) {\r
+                               t.domLoaded = 1;\r
+                               return;\r
                        }\r
 \r
-                       t.setRng(rng);\r
-\r
-                       return node;\r
-               },\r
+                       // Use IE method\r
+                       if (doc.attachEvent) {\r
+                               doc.attachEvent("onreadystatechange", function() {\r
+                                       if (doc.readyState === "complete") {\r
+                                               doc.detachEvent("onreadystatechange", arguments.callee);\r
+                                               t._pageInit(win);\r
+                                       }\r
+                               });\r
 \r
-               isCollapsed : function() {\r
-                       var t = this, r = t.getRng(), s = t.getSel();\r
+                               if (doc.documentElement.doScroll && win == win.top) {\r
+                                       (function() {\r
+                                               if (t.domLoaded)\r
+                                                       return;\r
 \r
-                       if (!r || r.item)\r
-                               return false;\r
+                                               try {\r
+                                                       // If IE is used, use the trick by Diego Perini\r
+                                                       // http://javascript.nwbox.com/IEContentLoaded/\r
+                                                       doc.documentElement.doScroll("left");\r
+                                               } catch (ex) {\r
+                                                       setTimeout(arguments.callee, 0);\r
+                                                       return;\r
+                                               }\r
 \r
-                       if (r.compareEndPoints)\r
-                               return r.compareEndPoints('StartToEnd', r) === 0;\r
+                                               t._pageInit(win);\r
+                                       })();\r
+                               }\r
+                       } else if (doc.addEventListener) {\r
+                               t._add(win, 'DOMContentLoaded', function() {\r
+                                       t._pageInit(win);\r
+                               });\r
+                       }\r
 \r
-                       return !s || r.collapsed;\r
+                       t._add(win, 'load', function() {\r
+                               t._pageInit(win);\r
+                       });\r
                },\r
 \r
-               collapse : function(b) {\r
-                       var t = this, r = t.getRng(), n;\r
+               _stoppers : {\r
+                       preventDefault : function() {\r
+                               this.returnValue = false;\r
+                       },\r
 \r
-                       // Control range on IE\r
-                       if (r.item) {\r
-                               n = r.item(0);\r
-                               r = this.win.document.body.createTextRange();\r
-                               r.moveToElementText(n);\r
+                       stopPropagation : function() {\r
+                               this.cancelBubble = true;\r
                        }\r
+               }\r
+       });\r
 \r
-                       r.collapse(!!b);\r
-                       t.setRng(r);\r
-               },\r
-\r
-               getSel : function() {\r
-                       var t = this, w = this.win;\r
+       Event = tinymce.dom.Event = new tinymce.dom.EventUtils();\r
 \r
-                       return w.getSelection ? w.getSelection() : w.document.selection;\r
-               },\r
+       // Dispatch DOM content loaded event for IE and Safari\r
+       Event._wait(window);\r
 \r
-               getRng : function(w3c) {\r
-                       var t = this, s, r;\r
+       tinymce.addUnload(function() {\r
+               Event.destroy();\r
+       });\r
+})(tinymce);\r
 \r
-                       // Found tridentSel object then we need to use that one\r
-                       if (w3c && t.tridentSel)\r
-                               return t.tridentSel.getRangeAt(0);\r
+(function(tinymce) {\r
+       tinymce.dom.Element = function(id, settings) {\r
+               var t = this, dom, el;\r
 \r
-                       try {\r
-                               if (s = t.getSel())\r
-                                       r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : t.win.document.createRange());\r
-                       } catch (ex) {\r
-                               // IE throws unspecified error here if TinyMCE is placed in a frame/iframe\r
-                       }\r
+               t.settings = settings = settings || {};\r
+               t.id = id;\r
+               t.dom = dom = settings.dom || tinymce.DOM;\r
 \r
-                       // No range found then create an empty one\r
-                       // This can occur when the editor is placed in a hidden container element on Gecko\r
-                       // Or on IE when there was an exception\r
-                       if (!r)\r
-                               r = t.win.document.createRange ? t.win.document.createRange() : t.win.document.body.createTextRange();\r
+               // Only IE leaks DOM references, this is a lot faster\r
+               if (!tinymce.isIE)\r
+                       el = dom.get(t.id);\r
 \r
-                       if (t.selectedRange && t.explicitRange) {\r
-                               if (r.compareBoundaryPoints(r.START_TO_START, t.selectedRange) === 0 && r.compareBoundaryPoints(r.END_TO_END, t.selectedRange) === 0) {\r
-                                       // Safari, Opera and Chrome only ever select text which causes the range to change.\r
-                                       // This lets us use the originally set range if the selection hasn't been changed by the user.\r
-                                       r = t.explicitRange;\r
-                               } else {\r
-                                       t.selectedRange = null;\r
-                                       t.explicitRange = null;\r
-                               }\r
-                       }\r
-                       return r;\r
-               },\r
+               tinymce.each(\r
+                               ('getPos,getRect,getParent,add,setStyle,getStyle,setStyles,' + \r
+                               'setAttrib,setAttribs,getAttrib,addClass,removeClass,' + \r
+                               'hasClass,getOuterHTML,setOuterHTML,remove,show,hide,' + \r
+                               'isHidden,setHTML,get').split(/,/)\r
+                       , function(k) {\r
+                               t[k] = function() {\r
+                                       var a = [id], i;\r
 \r
-               setRng : function(r) {\r
-                       var s, t = this;\r
-                       \r
-                       if (!t.tridentSel) {\r
-                               s = t.getSel();\r
+                                       for (i = 0; i < arguments.length; i++)\r
+                                               a.push(arguments[i]);\r
 \r
-                               if (s) {\r
-                                       t.explicitRange = r;\r
-                                       s.removeAllRanges();\r
-                                       s.addRange(r);\r
-                                       t.selectedRange = s.getRangeAt(0);\r
-                               }\r
-                       } else {\r
-                               // Is W3C Range\r
-                               if (r.cloneRange) {\r
-                                       t.tridentSel.addRange(r);\r
-                                       return;\r
-                               }\r
+                                       a = dom[k].apply(dom, a);\r
+                                       t.update(k);\r
 \r
-                               // Is IE specific range\r
-                               try {\r
-                                       r.select();\r
-                               } catch (ex) {\r
-                                       // Needed for some odd IE bug #1843306\r
-                               }\r
-                       }\r
-               },\r
+                                       return a;\r
+                               };\r
+               });\r
 \r
-               setNode : function(n) {\r
-                       var t = this;\r
+               tinymce.extend(t, {\r
+                       on : function(n, f, s) {\r
+                               return tinymce.dom.Event.add(t.id, n, f, s);\r
+                       },\r
 \r
-                       t.setContent(t.dom.getOuterHTML(n));\r
+                       getXY : function() {\r
+                               return {\r
+                                       x : parseInt(t.getStyle('left')),\r
+                                       y : parseInt(t.getStyle('top'))\r
+                               };\r
+                       },\r
 \r
-                       return n;\r
-               },\r
+                       getSize : function() {\r
+                               var n = dom.get(t.id);\r
 \r
-               getNode : function() {\r
-                       var t = this, rng = t.getRng(), sel = t.getSel(), elm;\r
+                               return {\r
+                                       w : parseInt(t.getStyle('width') || n.clientWidth),\r
+                                       h : parseInt(t.getStyle('height') || n.clientHeight)\r
+                               };\r
+                       },\r
 \r
-                       if (rng.setStart) {\r
-                               // Range maybe lost after the editor is made visible again\r
-                               if (!rng)\r
-                                       return t.dom.getRoot();\r
+                       moveTo : function(x, y) {\r
+                               t.setStyles({left : x, top : y});\r
+                       },\r
 \r
-                               elm = rng.commonAncestorContainer;\r
+                       moveBy : function(x, y) {\r
+                               var p = t.getXY();\r
 \r
-                               // Handle selection a image or other control like element such as anchors\r
-                               if (!rng.collapsed) {\r
-                                       if (rng.startContainer == rng.endContainer) {\r
-                                               if (rng.startOffset - rng.endOffset < 2) {\r
-                                                       if (rng.startContainer.hasChildNodes())\r
-                                                               elm = rng.startContainer.childNodes[rng.startOffset];\r
-                                               }\r
-                                       }\r
+                               t.moveTo(p.x + x, p.y + y);\r
+                       },\r
 \r
-                                       // If the anchor node is a element instead of a text node then return this element\r
-                                       if (tinymce.isWebKit && sel.anchorNode && sel.anchorNode.nodeType == 1) \r
-                                               return sel.anchorNode.childNodes[sel.anchorOffset]; \r
-                               }\r
+                       resizeTo : function(w, h) {\r
+                               t.setStyles({width : w, height : h});\r
+                       },\r
 \r
-                               if (elm && elm.nodeType == 3)\r
-                                       return elm.parentNode;\r
+                       resizeBy : function(w, h) {\r
+                               var s = t.getSize();\r
 \r
-                               return elm;\r
-                       }\r
+                               t.resizeTo(s.w + w, s.h + h);\r
+                       },\r
 \r
-                       return rng.item ? rng.item(0) : rng.parentElement();\r
-               },\r
+                       update : function(k) {\r
+                               var b;\r
 \r
-               getSelectedBlocks : function(st, en) {\r
-                       var t = this, dom = t.dom, sb, eb, n, bl = [];\r
+                               if (tinymce.isIE6 && settings.blocker) {\r
+                                       k = k || '';\r
 \r
-                       sb = dom.getParent(st || t.getStart(), dom.isBlock);\r
-                       eb = dom.getParent(en || t.getEnd(), dom.isBlock);\r
+                                       // Ignore getters\r
+                                       if (k.indexOf('get') === 0 || k.indexOf('has') === 0 || k.indexOf('is') === 0)\r
+                                               return;\r
 \r
-                       if (sb)\r
-                               bl.push(sb);\r
+                                       // Remove blocker on remove\r
+                                       if (k == 'remove') {\r
+                                               dom.remove(t.blocker);\r
+                                               return;\r
+                                       }\r
 \r
-                       if (sb && eb && sb != eb) {\r
-                               n = sb;\r
+                                       if (!t.blocker) {\r
+                                               t.blocker = dom.uniqueId();\r
+                                               b = dom.add(settings.container || dom.getRoot(), 'iframe', {id : t.blocker, style : 'position:absolute;', frameBorder : 0, src : 'javascript:""'});\r
+                                               dom.setStyle(b, 'opacity', 0);\r
+                                       } else\r
+                                               b = dom.get(t.blocker);\r
 \r
-                               while ((n = n.nextSibling) && n != eb) {\r
-                                       if (dom.isBlock(n))\r
-                                               bl.push(n);\r
+                                       dom.setStyles(b, {\r
+                                               left : t.getStyle('left', 1),\r
+                                               top : t.getStyle('top', 1),\r
+                                               width : t.getStyle('width', 1),\r
+                                               height : t.getStyle('height', 1),\r
+                                               display : t.getStyle('display', 1),\r
+                                               zIndex : parseInt(t.getStyle('zIndex', 1) || 0) - 1\r
+                                       });\r
                                }\r
                        }\r
+               });\r
+       };\r
+})(tinymce);\r
 \r
-                       if (eb && sb != eb)\r
-                               bl.push(eb);\r
+(function(tinymce) {\r
+       function trimNl(s) {\r
+               return s.replace(/[\n\r]+/g, '');\r
+       };\r
 \r
-                       return bl;\r
-               },\r
+       // Shorten names\r
+       var is = tinymce.is, isIE = tinymce.isIE, each = tinymce.each;\r
 \r
-               destroy : function(s) {\r
+       tinymce.create('tinymce.dom.Selection', {\r
+               Selection : function(dom, win, serializer) {\r
                        var t = this;\r
 \r
-                       t.win = null;\r
+                       t.dom = dom;\r
+                       t.win = win;\r
+                       t.serializer = serializer;\r
 \r
-                       if (t.tridentSel)\r
-                               t.tridentSel.destroy();\r
+                       // Add events\r
+                       each([\r
+                               'onBeforeSetContent',\r
 \r
-                       // Manual destroy then remove unload handler\r
-                       if (!s)\r
-                               tinymce.removeUnload(t.destroy);\r
-               }\r
-       });\r
-})(tinymce);\r
+                               'onBeforeGetContent',\r
 \r
-(function(tinymce) {\r
-       tinymce.create('tinymce.dom.XMLWriter', {\r
-               node : null,\r
-\r
-               XMLWriter : function(s) {\r
-                       // Get XML document\r
-                       function getXML() {\r
-                               var i = document.implementation;\r
-\r
-                               if (!i || !i.createDocument) {\r
-                                       // Try IE objects\r
-                                       try {return new ActiveXObject('MSXML2.DOMDocument');} catch (ex) {}\r
-                                       try {return new ActiveXObject('Microsoft.XmlDom');} catch (ex) {}\r
-                               } else\r
-                                       return i.createDocument('', '', null);\r
-                       };\r
+                               'onSetContent',\r
 \r
-                       this.doc = getXML();\r
-                       \r
-                       // Since Opera and WebKit doesn't escape > into &gt; we need to do it our self to normalize the output for all browsers\r
-                       this.valid = tinymce.isOpera || tinymce.isWebKit;\r
+                               'onGetContent'\r
+                       ], function(e) {\r
+                               t[e] = new tinymce.util.Dispatcher(t);\r
+                       });\r
+\r
+                       // No W3C Range support\r
+                       if (!t.win.getSelection)\r
+                               t.tridentSel = new tinymce.dom.TridentSelection(t);\r
+\r
+                       if (tinymce.isIE && dom.boxModel)\r
+                               this._fixIESelection();\r
 \r
-                       this.reset();\r
+                       // Prevent leaks\r
+                       tinymce.addUnload(t.destroy, t);\r
                },\r
 \r
-               reset : function() {\r
-                       var t = this, d = t.doc;\r
+               getContent : function(s) {\r
+                       var t = this, r = t.getRng(), e = t.dom.create("body"), se = t.getSel(), wb, wa, n;\r
 \r
-                       if (d.firstChild)\r
-                               d.removeChild(d.firstChild);\r
+                       s = s || {};\r
+                       wb = wa = '';\r
+                       s.get = true;\r
+                       s.format = s.format || 'html';\r
+                       t.onBeforeGetContent.dispatch(t, s);\r
 \r
-                       t.node = d.appendChild(d.createElement("html"));\r
-               },\r
+                       if (s.format == 'text')\r
+                               return t.isCollapsed() ? '' : (r.text || (se.toString ? se.toString() : ''));\r
 \r
-               writeStartElement : function(n) {\r
-                       var t = this;\r
+                       if (r.cloneContents) {\r
+                               n = r.cloneContents();\r
 \r
-                       t.node = t.node.appendChild(t.doc.createElement(n));\r
-               },\r
+                               if (n)\r
+                                       e.appendChild(n);\r
+                       } else if (is(r.item) || is(r.htmlText))\r
+                               e.innerHTML = r.item ? r.item(0).outerHTML : r.htmlText;\r
+                       else\r
+                               e.innerHTML = r.toString();\r
 \r
-               writeAttribute : function(n, v) {\r
-                       if (this.valid)\r
-                               v = v.replace(/>/g, '%MCGT%');\r
+                       // Keep whitespace before and after\r
+                       if (/^\s/.test(e.innerHTML))\r
+                               wb = ' ';\r
 \r
-                       this.node.setAttribute(n, v);\r
-               },\r
+                       if (/\s+$/.test(e.innerHTML))\r
+                               wa = ' ';\r
 \r
-               writeEndElement : function() {\r
-                       this.node = this.node.parentNode;\r
-               },\r
+                       s.getInner = true;\r
 \r
-               writeFullEndElement : function() {\r
-                       var t = this, n = t.node;\r
+                       s.content = t.isCollapsed() ? '' : wb + t.serializer.serialize(e, s) + wa;\r
+                       t.onGetContent.dispatch(t, s);\r
 \r
-                       n.appendChild(t.doc.createTextNode(""));\r
-                       t.node = n.parentNode;\r
+                       return s.content;\r
                },\r
 \r
-               writeText : function(v) {\r
-                       if (this.valid)\r
-                               v = v.replace(/>/g, '%MCGT%');\r
-\r
-                       this.node.appendChild(this.doc.createTextNode(v));\r
-               },\r
+               setContent : function(content, args) {\r
+                       var self = this, rng = self.getRng(), caretNode, doc = self.win.document, frag, temp;\r
 \r
-               writeCDATA : function(v) {\r
-                       this.node.appendChild(this.doc.createCDATASection(v));\r
-               },\r
+                       args = args || {format : 'html'};\r
+                       args.set = true;\r
+                       content = args.content = content;\r
 \r
-               writeComment : function(v) {\r
-                       // Fix for bug #2035694\r
-                       if (tinymce.isIE)\r
-                               v = v.replace(/^\-|\-$/g, ' ');\r
+                       // Dispatch before set content event\r
+                       if (!args.no_events)\r
+                               self.onBeforeSetContent.dispatch(self, args);\r
 \r
-                       this.node.appendChild(this.doc.createComment(v.replace(/\-\-/g, ' ')));\r
-               },\r
+                       content = args.content;\r
 \r
-               getContent : function() {\r
-                       var h;\r
+                       if (rng.insertNode) {\r
+                               // Make caret marker since insertNode places the caret in the beginning of text after insert\r
+                               content += '<span id="__caret">_</span>';\r
 \r
-                       h = this.doc.xml || new XMLSerializer().serializeToString(this.doc);\r
-                       h = h.replace(/<\?[^?]+\?>|<html>|<\/html>|<html\/>|<!DOCTYPE[^>]+>/g, '');\r
-                       h = h.replace(/ ?\/>/g, ' />');\r
+                               // Delete and insert new node\r
+                               if (rng.startContainer == doc && rng.endContainer == doc) {\r
+                                       // WebKit will fail if the body is empty since the range is then invalid and it can't insert contents\r
+                                       doc.body.innerHTML = content;\r
+                               } else {\r
+                                       rng.deleteContents();\r
 \r
-                       if (this.valid)\r
-                               h = h.replace(/\%MCGT%/g, '&gt;');\r
+                                       if (doc.body.childNodes.length == 0) {\r
+                                               doc.body.innerHTML = content;\r
+                                       } else {\r
+                                               // createContextualFragment doesn't exists in IE 9 DOMRanges\r
+                                               if (rng.createContextualFragment) {\r
+                                                       rng.insertNode(rng.createContextualFragment(content));\r
+                                               } else {\r
+                                                       // Fake createContextualFragment call in IE 9\r
+                                                       frag = doc.createDocumentFragment();\r
+                                                       temp = doc.createElement('div');\r
 \r
-                       return h;\r
-               }\r
-       });\r
-})(tinymce);\r
+                                                       frag.appendChild(temp);\r
+                                                       temp.outerHTML = content;\r
 \r
-(function(tinymce) {\r
-       tinymce.create('tinymce.dom.StringWriter', {\r
-               str : null,\r
-               tags : null,\r
-               count : 0,\r
-               settings : null,\r
-               indent : null,\r
-\r
-               StringWriter : function(s) {\r
-                       this.settings = tinymce.extend({\r
-                               indent_char : ' ',\r
-                               indentation : 0\r
-                       }, s);\r
+                                                       rng.insertNode(frag);\r
+                                               }\r
+                                       }\r
+                               }\r
 \r
-                       this.reset();\r
-               },\r
+                               // Move to caret marker\r
+                               caretNode = self.dom.get('__caret');\r
 \r
-               reset : function() {\r
-                       this.indent = '';\r
-                       this.str = "";\r
-                       this.tags = [];\r
-                       this.count = 0;\r
-               },\r
+                               // Make sure we wrap it compleatly, Opera fails with a simple select call\r
+                               rng = doc.createRange();\r
+                               rng.setStartBefore(caretNode);\r
+                               rng.setEndBefore(caretNode);\r
+                               self.setRng(rng);\r
 \r
-               writeStartElement : function(n) {\r
-                       this._writeAttributesEnd();\r
-                       this.writeRaw('<' + n);\r
-                       this.tags.push(n);\r
-                       this.inAttr = true;\r
-                       this.count++;\r
-                       this.elementCount = this.count;\r
-               },\r
+                               // Remove the caret position\r
+                               self.dom.remove('__caret');\r
+                               self.setRng(rng);\r
+                       } else {\r
+                               if (rng.item) {\r
+                                       // Delete content and get caret text selection\r
+                                       doc.execCommand('Delete', false, null);\r
+                                       rng = self.getRng();\r
+                               }\r
 \r
-               writeAttribute : function(n, v) {\r
-                       var t = this;\r
+                               rng.pasteHTML(content);\r
+                       }\r
 \r
-                       t.writeRaw(" " + t.encode(n) + '="' + t.encode(v) + '"');\r
+                       // Dispatch set content event\r
+                       if (!args.no_events)\r
+                               self.onSetContent.dispatch(self, args);\r
                },\r
 \r
-               writeEndElement : function() {\r
-                       var n;\r
+               getStart : function() {\r
+                       var rng = this.getRng(), startElement, parentElement, checkRng, node;\r
 \r
-                       if (this.tags.length > 0) {\r
-                               n = this.tags.pop();\r
+                       if (rng.duplicate || rng.item) {\r
+                               // Control selection, return first item\r
+                               if (rng.item)\r
+                                       return rng.item(0);\r
 \r
-                               if (this._writeAttributesEnd(1))\r
-                                       this.writeRaw('</' + n + '>');\r
+                               // Get start element\r
+                               checkRng = rng.duplicate();\r
+                               checkRng.collapse(1);\r
+                               startElement = checkRng.parentElement();\r
 \r
-                               if (this.settings.indentation > 0)\r
-                                       this.writeRaw('\n');\r
-                       }\r
-               },\r
+                               // Check if range parent is inside the start element, then return the inner parent element\r
+                               // This will fix issues when a single element is selected, IE would otherwise return the wrong start element\r
+                               parentElement = node = rng.parentElement();\r
+                               while (node = node.parentNode) {\r
+                                       if (node == startElement) {\r
+                                               startElement = parentElement;\r
+                                               break;\r
+                                       }\r
+                               }\r
 \r
-               writeFullEndElement : function() {\r
-                       if (this.tags.length > 0) {\r
-                               this._writeAttributesEnd();\r
-                               this.writeRaw('</' + this.tags.pop() + '>');\r
+                               return startElement;\r
+                       } else {\r
+                               startElement = rng.startContainer;\r
 \r
-                               if (this.settings.indentation > 0)\r
-                                       this.writeRaw('\n');\r
-                       }\r
-               },\r
+                               if (startElement.nodeType == 1 && startElement.hasChildNodes())\r
+                                       startElement = startElement.childNodes[Math.min(startElement.childNodes.length - 1, rng.startOffset)];\r
 \r
-               writeText : function(v) {\r
-                       this._writeAttributesEnd();\r
-                       this.writeRaw(this.encode(v));\r
-                       this.count++;\r
-               },\r
+                               if (startElement && startElement.nodeType == 3)\r
+                                       return startElement.parentNode;\r
 \r
-               writeCDATA : function(v) {\r
-                       this._writeAttributesEnd();\r
-                       this.writeRaw('<![CDATA[' + v + ']]>');\r
-                       this.count++;\r
+                               return startElement;\r
+                       }\r
                },\r
 \r
-               writeComment : function(v) {\r
-                       this._writeAttributesEnd();\r
-                       this.writeRaw('<!-- ' + v + '-->');\r
-                       this.count++;\r
-               },\r
+               getEnd : function() {\r
+                       var t = this, r = t.getRng(), e, eo;\r
 \r
-               writeRaw : function(v) {\r
-                       this.str += v;\r
-               },\r
+                       if (r.duplicate || r.item) {\r
+                               if (r.item)\r
+                                       return r.item(0);\r
 \r
-               encode : function(s) {\r
-                       return s.replace(/[<>&"]/g, function(v) {\r
-                               switch (v) {\r
-                                       case '<':\r
-                                               return '&lt;';\r
+                               r = r.duplicate();\r
+                               r.collapse(0);\r
+                               e = r.parentElement();\r
 \r
-                                       case '>':\r
-                                               return '&gt;';\r
+                               if (e && e.nodeName == 'BODY')\r
+                                       return e.lastChild || e;\r
 \r
-                                       case '&':\r
-                                               return '&amp;';\r
+                               return e;\r
+                       } else {\r
+                               e = r.endContainer;\r
+                               eo = r.endOffset;\r
 \r
-                                       case '"':\r
-                                               return '&quot;';\r
-                               }\r
+                               if (e.nodeType == 1 && e.hasChildNodes())\r
+                                       e = e.childNodes[eo > 0 ? eo - 1 : eo];\r
 \r
-                               return v;\r
-                       });\r
-               },\r
+                               if (e && e.nodeType == 3)\r
+                                       return e.parentNode;\r
 \r
-               getContent : function() {\r
-                       return this.str;\r
+                               return e;\r
+                       }\r
                },\r
 \r
-               _writeAttributesEnd : function(s) {\r
-                       if (!this.inAttr)\r
-                               return;\r
+               getBookmark : function(type, normalized) {\r
+                       var t = this, dom = t.dom, rng, rng2, id, collapsed, name, element, index, chr = '\uFEFF', styles;\r
 \r
-                       this.inAttr = false;\r
+                       function findIndex(name, element) {\r
+                               var index = 0;\r
 \r
-                       if (s && this.elementCount == this.count) {\r
-                               this.writeRaw(' />');\r
-                               return false;\r
-                       }\r
+                               each(dom.select(name), function(node, i) {\r
+                                       if (node == element)\r
+                                               index = i;\r
+                               });\r
 \r
-                       this.writeRaw('>');\r
+                               return index;\r
+                       };\r
 \r
-                       return true;\r
-               }\r
-       });\r
-})(tinymce);\r
+                       if (type == 2) {\r
+                               function getLocation() {\r
+                                       var rng = t.getRng(true), root = dom.getRoot(), bookmark = {};\r
 \r
-(function(tinymce) {\r
-       // Shorten names\r
-       var extend = tinymce.extend, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher, isIE = tinymce.isIE, isGecko = tinymce.isGecko;\r
+                                       function getPoint(rng, start) {\r
+                                               var container = rng[start ? 'startContainer' : 'endContainer'],\r
+                                                       offset = rng[start ? 'startOffset' : 'endOffset'], point = [], node, childNodes, after = 0;\r
 \r
-       function wildcardToRE(s) {\r
-               return s.replace(/([?+*])/g, '.$1');\r
-       };\r
+                                               if (container.nodeType == 3) {\r
+                                                       if (normalized) {\r
+                                                               for (node = container.previousSibling; node && node.nodeType == 3; node = node.previousSibling)\r
+                                                                       offset += node.nodeValue.length;\r
+                                                       }\r
 \r
-       tinymce.create('tinymce.dom.Serializer', {\r
-               Serializer : function(s) {\r
-                       var t = this;\r
+                                                       point.push(offset);\r
+                                               } else {\r
+                                                       childNodes = container.childNodes;\r
 \r
-                       t.key = 0;\r
-                       t.onPreProcess = new Dispatcher(t);\r
-                       t.onPostProcess = new Dispatcher(t);\r
+                                                       if (offset >= childNodes.length && childNodes.length) {\r
+                                                               after = 1;\r
+                                                               offset = Math.max(0, childNodes.length - 1);\r
+                                                       }\r
 \r
-                       try {\r
-                               t.writer = new tinymce.dom.XMLWriter();\r
-                       } catch (ex) {\r
-                               // IE might throw exception if ActiveX is disabled so we then switch to the slightly slower StringWriter\r
-                               t.writer = new tinymce.dom.StringWriter();\r
-                       }\r
+                                                       point.push(t.dom.nodeIndex(childNodes[offset], normalized) + after);\r
+                                               }\r
 \r
-                       // Default settings\r
-                       t.settings = s = extend({\r
-                               dom : tinymce.DOM,\r
-                               valid_nodes : 0,\r
-                               node_filter : 0,\r
-                               attr_filter : 0,\r
-                               invalid_attrs : /^(_mce_|_moz_|sizset|sizcache)/,\r
-                               closed : /^(br|hr|input|meta|img|link|param|area)$/,\r
-                               entity_encoding : 'named',\r
-                               entities : '160,nbsp,161,iexcl,162,cent,163,pound,164,curren,165,yen,166,brvbar,167,sect,168,uml,169,copy,170,ordf,171,laquo,172,not,173,shy,174,reg,175,macr,176,deg,177,plusmn,178,sup2,179,sup3,180,acute,181,micro,182,para,183,middot,184,cedil,185,sup1,186,ordm,187,raquo,188,frac14,189,frac12,190,frac34,191,iquest,192,Agrave,193,Aacute,194,Acirc,195,Atilde,196,Auml,197,Aring,198,AElig,199,Ccedil,200,Egrave,201,Eacute,202,Ecirc,203,Euml,204,Igrave,205,Iacute,206,Icirc,207,Iuml,208,ETH,209,Ntilde,210,Ograve,211,Oacute,212,Ocirc,213,Otilde,214,Ouml,215,times,216,Oslash,217,Ugrave,218,Uacute,219,Ucirc,220,Uuml,221,Yacute,222,THORN,223,szlig,224,agrave,225,aacute,226,acirc,227,atilde,228,auml,229,aring,230,aelig,231,ccedil,232,egrave,233,eacute,234,ecirc,235,euml,236,igrave,237,iacute,238,icirc,239,iuml,240,eth,241,ntilde,242,ograve,243,oacute,244,ocirc,245,otilde,246,ouml,247,divide,248,oslash,249,ugrave,250,uacute,251,ucirc,252,uuml,253,yacute,254,thorn,255,yuml,402,fnof,913,Alpha,914,Beta,915,Gamma,916,Delta,917,Epsilon,918,Zeta,919,Eta,920,Theta,921,Iota,922,Kappa,923,Lambda,924,Mu,925,Nu,926,Xi,927,Omicron,928,Pi,929,Rho,931,Sigma,932,Tau,933,Upsilon,934,Phi,935,Chi,936,Psi,937,Omega,945,alpha,946,beta,947,gamma,948,delta,949,epsilon,950,zeta,951,eta,952,theta,953,iota,954,kappa,955,lambda,956,mu,957,nu,958,xi,959,omicron,960,pi,961,rho,962,sigmaf,963,sigma,964,tau,965,upsilon,966,phi,967,chi,968,psi,969,omega,977,thetasym,978,upsih,982,piv,8226,bull,8230,hellip,8242,prime,8243,Prime,8254,oline,8260,frasl,8472,weierp,8465,image,8476,real,8482,trade,8501,alefsym,8592,larr,8593,uarr,8594,rarr,8595,darr,8596,harr,8629,crarr,8656,lArr,8657,uArr,8658,rArr,8659,dArr,8660,hArr,8704,forall,8706,part,8707,exist,8709,empty,8711,nabla,8712,isin,8713,notin,8715,ni,8719,prod,8721,sum,8722,minus,8727,lowast,8730,radic,8733,prop,8734,infin,8736,ang,8743,and,8744,or,8745,cap,8746,cup,8747,int,8756,there4,8764,sim,8773,cong,8776,asymp,8800,ne,8801,equiv,8804,le,8805,ge,8834,sub,8835,sup,8836,nsub,8838,sube,8839,supe,8853,oplus,8855,otimes,8869,perp,8901,sdot,8968,lceil,8969,rceil,8970,lfloor,8971,rfloor,9001,lang,9002,rang,9674,loz,9824,spades,9827,clubs,9829,hearts,9830,diams,338,OElig,339,oelig,352,Scaron,353,scaron,376,Yuml,710,circ,732,tilde,8194,ensp,8195,emsp,8201,thinsp,8204,zwnj,8205,zwj,8206,lrm,8207,rlm,8211,ndash,8212,mdash,8216,lsquo,8217,rsquo,8218,sbquo,8220,ldquo,8221,rdquo,8222,bdquo,8224,dagger,8225,Dagger,8240,permil,8249,lsaquo,8250,rsaquo,8364,euro',\r
-                               valid_elements : '*[*]',\r
-                               extended_valid_elements : 0,\r
-                               invalid_elements : 0,\r
-                               fix_table_elements : 1,\r
-                               fix_list_elements : true,\r
-                               fix_content_duplication : true,\r
-                               convert_fonts_to_spans : false,\r
-                               font_size_classes : 0,\r
-                               apply_source_formatting : 0,\r
-                               indent_mode : 'simple',\r
-                               indent_char : '\t',\r
-                               indent_levels : 1,\r
-                               remove_linebreaks : 1,\r
-                               remove_redundant_brs : 1,\r
-                               element_format : 'xhtml'\r
-                       }, s);\r
+                                               for (; container && container != root; container = container.parentNode)\r
+                                                       point.push(t.dom.nodeIndex(container, normalized));\r
 \r
-                       t.dom = s.dom;\r
-                       t.schema = s.schema;\r
+                                               return point;\r
+                                       };\r
 \r
-                       // Use raw entities if no entities are defined\r
-                       if (s.entity_encoding == 'named' && !s.entities)\r
-                               s.entity_encoding = 'raw';\r
+                                       bookmark.start = getPoint(rng, true);\r
 \r
-                       if (s.remove_redundant_brs) {\r
-                               t.onPostProcess.add(function(se, o) {\r
-                                       // Remove single BR at end of block elements since they get rendered\r
-                                       o.content = o.content.replace(/(<br \/>\s*)+<\/(p|h[1-6]|div|li)>/gi, function(a, b, c) {\r
-                                               // Check if it's a single element\r
-                                               if (/^<br \/>\s*<\//.test(a))\r
-                                                       return '</' + c + '>';\r
+                                       if (!t.isCollapsed())\r
+                                               bookmark.end = getPoint(rng);\r
 \r
-                                               return a;\r
-                                       });\r
-                               });\r
-                       }\r
+                                       return bookmark;\r
+                               };\r
 \r
-                       // Remove XHTML element endings i.e. produce crap :) XHTML is better\r
-                       if (s.element_format == 'html') {\r
-                               t.onPostProcess.add(function(se, o) {\r
-                                       o.content = o.content.replace(/<([^>]+) \/>/g, '<$1>');\r
-                               });\r
+                               return getLocation();\r
                        }\r
 \r
-                       if (s.fix_list_elements) {\r
-                               t.onPreProcess.add(function(se, o) {\r
-                                       var nl, x, a = ['ol', 'ul'], i, n, p, r = /^(OL|UL)$/, np;\r
-\r
-                                       function prevNode(e, n) {\r
-                                               var a = n.split(','), i;\r
+                       // Handle simple range\r
+                       if (type)\r
+                               return {rng : t.getRng()};\r
 \r
-                                               while ((e = e.previousSibling) != null) {\r
-                                                       for (i=0; i<a.length; i++) {\r
-                                                               if (e.nodeName == a[i])\r
-                                                                       return e;\r
-                                                       }\r
-                                               }\r
+                       rng = t.getRng();\r
+                       id = dom.uniqueId();\r
+                       collapsed = tinyMCE.activeEditor.selection.isCollapsed();\r
+                       styles = 'overflow:hidden;line-height:0px';\r
 \r
-                                               return null;\r
-                                       };\r
+                       // Explorer method\r
+                       if (rng.duplicate || rng.item) {\r
+                               // Text selection\r
+                               if (!rng.item) {\r
+                                       rng2 = rng.duplicate();\r
 \r
-                                       for (x=0; x<a.length; x++) {\r
-                                               nl = t.dom.select(a[x], o.node);\r
+                                       try {\r
+                                               // Insert start marker\r
+                                               rng.collapse();\r
+                                               rng.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_start" style="' + styles + '">' + chr + '</span>');\r
 \r
-                                               for (i=0; i<nl.length; i++) {\r
-                                                       n = nl[i];\r
-                                                       p = n.parentNode;\r
+                                               // Insert end marker\r
+                                               if (!collapsed) {\r
+                                                       rng2.collapse(false);\r
 \r
-                                                       if (r.test(p.nodeName)) {\r
-                                                               np = prevNode(n, 'LI');\r
+                                                       // Detect the empty space after block elements in IE and move the end back one character <p></p>] becomes <p>]</p>\r
+                                                       rng.moveToElementText(rng2.parentElement());\r
+                                                       if (rng.compareEndPoints('StartToEnd', rng2) == 0)\r
+                                                               rng2.move('character', -1);\r
 \r
-                                                               if (!np) {\r
-                                                                       np = t.dom.create('li');\r
-                                                                       np.innerHTML = '&nbsp;';\r
-                                                                       np.appendChild(n);\r
-                                                                       p.insertBefore(np, p.firstChild);\r
-                                                               } else\r
-                                                                       np.appendChild(n);\r
-                                                       }\r
+                                                       rng2.pasteHTML('<span data-mce-type="bookmark" id="' + id + '_end" style="' + styles + '">' + chr + '</span>');\r
                                                }\r
+                                       } catch (ex) {\r
+                                               // IE might throw unspecified error so lets ignore it\r
+                                               return null;\r
                                        }\r
-                               });\r
-                       }\r
-\r
-                       if (s.fix_table_elements) {\r
-                               t.onPreProcess.add(function(se, o) {\r
-                                       // Since Opera will crash if you attach the node to a dynamic document we need to brrowser sniff a specific build\r
-                                       // so Opera users with an older version will have to live with less compaible output not much we can do here\r
-                                       if (!tinymce.isOpera || opera.buildNumber() >= 1767) {\r
-                                               each(t.dom.select('p table', o.node).reverse(), function(n) {\r
-                                                       var parent = t.dom.getParent(n.parentNode, 'table,p');\r
-\r
-                                                       if (parent.nodeName != 'TABLE') {\r
-                                                               try {\r
-                                                                       t.dom.split(parent, n);\r
-                                                               } catch (ex) {\r
-                                                                       // IE can sometimes fire an unknown runtime error so we just ignore it\r
-                                                               }\r
-                                                       }\r
-                                               });\r
-                                       }\r
-                               });\r
-                       }\r
-               },\r
-\r
-               setEntities : function(s) {\r
-                       var t = this, a, i, l = {}, v;\r
-\r
-                       // No need to setup more than once\r
-                       if (t.entityLookup)\r
-                               return;\r
+                               } else {\r
+                                       // Control selection\r
+                                       element = rng.item(0);\r
+                                       name = element.nodeName;\r
 \r
-                       // Build regex and lookup array\r
-                       a = s.split(',');\r
-                       for (i = 0; i < a.length; i += 2) {\r
-                               v = a[i];\r
+                                       return {name : name, index : findIndex(name, element)};\r
+                               }\r
+                       } else {\r
+                               element = t.getNode();\r
+                               name = element.nodeName;\r
+                               if (name == 'IMG')\r
+                                       return {name : name, index : findIndex(name, element)};\r
 \r
-                               // Don't add default &amp; &quot; etc.\r
-                               if (v == 34 || v == 38 || v == 60 || v == 62)\r
-                                       continue;\r
+                               // W3C method\r
+                               rng2 = rng.cloneRange();\r
 \r
-                               l[String.fromCharCode(a[i])] = a[i + 1];\r
+                               // Insert end marker\r
+                               if (!collapsed) {\r
+                                       rng2.collapse(false);\r
+                                       rng2.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_end', style : styles}, chr));\r
+                               }\r
 \r
-                               v = parseInt(a[i]).toString(16);\r
+                               rng.collapse(true);\r
+                               rng.insertNode(dom.create('span', {'data-mce-type' : "bookmark", id : id + '_start', style : styles}, chr));\r
                        }\r
 \r
-                       t.entityLookup = l;\r
-               },\r
-\r
-               setRules : function(s) {\r
-                       var t = this;\r
-\r
-                       t._setup();\r
-                       t.rules = {};\r
-                       t.wildRules = [];\r
-                       t.validElements = {};\r
+                       t.moveToBookmark({id : id, keep : 1});\r
 \r
-                       return t.addRules(s);\r
+                       return {id : id};\r
                },\r
 \r
-               addRules : function(s) {\r
-                       var t = this, dr;\r
-\r
-                       if (!s)\r
-                               return;\r
-\r
-                       t._setup();\r
-\r
-                       each(s.split(','), function(s) {\r
-                               var p = s.split(/\[|\]/), tn = p[0].split('/'), ra, at, wat, va = [];\r
-\r
-                               // Extend with default rules\r
-                               if (dr)\r
-                                       at = tinymce.extend([], dr.attribs);\r
-\r
-                               // Parse attributes\r
-                               if (p.length > 1) {\r
-                                       each(p[1].split('|'), function(s) {\r
-                                               var ar = {}, i;\r
-\r
-                                               at = at || [];\r
+               moveToBookmark : function(bookmark) {\r
+                       var t = this, dom = t.dom, marker1, marker2, rng, root, startContainer, endContainer, startOffset, endOffset;\r
 \r
-                                               // Parse attribute rule\r
-                                               s = s.replace(/::/g, '~');\r
-                                               s = /^([!\-])?([\w*.?~_\-]+|)([=:<])?(.+)?$/.exec(s);\r
-                                               s[2] = s[2].replace(/~/g, ':');\r
+                       // Clear selection cache\r
+                       if (t.tridentSel)\r
+                               t.tridentSel.destroy();\r
 \r
-                                               // Add required attributes\r
-                                               if (s[1] == '!') {\r
-                                                       ra = ra || [];\r
-                                                       ra.push(s[2]);\r
-                                               }\r
+                       if (bookmark) {\r
+                               if (bookmark.start) {\r
+                                       rng = dom.createRng();\r
+                                       root = dom.getRoot();\r
 \r
-                                               // Remove inherited attributes\r
-                                               if (s[1] == '-') {\r
-                                                       for (i = 0; i <at.length; i++) {\r
-                                                               if (at[i].name == s[2]) {\r
-                                                                       at.splice(i, 1);\r
-                                                                       return;\r
-                                                               }\r
-                                                       }\r
-                                               }\r
+                                       function setEndPoint(start) {\r
+                                               var point = bookmark[start ? 'start' : 'end'], i, node, offset, children;\r
 \r
-                                               switch (s[3]) {\r
-                                                       // Add default attrib values\r
-                                                       case '=':\r
-                                                               ar.defaultVal = s[4] || '';\r
-                                                               break;\r
+                                               if (point) {\r
+                                                       offset = point[0];\r
 \r
-                                                       // Add forced attrib values\r
-                                                       case ':':\r
-                                                               ar.forcedVal = s[4];\r
-                                                               break;\r
+                                                       // Find container node\r
+                                                       for (node = root, i = point.length - 1; i >= 1; i--) {\r
+                                                               children = node.childNodes;\r
 \r
-                                                       // Add validation values\r
-                                                       case '<':\r
-                                                               ar.validVals = s[4].split('?');\r
-                                                               break;\r
-                                               }\r
+                                                               if (point[i] > children.length - 1)\r
+                                                                       return;\r
 \r
-                                               if (/[*.?]/.test(s[2])) {\r
-                                                       wat = wat || [];\r
-                                                       ar.nameRE = new RegExp('^' + wildcardToRE(s[2]) + '$');\r
-                                                       wat.push(ar);\r
-                                               } else {\r
-                                                       ar.name = s[2];\r
-                                                       at.push(ar);\r
-                                               }\r
+                                                               node = children[point[i]];\r
+                                                       }\r
 \r
-                                               va.push(s[2]);\r
-                                       });\r
-                               }\r
+                                                       // Move text offset to best suitable location\r
+                                                       if (node.nodeType === 3)\r
+                                                               offset = Math.min(point[0], node.nodeValue.length);\r
 \r
-                               // Handle element names\r
-                               each(tn, function(s, i) {\r
-                                       var pr = s.charAt(0), x = 1, ru = {};\r
+                                                       // Move element offset to best suitable location\r
+                                                       if (node.nodeType === 1)\r
+                                                               offset = Math.min(point[0], node.childNodes.length);\r
 \r
-                                       // Extend with default rule data\r
-                                       if (dr) {\r
-                                               if (dr.noEmpty)\r
-                                                       ru.noEmpty = dr.noEmpty;\r
+                                                       // Set offset within container node\r
+                                                       if (start)\r
+                                                               rng.setStart(node, offset);\r
+                                                       else\r
+                                                               rng.setEnd(node, offset);\r
+                                               }\r
 \r
-                                               if (dr.fullEnd)\r
-                                                       ru.fullEnd = dr.fullEnd;\r
+                                               return true;\r
+                                       };\r
 \r
-                                               if (dr.padd)\r
-                                                       ru.padd = dr.padd;\r
+                                       if (setEndPoint(true) && setEndPoint()) {\r
+                                               t.setRng(rng);\r
                                        }\r
+                               } else if (bookmark.id) {\r
+                                       function restoreEndPoint(suffix) {\r
+                                               var marker = dom.get(bookmark.id + '_' + suffix), node, idx, next, prev, keep = bookmark.keep;\r
 \r
-                                       // Handle prefixes\r
-                                       switch (pr) {\r
-                                               case '-':\r
-                                                       ru.noEmpty = true;\r
-                                                       break;\r
+                                               if (marker) {\r
+                                                       node = marker.parentNode;\r
 \r
-                                               case '+':\r
-                                                       ru.fullEnd = true;\r
-                                                       break;\r
+                                                       if (suffix == 'start') {\r
+                                                               if (!keep) {\r
+                                                                       idx = dom.nodeIndex(marker);\r
+                                                               } else {\r
+                                                                       node = marker.firstChild;\r
+                                                                       idx = 1;\r
+                                                               }\r
 \r
-                                               case '#':\r
-                                                       ru.padd = true;\r
-                                                       break;\r
+                                                               startContainer = endContainer = node;\r
+                                                               startOffset = endOffset = idx;\r
+                                                       } else {\r
+                                                               if (!keep) {\r
+                                                                       idx = dom.nodeIndex(marker);\r
+                                                               } else {\r
+                                                                       node = marker.firstChild;\r
+                                                                       idx = 1;\r
+                                                               }\r
 \r
-                                               default:\r
-                                                       x = 0;\r
-                                       }\r
+                                                               endContainer = node;\r
+                                                               endOffset = idx;\r
+                                                       }\r
 \r
-                                       tn[i] = s = s.substring(x);\r
-                                       t.validElements[s] = 1;\r
+                                                       if (!keep) {\r
+                                                               prev = marker.previousSibling;\r
+                                                               next = marker.nextSibling;\r
 \r
-                                       // Add element name or element regex\r
-                                       if (/[*.?]/.test(tn[0])) {\r
-                                               ru.nameRE = new RegExp('^' + wildcardToRE(tn[0]) + '$');\r
-                                               t.wildRules = t.wildRules || {};\r
-                                               t.wildRules.push(ru);\r
-                                       } else {\r
-                                               ru.name = tn[0];\r
+                                                               // Remove all marker text nodes\r
+                                                               each(tinymce.grep(marker.childNodes), function(node) {\r
+                                                                       if (node.nodeType == 3)\r
+                                                                               node.nodeValue = node.nodeValue.replace(/\uFEFF/g, '');\r
+                                                               });\r
 \r
-                                               // Store away default rule\r
-                                               if (tn[0] == '@')\r
-                                                       dr = ru;\r
+                                                               // Remove marker but keep children if for example contents where inserted into the marker\r
+                                                               // Also remove duplicated instances of the marker for example by a split operation or by WebKit auto split on paste feature\r
+                                                               while (marker = dom.get(bookmark.id + '_' + suffix))\r
+                                                                       dom.remove(marker, 1);\r
 \r
-                                               t.rules[s] = ru;\r
-                                       }\r
+                                                               // If siblings are text nodes then merge them unless it's Opera since it some how removes the node\r
+                                                               // 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\r
+                                                               if (prev && next && prev.nodeType == next.nodeType && prev.nodeType == 3 && !tinymce.isOpera) {\r
+                                                                       idx = prev.nodeValue.length;\r
+                                                                       prev.appendData(next.nodeValue);\r
+                                                                       dom.remove(next);\r
+\r
+                                                                       if (suffix == 'start') {\r
+                                                                               startContainer = endContainer = prev;\r
+                                                                               startOffset = endOffset = idx;\r
+                                                                       } else {\r
+                                                                               endContainer = prev;\r
+                                                                               endOffset = idx;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       };\r
 \r
-                                       ru.attribs = at;\r
+                                       function addBogus(node) {\r
+                                               // Adds a bogus BR element for empty block elements or just a space on IE since it renders BR elements incorrectly\r
+                                               if (dom.isBlock(node) && !node.innerHTML)\r
+                                                       node.innerHTML = !isIE ? '<br data-mce-bogus="1" />' : ' ';\r
 \r
-                                       if (ra)\r
-                                               ru.requiredAttribs = ra;\r
+                                               return node;\r
+                                       };\r
 \r
-                                       if (wat) {\r
-                                               // Build valid attributes regexp\r
-                                               s = '';\r
-                                               each(va, function(v) {\r
-                                                       if (s)\r
-                                                               s += '|';\r
+                                       // Restore start/end points\r
+                                       restoreEndPoint('start');\r
+                                       restoreEndPoint('end');\r
 \r
-                                                       s += '(' + wildcardToRE(v) + ')';\r
-                                               });\r
-                                               ru.validAttribsRE = new RegExp('^' + s.toLowerCase() + '$');\r
-                                               ru.wildAttribs = wat;\r
+                                       if (startContainer) {\r
+                                               rng = dom.createRng();\r
+                                               rng.setStart(addBogus(startContainer), startOffset);\r
+                                               rng.setEnd(addBogus(endContainer), endOffset);\r
+                                               t.setRng(rng);\r
                                        }\r
-                               });\r
-                       });\r
+                               } else if (bookmark.name) {\r
+                                       t.select(dom.select(bookmark.name)[bookmark.index]);\r
+                               } else if (bookmark.rng)\r
+                                       t.setRng(bookmark.rng);\r
+                       }\r
+               },\r
 \r
-                       // Build valid elements regexp\r
-                       s = '';\r
-                       each(t.validElements, function(v, k) {\r
-                               if (s)\r
-                                       s += '|';\r
+               select : function(node, content) {\r
+                       var t = this, dom = t.dom, rng = dom.createRng(), idx;\r
 \r
-                               if (k != '@')\r
-                                       s += k;\r
-                       });\r
-                       t.validElementsRE = new RegExp('^(' + wildcardToRE(s.toLowerCase()) + ')$');\r
+                       if (node) {\r
+                               idx = dom.nodeIndex(node);\r
+                               rng.setStart(node.parentNode, idx);\r
+                               rng.setEnd(node.parentNode, idx + 1);\r
+\r
+                               // Find first/last text node or BR element\r
+                               if (content) {\r
+                                       function setPoint(node, start) {\r
+                                               var walker = new tinymce.dom.TreeWalker(node, node);\r
+\r
+                                               do {\r
+                                                       // Text node\r
+                                                       if (node.nodeType == 3 && tinymce.trim(node.nodeValue).length != 0) {\r
+                                                               if (start)\r
+                                                                       rng.setStart(node, 0);\r
+                                                               else\r
+                                                                       rng.setEnd(node, node.nodeValue.length);\r
 \r
-                       //console.debug(t.validElementsRE.toString());\r
-                       //console.dir(t.rules);\r
-                       //console.dir(t.wildRules);\r
-               },\r
+                                                               return;\r
+                                                       }\r
 \r
-               findRule : function(n) {\r
-                       var t = this, rl = t.rules, i, r;\r
+                                                       // BR element\r
+                                                       if (node.nodeName == 'BR') {\r
+                                                               if (start)\r
+                                                                       rng.setStartBefore(node);\r
+                                                               else\r
+                                                                       rng.setEndBefore(node);\r
 \r
-                       t._setup();\r
+                                                               return;\r
+                                                       }\r
+                                               } while (node = (start ? walker.next() : walker.prev()));\r
+                                       };\r
 \r
-                       // Exact match\r
-                       r = rl[n];\r
-                       if (r)\r
-                               return r;\r
+                                       setPoint(node, 1);\r
+                                       setPoint(node);\r
+                               }\r
 \r
-                       // Try wildcards\r
-                       rl = t.wildRules;\r
-                       for (i = 0; i < rl.length; i++) {\r
-                               if (rl[i].nameRE.test(n))\r
-                                       return rl[i];\r
+                               t.setRng(rng);\r
                        }\r
 \r
-                       return null;\r
+                       return node;\r
                },\r
 \r
-               findAttribRule : function(ru, n) {\r
-                       var i, wa = ru.wildAttribs;\r
-\r
-                       for (i = 0; i < wa.length; i++) {\r
-                               if (wa[i].nameRE.test(n))\r
-                                       return wa[i];\r
-                       }\r
+               isCollapsed : function() {\r
+                       var t = this, r = t.getRng(), s = t.getSel();\r
 \r
-                       return null;\r
-               },\r
+                       if (!r || r.item)\r
+                               return false;\r
 \r
-               serialize : function(n, o) {\r
-                       var h, t = this, doc, oldDoc, impl, selected;\r
+                       if (r.compareEndPoints)\r
+                               return r.compareEndPoints('StartToEnd', r) === 0;\r
 \r
-                       t._setup();\r
-                       o = o || {};\r
-                       o.format = o.format || 'html';\r
-                       t.processObj = o;\r
+                       return !s || r.collapsed;\r
+               },\r
 \r
-                       // IE looses the selected attribute on option elements so we need to store it\r
-                       // See: http://support.microsoft.com/kb/829907\r
-                       if (isIE) {\r
-                               selected = [];\r
-                               each(n.getElementsByTagName('option'), function(n) {\r
-                                       var v = t.dom.getAttrib(n, 'selected');\r
+               collapse : function(to_start) {\r
+                       var self = this, rng = self.getRng(), node;\r
 \r
-                                       selected.push(v ? v : null);\r
-                               });\r
+                       // Control range on IE\r
+                       if (rng.item) {\r
+                               node = rng.item(0);\r
+                               rng = self.win.document.body.createTextRange();\r
+                               rng.moveToElementText(node);\r
                        }\r
 \r
-                       n = n.cloneNode(true);\r
+                       rng.collapse(!!to_start);\r
+                       self.setRng(rng);\r
+               },\r
 \r
-                       // IE looses the selected attribute on option elements so we need to restore it\r
-                       if (isIE) {\r
-                               each(n.getElementsByTagName('option'), function(n, i) {\r
-                                       t.dom.setAttrib(n, 'selected', selected[i]);\r
-                               });\r
-                       }\r
+               getSel : function() {\r
+                       var t = this, w = this.win;\r
 \r
-                       // Nodes needs to be attached to something in WebKit/Opera\r
-                       // Older builds of Opera crashes if you attach the node to an document created dynamically\r
-                       // and since we can't feature detect a crash we need to sniff the acutal build number\r
-                       // This fix will make DOM ranges and make Sizzle happy!\r
-                       impl = n.ownerDocument.implementation;\r
-                       if (impl.createHTMLDocument && (tinymce.isOpera && opera.buildNumber() >= 1767)) {\r
-                               // Create an empty HTML document\r
-                               doc = impl.createHTMLDocument("");\r
+                       return w.getSelection ? w.getSelection() : w.document.selection;\r
+               },\r
 \r
-                               // Add the element or it's children if it's a body element to the new document\r
-                               each(n.nodeName == 'BODY' ? n.childNodes : [n], function(node) {\r
-                                       doc.body.appendChild(doc.importNode(node, true));\r
-                               });\r
+               getRng : function(w3c) {\r
+                       var t = this, s, r, elm, doc = t.win.document;\r
 \r
-                               // Grab first child or body element for serialization\r
-                               if (n.nodeName != 'BODY')\r
-                                       n = doc.body.firstChild;\r
-                               else\r
-                                       n = doc.body;\r
+                       // Found tridentSel object then we need to use that one\r
+                       if (w3c && t.tridentSel)\r
+                               return t.tridentSel.getRangeAt(0);\r
+\r
+                       try {\r
+                               if (s = t.getSel())\r
+                                       r = s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : doc.createRange());\r
+                       } catch (ex) {\r
+                               // IE throws unspecified error here if TinyMCE is placed in a frame/iframe\r
+                       }\r
 \r
-                               // set the new document in DOMUtils so createElement etc works\r
-                               oldDoc = t.dom.doc;\r
-                               t.dom.doc = doc;\r
+                       // We have W3C ranges and it's IE then fake control selection since IE9 doesn't handle that correctly yet\r
+                       if (tinymce.isIE && r && r.setStart && doc.selection.createRange().item) {\r
+                               elm = doc.selection.createRange().item(0);\r
+                               r = doc.createRange();\r
+                               r.setStartBefore(elm);\r
+                               r.setEndAfter(elm);\r
                        }\r
 \r
-                       t.key = '' + (parseInt(t.key) + 1);\r
+                       // No range found then create an empty one\r
+                       // This can occur when the editor is placed in a hidden container element on Gecko\r
+                       // Or on IE when there was an exception\r
+                       if (!r)\r
+                               r = doc.createRange ? doc.createRange() : doc.body.createTextRange();\r
 \r
-                       // Pre process\r
-                       if (!o.no_events) {\r
-                               o.node = n;\r
-                               t.onPreProcess.dispatch(t, o);\r
+                       if (t.selectedRange && t.explicitRange) {\r
+                               if (r.compareBoundaryPoints(r.START_TO_START, t.selectedRange) === 0 && r.compareBoundaryPoints(r.END_TO_END, t.selectedRange) === 0) {\r
+                                       // Safari, Opera and Chrome only ever select text which causes the range to change.\r
+                                       // This lets us use the originally set range if the selection hasn't been changed by the user.\r
+                                       r = t.explicitRange;\r
+                               } else {\r
+                                       t.selectedRange = null;\r
+                                       t.explicitRange = null;\r
+                               }\r
                        }\r
 \r
-                       // Serialize HTML DOM into a string\r
-                       t.writer.reset();\r
-                       t._info = o;\r
-                       t._serializeNode(n, o.getInner);\r
+                       return r;\r
+               },\r
 \r
-                       // Post process\r
-                       o.content = t.writer.getContent();\r
+               setRng : function(r) {\r
+                       var s, t = this;\r
+                       \r
+                       if (!t.tridentSel) {\r
+                               s = t.getSel();\r
 \r
-                       // Restore the old document if it was changed\r
-                       if (oldDoc)\r
-                               t.dom.doc = oldDoc;\r
+                               if (s) {\r
+                                       t.explicitRange = r;\r
 \r
-                       if (!o.no_events)\r
-                               t.onPostProcess.dispatch(t, o);\r
+                                       try {\r
+                                               s.removeAllRanges();\r
+                                       } catch (ex) {\r
+                                               // IE9 might throw errors here don't know why\r
+                                       }\r
 \r
-                       t._postProcess(o);\r
-                       o.node = null;\r
+                                       s.addRange(r);\r
+                                       t.selectedRange = s.getRangeAt(0);\r
+                               }\r
+                       } else {\r
+                               // Is W3C Range\r
+                               if (r.cloneRange) {\r
+                                       t.tridentSel.addRange(r);\r
+                                       return;\r
+                               }\r
 \r
-                       return tinymce.trim(o.content);\r
+                               // Is IE specific range\r
+                               try {\r
+                                       r.select();\r
+                               } catch (ex) {\r
+                                       // Needed for some odd IE bug #1843306\r
+                               }\r
+                       }\r
                },\r
 \r
-               // Internal functions\r
+               setNode : function(n) {\r
+                       var t = this;\r
 \r
-               _postProcess : function(o) {\r
-                       var t = this, s = t.settings, h = o.content, sc = [], p;\r
-\r
-                       if (o.format == 'html') {\r
-                               // Protect some elements\r
-                               p = t._protect({\r
-                                       content : h,\r
-                                       patterns : [\r
-                                               {pattern : /(<script[^>]*>)(.*?)(<\/script>)/g},\r
-                                               {pattern : /(<noscript[^>]*>)(.*?)(<\/noscript>)/g},\r
-                                               {pattern : /(<style[^>]*>)(.*?)(<\/style>)/g},\r
-                                               {pattern : /(<pre[^>]*>)(.*?)(<\/pre>)/g, encode : 1},\r
-                                               {pattern : /(<!--\[CDATA\[)(.*?)(\]\]-->)/g}\r
-                                       ]\r
-                               });\r
+                       t.setContent(t.dom.getOuterHTML(n));\r
 \r
-                               h = p.content;\r
+                       return n;\r
+               },\r
 \r
-                               // Entity encode\r
-                               if (s.entity_encoding !== 'raw')\r
-                                       h = t._encode(h);\r
+               getNode : function() {\r
+                       var t = this, rng = t.getRng(), sel = t.getSel(), elm, start = rng.startContainer, end = rng.endContainer;\r
 \r
-                               // Use BR instead of &nbsp; padded P elements inside editor and use <p>&nbsp;</p> outside editor\r
-/*                             if (o.set)\r
-                                       h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p><br /></p>');\r
-                               else\r
-                                       h = h.replace(/<p>\s+(&nbsp;|&#160;|\u00a0|<br \/>)\s+<\/p>/g, '<p>$1</p>');*/\r
+                       // Range maybe lost after the editor is made visible again\r
+                       if (!rng)\r
+                               return t.dom.getRoot();\r
 \r
-                               // Since Gecko and Safari keeps whitespace in the DOM we need to\r
-                               // remove it inorder to match other browsers. But I think Gecko and Safari is right.\r
-                               // This process is only done when getting contents out from the editor.\r
-                               if (!o.set) {\r
-                                       // We need to replace paragraph whitespace with an nbsp before indentation to keep the \u00a0 char\r
-                                       h = h.replace(/<p>\s+<\/p>|<p([^>]+)>\s+<\/p>/g, s.entity_encoding == 'numeric' ? '<p$1>&#160;</p>' : '<p$1>&nbsp;</p>');\r
+                       if (rng.setStart) {\r
+                               elm = rng.commonAncestorContainer;\r
 \r
-                                       if (s.remove_linebreaks) {\r
-                                               h = h.replace(/\r?\n|\r/g, ' ');\r
-                                               h = h.replace(/(<[^>]+>)\s+/g, '$1 ');\r
-                                               h = h.replace(/\s+(<\/[^>]+>)/g, ' $1');\r
-                                               h = h.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object) ([^>]+)>\s+/g, '<$1 $2>'); // Trim block start\r
-                                               h = h.replace(/<(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>\s+/g, '<$1>'); // Trim block start\r
-                                               h = h.replace(/\s+<\/(p|h[1-6]|blockquote|hr|div|table|tbody|tr|td|body|head|html|title|meta|style|pre|script|link|object)>/g, '</$1>'); // Trim block end\r
+                               // Handle selection a image or other control like element such as anchors\r
+                               if (!rng.collapsed) {\r
+                                       if (rng.startContainer == rng.endContainer) {\r
+                                               if (rng.endOffset - rng.startOffset < 2) {\r
+                                                       if (rng.startContainer.hasChildNodes())\r
+                                                               elm = rng.startContainer.childNodes[rng.startOffset];\r
+                                               }\r
                                        }\r
 \r
-                                       // Simple indentation\r
-                                       if (s.apply_source_formatting && s.indent_mode == 'simple') {\r
-                                               // Add line breaks before and after block elements\r
-                                               h = h.replace(/<(\/?)(ul|hr|table|meta|link|tbody|tr|object|body|head|html|map)(|[^>]+)>\s*/g, '\n<$1$2$3>\n');\r
-                                               h = h.replace(/\s*<(p|h[1-6]|blockquote|div|title|style|pre|script|td|li|area)(|[^>]+)>/g, '\n<$1$2>');\r
-                                               h = h.replace(/<\/(p|h[1-6]|blockquote|div|title|style|pre|script|td|li)>\s*/g, '</$1>\n');\r
-                                               h = h.replace(/\n\n/g, '\n');\r
+                                       // If the anchor node is a element instead of a text node then return this element\r
+                                       //if (tinymce.isWebKit && sel.anchorNode && sel.anchorNode.nodeType == 1) \r
+                                       //      return sel.anchorNode.childNodes[sel.anchorOffset];\r
+\r
+                                       // Handle cases where the selection is immediately wrapped around a node and return that node instead of it's parent.\r
+                                       // This happens when you double click an underlined word in FireFox.\r
+                                       if (start.nodeType === 3 && end.nodeType === 3) {\r
+                                               function skipEmptyTextNodes(n, forwards) {\r
+                                                       var orig = n;\r
+                                                       while (n && n.nodeType === 3 && n.length === 0) {\r
+                                                               n = forwards ? n.nextSibling : n.previousSibling;\r
+                                                       }\r
+                                                       return n || orig;\r
+                                               }\r
+                                               if (start.length === rng.startOffset) {\r
+                                                       start = skipEmptyTextNodes(start.nextSibling, true);\r
+                                               } else {\r
+                                                       start = start.parentNode;\r
+                                               }\r
+                                               if (rng.endOffset === 0) {\r
+                                                       end = skipEmptyTextNodes(end.previousSibling, false);\r
+                                               } else {\r
+                                                       end = end.parentNode;\r
+                                               }\r
+\r
+                                               if (start && start === end)\r
+                                                       return start;\r
                                        }\r
                                }\r
 \r
-                               h = t._unprotect(h, p);\r
-\r
-                               // Restore CDATA sections\r
-                               h = h.replace(/<!--\[CDATA\[([\s\S]+)\]\]-->/g, '<![CDATA[$1]]>');\r
-\r
-                               // Restore the \u00a0 character if raw mode is enabled\r
-                               if (s.entity_encoding == 'raw')\r
-                                       h = h.replace(/<p>&nbsp;<\/p>|<p([^>]+)>&nbsp;<\/p>/g, '<p$1>\u00a0</p>');\r
+                               if (elm && elm.nodeType == 3)\r
+                                       return elm.parentNode;\r
 \r
-                               // Restore noscript elements\r
-                               h = h.replace(/<noscript([^>]+|)>([\s\S]*?)<\/noscript>/g, function(v, attribs, text) {\r
-                                       return '<noscript' + attribs + '>' + t.dom.decode(text.replace(/<!--|-->/g, '')) + '</noscript>';\r
-                               });\r
+                               return elm;\r
                        }\r
 \r
-                       o.content = h;\r
+                       return rng.item ? rng.item(0) : rng.parentElement();\r
                },\r
 \r
-               _serializeNode : function(n, inner) {\r
-                       var t = this, s = t.settings, w = t.writer, hc, el, cn, i, l, a, at, no, v, nn, ru, ar, iv, closed, keep, type;\r
+               getSelectedBlocks : function(st, en) {\r
+                       var t = this, dom = t.dom, sb, eb, n, bl = [];\r
 \r
-                       if (!s.node_filter || s.node_filter(n)) {\r
-                               switch (n.nodeType) {\r
-                                       case 1: // Element\r
-                                               if (n.hasAttribute ? n.hasAttribute('_mce_bogus') : n.getAttribute('_mce_bogus'))\r
-                                                       return;\r
+                       sb = dom.getParent(st || t.getStart(), dom.isBlock);\r
+                       eb = dom.getParent(en || t.getEnd(), dom.isBlock);\r
 \r
-                                               iv = keep = false;\r
-                                               hc = n.hasChildNodes();\r
-                                               nn = n.getAttribute('_mce_name') || n.nodeName.toLowerCase();\r
+                       if (sb)\r
+                               bl.push(sb);\r
 \r
-                                               // Get internal type\r
-                                               type = n.getAttribute('_mce_type');\r
-                                               if (type) {\r
-                                                       if (!t._info.cleanup) {\r
-                                                               iv = true;\r
-                                                               return;\r
-                                                       } else\r
-                                                               keep = 1;\r
-                                               }\r
+                       if (sb && eb && sb != eb) {\r
+                               n = sb;\r
 \r
-                                               // Add correct prefix on IE\r
-                                               if (isIE) {\r
-                                                       if (n.scopeName !== 'HTML' && n.scopeName !== 'html')\r
-                                                               nn = n.scopeName + ':' + nn;\r
-                                               }\r
+                               while ((n = n.nextSibling) && n != eb) {\r
+                                       if (dom.isBlock(n))\r
+                                               bl.push(n);\r
+                               }\r
+                       }\r
 \r
-                                               // Remove mce prefix on IE needed for the abbr element\r
-                                               if (nn.indexOf('mce:') === 0)\r
-                                                       nn = nn.substring(4);\r
+                       if (eb && sb != eb)\r
+                               bl.push(eb);\r
 \r
-                                               // Check if valid\r
-                                               if (!keep) {\r
-                                                       if (!t.validElementsRE || !t.validElementsRE.test(nn) || (t.invalidElementsRE && t.invalidElementsRE.test(nn)) || inner) {\r
-                                                               iv = true;\r
-                                                               break;\r
-                                                       }\r
-                                               }\r
+                       return bl;\r
+               },\r
 \r
-                                               if (isIE) {\r
-                                                       // Fix IE content duplication (DOM can have multiple copies of the same node)\r
-                                                       if (s.fix_content_duplication) {\r
-                                                               if (n._mce_serialized == t.key)\r
-                                                                       return;\r
+               destroy : function(s) {\r
+                       var t = this;\r
 \r
-                                                               n._mce_serialized = t.key;\r
-                                                       }\r
+                       t.win = null;\r
 \r
-                                                       // IE sometimes adds a / infront of the node name\r
-                                                       if (nn.charAt(0) == '/')\r
-                                                               nn = nn.substring(1);\r
-                                               } else if (isGecko) {\r
-                                                       // Ignore br elements\r
-                                                       if (n.nodeName === 'BR' && n.getAttribute('type') == '_moz')\r
-                                                               return;\r
-                                               }\r
+                       if (t.tridentSel)\r
+                               t.tridentSel.destroy();\r
+\r
+                       // Manual destroy then remove unload handler\r
+                       if (!s)\r
+                               tinymce.removeUnload(t.destroy);\r
+               },\r
+\r
+               // IE has an issue where you can't select/move the caret by clicking outside the body if the document is in standards mode\r
+               _fixIESelection : function() {\r
+                       var dom = this.dom, doc = dom.doc, body = doc.body, started, startRng, htmlElm;\r
 \r
-                                               // Check if valid child\r
-                                               if (s.validate_children) {\r
-                                                       if (t.elementName && !t.schema.isValid(t.elementName, nn)) {\r
-                                                               iv = true;\r
-                                                               break;\r
-                                                       }\r
+                       // Make HTML element unselectable since we are going to handle selection by hand\r
+                       doc.documentElement.unselectable = true;\r
 \r
-                                                       t.elementName = nn;\r
-                                               }\r
+                       // Return range from point or null if it failed\r
+                       function rngFromPoint(x, y) {\r
+                               var rng = body.createTextRange();\r
 \r
-                                               ru = t.findRule(nn);\r
-                                               \r
-                                               // No valid rule for this element could be found then skip it\r
-                                               if (!ru) {\r
-                                                       iv = true;\r
-                                                       break;\r
-                                               }\r
+                               try {\r
+                                       rng.moveToPoint(x, y);\r
+                               } catch (ex) {\r
+                                       // IE sometimes throws and exception, so lets just ignore it\r
+                                       rng = null;\r
+                               }\r
 \r
-                                               nn = ru.name || nn;\r
-                                               closed = s.closed.test(nn);\r
+                               return rng;\r
+                       };\r
 \r
-                                               // Skip empty nodes or empty node name in IE\r
-                                               if ((!hc && ru.noEmpty) || (isIE && !nn)) {\r
-                                                       iv = true;\r
-                                                       break;\r
-                                               }\r
+                       // Fires while the selection is changing\r
+                       function selectionChange(e) {\r
+                               var pointRng;\r
 \r
-                                               // Check required\r
-                                               if (ru.requiredAttribs) {\r
-                                                       a = ru.requiredAttribs;\r
+                               // Check if the button is down or not\r
+                               if (e.button) {\r
+                                       // Create range from mouse position\r
+                                       pointRng = rngFromPoint(e.x, e.y);\r
 \r
-                                                       for (i = a.length - 1; i >= 0; i--) {\r
-                                                               if (this.dom.getAttrib(n, a[i]) !== '')\r
-                                                                       break;\r
-                                                       }\r
+                                       if (pointRng) {\r
+                                               // Check if pointRange is before/after selection then change the endPoint\r
+                                               if (pointRng.compareEndPoints('StartToStart', startRng) > 0)\r
+                                                       pointRng.setEndPoint('StartToStart', startRng);\r
+                                               else\r
+                                                       pointRng.setEndPoint('EndToEnd', startRng);\r
 \r
-                                                       // None of the required was there\r
-                                                       if (i == -1) {\r
-                                                               iv = true;\r
-                                                               break;\r
-                                                       }\r
-                                               }\r
+                                               pointRng.select();\r
+                                       }\r
+                               } else\r
+                                       endSelection();\r
+                       }\r
 \r
-                                               w.writeStartElement(nn);\r
+                       // Removes listeners\r
+                       function endSelection() {\r
+                               var rng = doc.selection.createRange();\r
 \r
-                                               // Add ordered attributes\r
-                                               if (ru.attribs) {\r
-                                                       for (i=0, at = ru.attribs, l = at.length; i<l; i++) {\r
-                                                               a = at[i];\r
-                                                               v = t._getAttrib(n, a);\r
+                               // If the range is collapsed then use the last start range\r
+                               if (startRng && !rng.item && rng.compareEndPoints('StartToEnd', rng) === 0)\r
+                                       startRng.select();\r
 \r
-                                                               if (v !== null)\r
-                                                                       w.writeAttribute(a.name, v);\r
-                                                       }\r
-                                               }\r
+                               dom.unbind(doc, 'mouseup', endSelection);\r
+                               dom.unbind(doc, 'mousemove', selectionChange);\r
+                               startRng = started = 0;\r
+                       };\r
 \r
-                                               // Add wild attributes\r
-                                               if (ru.validAttribsRE) {\r
-                                                       at = t.dom.getAttribs(n);\r
-                                                       for (i=at.length-1; i>-1; i--) {\r
-                                                               no = at[i];\r
+                       // Detect when user selects outside BODY\r
+                       dom.bind(doc, ['mousedown', 'contextmenu'], function(e) {\r
+                               if (e.target.nodeName === 'HTML') {\r
+                                       if (started)\r
+                                               endSelection();\r
 \r
-                                                               if (no.specified) {\r
-                                                                       a = no.nodeName.toLowerCase();\r
+                                       // Detect vertical scrollbar, since IE will fire a mousedown on the scrollbar and have target set as HTML\r
+                                       htmlElm = doc.documentElement;\r
+                                       if (htmlElm.scrollHeight > htmlElm.clientHeight)\r
+                                               return;\r
 \r
-                                                                       if (s.invalid_attrs.test(a) || !ru.validAttribsRE.test(a))\r
-                                                                               continue;\r
+                                       started = 1;\r
+                                       // Setup start position\r
+                                       startRng = rngFromPoint(e.x, e.y);\r
+                                       if (startRng) {\r
+                                               // Listen for selection change events\r
+                                               dom.bind(doc, 'mouseup', endSelection);\r
+                                               dom.bind(doc, 'mousemove', selectionChange);\r
+\r
+                                               dom.win.focus();\r
+                                               startRng.select();\r
+                                       }\r
+                               }\r
+                       });\r
+               }\r
+       });\r
+})(tinymce);\r
 \r
-                                                                       ar = t.findAttribRule(ru, a);\r
-                                                                       v = t._getAttrib(n, ar, a);\r
+(function(tinymce) {\r
+       tinymce.dom.Serializer = function(settings, dom, schema) {\r
+               var onPreProcess, onPostProcess, isIE = tinymce.isIE, each = tinymce.each, htmlParser;\r
 \r
-                                                                       if (v !== null)\r
-                                                                               w.writeAttribute(a, v);\r
-                                                               }\r
-                                                       }\r
-                                               }\r
+               // Support the old apply_source_formatting option\r
+               if (!settings.apply_source_formatting)\r
+                       settings.indent = false;\r
 \r
-                                               // Keep type attribute\r
-                                               if (type && keep)\r
-                                                       w.writeAttribute('_mce_type', type);\r
+               settings.remove_trailing_brs = true;\r
 \r
-                                               // Write text from script\r
-                                               if (nn === 'script' && tinymce.trim(n.innerHTML)) {\r
-                                                       w.writeText('// '); // Padd it with a comment so it will parse on older browsers\r
-                                                       w.writeCDATA(n.innerHTML.replace(/<!--|-->|<\[CDATA\[|\]\]>/g, '')); // Remove comments and cdata stuctures\r
-                                                       hc = false;\r
-                                                       break;\r
-                                               }\r
+               // Default DOM and Schema if they are undefined\r
+               dom = dom || tinymce.DOM;\r
+               schema = schema || new tinymce.html.Schema(settings);\r
+               settings.entity_encoding = settings.entity_encoding || 'named';\r
 \r
-                                               // Padd empty nodes with a &nbsp;\r
-                                               if (ru.padd) {\r
-                                                       // If it has only one bogus child, padd it anyway workaround for <td><br /></td> bug\r
-                                                       if (hc && (cn = n.firstChild) && cn.nodeType === 1 && n.childNodes.length === 1) {\r
-                                                               if (cn.hasAttribute ? cn.hasAttribute('_mce_bogus') : cn.getAttribute('_mce_bogus'))\r
-                                                                       w.writeText('\u00a0');\r
-                                                       } else if (!hc)\r
-                                                               w.writeText('\u00a0'); // No children then padd it\r
-                                               }\r
+               onPreProcess = new tinymce.util.Dispatcher(self);\r
 \r
-                                               break;\r
+               onPostProcess = new tinymce.util.Dispatcher(self);\r
 \r
-                                       case 3: // Text\r
-                                               // Check if valid child\r
-                                               if (s.validate_children && t.elementName && !t.schema.isValid(t.elementName, '#text'))\r
-                                                       return;\r
+               htmlParser = new tinymce.html.DomParser(settings, schema);\r
 \r
-                                               return w.writeText(n.nodeValue);\r
+               // Convert move data-mce-src, data-mce-href and data-mce-style into nodes or process them if needed\r
+               htmlParser.addAttributeFilter('src,href,style', function(nodes, name) {\r
+                       var i = nodes.length, node, value, internalName = 'data-mce-' + name, urlConverter = settings.url_converter, urlConverterScope = settings.url_converter_scope, undef;\r
 \r
-                                       case 4: // CDATA\r
-                                               return w.writeCDATA(n.nodeValue);\r
+                       while (i--) {\r
+                               node = nodes[i];\r
 \r
-                                       case 8: // Comment\r
-                                               return w.writeComment(n.nodeValue);\r
-                               }\r
-                       } else if (n.nodeType == 1)\r
-                               hc = n.hasChildNodes();\r
+                               value = node.attributes.map[internalName];\r
+                               if (value !== undef) {\r
+                                       // Set external name to internal value and remove internal\r
+                                       node.attr(name, value.length > 0 ? value : null);\r
+                                       node.attr(internalName, null);\r
+                               } else {\r
+                                       // No internal attribute found then convert the value we have in the DOM\r
+                                       value = node.attributes.map[name];\r
 \r
-                       if (hc && !closed) {\r
-                               cn = n.firstChild;\r
+                                       if (name === "style")\r
+                                               value = dom.serializeStyle(dom.parseStyle(value), node.name);\r
+                                       else if (urlConverter)\r
+                                               value = urlConverter.call(urlConverterScope, value, name, node.name);\r
 \r
-                               while (cn) {\r
-                                       t._serializeNode(cn);\r
-                                       t.elementName = nn;\r
-                                       cn = cn.nextSibling;\r
+                                       node.attr(name, value.length > 0 ? value : null);\r
                                }\r
                        }\r
+               });\r
 \r
-                       // Write element end\r
-                       if (!iv) {\r
-                               if (!closed)\r
-                                       w.writeFullEndElement();\r
-                               else\r
-                                       w.writeEndElement();\r
-                       }\r
-               },\r
+               // Remove internal classes mceItem<..>\r
+               htmlParser.addAttributeFilter('class', function(nodes, name) {\r
+                       var i = nodes.length, node, value;\r
 \r
-               _protect : function(o) {\r
-                       var t = this;\r
+                       while (i--) {\r
+                               node = nodes[i];\r
+                               value = node.attr('class').replace(/\s*mce(Item\w+|Selected)\s*/g, '');\r
+                               node.attr('class', value.length > 0 ? value : null);\r
+                       }\r
+               });\r
 \r
-                       o.items = o.items || [];\r
+               // Remove bookmark elements\r
+               htmlParser.addAttributeFilter('data-mce-type', function(nodes, name, args) {\r
+                       var i = nodes.length, node;\r
 \r
-                       function enc(s) {\r
-                               return s.replace(/[\r\n\\]/g, function(c) {\r
-                                       if (c === '\n')\r
-                                               return '\\n';\r
-                                       else if (c === '\\')\r
-                                               return '\\\\';\r
+                       while (i--) {\r
+                               node = nodes[i];\r
 \r
-                                       return '\\r';\r
-                               });\r
-                       };\r
+                               if (node.attributes.map['data-mce-type'] === 'bookmark' && !args.cleanup)\r
+                                       node.remove();\r
+                       }\r
+               });\r
 \r
-                       function dec(s) {\r
-                               return s.replace(/\\[\\rn]/g, function(c) {\r
-                                       if (c === '\\n')\r
-                                               return '\n';\r
-                                       else if (c === '\\\\')\r
-                                               return '\\';\r
+               // Force script into CDATA sections and remove the mce- prefix also add comments around styles\r
+               htmlParser.addNodeFilter('script,style', function(nodes, name) {\r
+                       var i = nodes.length, node, value;\r
 \r
-                                       return '\r';\r
-                               });\r
+                       function trim(value) {\r
+                               return value.replace(/(<!--\[CDATA\[|\]\]-->)/g, '\n')\r
+                                               .replace(/^[\r\n]*|[\r\n]*$/g, '')\r
+                                               .replace(/^\s*(\/\/\s*<!--|\/\/\s*<!\[CDATA\[|<!--|<!\[CDATA\[)[\r\n]*/g, '')\r
+                                               .replace(/\s*(\/\/\s*\]\]>|\/\/\s*-->|\]\]>|-->|\]\]-->)\s*$/g, '');\r
                        };\r
 \r
-                       each(o.patterns, function(p) {\r
-                               o.content = dec(enc(o.content).replace(p.pattern, function(x, a, b, c) {\r
-                                       b = dec(b);\r
+                       while (i--) {\r
+                               node = nodes[i];\r
+                               value = node.firstChild ? node.firstChild.value : '';\r
 \r
-                                       if (p.encode)\r
-                                               b = t._encode(b);\r
-\r
-                                       o.items.push(b);\r
-                                       return a + '<!--mce:' + (o.items.length - 1) + '-->' + c;\r
-                               }));\r
-                       });\r
+                               if (name === "script") {\r
+                                       // Remove mce- prefix from script elements\r
+                                       node.attr('type', (node.attr('type') || 'text/javascript').replace(/^mce\-/, ''));\r
 \r
-                       return o;\r
-               },\r
+                                       if (value.length > 0)\r
+                                               node.firstChild.value = '// <![CDATA[\n' + trim(value) + '\n// ]]>';\r
+                               } else {\r
+                                       if (value.length > 0)\r
+                                               node.firstChild.value = '<!--\n' + trim(value) + '\n-->';\r
+                               }\r
+                       }\r
+               });\r
 \r
-               _unprotect : function(h, o) {\r
-                       h = h.replace(/\<!--mce:([0-9]+)--\>/g, function(a, b) {\r
-                               return o.items[parseInt(b)];\r
-                       });\r
+               // Convert comments to cdata and handle protected comments\r
+               htmlParser.addNodeFilter('#comment', function(nodes, name) {\r
+                       var i = nodes.length, node;\r
 \r
-                       o.items = [];\r
+                       while (i--) {\r
+                               node = nodes[i];\r
 \r
-                       return h;\r
-               },\r
+                               if (node.value.indexOf('[CDATA[') === 0) {\r
+                                       node.name = '#cdata';\r
+                                       node.type = 4;\r
+                                       node.value = node.value.replace(/^\[CDATA\[|\]\]$/g, '');\r
+                               } else if (node.value.indexOf('mce:protected ') === 0) {\r
+                                       node.name = "#text";\r
+                                       node.type = 3;\r
+                                       node.raw = true;\r
+                                       node.value = unescape(node.value).substr(14);\r
+                               }\r
+                       }\r
+               });\r
 \r
-               _encode : function(h) {\r
-                       var t = this, s = t.settings, l;\r
+               htmlParser.addNodeFilter('xml:namespace,input', function(nodes, name) {\r
+                       var i = nodes.length, node;\r
 \r
-                       // Entity encode\r
-                       if (s.entity_encoding !== 'raw') {\r
-                               if (s.entity_encoding.indexOf('named') != -1) {\r
-                                       t.setEntities(s.entities);\r
-                                       l = t.entityLookup;\r
+                       while (i--) {\r
+                               node = nodes[i];\r
+                               if (node.type === 7)\r
+                                       node.remove();\r
+                               else if (node.type === 1) {\r
+                                       if (name === "input" && !("type" in node.attributes.map))\r
+                                               node.attr('type', 'text');\r
+                               }\r
+                       }\r
+               });\r
 \r
-                                       h = h.replace(/[\u007E-\uFFFF]/g, function(a) {\r
-                                               var v;\r
+               // Fix list elements, TODO: Replace this later\r
+               if (settings.fix_list_elements) {\r
+                       htmlParser.addNodeFilter('ul,ol', function(nodes, name) {\r
+                               var i = nodes.length, node, parentNode;\r
 \r
-                                               if (v = l[a])\r
-                                                       a = '&' + v + ';';\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       parentNode = node.parent;\r
 \r
-                                               return a;\r
-                                       });\r
+                                       if (parentNode.name === 'ul' || parentNode.name === 'ol') {\r
+                                               if (node.prev && node.prev.name === 'li') {\r
+                                                       node.prev.append(node);\r
+                                               }\r
+                                       }\r
                                }\r
+                       });\r
+               }\r
 \r
-                               if (s.entity_encoding.indexOf('numeric') != -1) {\r
-                                       h = h.replace(/[\u007E-\uFFFF]/g, function(a) {\r
-                                               return '&#' + a.charCodeAt(0) + ';';\r
-                                       });\r
-                               }\r
+               // Remove internal data attributes\r
+               htmlParser.addAttributeFilter('data-mce-src,data-mce-href,data-mce-style', function(nodes, name) {\r
+                       var i = nodes.length;\r
+\r
+                       while (i--) {\r
+                               nodes[i].attr(name, null);\r
                        }\r
+               });\r
 \r
-                       return h;\r
-               },\r
+               // Return public methods\r
+               return {\r
+                       schema : schema,\r
 \r
-               _setup : function() {\r
-                       var t = this, s = this.settings;\r
+                       addNodeFilter : htmlParser.addNodeFilter,\r
 \r
-                       if (t.done)\r
-                               return;\r
+                       addAttributeFilter : htmlParser.addAttributeFilter,\r
 \r
-                       t.done = 1;\r
+                       onPreProcess : onPreProcess,\r
 \r
-                       t.setRules(s.valid_elements);\r
-                       t.addRules(s.extended_valid_elements);\r
+                       onPostProcess : onPostProcess,\r
 \r
-                       if (s.invalid_elements)\r
-                               t.invalidElementsRE = new RegExp('^(' + wildcardToRE(s.invalid_elements.replace(/,/g, '|').toLowerCase()) + ')$');\r
+                       serialize : function(node, args) {\r
+                               var impl, doc, oldDoc, htmlSerializer, content;\r
 \r
-                       if (s.attrib_value_filter)\r
-                               t.attribValueFilter = s.attribValueFilter;\r
-               },\r
+                               // Explorer won't clone contents of script and style and the\r
+                               // selected index of select elements are cleared on a clone operation.\r
+                               if (isIE && dom.select('script,style,select').length > 0) {\r
+                                       content = node.innerHTML;\r
+                                       node = node.cloneNode(false);\r
+                                       dom.setHTML(node, content);\r
+                               } else\r
+                                       node = node.cloneNode(true);\r
+\r
+                               // Nodes needs to be attached to something in WebKit/Opera\r
+                               // Older builds of Opera crashes if you attach the node to an document created dynamically\r
+                               // and since we can't feature detect a crash we need to sniff the acutal build number\r
+                               // This fix will make DOM ranges and make Sizzle happy!\r
+                               impl = node.ownerDocument.implementation;\r
+                               if (impl.createHTMLDocument) {\r
+                                       // Create an empty HTML document\r
+                                       doc = impl.createHTMLDocument("");\r
+\r
+                                       // Add the element or it's children if it's a body element to the new document\r
+                                       each(node.nodeName == 'BODY' ? node.childNodes : [node], function(node) {\r
+                                               doc.body.appendChild(doc.importNode(node, true));\r
+                                       });\r
 \r
-               _getAttrib : function(n, a, na) {\r
-                       var i, v;\r
+                                       // Grab first child or body element for serialization\r
+                                       if (node.nodeName != 'BODY')\r
+                                               node = doc.body.firstChild;\r
+                                       else\r
+                                               node = doc.body;\r
 \r
-                       na = na || a.name;\r
+                                       // set the new document in DOMUtils so createElement etc works\r
+                                       oldDoc = dom.doc;\r
+                                       dom.doc = doc;\r
+                               }\r
 \r
-                       if (a.forcedVal && (v = a.forcedVal)) {\r
-                               if (v === '{$uid}')\r
-                                       return this.dom.uniqueId();\r
+                               args = args || {};\r
+                               args.format = args.format || 'html';\r
 \r
-                               return v;\r
-                       }\r
+                               // Pre process\r
+                               if (!args.no_events) {\r
+                                       args.node = node;\r
+                                       onPreProcess.dispatch(self, args);\r
+                               }\r
 \r
-                       v = this.dom.getAttrib(n, na);\r
+                               // Setup serializer\r
+                               htmlSerializer = new tinymce.html.Serializer(settings, schema);\r
 \r
-                       switch (na) {\r
-                               case 'rowspan':\r
-                               case 'colspan':\r
-                                       // Whats the point? Remove usless attribute value\r
-                                       if (v == '1')\r
-                                               v = '';\r
+                               // Parse and serialize HTML\r
+                               args.content = htmlSerializer.serialize(\r
+                                       htmlParser.parse(args.getInner ? node.innerHTML : tinymce.trim(dom.getOuterHTML(node), args), args)\r
+                               );\r
 \r
-                                       break;\r
-                       }\r
+                               // Replace all BOM characters for now until we can find a better solution\r
+                               if (!args.cleanup)\r
+                                       args.content = args.content.replace(/\uFEFF/g, '');\r
 \r
-                       if (this.attribValueFilter)\r
-                               v = this.attribValueFilter(na, v, n);\r
+                               // Post process\r
+                               if (!args.no_events)\r
+                                       onPostProcess.dispatch(self, args);\r
 \r
-                       if (a.validVals) {\r
-                               for (i = a.validVals.length - 1; i >= 0; i--) {\r
-                                       if (v == a.validVals[i])\r
-                                               break;\r
-                               }\r
+                               // Restore the old document if it was changed\r
+                               if (oldDoc)\r
+                                       dom.doc = oldDoc;\r
 \r
-                               if (i == -1)\r
-                                       return null;\r
-                       }\r
+                               args.node = null;\r
 \r
-                       if (v === '' && typeof(a.defaultVal) != 'undefined') {\r
-                               v = a.defaultVal;\r
+                               return args.content;\r
+                       },\r
 \r
-                               if (v === '{$uid}')\r
-                                       return this.dom.uniqueId();\r
+                       addRules : function(rules) {\r
+                               schema.addValidElements(rules);\r
+                       },\r
 \r
-                               return v;\r
-                       } else {\r
-                               // Remove internal mceItemXX classes when content is extracted from editor\r
-                               if (na == 'class' && this.processObj.get)\r
-                                       v = v.replace(/\s?mceItem\w+\s?/g, '');\r
+                       setRules : function(rules) {\r
+                               schema.setValidElements(rules);\r
                        }\r
-\r
-                       if (v === '')\r
-                               return null;\r
-\r
-\r
-                       return v;\r
-               }\r
-       });\r
+               };\r
+       };\r
 })(tinymce);\r
-\r
 (function(tinymce) {\r
        tinymce.dom.ScriptLoader = function(settings) {\r
                var QUEUED = 0,\r
@@ -6850,6 +7976,17 @@ window.tinymce.dom.Sizzle = Sizzle;
 \r
                                callback();\r
                        };\r
+                       \r
+                       function error() {\r
+                               // Report the error so it's easier for people to spot loading errors\r
+                               if (typeof(console) !== "undefined" && console.log)\r
+                                       console.log("Failed to load: " + url);\r
+\r
+                               // We can't mark it as done if there is a load error since\r
+                               // A) We don't want to produce 404 errors on the server and\r
+                               // B) the onerror event won't fire on all browsers.\r
+                               // done();\r
+                       };\r
 \r
                        id = dom.uniqueId();\r
 \r
@@ -6859,7 +7996,7 @@ window.tinymce.dom.Sizzle = Sizzle;
 \r
                                // If script is from same domain and we\r
                                // use IE 6 then use XHR since it's more reliable\r
-                               if (uri.host == loc.hostname && uri.port == loc.port && (uri.protocol + ':') == loc.protocol) {\r
+                               if (uri.host == loc.hostname && uri.port == loc.port && (uri.protocol + ':') == loc.protocol && uri.protocol.toLowerCase() != 'file') {\r
                                        tinymce.util.XHR.send({\r
                                                url : tinymce._addVer(uri.getURI()),\r
                                                success : function(content) {\r
@@ -6874,7 +8011,9 @@ window.tinymce.dom.Sizzle = Sizzle;
                                                        dom.remove(script);\r
 \r
                                                        done();\r
-                                               }\r
+                                               },\r
+                                               \r
+                                               error : error\r
                                        });\r
 \r
                                        return;\r
@@ -6888,17 +8027,26 @@ window.tinymce.dom.Sizzle = Sizzle;
                                src : tinymce._addVer(url)\r
                        });\r
 \r
-                       // Add onload and readystate listeners\r
-                       elm.onload = done;\r
-                       elm.onreadystatechange = function() {\r
-                               var state = elm.readyState;\r
+                       // Add onload listener for non IE browsers since IE9\r
+                       // fires onload event before the script is parsed and executed\r
+                       if (!tinymce.isIE)\r
+                               elm.onload = done;\r
 \r
-                               // Loaded state is passed on IE 6 however there\r
-                               // are known issues with this method but we can't use\r
-                               // XHR in a cross domain loading\r
-                               if (state == 'complete' || state == 'loaded')\r
-                                       done();\r
-                       };\r
+                       // Add onerror event will get fired on some browsers but not all of them\r
+                       elm.onerror = error;\r
+\r
+                       // Opera 9.60 doesn't seem to fire the onreadystate event at correctly\r
+                       if (!tinymce.isOpera) {\r
+                               elm.onreadystatechange = function() {\r
+                                       var state = elm.readyState;\r
+\r
+                                       // Loaded state is passed on IE 6 however there\r
+                                       // are known issues with this method but we can't use\r
+                                       // XHR in a cross domain loading\r
+                                       if (state == 'complete' || state == 'loaded')\r
+                                               done();\r
+                               };\r
+                       }\r
 \r
                        // Most browsers support this feature so we report errors\r
                        // for those at least to help users track their missing plugins etc\r
@@ -7046,164 +8194,10 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
        };\r
 \r
        this.prev = function(shallow) {\r
-               return (node = findSibling(node, 'lastChild', 'lastSibling', shallow));\r
+               return (node = findSibling(node, 'lastChild', 'previousSibling', shallow));\r
        };\r
 };\r
 \r
-(function() {\r
-       var transitional = {};\r
-\r
-       function unpack(lookup, data) {\r
-               var key;\r
-\r
-               function replace(value) {\r
-                       return value.replace(/[A-Z]+/g, function(key) {\r
-                               return replace(lookup[key]);\r
-                       });\r
-               };\r
-\r
-               // Unpack lookup\r
-               for (key in lookup) {\r
-                       if (lookup.hasOwnProperty(key))\r
-                               lookup[key] = replace(lookup[key]);\r
-               }\r
-\r
-               // Unpack and parse data into object map\r
-               replace(data).replace(/#/g, '#text').replace(/(\w+)\[([^\]]+)\]/g, function(str, name, children) {\r
-                       var i, map = {};\r
-\r
-                       children = children.split(/\|/);\r
-\r
-                       for (i = children.length - 1; i >= 0; i--)\r
-                               map[children[i]] = 1;\r
-\r
-                       transitional[name] = map;\r
-               });\r
-       };\r
-\r
-       // This is the XHTML 1.0 transitional elements with it's children packed to reduce it's size\r
-       // we will later include the attributes here and use it as a default for valid elements but it\r
-       // requires us to rewrite the serializer engine\r
-       unpack({\r
-               Z : '#|H|K|N|O|P',\r
-               Y : '#|X|form|R|Q',\r
-               X : 'p|T|div|U|W|isindex|fieldset|table',\r
-               W : 'pre|hr|blockquote|address|center|noframes',\r
-               U : 'ul|ol|dl|menu|dir',\r
-               ZC : '#|p|Y|div|U|W|table|br|span|bdo|object|applet|img|map|K|N|Q',\r
-               T : 'h1|h2|h3|h4|h5|h6',\r
-               ZB : '#|X|S|Q',\r
-               S : 'R|P',\r
-               ZA : '#|a|G|J|M|O|P',\r
-               R : '#|a|H|K|N|O',\r
-               Q : 'noscript|P',\r
-               P : 'ins|del|script',\r
-               O : 'input|select|textarea|label|button',\r
-               N : 'M|L',\r
-               M : 'em|strong|dfn|code|q|samp|kbd|var|cite|abbr|acronym',\r
-               L : 'sub|sup',\r
-               K : 'J|I',\r
-               J : 'tt|i|b|u|s|strike',\r
-               I : 'big|small|font|basefont',\r
-               H : 'G|F',\r
-               G : 'br|span|bdo',\r
-               F : 'object|applet|img|map|iframe'\r
-       }, 'script[]' + \r
-               'style[]' + \r
-               'object[#|param|X|form|a|H|K|N|O|Q]' + \r
-               'param[]' + \r
-               'p[S]' + \r
-               'a[Z]' + \r
-               'br[]' + \r
-               'span[S]' + \r
-               'bdo[S]' + \r
-               'applet[#|param|X|form|a|H|K|N|O|Q]' + \r
-               'h1[S]' + \r
-               'img[]' + \r
-               'map[X|form|Q|area]' + \r
-               'h2[S]' + \r
-               'iframe[#|X|form|a|H|K|N|O|Q]' + \r
-               'h3[S]' + \r
-               'tt[S]' + \r
-               'i[S]' + \r
-               'b[S]' + \r
-               'u[S]' + \r
-               's[S]' + \r
-               'strike[S]' + \r
-               'big[S]' + \r
-               'small[S]' + \r
-               'font[S]' + \r
-               'basefont[]' + \r
-               'em[S]' + \r
-               'strong[S]' + \r
-               'dfn[S]' + \r
-               'code[S]' + \r
-               'q[S]' + \r
-               'samp[S]' + \r
-               'kbd[S]' + \r
-               'var[S]' + \r
-               'cite[S]' + \r
-               'abbr[S]' + \r
-               'acronym[S]' + \r
-               'sub[S]' + \r
-               'sup[S]' + \r
-               'input[]' + \r
-               'select[optgroup|option]' + \r
-               'optgroup[option]' + \r
-               'option[]' + \r
-               'textarea[]' + \r
-               'label[S]' + \r
-               'button[#|p|T|div|U|W|table|G|object|applet|img|map|K|N|Q]' + \r
-               'h4[S]' + \r
-               'ins[#|X|form|a|H|K|N|O|Q]' + \r
-               'h5[S]' + \r
-               'del[#|X|form|a|H|K|N|O|Q]' + \r
-               'h6[S]' + \r
-               'div[#|X|form|a|H|K|N|O|Q]' + \r
-               'ul[li]' + \r
-               'li[#|X|form|a|H|K|N|O|Q]' + \r
-               'ol[li]' + \r
-               'dl[dt|dd]' + \r
-               'dt[S]' + \r
-               'dd[#|X|form|a|H|K|N|O|Q]' + \r
-               'menu[li]' + \r
-               'dir[li]' + \r
-               'pre[ZA]' + \r
-               'hr[]' + \r
-               'blockquote[#|X|form|a|H|K|N|O|Q]' + \r
-               'address[S|p]' + \r
-               'center[#|X|form|a|H|K|N|O|Q]' + \r
-               'noframes[#|X|form|a|H|K|N|O|Q]' + \r
-               'isindex[]' + \r
-               'fieldset[#|legend|X|form|a|H|K|N|O|Q]' + \r
-               'legend[S]' + \r
-               'table[caption|col|colgroup|thead|tfoot|tbody|tr]' + \r
-               'caption[S]' + \r
-               'col[]' + \r
-               'colgroup[col]' + \r
-               'thead[tr]' + \r
-               'tr[th|td]' + \r
-               'th[#|X|form|a|H|K|N|O|Q]' + \r
-               'form[#|X|a|H|K|N|O|Q]' + \r
-               'noscript[#|X|form|a|H|K|N|O|Q]' + \r
-               'td[#|X|form|a|H|K|N|O|Q]' + \r
-               'tfoot[tr]' + \r
-               'tbody[tr]' + \r
-               'area[]' + \r
-               'base[]' + \r
-               'body[#|X|form|a|H|K|N|O|Q]'\r
-       );\r
-\r
-       tinymce.dom.Schema = function() {\r
-               var t = this, elements = transitional;\r
-\r
-               t.isValid = function(name, child_name) {\r
-                       var element = elements[name];\r
-\r
-                       return !!(element && (!child_name || element[child_name]));\r
-               };\r
-       };\r
-})();\r
 (function(tinymce) {\r
        tinymce.dom.RangeUtils = function(dom) {\r
                var INVISIBLE_CHAR = '\uFEFF';\r
@@ -7267,7 +8261,7 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
 \r
                        // If index based end position then resolve it\r
                        if (endContainer.nodeType == 1 && endContainer.hasChildNodes())\r
-                               endContainer = endContainer.childNodes[Math.min(startOffset == endOffset ? endOffset : endOffset - 1, endContainer.childNodes.length - 1)];\r
+                               endContainer = endContainer.childNodes[Math.min(endOffset - 1, endContainer.childNodes.length - 1)];\r
 \r
                        // Find common ancestor and end points\r
                        ancestor = dom.findCommonAncestor(startContainer, endContainer);\r
@@ -7349,50 +8343,196 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
                                        startOffset = 0;\r
                                }\r
 \r
-                               // Split endContainer text node if needed\r
-                               if (endContainer.nodeType == 3 && endOffset != endContainer.nodeValue.length) {\r
-                                       endContainer = splitText(endContainer, endOffset).previousSibling;\r
-                                       endOffset = endContainer.nodeValue.length;\r
-                               }\r
-                       }\r
+                               // Split endContainer text node if needed\r
+                               if (endContainer.nodeType == 3 && endOffset != endContainer.nodeValue.length) {\r
+                                       endContainer = splitText(endContainer, endOffset).previousSibling;\r
+                                       endOffset = endContainer.nodeValue.length;\r
+                               }\r
+                       }\r
+\r
+                       return {\r
+                               startContainer : startContainer,\r
+                               startOffset : startOffset,\r
+                               endContainer : endContainer,\r
+                               endOffset : endOffset\r
+                       };\r
+               };\r
+*/\r
+       };\r
+\r
+       tinymce.dom.RangeUtils.compareRanges = function(rng1, rng2) {\r
+               if (rng1 && rng2) {\r
+                       // Compare native IE ranges\r
+                       if (rng1.item || rng1.duplicate) {\r
+                               // Both are control ranges and the selected element matches\r
+                               if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))\r
+                                       return true;\r
+\r
+                               // Both are text ranges and the range matches\r
+                               if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))\r
+                                       return true;\r
+                       } else {\r
+                               // Compare w3c ranges\r
+                               return rng1.startContainer == rng2.startContainer && rng1.startOffset == rng2.startOffset;\r
+                       }\r
+               }\r
+\r
+               return false;\r
+       };\r
+})(tinymce);\r
+\r
+(function(tinymce) {\r
+       var Event = tinymce.dom.Event, each = tinymce.each;\r
+\r
+       tinymce.create('tinymce.ui.KeyboardNavigation', {\r
+               KeyboardNavigation: function(settings, dom) {\r
+                       var t = this, root = settings.root, items = settings.items,\r
+                                       enableUpDown = settings.enableUpDown, enableLeftRight = settings.enableLeftRight || !settings.enableUpDown,\r
+                                       excludeFromTabOrder = settings.excludeFromTabOrder,\r
+                                       itemFocussed, itemBlurred, rootKeydown, rootFocussed, focussedId;\r
+\r
+                       dom = dom || tinymce.DOM;\r
+\r
+                       itemFocussed = function(evt) {\r
+                               focussedId = evt.target.id;\r
+                       };\r
+                       \r
+                       itemBlurred = function(evt) {\r
+                               dom.setAttrib(evt.target.id, 'tabindex', '-1');\r
+                       };\r
+                       \r
+                       rootFocussed = function(evt) {\r
+                               var item = dom.get(focussedId);\r
+                               dom.setAttrib(item, 'tabindex', '0');\r
+                               item.focus();\r
+                       };\r
+                       \r
+                       t.focus = function() {\r
+                               dom.get(focussedId).focus();\r
+                       };\r
+\r
+                       t.destroy = function() {\r
+                               each(items, function(item) {\r
+                                       dom.unbind(dom.get(item.id), 'focus', itemFocussed);\r
+                                       dom.unbind(dom.get(item.id), 'blur', itemBlurred);\r
+                               });\r
+\r
+                               dom.unbind(dom.get(root), 'focus', rootFocussed);\r
+                               dom.unbind(dom.get(root), 'keydown', rootKeydown);\r
+\r
+                               items = dom = root = t.focus = itemFocussed = itemBlurred = rootKeydown = rootFocussed = null;\r
+                               t.destroy = function() {};\r
+                       };\r
+                       \r
+                       t.moveFocus = function(dir, evt) {\r
+                               var idx = -1, controls = t.controls, newFocus;\r
+\r
+                               if (!focussedId)\r
+                                       return;\r
+\r
+                               each(items, function(item, index) {\r
+                                       if (item.id === focussedId) {\r
+                                               idx = index;\r
+                                               return false;\r
+                                       }\r
+                               });\r
+\r
+                               idx += dir;\r
+                               if (idx < 0) {\r
+                                       idx = items.length - 1;\r
+                               } else if (idx >= items.length) {\r
+                                       idx = 0;\r
+                               }\r
+                               \r
+                               newFocus = items[idx];\r
+                               dom.setAttrib(focussedId, 'tabindex', '-1');\r
+                               dom.setAttrib(newFocus.id, 'tabindex', '0');\r
+                               dom.get(newFocus.id).focus();\r
+\r
+                               if (settings.actOnFocus) {\r
+                                       settings.onAction(newFocus.id);\r
+                               }\r
+\r
+                               if (evt)\r
+                                       Event.cancel(evt);\r
+                       };\r
+                       \r
+                       rootKeydown = function(evt) {\r
+                               var DOM_VK_LEFT = 37, DOM_VK_RIGHT = 39, DOM_VK_UP = 38, DOM_VK_DOWN = 40, DOM_VK_ESCAPE = 27, DOM_VK_ENTER = 14, DOM_VK_RETURN = 13, DOM_VK_SPACE = 32;\r
+                               \r
+                               switch (evt.keyCode) {\r
+                                       case DOM_VK_LEFT:\r
+                                               if (enableLeftRight) t.moveFocus(-1);\r
+                                               break;\r
+       \r
+                                       case DOM_VK_RIGHT:\r
+                                               if (enableLeftRight) t.moveFocus(1);\r
+                                               break;\r
+       \r
+                                       case DOM_VK_UP:\r
+                                               if (enableUpDown) t.moveFocus(-1);\r
+                                               break;\r
+\r
+                                       case DOM_VK_DOWN:\r
+                                               if (enableUpDown) t.moveFocus(1);\r
+                                               break;\r
+\r
+                                       case DOM_VK_ESCAPE:\r
+                                               if (settings.onCancel) {\r
+                                                       settings.onCancel();\r
+                                                       Event.cancel(evt);\r
+                                               }\r
+                                               break;\r
+\r
+                                       case DOM_VK_ENTER:\r
+                                       case DOM_VK_RETURN:\r
+                                       case DOM_VK_SPACE:\r
+                                               if (settings.onAction) {\r
+                                                       settings.onAction(focussedId);\r
+                                                       Event.cancel(evt);\r
+                                               }\r
+                                               break;\r
+                               }\r
+                       };\r
+\r
+                       // Set up state and listeners for each item.\r
+                       each(items, function(item, idx) {\r
+                               var tabindex;\r
 \r
-                       return {\r
-                               startContainer : startContainer,\r
-                               startOffset : startOffset,\r
-                               endContainer : endContainer,\r
-                               endOffset : endOffset\r
-                       };\r
-               };\r
-*/\r
-       };\r
+                               if (!item.id) {\r
+                                       item.id = dom.uniqueId('_mce_item_');\r
+                               }\r
 \r
-       tinymce.dom.RangeUtils.compareRanges = function(rng1, rng2) {\r
-               if (rng1 && rng2) {\r
-                       // Compare native IE ranges\r
-                       if (rng1.item || rng1.duplicate) {\r
-                               // Both are control ranges and the selected element matches\r
-                               if (rng1.item && rng2.item && rng1.item(0) === rng2.item(0))\r
-                                       return true;\r
+                               if (excludeFromTabOrder) {\r
+                                       dom.bind(item.id, 'blur', itemBlurred);\r
+                                       tabindex = '-1';\r
+                               } else {\r
+                                       tabindex = (idx === 0 ? '0' : '-1');\r
+                               }\r
 \r
-                               // Both are text ranges and the range matches\r
-                               if (rng1.isEqual && rng2.isEqual && rng2.isEqual(rng1))\r
-                                       return true;\r
-                       } else {\r
-                               // Compare w3c ranges\r
-                               return rng1.startContainer == rng2.startContainer && rng1.startOffset == rng2.startOffset;\r
+                               dom.setAttrib(item.id, 'tabindex', tabindex);\r
+                               dom.bind(dom.get(item.id), 'focus', itemFocussed);\r
+                       });\r
+                       \r
+                       // Setup initial state for root element.\r
+                       if (items[0]){\r
+                               focussedId = items[0].id;\r
                        }\r
-               }\r
 \r
-               return false;\r
-       };\r
+                       dom.setAttrib(root, 'tabindex', '-1');\r
+                       \r
+                       // Setup listeners for root element.\r
+                       dom.bind(dom.get(root), 'focus', rootFocussed);\r
+                       dom.bind(dom.get(root), 'keydown', rootKeydown);\r
+               }\r
+       });\r
 })(tinymce);\r
-\r
 (function(tinymce) {\r
        // Shorten class names\r
        var DOM = tinymce.DOM, is = tinymce.is;\r
 \r
        tinymce.create('tinymce.ui.Control', {\r
-               Control : function(id, s) {\r
+               Control : function(id, s, editor) {\r
                        this.id = id;\r
                        this.settings = s = s || {};\r
                        this.rendered = false;\r
@@ -7401,22 +8541,23 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
                        this.scope = s.scope || this;\r
                        this.disabled = 0;\r
                        this.active = 0;\r
+                       this.editor = editor;\r
+               },\r
+               \r
+               setAriaProperty : function(property, value) {\r
+                       var element = DOM.get(this.id + '_aria') || DOM.get(this.id);\r
+                       if (element) {\r
+                               DOM.setAttrib(element, 'aria-' + property, !!value);\r
+                       }\r
+               },\r
+               \r
+               focus : function() {\r
+                       DOM.get(this.id).focus();\r
                },\r
 \r
                setDisabled : function(s) {\r
-                       var e;\r
-\r
                        if (s != this.disabled) {\r
-                               e = DOM.get(this.id);\r
-\r
-                               // Add accessibility title for unavailable actions\r
-                               if (e && this.settings.unavailable_prefix) {\r
-                                       if (s) {\r
-                                               this.prevTitle = e.title;\r
-                                               e.title = this.settings.unavailable_prefix + ": " + e.title;\r
-                                       } else\r
-                                               e.title = this.prevTitle;\r
-                               }\r
+                               this.setAriaProperty('disabled', s);\r
 \r
                                this.setState('Disabled', s);\r
                                this.setState('Enabled', !s);\r
@@ -7432,6 +8573,7 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
                        if (s != this.active) {\r
                                this.setState('Active', s);\r
                                this.active = s;\r
+                               this.setAriaProperty('pressed', s);\r
                        }\r
                },\r
 \r
@@ -7489,8 +8631,8 @@ tinymce.dom.TreeWalker = function(start_node, root_node) {
        });\r
 })(tinymce);\r
 tinymce.create('tinymce.ui.Container:tinymce.ui.Control', {\r
-       Container : function(id, s) {\r
-               this.parent(id, s);\r
+       Container : function(id, s, editor) {\r
+               this.parent(id, s, editor);\r
 \r
                this.controls = [];\r
 \r
@@ -7514,10 +8656,11 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        Separator : function(id, s) {\r
                this.parent(id, s);\r
                this.classPrefix = 'mceSeparator';\r
+               this.setDisabled(true);\r
        },\r
 \r
        renderHTML : function() {\r
-               return tinymce.DOM.createHTML('span', {'class' : this.classPrefix});\r
+               return tinymce.DOM.createHTML('span', {'class' : this.classPrefix, role : 'separator', 'aria-orientation' : 'vertical', tabindex : '-1'});\r
        }\r
 });\r
 \r
@@ -7532,6 +8675,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
 \r
                setSelected : function(s) {\r
                        this.setState('Selected', s);\r
+                       this.setAriaProperty('checked', !!s);\r
                        this.selected = s;\r
                },\r
 \r
@@ -7679,12 +8823,20 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        s['class'] = s['class'] || cs['class'];\r
                        s.vp_offset_x = s.vp_offset_x || cs.vp_offset_x;\r
                        s.vp_offset_y = s.vp_offset_y || cs.vp_offset_y;\r
+                       s.keyboard_focus = cs.keyboard_focus;\r
                        m = new tinymce.ui.DropMenu(s.id || DOM.uniqueId(), s);\r
 \r
                        m.onAddItem.add(t.onAddItem.dispatch, t.onAddItem);\r
 \r
                        return m;\r
                },\r
+               \r
+               focus : function() {\r
+                       var t = this;\r
+                       if (t.keyboardNav) {\r
+                               t.keyboardNav.focus();\r
+                       }\r
+               },\r
 \r
                update : function() {\r
                        var t = this, s = t.settings, tb = DOM.get('menu_' + t.id + '_tbl'), co = DOM.get('menu_' + t.id + '_co'), tw, th;\r
@@ -7808,13 +8960,13 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                        }\r
                                });\r
                        }\r
+                       \r
+                       Event.add(co, 'keydown', t._keyHandler, t);\r
 \r
                        t.onShowMenu.dispatch(t);\r
 \r
-                       if (s.keyboard_focus) {\r
-                               Event.add(co, 'keydown', t._keyHandler, t);\r
-                               DOM.select('a', 'menu_' + t.id)[0].focus(); // Select first link\r
-                               t._focusIdx = 0;\r
+                       if (s.keyboard_focus) { \r
+                               t._setupKeyboardNav(); \r
                        }\r
                },\r
 \r
@@ -7824,6 +8976,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        if (!t.isMenuVisible)\r
                                return;\r
 \r
+                       if (t.keyboardNav) t.keyboardNav.destroy();\r
                        Event.remove(co, 'mouseover', t.mouseOverFunc);\r
                        Event.remove(co, 'click', t.mouseClickFunc);\r
                        Event.remove(co, 'keydown', t._keyHandler);\r
@@ -7868,8 +9021,11 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                destroy : function() {\r
                        var t = this, co = DOM.get('menu_' + t.id);\r
 \r
+                       if (t.keyboardNav) t.keyboardNav.destroy();\r
                        Event.remove(co, 'mouseover', t.mouseOverFunc);\r
+                       Event.remove(DOM.select('a', co), 'focus', t.mouseOverFunc);\r
                        Event.remove(co, 'click', t.mouseClickFunc);\r
+                       Event.remove(co, 'keydown', t._keyHandler);\r
 \r
                        if (t.element)\r
                                t.element.remove();\r
@@ -7880,15 +9036,18 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                renderNode : function() {\r
                        var t = this, s = t.settings, n, tb, co, w;\r
 \r
-                       w = DOM.create('div', {id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:200000'});\r
-                       co = DOM.add(w, 'div', {id : 'menu_' + t.id + '_co', 'class' : t.classPrefix + (s['class'] ? ' ' + s['class'] : '')});\r
+                       w = DOM.create('div', {role: 'listbox', id : 'menu_' + t.id, 'class' : s['class'], 'style' : 'position:absolute;left:0;top:0;z-index:200000;outline:0'});\r
+                       if (t.settings.parent) {\r
+                               DOM.setAttrib(w, 'aria-parent', 'menu_' + t.settings.parent.id);\r
+                       }\r
+                       co = DOM.add(w, 'div', {role: 'presentation', id : 'menu_' + t.id + '_co', 'class' : t.classPrefix + (s['class'] ? ' ' + s['class'] : '')});\r
                        t.element = new Element('menu_' + t.id, {blocker : 1, container : s.container});\r
 \r
                        if (s.menu_line)\r
                                DOM.add(co, 'span', {'class' : t.classPrefix + 'Line'});\r
 \r
 //                     n = DOM.add(co, 'div', {id : 'menu_' + t.id + '_co', 'class' : 'mceMenuContainer'});\r
-                       n = DOM.add(co, 'table', {id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0});\r
+                       n = DOM.add(co, 'table', {role: 'presentation', id : 'menu_' + t.id + '_tbl', border : 0, cellPadding : 0, cellSpacing : 0});\r
                        tb = DOM.add(n, 'tbody');\r
 \r
                        each(t.items, function(o) {\r
@@ -7901,33 +9060,36 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                },\r
 \r
                // Internal functions\r
+               _setupKeyboardNav : function(){\r
+                       var contextMenu, menuItems, t=this; \r
+                       contextMenu = DOM.select('#menu_' + t.id)[0];\r
+                       menuItems = DOM.select('a[role=option]', 'menu_' + t.id);\r
+                       menuItems.splice(0,0,contextMenu);\r
+                       t.keyboardNav = new tinymce.ui.KeyboardNavigation({\r
+                               root: 'menu_' + t.id,\r
+                               items: menuItems,\r
+                               onCancel: function() {\r
+                                       t.hideMenu();\r
+                               },\r
+                               enableUpDown: true\r
+                       });\r
+                       contextMenu.focus();\r
+               },\r
 \r
-               _keyHandler : function(e) {\r
-                       var t = this, kc = e.keyCode;\r
-\r
-                       function focus(d) {\r
-                               var i = t._focusIdx + d, e = DOM.select('a', 'menu_' + t.id)[i];\r
-\r
-                               if (e) {\r
-                                       t._focusIdx = i;\r
-                                       e.focus();\r
-                               }\r
-                       };\r
-\r
-                       switch (kc) {\r
-                               case 38:\r
-                                       focus(-1); // Select first link\r
-                                       return;\r
-\r
-                               case 40:\r
-                                       focus(1);\r
-                                       return;\r
-\r
-                               case 13:\r
-                                       return;\r
-\r
-                               case 27:\r
-                                       return this.hideMenu();\r
+               _keyHandler : function(evt) {\r
+                       var t = this, e;\r
+                       switch (evt.keyCode) {\r
+                               case 37: // Left\r
+                                       if (t.settings.parent) {\r
+                                               t.hideMenu();\r
+                                               t.settings.parent.focus();\r
+                                               Event.cancel(evt);\r
+                                       }\r
+                                       break;\r
+                               case 39: // Right\r
+                                       if (t.mouseOverFunc)\r
+                                               t.mouseOverFunc(evt);\r
+                                       break;\r
                        }\r
                },\r
 \r
@@ -7945,8 +9107,13 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        }\r
 \r
                        n = ro = DOM.add(tb, 'tr', {id : o.id, 'class' : cp + 'Item ' + cp + 'ItemEnabled'});\r
-                       n = it = DOM.add(n, 'td');\r
-                       n = a = DOM.add(n, 'a', {href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});\r
+                       n = it = DOM.add(n, s.titleItem ? 'th' : 'td');\r
+                       n = a = DOM.add(n, 'a', {id: o.id + '_aria',  role: s.titleItem ? 'presentation' : 'option', href : 'javascript:;', onclick : "return false;", onmousedown : 'return false;'});\r
+\r
+                       if (s.parent) {\r
+                               DOM.setAttrib(a, 'aria-haspopup', 'true');\r
+                               DOM.setAttrib(a, 'aria-owns', 'menu_' + o.id);\r
+                       }\r
 \r
                        DOM.addClass(it, s['class']);\r
 //                     n = DOM.add(n, 'span', {'class' : 'item'});\r
@@ -7981,8 +9148,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        var DOM = tinymce.DOM;\r
 \r
        tinymce.create('tinymce.ui.Button:tinymce.ui.Control', {\r
-               Button : function(id, s) {\r
-                       this.parent(id, s);\r
+               Button : function(id, s, ed) {\r
+                       this.parent(id, s, ed);\r
                        this.classPrefix = 'mceButton';\r
                },\r
 \r
@@ -7990,13 +9157,15 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        var cp = this.classPrefix, s = this.settings, h, l;\r
 \r
                        l = DOM.encode(s.label || '');\r
-                       h = '<a id="' + this.id + '" href="javascript:;" class="' + cp + ' ' + cp + 'Enabled ' + s['class'] + (l ? ' ' + cp + 'Labeled' : '') +'" onmousedown="return false;" onclick="return false;" title="' + DOM.encode(s.title) + '">';\r
+                       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) + '">';\r
 \r
                        if (s.image)\r
-                               h += '<img class="mceIcon" src="' + s.image + '" />' + l + '</a>';\r
+                               h += '<img class="mceIcon" src="' + s.image + '" alt="' + DOM.encode(s.title) + '" />' + l;\r
                        else\r
-                               h += '<span class="mceIcon ' + s['class'] + '"></span>' + (l ? '<span class="' + cp + 'Label">' + l + '</span>' : '') + '</a>';\r
+                               h += '<span class="mceIcon ' + s['class'] + '"></span>' + (l ? '<span class="' + cp + 'Label">' + l + '</span>' : '');\r
 \r
+                       h += '<span class="mceVoiceLabel mceIconOnly" style="display: none;" id="' + this.id + '_voice">' + s.title + '</span>'; \r
+                       h += '</a>';\r
                        return h;\r
                },\r
 \r
@@ -8015,10 +9184,10 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each, Dispatcher = tinymce.util.Dispatcher;\r
 \r
        tinymce.create('tinymce.ui.ListBox:tinymce.ui.Control', {\r
-               ListBox : function(id, s) {\r
+               ListBox : function(id, s, ed) {\r
                        var t = this;\r
 \r
-                       t.parent(id, s);\r
+                       t.parent(id, s, ed);\r
 \r
                        t.items = [];\r
 \r
@@ -8076,12 +9245,13 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                        t.selectedIndex = idx;\r
                                        DOM.setHTML(e, DOM.encode(o.title));\r
                                        DOM.removeClass(e, 'mceTitle');\r
+                                       DOM.setAttrib(t.id, 'aria-valuenow', o.title);\r
                                } else {\r
                                        DOM.setHTML(e, DOM.encode(t.settings.title));\r
                                        DOM.addClass(e, 'mceTitle');\r
                                        t.selectedValue = t.selectedIndex = null;\r
+                                       DOM.setAttrib(t.id, 'aria-valuenow', t.settings.title);\r
                                }\r
-\r
                                e = 0;\r
                        }\r
                },\r
@@ -8106,10 +9276,11 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                renderHTML : function() {\r
                        var h = '', t = this, s = t.settings, cp = t.classPrefix;\r
 \r
-                       h = '<table id="' + t.id + '" cellpadding="0" cellspacing="0" class="' + cp + ' ' + cp + 'Enabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';\r
-                       h += '<td>' + DOM.createHTML('a', {id : t.id + '_text', href : 'javascript:;', 'class' : 'mceText', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>';\r
-                       h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', tabindex : -1, href : 'javascript:;', 'class' : 'mceOpen', onclick : "return false;", onmousedown : 'return false;'}, '<span></span>') + '</td>';\r
-                       h += '</tr></tbody></table>';\r
+                       h = '<span role="button" aria-haspopup="true" aria-labelledby="' + t.id +'_text" aria-describedby="' + t.id + '_voiceDesc"><table role="presentation" tabindex="0" id="' + t.id + '" cellpadding="0" cellspacing="0" class="' + cp + ' ' + cp + 'Enabled' + (s['class'] ? (' ' + s['class']) : '') + '"><tbody><tr>';\r
+                       h += '<td>' + DOM.createHTML('span', {id: t.id + '_voiceDesc', 'class': 'voiceLabel', style:'display:none;'}, t.settings.title); \r
+                       h += DOM.createHTML('a', {id : t.id + '_text', tabindex : -1, href : 'javascript:;', 'class' : 'mceText', onclick : "return false;", onmousedown : 'return false;'}, DOM.encode(t.settings.title)) + '</td>';\r
+                       h += '<td>' + DOM.createHTML('a', {id : t.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>';\r
+                       h += '</tr></tbody></table></span>';\r
 \r
                        return h;\r
                },\r
@@ -8159,6 +9330,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        var t = this;\r
 \r
                        if (t.menu && t.menu.isMenuVisible) {\r
+                               DOM.removeClass(t.id, t.classPrefix + 'Selected');\r
+\r
                                // Prevent double toogles by canceling the mouse click event to the button\r
                                if (e && e.type == "mousedown" && (e.target.id == t.id + '_text' || e.target.id == t.id + '_open'))\r
                                        return;\r
@@ -8181,7 +9354,10 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                max_height : 150\r
                        });\r
 \r
-                       m.onHideMenu.add(t.hideMenu, t);\r
+                       m.onHideMenu.add(function() {\r
+                               t.hideMenu();\r
+                               t.focus();\r
+                       });\r
 \r
                        m.add({\r
                                title : t.settings.title,\r
@@ -8222,40 +9398,39 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        var t = this, cp = t.classPrefix;\r
 \r
                        Event.add(t.id, 'click', t.showMenu, t);\r
-                       Event.add(t.id + '_text', 'focus', function() {\r
+                       Event.add(t.id, 'keydown', function(evt) {\r
+                               if (evt.keyCode == 32) { // Space\r
+                                       t.showMenu(evt);\r
+                                       Event.cancel(evt);\r
+                               }\r
+                       });\r
+                       Event.add(t.id, 'focus', function() {\r
                                if (!t._focused) {\r
-                                       t.keyDownHandler = Event.add(t.id + '_text', 'keydown', function(e) {\r
-                                               var idx = -1, v, kc = e.keyCode;\r
-\r
-                                               // Find current index\r
-                                               each(t.items, function(v, i) {\r
-                                                       if (t.selectedValue == v.value)\r
-                                                               idx = i;\r
-                                               });\r
-\r
-                                               // Move up/down\r
-                                               if (kc == 38)\r
-                                                       v = t.items[idx - 1];\r
-                                               else if (kc == 40)\r
-                                                       v = t.items[idx + 1];\r
-                                               else if (kc == 13) {\r
+                                       t.keyDownHandler = Event.add(t.id, 'keydown', function(e) {\r
+                                               if (e.keyCode == 40) {\r
+                                                       t.showMenu();\r
+                                                       Event.cancel(e);\r
+                                               }\r
+                                       });\r
+                                       t.keyPressHandler = Event.add(t.id, 'keypress', function(e) {\r
+                                               var v;\r
+                                               if (e.keyCode == 13) {\r
                                                        // Fake select on enter\r
                                                        v = t.selectedValue;\r
                                                        t.selectedValue = null; // Needs to be null to fake change\r
+                                                       Event.cancel(e);\r
                                                        t.settings.onselect(v);\r
-                                                       return Event.cancel(e);\r
-                                               }\r
-\r
-                                               if (v) {\r
-                                                       t.hideMenu();\r
-                                                       t.select(v.value);\r
                                                }\r
                                        });\r
                                }\r
 \r
                                t._focused = 1;\r
                        });\r
-                       Event.add(t.id + '_text', 'blur', function() {Event.remove(t.id + '_text', 'keydown', t.keyDownHandler); t._focused = 0;});\r
+                       Event.add(t.id, 'blur', function() {\r
+                               Event.remove(t.id, 'keydown', t.keyDownHandler);\r
+                               Event.remove(t.id, 'keypress', t.keyPressHandler);\r
+                               t._focused = 0;\r
+                       });\r
 \r
                        // Old IE doesn't have hover on all elements\r
                        if (tinymce.isIE6 || !DOM.boxModel) {\r
@@ -8292,6 +9467,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
 \r
                setDisabled : function(s) {\r
                        DOM.get(this.id).disabled = s;\r
+                       this.setAriaProperty('disabled', s);\r
                },\r
 \r
                isDisabled : function() {\r
@@ -8366,13 +9542,13 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                h += DOM.createHTML('option', {value : it.value}, it.title);\r
                        });\r
 \r
-                       h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox'}, h);\r
-\r
+                       h = DOM.createHTML('select', {id : t.id, 'class' : 'mceNativeListBox', 'aria-labelledby': t.id + '_aria'}, h);\r
+                       h += DOM.createHTML('span', {id : t.id + '_aria', 'style': 'display: none'}, t.settings.title);\r
                        return h;\r
                },\r
 \r
                postRender : function() {\r
-                       var t = this, ch;\r
+                       var t = this, ch, changeListenerAdded = true;\r
 \r
                        t.rendered = true;\r
 \r
@@ -8394,8 +9570,11 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                var bf;\r
 \r
                                Event.remove(t.id, 'change', ch);\r
+                               changeListenerAdded = false;\r
 \r
                                bf = Event.add(t.id, 'blur', function() {\r
+                                       if (changeListenerAdded) return;\r
+                                       changeListenerAdded = true;\r
                                        Event.add(t.id, 'change', onChange);\r
                                        Event.remove(t.id, 'blur', bf);\r
                                });\r
@@ -8414,8 +9593,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.ui.MenuButton:tinymce.ui.Button', {\r
-               MenuButton : function(id, s) {\r
-                       this.parent(id, s);\r
+               MenuButton : function(id, s, ed) {\r
+                       this.parent(id, s, ed);\r
 \r
                        this.onRenderMenu = new tinymce.util.Dispatcher(this);\r
 \r
@@ -8462,7 +9641,10 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                icons : t.settings.icons\r
                        });\r
 \r
-                       m.onHideMenu.add(t.hideMenu, t);\r
+                       m.onHideMenu.add(function() {\r
+                               t.hideMenu();\r
+                               t.focus();\r
+                       });\r
 \r
                        t.onRenderMenu.dispatch(t, m);\r
                        t.menu = m;\r
@@ -8504,8 +9686,8 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.ui.SplitButton:tinymce.ui.MenuButton', {\r
-               SplitButton : function(id, s) {\r
-                       this.parent(id, s);\r
+               SplitButton : function(id, s, ed) {\r
+                       this.parent(id, s, ed);\r
                        this.classPrefix = 'mceSplitButton';\r
                },\r
 \r
@@ -8515,33 +9697,50 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        h = '<tbody><tr>';\r
 \r
                        if (s.image)\r
-                               h1 = DOM.createHTML('img ', {src : s.image, 'class' : 'mceAction ' + s['class']});\r
+                               h1 = DOM.createHTML('img ', {src : s.image, role: 'presentation', 'class' : 'mceAction ' + s['class']});\r
                        else\r
                                h1 = DOM.createHTML('span', {'class' : 'mceAction ' + s['class']}, '');\r
 \r
-                       h += '<td>' + DOM.createHTML('a', {id : t.id + '_action', href : 'javascript:;', 'class' : 'mceAction ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';\r
+                       h1 += DOM.createHTML('span', {'class': 'mceVoiceLabel mceIconOnly', id: t.id + '_voice', style: 'display:none;'}, s.title);\r
+                       h += '<td >' + DOM.createHTML('a', {role: 'button', id : t.id + '_action', tabindex: '-1', href : 'javascript:;', 'class' : 'mceAction ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';\r
        \r
-                       h1 = DOM.createHTML('span', {'class' : 'mceOpen ' + s['class']});\r
-                       h += '<td>' + DOM.createHTML('a', {id : t.id + '_open', href : 'javascript:;', 'class' : 'mceOpen ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';\r
+                       h1 = DOM.createHTML('span', {'class' : 'mceOpen ' + s['class']}, '<span style="display:none;" class="mceIconOnly" aria-hidden="true">\u25BC</span>');\r
+                       h += '<td >' + DOM.createHTML('a', {role: 'button', id : t.id + '_open', tabindex: '-1', href : 'javascript:;', 'class' : 'mceOpen ' + s['class'], onclick : "return false;", onmousedown : 'return false;', title : s.title}, h1) + '</td>';\r
 \r
                        h += '</tr></tbody>';\r
-\r
-                       return DOM.createHTML('table', {id : t.id, 'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', onmousedown : 'return false;', title : s.title}, h);\r
+                       h = DOM.createHTML('table', {id : t.id, role: 'presentation', tabindex: '0',  'class' : 'mceSplitButton mceSplitButtonEnabled ' + s['class'], cellpadding : '0', cellspacing : '0', title : s.title}, h);\r
+                       return DOM.createHTML('span', {role: 'button', 'aria-labelledby': t.id + '_voice', 'aria-haspopup': 'true'}, h);\r
                },\r
 \r
                postRender : function() {\r
-                       var t = this, s = t.settings;\r
+                       var t = this, s = t.settings, activate;\r
 \r
                        if (s.onclick) {\r
-                               Event.add(t.id + '_action', 'click', function() {\r
-                                       if (!t.isDisabled())\r
+                               activate = function(evt) {\r
+                                       if (!t.isDisabled()) {\r
                                                s.onclick(t.value);\r
+                                               Event.cancel(evt);\r
+                                       }\r
+                               };\r
+                               Event.add(t.id + '_action', 'click', activate);\r
+                               Event.add(t.id, ['click', 'keydown'], function(evt) {\r
+                                       var DOM_VK_SPACE = 32, DOM_VK_ENTER = 14, DOM_VK_RETURN = 13, DOM_VK_UP = 38, DOM_VK_DOWN = 40;\r
+                                       if ((evt.keyCode === 32 || evt.keyCode === 13 || evt.keyCode === 14) && !evt.altKey && !evt.ctrlKey && !evt.metaKey) {\r
+                                               activate();\r
+                                               Event.cancel(evt);\r
+                                       } else if (evt.type === 'click' || evt.keyCode === DOM_VK_DOWN) {\r
+                                               t.showMenu();\r
+                                               Event.cancel(evt);\r
+                                       }\r
                                });\r
                        }\r
 \r
-                       Event.add(t.id + '_open', 'click', t.showMenu, t);\r
-                       Event.add(t.id + '_open', 'focus', function() {t._focused = 1;});\r
-                       Event.add(t.id + '_open', 'blur', function() {t._focused = 0;});\r
+                       Event.add(t.id + '_open', 'click', function (evt) {\r
+                               t.showMenu();\r
+                               Event.cancel(evt);\r
+                       });\r
+                       Event.add([t.id, t.id + '_open'], 'focus', function() {t._focused = 1;});\r
+                       Event.add([t.id, t.id + '_open'], 'blur', function() {t._focused = 0;});\r
 \r
                        // Old IE doesn't have hover on all elements\r
                        if (tinymce.isIE6 || !DOM.boxModel) {\r
@@ -8562,6 +9761,7 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
 \r
                        Event.clear(this.id + '_action');\r
                        Event.clear(this.id + '_open');\r
+                       Event.clear(this.id);\r
                }\r
        });\r
 })(tinymce);\r
@@ -8570,10 +9770,10 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        var DOM = tinymce.DOM, Event = tinymce.dom.Event, is = tinymce.is, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.ui.ColorSplitButton:tinymce.ui.SplitButton', {\r
-               ColorSplitButton : function(id, s) {\r
+               ColorSplitButton : function(id, s, ed) {\r
                        var t = this;\r
 \r
-                       t.parent(id, s);\r
+                       t.parent(id, s, ed);\r
 \r
                        t.settings = s = tinymce.extend({\r
                                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',\r
@@ -8631,30 +9831,30 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                hideMenu : function(e) {\r
                        var t = this;\r
 \r
-                       // Prevent double toogles by canceling the mouse click event to the button\r
-                       if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))\r
-                               return;\r
-\r
-                       if (!e || !DOM.getParent(e.target, '.mceSplitButtonMenu')) {\r
-                               DOM.removeClass(t.id, 'mceSplitButtonSelected');\r
-                               Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
-                               Event.remove(t.id + '_menu', 'keydown', t._keyHandler);\r
-                               DOM.hide(t.id + '_menu');\r
-                       }\r
+                       if (t.isMenuVisible) {\r
+                               // Prevent double toogles by canceling the mouse click event to the button\r
+                               if (e && e.type == "mousedown" && DOM.getParent(e.target, function(e) {return e.id === t.id + '_open';}))\r
+                                       return;\r
 \r
-                       t.onHideMenu.dispatch(t);\r
+                               if (!e || !DOM.getParent(e.target, '.mceSplitButtonMenu')) {\r
+                                       DOM.removeClass(t.id, 'mceSplitButtonSelected');\r
+                                       Event.remove(DOM.doc, 'mousedown', t.hideMenu, t);\r
+                                       Event.remove(t.id + '_menu', 'keydown', t._keyHandler);\r
+                                       DOM.hide(t.id + '_menu');\r
+                               }\r
 \r
-                       t.isMenuVisible = 0;\r
+                               t.isMenuVisible = 0;\r
+                       }\r
                },\r
 \r
                renderMenu : function() {\r
-                       var t = this, m, i = 0, s = t.settings, n, tb, tr, w;\r
+                       var t = this, m, i = 0, s = t.settings, n, tb, tr, w, context;\r
 \r
-                       w = DOM.add(s.menu_container, 'div', {id : t.id + '_menu', 'class' : s['menu_class'] + ' ' + s['class'], style : 'position:absolute;left:0;top:-1000px;'});\r
+                       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;'});\r
                        m = DOM.add(w, 'div', {'class' : s['class'] + ' mceSplitButtonMenu'});\r
                        DOM.add(m, 'span', {'class' : 'mceMenuLine'});\r
 \r
-                       n = DOM.add(m, 'table', {'class' : 'mceColorSplitMenu'});\r
+                       n = DOM.add(m, 'table', {role: 'presentation', 'class' : 'mceColorSplitMenu'});\r
                        tb = DOM.add(n, 'tbody');\r
 \r
                        // Generate color grid\r
@@ -8668,20 +9868,32 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                                }\r
 \r
                                n = DOM.add(tr, 'td');\r
-\r
                                n = DOM.add(n, 'a', {\r
+                                       role : 'option',\r
                                        href : 'javascript:;',\r
                                        style : {\r
                                                backgroundColor : '#' + c\r
                                        },\r
-                                       _mce_color : '#' + c\r
+                                       'title': t.editor.getLang('colors.' + c, c),\r
+                                       'data-mce-color' : '#' + c\r
                                });\r
+\r
+                               if (t.editor.forcedHighContrastMode) {\r
+                                       n = DOM.add(n, 'canvas', { width: 16, height: 16, 'aria-hidden': 'true' });\r
+                                       if (n.getContext && (context = n.getContext("2d"))) {\r
+                                               context.fillStyle = '#' + c;\r
+                                               context.fillRect(0, 0, 16, 16);\r
+                                       } else {\r
+                                               // No point leaving a canvas element around if it's not supported for drawing on anyway.\r
+                                               DOM.remove(n);\r
+                                       }\r
+                               }\r
                        });\r
 \r
                        if (s.more_colors_func) {\r
                                n = DOM.add(tb, 'tr');\r
                                n = DOM.add(n, 'td', {colspan : s.grid_width, 'class' : 'mceMoreColors'});\r
-                               n = DOM.add(n, 'a', {id : t.id + '_more', href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);\r
+                               n = DOM.add(n, 'a', {role: 'option', id : t.id + '_more', href : 'javascript:;', onclick : 'return false;', 'class' : 'mceMoreColors'}, s.more_colors_title);\r
 \r
                                Event.add(n, 'click', function(e) {\r
                                        s.more_colors_func.call(s.more_colors_scope || this);\r
@@ -8690,13 +9902,25 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                        }\r
 \r
                        DOM.addClass(m, 'mceColorSplitMenu');\r
+                       \r
+                       new tinymce.ui.KeyboardNavigation({\r
+                               root: t.id + '_menu',\r
+                               items: DOM.select('a', t.id + '_menu'),\r
+                               onCancel: function() {\r
+                                       t.hideMenu();\r
+                                       t.focus();\r
+                               }\r
+                       });\r
+\r
+                       // Prevent IE from scrolling and hindering click to occur #4019\r
+                       Event.add(t.id + '_menu', 'mousedown', function(e) {return Event.cancel(e);});\r
 \r
                        Event.add(t.id + '_menu', 'click', function(e) {\r
                                var c;\r
 \r
-                               e = e.target;\r
+                               e = DOM.getParent(e.target, 'a', tb);\r
 \r
-                               if (e.nodeName == 'A' && (c = e.getAttribute('_mce_color')))\r
+                               if (e && e.nodeName.toLowerCase() == 'a' && (c = e.getAttribute('data-mce-color')))\r
                                        t.setColor(c);\r
 \r
                                return Event.cancel(e); // Prevent IE auto save warning\r
@@ -8706,13 +9930,17 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
                },\r
 \r
                setColor : function(c) {\r
+                       this.displayColor(c);\r
+                       this.hideMenu();\r
+                       this.settings.onselect(c);\r
+               },\r
+               \r
+               displayColor : function(c) {\r
                        var t = this;\r
 \r
                        DOM.setStyle(t.id + '_preview', 'backgroundColor', c);\r
 \r
                        t.value = c;\r
-                       t.hideMenu();\r
-                       t.settings.onselect(c);\r
                },\r
 \r
                postRender : function() {\r
@@ -8733,9 +9961,67 @@ tinymce.create('tinymce.ui.Separator:tinymce.ui.Control', {
        });\r
 })(tinymce);\r
 \r
+(function(tinymce) {\r
+// Shorten class names\r
+var dom = tinymce.DOM, each = tinymce.each, Event = tinymce.dom.Event;\r
+tinymce.create('tinymce.ui.ToolbarGroup:tinymce.ui.Container', {\r
+       renderHTML : function() {\r
+               var t = this, h = [], controls = t.controls, each = tinymce.each, settings = t.settings;\r
+\r
+               h.push('<div id="' + t.id + '" role="group" aria-labelledby="' + t.id + '_voice">');\r
+               //TODO: ACC test this out - adding a role = application for getting the landmarks working well.\r
+               h.push("<span role='application'>");\r
+               h.push('<span id="' + t.id + '_voice" class="mceVoiceLabel" style="display:none;">' + dom.encode(settings.name) + '</span>');\r
+               each(controls, function(toolbar) {\r
+                       h.push(toolbar.renderHTML());\r
+               });\r
+               h.push("</span>");\r
+               h.push('</div>');\r
+\r
+               return h.join('');\r
+       },\r
+       \r
+       focus : function() {\r
+               this.keyNav.focus();\r
+       },\r
+       \r
+       postRender : function() {\r
+               var t = this, items = [];\r
+\r
+               each(t.controls, function(toolbar) {\r
+                       each (toolbar.controls, function(control) {\r
+                               if (control.id) {\r
+                                       items.push(control);\r
+                               }\r
+                       });\r
+               });\r
+\r
+               t.keyNav = new tinymce.ui.KeyboardNavigation({\r
+                       root: t.id,\r
+                       items: items,\r
+                       onCancel: function() {\r
+                               t.editor.focus();\r
+                       },\r
+                       excludeFromTabOrder: !t.settings.tab_focus_toolbar\r
+               });\r
+       },\r
+       \r
+       destroy : function() {\r
+               var self = this;\r
+\r
+               self.parent();\r
+               self.keyNav.destroy();\r
+               Event.clear(self.id);\r
+       }\r
+});\r
+})(tinymce);\r
+\r
+(function(tinymce) {\r
+// Shorten class names\r
+var dom = tinymce.DOM, each = tinymce.each;\r
 tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {\r
        renderHTML : function() {\r
-               var t = this, h = '', c, co, dom = tinymce.DOM, s = t.settings, i, pr, nx, cl;\r
+               var t = this, h = '', c, co, s = t.settings, i, pr, nx, cl;\r
 \r
                cl = t.controls;\r
                for (i=0; i<cl.length; i++) {\r
@@ -8792,19 +10078,23 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                h += dom.createHTML('td', {'class' : c}, dom.createHTML('span', null, '<!-- IE -->'));\r
 \r
-               return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || ''}, '<tbody><tr>' + h + '</tr></tbody>');\r
+               return dom.createHTML('table', {id : t.id, 'class' : 'mceToolbar' + (s['class'] ? ' ' + s['class'] : ''), cellpadding : '0', cellspacing : '0', align : t.settings.align || '', role: 'presentation', tabindex: '-1'}, '<tbody><tr>' + h + '</tr></tbody>');\r
        }\r
 });\r
+})(tinymce);\r
 \r
 (function(tinymce) {\r
        var Dispatcher = tinymce.util.Dispatcher, each = tinymce.each;\r
 \r
        tinymce.create('tinymce.AddOnManager', {\r
-               items : [],\r
-               urls : {},\r
-               lookup : {},\r
+               AddOnManager : function() {\r
+                       var self = this;\r
 \r
-               onAdd : new Dispatcher(this),\r
+                       self.items = [];\r
+                       self.urls = {};\r
+                       self.lookup = {};\r
+                       self.onAdd = new Dispatcher(self);\r
+               },\r
 \r
                get : function(n) {\r
                        return this.lookup[n];\r
@@ -8813,7 +10103,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                requireLangPack : function(n) {\r
                        var s = tinymce.settings;\r
 \r
-                       if (s && s.language)\r
+                       if (s && s.language && s.language_load !== false)\r
                                tinymce.ScriptLoader.add(this.urls[n] + '/langs/' + s.language + '.js');\r
                },\r
 \r
@@ -8832,10 +10122,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                return;\r
 \r
                        if (u.indexOf('/') != 0 && u.indexOf('://') == -1)\r
-                               u = tinymce.baseURL + '/' +  u;\r
+                               u = tinymce.baseURL + '/' + u;\r
 \r
                        t.urls[n] = u.substring(0, u.lastIndexOf('/'));\r
-                       tinymce.ScriptLoader.add(u, cb, s);\r
+\r
+                       if (!t.lookup[n])\r
+                               tinymce.ScriptLoader.add(u, cb, s);\r
                }\r
        });\r
 \r
@@ -9292,7 +10584,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                apply_source_formatting : 1,\r
                                directionality : 'ltr',\r
                                forced_root_block : 'p',\r
-                               valid_elements : '@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],a[rel|rev|charset|hreflang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur],strong/b,em/i,strike,u,#p,-ol[type|compact],-ul[type|compact],-li,br,img[longdesc|usemap|src|border|alt=|title|hspace|vspace|width|height|align],-sub,-sup,-blockquote[cite],-table[border|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],caption,-div,-span,-code,-pre,address,-h1,-h2,-h3,-h4,-h5,-h6,hr[size|noshade],-font[face|size|color],dd,dl,dt,cite,abbr,acronym,del[datetime|cite],ins[datetime|cite],object[classid|width|height|codebase|*],param[name|value],embed[type|width|height|src|*],script[src|type],map[name],area[shape|coords|href|alt|target],bdo,button,col[align|char|charoff|span|valign|width],colgroup[align|char|charoff|span|valign|width],dfn,fieldset,form[action|accept|accept-charset|enctype|method],input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value|tabindex|accesskey],kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],q[cite],samp,select[disabled|multiple|name|size],small,textarea[cols|rows|disabled|name|readonly],tt,var,big',\r
                                hidden_input : 1,\r
                                padd_empty_editor : 1,\r
                                render_ui : 1,\r
@@ -9302,7 +10593,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                keep_styles : 1,\r
                                fix_table_elements : 1,\r
                                inline_styles : 1,\r
-                               convert_fonts_to_spans : true\r
+                               convert_fonts_to_spans : true,\r
+                               indent : 'simple',\r
+                               indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr',\r
+                               indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr',\r
+                               validate : true,\r
+                               entity_encoding : 'named',\r
+                               url_converter : t.convertURL,\r
+                               url_converter_scope : t,\r
+                               ie7_compat : true\r
                        }, s);\r
 \r
                        t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {\r
@@ -9311,6 +10610,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        t.baseURI = tinymce.baseURI;\r
 \r
+                       t.contentCSS = [];\r
+\r
                        // Call setup\r
                        t.execCallback('setup', t);\r
                },\r
@@ -9400,7 +10701,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        // Load scripts\r
                        function loadScripts() {\r
-                               if (s.language)\r
+                               if (s.language && s.language_load !== false)\r
                                        sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');\r
 \r
                                if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])\r
@@ -9427,10 +10728,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                },\r
 \r
                init : function() {\r
-                       var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re;\r
+                       var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re, i;\r
 \r
                        tinymce.add(t);\r
 \r
+                       s.aria_label = s.aria_label || DOM.getAttrib(e, 'aria-label', t.getLang('aria.rich_text_area'));\r
+\r
                        if (s.theme) {\r
                                s.theme = s.theme.replace(/-/, '');\r
                                o = ThemeManager.get(s.theme);\r
@@ -9468,12 +10771,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        t.controlManager = new tinymce.ControlManager(t);\r
 \r
                        if (s.custom_undo_redo) {\r
-                               // Add initial undo level\r
                                t.onBeforeExecCommand.add(function(ed, cmd, ui, val, a) {\r
-                                       if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo)) {\r
-                                               if (!t.undoManager.hasUndo())\r
-                                                       t.undoManager.add();\r
-                                       }\r
+                                       if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))\r
+                                               t.undoManager.beforeChange();\r
                                });\r
 \r
                                t.onExecCommand.add(function(ed, cmd, ui, val, a) {\r
@@ -9539,6 +10839,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                height : h\r
                        });\r
 \r
+                       // Load specified content CSS last\r
+                       if (s.content_css) {\r
+                               tinymce.each(explode(s.content_css), function(u) {\r
+                                       t.contentCSS.push(t.documentBaseURI.toAbsolute(u));\r
+                               });\r
+                       }\r
+\r
                        h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');\r
                        if (h < 100)\r
                                h = 100;\r
@@ -9550,10 +10857,21 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        if (s.document_base_url != tinymce.documentBaseURL)\r
                                t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />';\r
 \r
-                       t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" /><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';\r
+                       // IE8 doesn't support carets behind images setting ie7_compat would force IE8+ to run in IE7 compat mode.\r
+                       if (s.ie7_compat)\r
+                               t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />';\r
+                       else\r
+                               t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />';\r
+\r
+                       t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';\r
+\r
+                       // Firefox 2 doesn't load stylesheets correctly this way\r
+                       if (!isGecko || !/Firefox\/2/.test(navigator.userAgent)) {\r
+                               for (i = 0; i < t.contentCSS.length; i++)\r
+                                       t.iframeHTML += '<link type="text/css" rel="stylesheet" href="' + t.contentCSS[i] + '" />';\r
 \r
-                       if (tinymce.relaxedDomain)\r
-                               t.iframeHTML += '<script type="text/javascript">document.domain = "' + tinymce.relaxedDomain + '";</script>';\r
+                               t.contentCSS = [];\r
+                       }\r
 \r
                        bi = s.body_id || 'tinymce';\r
                        if (bi.indexOf('=') != -1) {\r
@@ -9570,19 +10888,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"></body></html>';\r
 \r
                        // Domain relaxing enabled, then set document domain\r
-                       if (tinymce.relaxedDomain) {\r
+                       if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {\r
                                // We need to write the contents here in IE since multiple writes messes up refresh button and back button\r
-                               if (isIE || (tinymce.isOpera && parseFloat(opera.version()) >= 9.5))\r
-                                       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();})()';\r
-                               else if (tinymce.isOpera)\r
-                                       u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";document.close();ed.setupIframe();})()';                                  \r
+                               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();})()';                         \r
                        }\r
 \r
                        // Create iframe\r
-                       n = DOM.add(o.iframeContainer, 'iframe', {\r
+                       // TODO: ACC add the appropriate description on this.\r
+                       n = DOM.add(o.iframeContainer, 'iframe', { \r
                                id : t.id + "_ifr",\r
                                src : u || 'javascript:""', // Workaround for HTTPS warning in IE6/7\r
-                               frameBorder : '0',\r
+                               frameBorder : '0', \r
+                               title : s.aria_label,\r
                                style : {\r
                                        width : '100%',\r
                                        height : h\r
@@ -9592,8 +10909,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        t.contentAreaContainer = o.iframeContainer;\r
                        DOM.get(o.editorContainer).style.display = t.orgDisplay;\r
                        DOM.get(t.id).style.display = 'none';\r
+                       DOM.setAttrib(t.id, 'aria-hidden', true);\r
 \r
-                       if (!isIE || !tinymce.relaxedDomain)\r
+                       if (!tinymce.relaxedDomain || !u)\r
                                t.setupIframe();\r
 \r
                        e = n = o = null; // Cleanup\r
@@ -9607,6 +10925,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                d.open();\r
                                d.write(t.iframeHTML);\r
                                d.close();\r
+\r
+                               if (tinymce.relaxedDomain)\r
+                                       d.domain = tinymce.relaxedDomain;\r
                        }\r
 \r
                        // Design mode needs to be added here Ctrl+A will fail otherwise\r
@@ -9632,6 +10953,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                DOM.show(b);\r
                        }\r
 \r
+                       t.schema = new tinymce.html.Schema(s);\r
+\r
                        t.dom = new tinymce.dom.DOMUtils(t.getDoc(), {\r
                                keep_values : true,\r
                                url_converter : t.convertURL,\r
@@ -9640,16 +10963,77 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                class_filter : s.class_filter,\r
                                update_styles : 1,\r
                                fix_ie_paragraphs : 1,\r
-                               valid_styles : s.valid_styles\r
+                               schema : t.schema\r
                        });\r
 \r
-                       t.schema = new tinymce.dom.Schema();\r
+                       t.parser = new tinymce.html.DomParser(s, t.schema);\r
 \r
-                       t.serializer = new tinymce.dom.Serializer(extend(s, {\r
-                               valid_elements : s.verify_html === false ? '*[*]' : s.valid_elements,\r
-                               dom : t.dom,\r
-                               schema : t.schema\r
-                       }));\r
+                       // Force anchor names closed\r
+                       t.parser.addAttributeFilter('name', function(nodes, name) {\r
+                               var i = nodes.length, sibling, prevSibling, parent, node;\r
+\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       if (node.name === 'a' && node.firstChild) {\r
+                                               parent = node.parent;\r
+\r
+                                               // Move children after current node\r
+                                               sibling = node.lastChild;\r
+                                               do {\r
+                                                       prevSibling = sibling.prev;\r
+                                                       parent.insert(sibling, node);\r
+                                                       sibling = prevSibling;\r
+                                               } while (sibling);\r
+                                       }\r
+                               }\r
+                       });\r
+\r
+                       // Convert src and href into data-mce-src, data-mce-href and data-mce-style\r
+                       t.parser.addAttributeFilter('src,href,style', function(nodes, name) {\r
+                               var i = nodes.length, node, dom = t.dom, value;\r
+\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       value = node.attr(name);\r
+\r
+                                       if (name === "style")\r
+                                               node.attr('data-mce-style', dom.serializeStyle(dom.parseStyle(value), node.name));\r
+                                       else\r
+                                               node.attr('data-mce-' + name, t.convertURL(value, name, node.name));\r
+                               }\r
+                       });\r
+\r
+                       // Keep scripts from executing\r
+                       t.parser.addNodeFilter('script', function(nodes, name) {\r
+                               var i = nodes.length;\r
+\r
+                               while (i--)\r
+                                       nodes[i].attr('type', 'mce-text/javascript');\r
+                       });\r
+\r
+                       t.parser.addNodeFilter('#cdata', function(nodes, name) {\r
+                               var i = nodes.length, node;\r
+\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       node.type = 8;\r
+                                       node.name = '#comment';\r
+                                       node.value = '[CDATA[' + node.value + ']]';\r
+                               }\r
+                       });\r
+\r
+                       t.parser.addNodeFilter('p,h1,h2,h3,h4,h5,h6,div', function(nodes, name) {\r
+                               var i = nodes.length, node, nonEmptyElements = t.schema.getNonEmptyElements();\r
+\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+\r
+                                       if (node.isEmpty(nonEmptyElements))\r
+                                               node.empty().append(new tinymce.html.Node('br', 1)).shortEnded = true;\r
+                               }\r
+                       });\r
+\r
+                       t.serializer = new tinymce.dom.Serializer(s, t.dom, t.schema);\r
 \r
                        t.selection = new tinymce.dom.Selection(t.dom, t.getWin(), t.serializer);\r
 \r
@@ -9659,18 +11043,18 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        t.formatter.register({\r
                                alignleft : [\r
                                        {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'left'}},\r
-                                       {selector : 'img,table', styles : {'float' : 'left'}}\r
+                                       {selector : 'img,table', collapsed : false, styles : {'float' : 'left'}}\r
                                ],\r
 \r
                                aligncenter : [\r
                                        {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'center'}},\r
-                                       {selector : 'img', styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}},\r
-                                       {selector : 'table', styles : {marginLeft : 'auto', marginRight : 'auto'}}\r
+                                       {selector : 'img', collapsed : false, styles : {display : 'block', marginLeft : 'auto', marginRight : 'auto'}},\r
+                                       {selector : 'table', collapsed : false, styles : {marginLeft : 'auto', marginRight : 'auto'}}\r
                                ],\r
 \r
                                alignright : [\r
                                        {selector : 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li', styles : {textAlign : 'right'}},\r
-                                       {selector : 'img,table', styles : {'float' : 'right'}}\r
+                                       {selector : 'img,table', collapsed : false, styles : {'float' : 'right'}}\r
                                ],\r
 \r
                                alignfull : [\r
@@ -9678,33 +11062,35 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                ],\r
 \r
                                bold : [\r
-                                       {inline : 'strong'},\r
+                                       {inline : 'strong', remove : 'all'},\r
                                        {inline : 'span', styles : {fontWeight : 'bold'}},\r
-                                       {inline : 'b'}\r
+                                       {inline : 'b', remove : 'all'}\r
                                ],\r
 \r
                                italic : [\r
-                                       {inline : 'em'},\r
+                                       {inline : 'em', remove : 'all'},\r
                                        {inline : 'span', styles : {fontStyle : 'italic'}},\r
-                                       {inline : 'i'}\r
+                                       {inline : 'i', remove : 'all'}\r
                                ],\r
 \r
                                underline : [\r
                                        {inline : 'span', styles : {textDecoration : 'underline'}, exact : true},\r
-                                       {inline : 'u'}\r
+                                       {inline : 'u', remove : 'all'}\r
                                ],\r
 \r
                                strikethrough : [\r
                                        {inline : 'span', styles : {textDecoration : 'line-through'}, exact : true},\r
-                                       {inline : 'u'}\r
+                                       {inline : 'strike', remove : 'all'}\r
                                ],\r
 \r
-                               forecolor : {inline : 'span', styles : {color : '%value'}},\r
-                               hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}},\r
+                               forecolor : {inline : 'span', styles : {color : '%value'}, wrap_links : false},\r
+                               hilitecolor : {inline : 'span', styles : {backgroundColor : '%value'}, wrap_links : false},\r
                                fontname : {inline : 'span', styles : {fontFamily : '%value'}},\r
                                fontsize : {inline : 'span', styles : {fontSize : '%value'}},\r
                                fontsize_class : {inline : 'span', attributes : {'class' : '%value'}},\r
                                blockquote : {block : 'blockquote', wrapper : 1, remove : 'all'},\r
+                               subscript : {inline : 'sub'},\r
+                               superscript : {inline : 'sup'},\r
 \r
                                removeformat : [\r
                                        {selector : 'b,strong,em,i,font,u,strike', remove : 'all', split : true, expand : false, block_expand : true, deep : true},\r
@@ -9725,7 +11111,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        // Pass through\r
                        t.undoManager.onAdd.add(function(um, l) {\r
-                               if (!l.initial)\r
+                               if (um.hasUndo())\r
                                        return t.onChange.dispatch(t, l, um);\r
                        });\r
 \r
@@ -9769,29 +11155,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        if (s.nowrap)\r
                                t.getBody().style.whiteSpace = "nowrap";\r
 \r
-                       if (s.custom_elements) {\r
-                               function handleCustom(ed, o) {\r
-                                       each(explode(s.custom_elements), function(v) {\r
-                                               var n;\r
-\r
-                                               if (v.indexOf('~') === 0) {\r
-                                                       v = v.substring(1);\r
-                                                       n = 'span';\r
-                                               } else\r
-                                                       n = 'div';\r
-\r
-                                               o.content = o.content.replace(new RegExp('<(' + v + ')([^>]*)>', 'g'), '<' + n + ' _mce_name="$1"$2>');\r
-                                               o.content = o.content.replace(new RegExp('</(' + v + ')>', 'g'), '</' + n + '>');\r
-                                       });\r
-                               };\r
-\r
-                               t.onBeforeSetContent.add(handleCustom);\r
-                               t.onPostProcess.add(function(ed, o) {\r
-                                       if (o.set)\r
-                                               handleCustom(ed, o);\r
-                               });\r
-                       }\r
-\r
                        if (s.handle_node_change_callback) {\r
                                t.onNodeChange.add(function(ed, cm, n) {\r
                                        t.execCallback('handle_node_change_callback', t.id, n, -1, -1, true, t.selection.isCollapsed());\r
@@ -9813,16 +11176,22 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                });\r
                        }\r
 \r
-                       if (s.convert_newlines_to_brs) {\r
+                       if (s.protect) {\r
                                t.onBeforeSetContent.add(function(ed, o) {\r
-                                       if (o.initial)\r
-                                               o.content = o.content.replace(/\r?\n/g, '<br />');\r
+                                       if (s.protect) {\r
+                                               each(s.protect, function(pattern) {\r
+                                                       o.content = o.content.replace(pattern, function(str) {\r
+                                                               return '<!--mce:protected ' + escape(str) + '-->';\r
+                                                       });\r
+                                               });\r
+                                       }\r
                                });\r
                        }\r
 \r
-                       if (s.fix_nesting && isIE) {\r
+                       if (s.convert_newlines_to_brs) {\r
                                t.onBeforeSetContent.add(function(ed, o) {\r
-                                       o.content = t._fixNesting(o.content);\r
+                                       if (o.initial)\r
+                                               o.content = o.content.replace(/\r?\n/g, '<br />');\r
                                });\r
                        }\r
 \r
@@ -9919,7 +11288,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                var pn = n.parentNode;\r
 \r
                                                if (ed.dom.isBlock(pn) && pn.lastChild === n)\r
-                                                       ed.dom.add(pn, 'br', {'_mce_bogus' : 1});\r
+                                                       ed.dom.add(pn, 'br', {'data-mce-bogus' : 1});\r
                                        });\r
                                };\r
 \r
@@ -9948,8 +11317,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                if (t.removed)\r
                                        return;\r
 \r
-                               t.load({initial : true, format : (s.cleanup_on_startup ? 'html' : 'raw')});\r
+                               t.load({initial : true, format : 'html'});\r
                                t.startContent = t.getContent({format : 'raw'});\r
+                               t.undoManager.add();\r
                                t.initialized = true;\r
 \r
                                t.onInit.dispatch(t);\r
@@ -9959,11 +11329,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                t.nodeChanged({initial : 1});\r
 \r
                                // Load specified content CSS last\r
-                               if (s.content_css) {\r
-                                       tinymce.each(explode(s.content_css), function(u) {\r
-                                               t.dom.loadCSS(t.documentBaseURI.toAbsolute(u));\r
-                                       });\r
-                               }\r
+                               each(t.contentCSS, function(u) {\r
+                                       t.dom.loadCSS(u);\r
+                               });\r
 \r
                                // Handle auto focus\r
                                if (s.auto_focus) {\r
@@ -10079,7 +11447,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                },\r
 \r
                nodeChanged : function(o) {\r
-                       var t = this, s = t.selection, n = (isIE ? s.getNode() : s.getStart()) || t.getBody();\r
+                       var t = this, s = t.selection, n = s.getStart() || t.getBody();\r
 \r
                        // Fix for bug #1896577 it seems that this can not be fired while the editor is loading\r
                        if (t.initialized) {\r
@@ -10112,16 +11480,16 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        t.buttons[n] = s;\r
                },\r
 \r
-               addCommand : function(n, f, s) {\r
-                       this.execCommands[n] = {func : f, scope : s || this};\r
+               addCommand : function(name, callback, scope) {\r
+                       this.execCommands[name] = {func : callback, scope : scope || this};\r
                },\r
 \r
-               addQueryStateHandler : function(n, f, s) {\r
-                       this.queryStateCommands[n] = {func : f, scope : s || this};\r
+               addQueryStateHandler : function(name, callback, scope) {\r
+                       this.queryStateCommands[name] = {func : callback, scope : scope || this};\r
                },\r
 \r
-               addQueryValueHandler : function(n, f, s) {\r
-                       this.queryValueCommands[n] = {func : f, scope : s || this};\r
+               addQueryValueHandler : function(name, callback, scope) {\r
+                       this.queryValueCommands[name] = {func : callback, scope : scope || this};\r
                },\r
 \r
                addShortcut : function(pa, desc, cmd_func, sc) {\r
@@ -10224,12 +11592,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                return true;\r
                        }\r
 \r
-                       // Execute global commands\r
-                       if (tinymce.GlobalCommands.execCommand(t, cmd, ui, val)) {\r
-                               t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
-                               return true;\r
-                       }\r
-\r
                        // Editor commands\r
                        if (t.editorCommands.execCommand(cmd, ui, val)) {\r
                                t.onExecCommand.dispatch(t, cmd, ui, val, a);\r
@@ -10361,7 +11723,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        // Add undo level will trigger onchange event\r
                        if (!o.no_events) {\r
-                               t.undoManager.typing = 0;\r
+                               t.undoManager.typing = false;\r
                                t.undoManager.add();\r
                        }\r
 \r
@@ -10393,66 +11755,77 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        return h;\r
                },\r
 \r
-               setContent : function(h, o) {\r
-                       var t = this;\r
+               setContent : function(content, args) {\r
+                       var self = this, rootNode, body = self.getBody();\r
 \r
-                       o = o || {};\r
-                       o.format = o.format || 'html';\r
-                       o.set = true;\r
-                       o.content = h;\r
+                       // Setup args object\r
+                       args = args || {};\r
+                       args.format = args.format || 'html';\r
+                       args.set = true;\r
+                       args.content = content;\r
 \r
-                       if (!o.no_events)\r
-                               t.onBeforeSetContent.dispatch(t, o);\r
+                       // Do preprocessing\r
+                       if (!args.no_events)\r
+                               self.onBeforeSetContent.dispatch(self, args);\r
+\r
+                       content = args.content;\r
 \r
                        // Padd empty content in Gecko and Safari. Commands will otherwise fail on the content\r
                        // It will also be impossible to place the caret in the editor unless there is a BR element present\r
-                       if (!tinymce.isIE && (h.length === 0 || /^\s+$/.test(h))) {\r
-                               o.content = t.dom.setHTML(t.getBody(), '<br _mce_bogus="1" />');\r
-                               o.format = 'raw';\r
+                       if (!tinymce.isIE && (content.length === 0 || /^\s+$/.test(content))) {\r
+                               body.innerHTML = '<br data-mce-bogus="1" />';\r
+                               return;\r
                        }\r
 \r
-                       o.content = t.dom.setHTML(t.getBody(), tinymce.trim(o.content));\r
-\r
-                       if (o.format != 'raw' && t.settings.cleanup) {\r
-                               o.getInner = true;\r
-                               o.content = t.dom.setHTML(t.getBody(), t.serializer.serialize(t.getBody(), o));\r
+                       // Parse and serialize the html\r
+                       if (args.format !== 'raw') {\r
+                               content = new tinymce.html.Serializer({}, self.schema).serialize(\r
+                                       self.parser.parse(content)\r
+                               );\r
                        }\r
 \r
-                       if (!o.no_events)\r
-                               t.onSetContent.dispatch(t, o);\r
+                       // Set the new cleaned contents to the editor\r
+                       args.content = tinymce.trim(content);\r
+                       self.dom.setHTML(body, args.content);\r
 \r
-                       return o.content;\r
+                       // Do post processing\r
+                       if (!args.no_events)\r
+                               self.onSetContent.dispatch(self, args);\r
+\r
+                       return args.content;\r
                },\r
 \r
-               getContent : function(o) {\r
-                       var t = this, h;\r
+               getContent : function(args) {\r
+                       var self = this, content;\r
 \r
-                       o = o || {};\r
-                       o.format = o.format || 'html';\r
-                       o.get = true;\r
+                       // Setup args object\r
+                       args = args || {};\r
+                       args.format = args.format || 'html';\r
+                       args.get = true;\r
 \r
-                       if (!o.no_events)\r
-                               t.onBeforeGetContent.dispatch(t, o);\r
+                       // Do preprocessing\r
+                       if (!args.no_events)\r
+                               self.onBeforeGetContent.dispatch(self, args);\r
 \r
-                       if (o.format != 'raw' && t.settings.cleanup) {\r
-                               o.getInner = true;\r
-                               h = t.serializer.serialize(t.getBody(), o);\r
-                       else\r
-                               h = t.getBody().innerHTML;\r
+                       // Get raw contents or by default the cleaned contents\r
+                       if (args.format == 'raw')\r
+                               content = self.getBody().innerHTML;\r
+                       else\r
+                               content = self.serializer.serialize(self.getBody(), args);\r
 \r
-                       h = h.replace(/^\s*|\s*$/g, '');\r
-                       o.content = h;\r
+                       args.content = tinymce.trim(content);\r
 \r
-                       if (!o.no_events)\r
-                               t.onGetContent.dispatch(t, o);\r
+                       // Do post processing\r
+                       if (!args.no_events)\r
+                               self.onGetContent.dispatch(self, args);\r
 \r
-                       return o.content;\r
+                       return args.content;\r
                },\r
 \r
                isDirty : function() {\r
-                       var t = this;\r
+                       var self = this;\r
 \r
-                       return tinymce.trim(t.startContent) != tinymce.trim(t.getContent({format : 'raw', no_events : 1})) && !t.isNotDirty;\r
+                       return tinymce.trim(self.startContent) != tinymce.trim(self.getContent({format : 'raw', no_events : 1})) && !self.isNotDirty;\r
                },\r
 \r
                getContainer : function() {\r
@@ -10630,7 +12003,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                _addEvents : function() {\r
                        // 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset\r
-                       var t = this, i, s = t.settings, lo = {\r
+                       var t = this, i, s = t.settings, dom = t.dom, lo = {\r
                                mouseup : 'onMouseUp',\r
                                mousedown : 'onMouseDown',\r
                                click : 'onClick',\r
@@ -10662,35 +12035,26 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        each(lo, function(v, k) {\r
                                switch (k) {\r
                                        case 'contextmenu':\r
-                                               if (tinymce.isOpera) {\r
-                                                       // Fake contextmenu on Opera\r
-                                                       t.dom.bind(t.getBody(), 'mousedown', function(e) {\r
-                                                               if (e.ctrlKey) {\r
-                                                                       e.fakeType = 'contextmenu';\r
-                                                                       eventHandler(e);\r
-                                                               }\r
-                                                       });\r
-                                               } else\r
-                                                       t.dom.bind(t.getBody(), k, eventHandler);\r
+                                               dom.bind(t.getDoc(), k, eventHandler);\r
                                                break;\r
 \r
                                        case 'paste':\r
-                                               t.dom.bind(t.getBody(), k, function(e) {\r
+                                               dom.bind(t.getBody(), k, function(e) {\r
                                                        eventHandler(e);\r
                                                });\r
                                                break;\r
 \r
                                        case 'submit':\r
                                        case 'reset':\r
-                                               t.dom.bind(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);\r
+                                               dom.bind(t.getElement().form || DOM.getParent(t.id, 'form'), k, eventHandler);\r
                                                break;\r
 \r
                                        default:\r
-                                               t.dom.bind(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);\r
+                                               dom.bind(s.content_editable ? t.getBody() : t.getDoc(), k, eventHandler);\r
                                }\r
                        });\r
 \r
-                       t.dom.bind(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {\r
+                       dom.bind(s.content_editable ? t.getBody() : (isGecko ? t.getDoc() : t.getWin()), 'focus', function(e) {\r
                                t.focus(true);\r
                        });\r
 \r
@@ -10698,22 +12062,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        // Fixes bug where a specified document_base_uri could result in broken images\r
                        // This will also fix drag drop of images in Gecko\r
                        if (tinymce.isGecko) {\r
-                               // Convert all images to absolute URLs\r
-/*                             t.onSetContent.add(function(ed, o) {\r
-                                       each(ed.dom.select('img'), function(e) {\r
-                                               var v;\r
-\r
-                                               if (v = e.getAttribute('_mce_src'))\r
-                                                       e.src = t.documentBaseURI.toAbsolute(v);\r
-                                       })\r
-                               });*/\r
-\r
-                               t.dom.bind(t.getDoc(), 'DOMNodeInserted', function(e) {\r
+                               dom.bind(t.getDoc(), 'DOMNodeInserted', function(e) {\r
                                        var v;\r
 \r
                                        e = e.target;\r
 \r
-                                       if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('_mce_src')))\r
+                                       if (e.nodeType === 1 && e.nodeName === 'IMG' && (v = e.getAttribute('data-mce-src')))\r
                                                e.src = t.documentBaseURI.toAbsolute(v);\r
                                });\r
                        }\r
@@ -10762,8 +12116,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                        e = e.target;\r
 \r
                                        // Needs tobe the setBaseAndExtend or it will fail to select floated images\r
-                                       if (e.nodeName == 'IMG' || (e.nodeName == 'A' && t.dom.hasClass(e, 'mceItemAnchor')))\r
+                                       if (e.nodeName == 'IMG' || (e.nodeName == 'A' && dom.hasClass(e, 'mceItemAnchor'))) {\r
                                                t.selection.getSel().setBaseAndExtent(e, 0, e, 1);\r
+                                               t.nodeChanged();\r
+                                       }\r
                                });\r
                        }\r
 \r
@@ -10856,7 +12212,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        if (tinymce.isIE) {\r
                                // Fix so resize will only update the width and height attributes not the styles of an image\r
                                // It will also block mceItemNoResize items\r
-                               t.dom.bind(t.getDoc(), 'controlselect', function(e) {\r
+                               dom.bind(t.getDoc(), 'controlselect', function(e) {\r
                                        var re = t.resizeInfo, cb;\r
 \r
                                        e = e.target;\r
@@ -10866,28 +12222,28 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                return;\r
 \r
                                        if (re)\r
-                                               t.dom.unbind(re.node, re.ev, re.cb);\r
+                                               dom.unbind(re.node, re.ev, re.cb);\r
 \r
-                                       if (!t.dom.hasClass(e, 'mceItemNoResize')) {\r
+                                       if (!dom.hasClass(e, 'mceItemNoResize')) {\r
                                                ev = 'resizeend';\r
-                                               cb = t.dom.bind(e, ev, function(e) {\r
+                                               cb = dom.bind(e, ev, function(e) {\r
                                                        var v;\r
 \r
                                                        e = e.target;\r
 \r
-                                                       if (v = t.dom.getStyle(e, 'width')) {\r
-                                                               t.dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));\r
-                                                               t.dom.setStyle(e, 'width', '');\r
+                                                       if (v = dom.getStyle(e, 'width')) {\r
+                                                               dom.setAttrib(e, 'width', v.replace(/[^0-9%]+/g, ''));\r
+                                                               dom.setStyle(e, 'width', '');\r
                                                        }\r
 \r
-                                                       if (v = t.dom.getStyle(e, 'height')) {\r
-                                                               t.dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));\r
-                                                               t.dom.setStyle(e, 'height', '');\r
+                                                       if (v = dom.getStyle(e, 'height')) {\r
+                                                               dom.setAttrib(e, 'height', v.replace(/[^0-9%]+/g, ''));\r
+                                                               dom.setStyle(e, 'height', '');\r
                                                        }\r
                                                });\r
                                        } else {\r
                                                ev = 'resizestart';\r
-                                               cb = t.dom.bind(e, 'resizestart', Event.cancel, Event);\r
+                                               cb = dom.bind(e, 'resizestart', Event.cancel, Event);\r
                                        }\r
 \r
                                        re = t.resizeInfo = {\r
@@ -10898,25 +12254,19 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                });\r
 \r
                                t.onKeyDown.add(function(ed, e) {\r
+                                       var sel;\r
+\r
                                        switch (e.keyCode) {\r
                                                case 8:\r
+                                                       sel = t.getDoc().selection;\r
+\r
                                                        // Fix IE control + backspace browser bug\r
-                                                       if (t.selection.getRng().item) {\r
-                                                               ed.dom.remove(t.selection.getRng().item(0));\r
+                                                       if (sel.createRange && sel.createRange().item) {\r
+                                                               ed.dom.remove(sel.createRange().item(0));\r
                                                                return Event.cancel(e);\r
                                                        }\r
                                        }\r
                                });\r
-\r
-                               /*if (t.dom.boxModel) {\r
-                                       t.getBody().style.height = '100%';\r
-\r
-                                       Event.add(t.getWin(), 'resize', function(e) {\r
-                                               var docElm = t.getDoc().documentElement;\r
-\r
-                                               docElm.style.height = (docElm.offsetHeight - 10) + 'px';\r
-                                       });\r
-                               }*/\r
                        }\r
 \r
                        if (tinymce.isOpera) {\r
@@ -10928,38 +12278,56 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        // Add custom undo/redo handlers\r
                        if (s.custom_undo_redo) {\r
                                function addUndo() {\r
-                                       t.undoManager.typing = 0;\r
+                                       t.undoManager.typing = false;\r
                                        t.undoManager.add();\r
                                };\r
 \r
-                               t.dom.bind(t.getDoc(), 'focusout', function(e) {\r
+                               dom.bind(t.getDoc(), 'focusout', function(e) {\r
                                        if (!t.removed && t.undoManager.typing)\r
                                                addUndo();\r
                                });\r
 \r
+                               // Add undo level when contents is drag/dropped within the editor\r
+                               t.dom.bind(t.dom.getRoot(), 'dragend', function(e) {\r
+                                       addUndo();\r
+                               });\r
+\r
                                t.onKeyUp.add(function(ed, e) {\r
+                                       var rng, parent, bookmark;\r
+\r
+                                       // Fix for bug #3168, to remove odd ".." nodes from the DOM we need to get/set the HTML of the parent node.\r
+                                       if (isIE && e.keyCode == 8) {\r
+                                               rng = t.selection.getRng();\r
+                                               if (rng.parentElement) {\r
+                                                       parent = rng.parentElement();\r
+                                                       bookmark = t.selection.getBookmark();\r
+                                                       parent.innerHTML = parent.innerHTML;\r
+                                                       t.selection.moveToBookmark(bookmark);\r
+                                               }\r
+                                       }\r
+\r
                                        if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45 || e.ctrlKey)\r
                                                addUndo();\r
                                });\r
 \r
                                t.onKeyDown.add(function(ed, e) {\r
-                                       var rng, tmpRng, parent, offset;\r
+                                       var rng, parent, bookmark, keyCode = e.keyCode;\r
 \r
                                        // IE has a really odd bug where the DOM might include an node that doesn't have\r
                                        // a proper structure. If you try to access nodeValue it would throw an illegal value exception.\r
                                        // This seems to only happen when you delete contents and it seems to be avoidable if you refresh the element\r
                                        // after you delete contents from it. See: #3008923\r
-                                       if (isIE && e.keyCode == 46) {\r
+                                       if (isIE && keyCode == 46) {\r
                                                rng = t.selection.getRng();\r
 \r
                                                if (rng.parentElement) {\r
                                                        parent = rng.parentElement();\r
 \r
-                                                       // Get the current caret position within the element\r
-                                                       tmpRng = rng.duplicate();\r
-                                                       tmpRng.moveToElementText(parent);\r
-                                                       tmpRng.setEndPoint('EndToEnd', rng);\r
-                                                       offset = tmpRng.text.length;\r
+                                                       if (!t.undoManager.typing) {\r
+                                                               t.undoManager.beforeChange();\r
+                                                               t.undoManager.typing = true;\r
+                                                               t.undoManager.add();\r
+                                                       }\r
 \r
                                                        // Select next word when ctrl key is used in combo with delete\r
                                                        if (e.ctrlKey) {\r
@@ -10972,6 +12340,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                                        // Check if we are within the same parent\r
                                                        if (rng.parentElement() == parent) {\r
+                                                               bookmark = t.selection.getBookmark();\r
+\r
                                                                try {\r
                                                                        // Update the HTML and hopefully it will remove the artifacts\r
                                                                        parent.innerHTML = parent.innerHTML;\r
@@ -10980,10 +12350,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                                }\r
 \r
                                                                // Restore the caret position\r
-                                                               tmpRng.moveToElementText(parent);\r
-                                                               tmpRng.collapse();\r
-                                                               tmpRng.move('character', offset);\r
-                                                               tmpRng.select();\r
+                                                               t.selection.moveToBookmark(bookmark);\r
                                                        }\r
 \r
                                                        // Block the default delete behavior since it might be broken\r
@@ -10992,17 +12359,24 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                }\r
                                        }\r
 \r
-                                       // Is caracter positon keys\r
-                                       if ((e.keyCode >= 33 && e.keyCode <= 36) || (e.keyCode >= 37 && e.keyCode <= 40) || e.keyCode == 13 || e.keyCode == 45) {\r
+                                       // Is caracter positon keys left,right,up,down,home,end,pgdown,pgup,enter\r
+                                       if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45) {\r
+                                               // Add position before enter key is pressed, used by IE since it still uses the default browser behavior\r
+                                               // Todo: Remove this once we normalize enter behavior on IE\r
+                                               if (tinymce.isIE && keyCode == 13)\r
+                                                       t.undoManager.beforeChange();\r
+\r
                                                if (t.undoManager.typing)\r
                                                        addUndo();\r
 \r
                                                return;\r
                                        }\r
 \r
-                                       if (!t.undoManager.typing) {\r
+                                       // If key isn't shift,ctrl,alt,capslock,metakey\r
+                                       if ((keyCode < 16 || keyCode > 20) && keyCode != 224 && keyCode != 91 && !t.undoManager.typing) {\r
+                                               t.undoManager.beforeChange();\r
                                                t.undoManager.add();\r
-                                               t.undoManager.typing = 1;\r
+                                               t.undoManager.typing = true;\r
                                        }\r
                                });\r
 \r
@@ -11011,68 +12385,64 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                addUndo();\r
                                });\r
                        }\r
-               },\r
-\r
-               _isHidden : function() {\r
-                       var s;\r
+                       \r
+                       // Bug fix for FireFox keeping styles from end of selection instead of start.\r
+                       if (tinymce.isGecko) {\r
+                               function getAttributeApplyFunction() {\r
+                                       var template = t.dom.getAttribs(t.selection.getStart().cloneNode(false));\r
+\r
+                                       return function() {\r
+                                               var target = t.selection.getStart();\r
+                                               t.dom.removeAllAttribs(target);\r
+                                               each(template, function(attr) {\r
+                                                       target.setAttributeNode(attr.cloneNode(true));\r
+                                               });\r
+                                       };\r
+                               }\r
 \r
-                       if (!isGecko)\r
-                               return 0;\r
+                               function isSelectionAcrossElements() {\r
+                                       var s = t.selection;\r
 \r
-                       // Weird, wheres that cursor selection?\r
-                       s = this.selection.getSel();\r
-                       return (!s || !s.rangeCount || s.rangeCount == 0);\r
-               },\r
+                                       return !s.isCollapsed() && s.getStart() != s.getEnd();\r
+                               }\r
 \r
-               // Fix for bug #1867292\r
-               _fixNesting : function(s) {\r
-                       var d = [], i;\r
+                               t.onKeyPress.add(function(ed, e) {\r
+                                       var applyAttributes;\r
 \r
-                       s = s.replace(/<(\/)?([^\s>]+)[^>]*?>/g, function(a, b, c) {\r
-                               var e;\r
+                                       if ((e.keyCode == 8 || e.keyCode == 46) && isSelectionAcrossElements()) {\r
+                                               applyAttributes = getAttributeApplyFunction();\r
+                                               t.getDoc().execCommand('delete', false, null);\r
+                                               applyAttributes();\r
 \r
-                               // Handle end element\r
-                               if (b === '/') {\r
-                                       if (!d.length)\r
-                                               return '';\r
+                                               return Event.cancel(e);\r
+                                       }\r
+                               });\r
 \r
-                                       if (c !== d[d.length - 1].tag) {\r
-                                               for (i=d.length - 1; i>=0; i--) {\r
-                                                       if (d[i].tag === c) {\r
-                                                               d[i].close = 1;\r
-                                                               break;\r
-                                                       }\r
-                                               }\r
+                               t.dom.bind(t.getDoc(), 'cut', function(e) {\r
+                                       var applyAttributes;\r
 \r
-                                               return '';\r
-                                       } else {\r
-                                               d.pop();\r
+                                       if (isSelectionAcrossElements()) {\r
+                                               applyAttributes = getAttributeApplyFunction();\r
+                                               t.onKeyUp.addToTop(Event.cancel, Event);\r
 \r
-                                               if (d.length && d[d.length - 1].close) {\r
-                                                       a = a + '</' + d[d.length - 1].tag + '>';\r
-                                                       d.pop();\r
-                                               }\r
+                                               setTimeout(function() {\r
+                                                       applyAttributes();\r
+                                                       t.onKeyUp.remove(Event.cancel, Event);\r
+                                               }, 0);\r
                                        }\r
-                               } else {\r
-                                       // Ignore these\r
-                                       if (/^(br|hr|input|meta|img|link|param)$/i.test(c))\r
-                                               return a;\r
-\r
-                                       // Ignore closed ones\r
-                                       if (/\/>$/.test(a))\r
-                                               return a;\r
-\r
-                                       d.push({tag : c}); // Push start element\r
-                               }\r
+                               });\r
+                       }\r
+               },\r
 \r
-                               return a;\r
-                       });\r
+               _isHidden : function() {\r
+                       var s;\r
 \r
-                       // End all open tags\r
-                       for (i=d.length - 1; i>=0; i--)\r
-                               s += '</' + d[i].tag + '>';\r
+                       if (!isGecko)\r
+                               return 0;\r
 \r
-                       return s;\r
+                       // Weird, wheres that cursor selection?\r
+                       s = this.selection.getSel();\r
+                       return (!s || !s.rangeCount || s.rangeCount == 0);\r
                }\r
        });\r
 })(tinymce);\r
@@ -11219,6 +12589,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                });\r
 \r
                                toggleFormat('align' + align);\r
+                               execCommand('mceRepaint');\r
                        },\r
 \r
                        // Override list commands to fix WebKit bug\r
@@ -11244,7 +12615,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        },\r
 \r
                        // Override commands to use the text formatter engine\r
-                       'Bold,Italic,Underline,Strikethrough' : function(command) {\r
+                       'Bold,Italic,Underline,Strikethrough,Superscript,Subscript' : function(command) {\r
                                toggleFormat(command);\r
                        },\r
 \r
@@ -11279,7 +12650,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        },\r
 \r
                        FormatBlock : function(command, ui, value) {\r
-                               return toggleFormat(value);\r
+                               return toggleFormat(value || 'p');\r
                        },\r
 \r
                        mceCleanup : function() {\r
@@ -11317,12 +12688,120 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        },\r
 \r
                        mceInsertContent : function(command, ui, value) {\r
-                               selection.setContent(value);\r
+                               var caretNode, rng, rootNode, parent, node, rng, nodeRect, viewPortRect, args;\r
+\r
+                               function findSuitableCaretNode(node, root_node, next) {\r
+                                       var walker = new tinymce.dom.TreeWalker(next ? node.nextSibling : node.previousSibling, root_node);\r
+\r
+                                       while ((node = walker.current())) {\r
+                                               if ((node.nodeType == 3 && tinymce.trim(node.nodeValue).length) || node.nodeName == 'BR' || node.nodeName == 'IMG')\r
+                                                       return node;\r
+\r
+                                               if (next)\r
+                                                       walker.next();\r
+                                               else\r
+                                                       walker.prev();\r
+                                       }\r
+                               };\r
+\r
+                               args = {content: value, format: 'html'};\r
+                               selection.onBeforeSetContent.dispatch(selection, args);\r
+                               value = args.content;\r
+\r
+                               // Add caret at end of contents if it's missing\r
+                               if (value.indexOf('{$caret}') == -1)\r
+                                       value += '{$caret}';\r
+\r
+                               // Set the content at selection to a span and replace it's contents with the value\r
+                               selection.setContent('<span id="__mce">\uFEFF</span>', {no_events : false});\r
+                               dom.setOuterHTML('__mce', value.replace(/\{\$caret\}/, '<span data-mce-type="bookmark" id="__mce">\uFEFF</span>'));\r
+\r
+                               caretNode = dom.select('#__mce')[0];\r
+                               rootNode = dom.getRoot();\r
+\r
+                               // Move the caret into the last suitable location within the previous sibling if it's a block since the block might be split\r
+                               if (caretNode.previousSibling && dom.isBlock(caretNode.previousSibling) || caretNode.parentNode == rootNode) {\r
+                                       node = findSuitableCaretNode(caretNode, rootNode);\r
+                                       if (node) {\r
+                                               if (node.nodeName == 'BR')\r
+                                                       node.parentNode.insertBefore(caretNode, node);\r
+                                               else\r
+                                                       dom.insertAfter(caretNode, node);\r
+                                       }\r
+                               }\r
+\r
+                               // Find caret root parent and clean it up using the serializer to avoid nesting\r
+                               while (caretNode) {\r
+                                       if (caretNode === rootNode) {\r
+                                               // Clean up the parent element by parsing and serializing it\r
+                                               // This will remove invalid elements/attributes and fix nesting issues\r
+                                               dom.setOuterHTML(parent, \r
+                                                       new tinymce.html.Serializer({}, editor.schema).serialize(\r
+                                                               editor.parser.parse(dom.getOuterHTML(parent))\r
+                                                       )\r
+                                               );\r
+\r
+                                               break;\r
+                                       }\r
+\r
+                                       parent = caretNode;\r
+                                       caretNode = caretNode.parentNode;\r
+                               }\r
+\r
+                               // Find caret after cleanup and move selection to that location\r
+                               caretNode = dom.select('#__mce')[0];\r
+                               if (caretNode) {\r
+                                       node = findSuitableCaretNode(caretNode, rootNode) || findSuitableCaretNode(caretNode, rootNode, true);\r
+                                       dom.remove(caretNode);\r
+\r
+                                       if (node) {\r
+                                               rng = dom.createRng();\r
+\r
+                                               if (node.nodeType == 3) {\r
+                                                       rng.setStart(node, node.length);\r
+                                                       rng.setEnd(node, node.length);\r
+                                               } else {\r
+                                                       if (node.nodeName == 'BR') {\r
+                                                               rng.setStartBefore(node);\r
+                                                               rng.setEndBefore(node);\r
+                                                       } else {\r
+                                                               rng.setStartAfter(node);\r
+                                                               rng.setEndAfter(node);\r
+                                                       }\r
+                                               }\r
+\r
+                                               selection.setRng(rng);\r
+\r
+                                               // Scroll range into view scrollIntoView on element can't be used since it will scroll the main view port as well\r
+                                               if (!tinymce.isIE) {\r
+                                                       node = dom.create('span', null, '\u00a0');\r
+                                                       rng.insertNode(node);\r
+                                                       nodeRect = dom.getRect(node);\r
+                                                       viewPortRect = dom.getViewPort(editor.getWin());\r
+\r
+                                                       // Check if node is out side the viewport if it is then scroll to it\r
+                                                       if ((nodeRect.y > viewPortRect.y + viewPortRect.h || nodeRect.y < viewPortRect.y) ||\r
+                                                               (nodeRect.x > viewPortRect.x + viewPortRect.w || nodeRect.x < viewPortRect.x)) {\r
+                                                               editor.getBody().scrollLeft = nodeRect.x;\r
+                                                               editor.getBody().scrollTop = nodeRect.y;\r
+                                                       }\r
+\r
+                                                       dom.remove(node);\r
+                                               }\r
+\r
+                                               // Make sure that the selection is collapsed after we removed the node fixes a WebKit bug\r
+                                               // where WebKit would place the endContainer/endOffset at a different location than the startContainer/startOffset\r
+                                               selection.collapse(true);\r
+                                       }\r
+                               }\r
+\r
+                               selection.onSetContent.dispatch(selection, args);\r
+                               editor.addVisual();\r
                        },\r
 \r
                        mceInsertRawHTML : function(command, ui, value) {\r
                                selection.setContent('tiny_mce_marker');\r
-                               editor.setContent(editor.getContent().replace(/tiny_mce_marker/g, value));\r
+                               editor.setContent(editor.getContent().replace(/tiny_mce_marker/g, function() { return value }));\r
                        },\r
 \r
                        mceSetContent : function(command, ui, value) {\r
@@ -11372,7 +12851,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        },\r
 \r
                        InsertHorizontalRule : function() {\r
-                               selection.setContent('<hr />');\r
+                               editor.execCommand('mceInsertContent', false, '<hr />');\r
                        },\r
 \r
                        mceToggleVisualAid : function() {\r
@@ -11381,18 +12860,36 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        },\r
 \r
                        mceReplaceContent : function(command, ui, value) {\r
-                               selection.setContent(value.replace(/\{\$selection\}/g, selection.getContent({format : 'text'})));\r
+                               editor.execCommand('mceInsertContent', false, value.replace(/\{\$selection\}/g, selection.getContent({format : 'text'})));\r
                        },\r
 \r
                        mceInsertLink : function(command, ui, value) {\r
-                               var link = dom.getParent(selection.getNode(), 'a');\r
+                               var link = dom.getParent(selection.getNode(), 'a'), img, floatVal;\r
 \r
                                if (tinymce.is(value, 'string'))\r
                                        value = {href : value};\r
 \r
+                               // Spaces are never valid in URLs and it's a very common mistake for people to make so we fix it here.\r
+                               value.href = value.href.replace(' ', '%20');\r
+\r
                                if (!link) {\r
+                                       // WebKit can't create links on float images for some odd reason so just remove it and restore it later\r
+                                       if (tinymce.isWebKit) {\r
+                                               img = dom.getParent(selection.getNode(), 'img');\r
+\r
+                                               if (img) {\r
+                                                       floatVal = img.style.cssFloat;\r
+                                                       img.style.cssFloat = null;\r
+                                               }\r
+                                       }\r
+\r
                                        execNativeCommand('CreateLink', FALSE, 'javascript:mctmp(0);');\r
-                                       each(dom.select('a[href=javascript:mctmp(0);]'), function(link) {\r
+\r
+                                       // Restore float value\r
+                                       if (floatVal)\r
+                                               img.style.cssFloat = floatVal;\r
+\r
+                                       each(dom.select("a[href='javascript:mctmp(0);']"), function(link) {\r
                                                dom.setAttribs(link, value);\r
                                        });\r
                                } else {\r
@@ -11404,10 +12901,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        },\r
                        \r
                        selectAll : function() {\r
-                               var root = dom.getRoot();\r
-                               var rng = dom.createRng();\r
+                               var root = dom.getRoot(), rng = dom.createRng();\r
+\r
                                rng.setStart(root, 0);\r
                                rng.setEnd(root, root.childNodes.length);\r
+\r
                                editor.selection.setRng(rng);\r
                        }\r
                });\r
@@ -11419,7 +12917,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                return isFormatMatch('align' + command.substring(7));\r
                        },\r
 \r
-                       'Bold,Italic,Underline,Strikethrough' : function(command) {\r
+                       'Bold,Italic,Underline,Strikethrough,Superscript,Subscript' : function(command) {\r
                                return isFormatMatch(command);\r
                        },\r
 \r
@@ -11476,6 +12974,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                }\r
        };\r
 })(tinymce);\r
+\r
 (function(tinymce) {\r
        var Dispatcher = tinymce.util.Dispatcher;\r
 \r
@@ -11487,12 +12986,20 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                };\r
 \r
                return self = {\r
-                       typing : 0,\r
+                       typing : false,\r
 \r
                        onAdd : new Dispatcher(self),\r
+\r
                        onUndo : new Dispatcher(self),\r
+\r
                        onRedo : new Dispatcher(self),\r
 \r
+                       beforeChange : function() {\r
+                               // Set before bookmark on previous level\r
+                               if (data[index])\r
+                                       data[index].beforeBookmark = editor.selection.getBookmark(2, true);\r
+                       },\r
+\r
                        add : function(level) {\r
                                var i, settings = editor.settings, lastLevel;\r
 \r
@@ -11501,10 +13008,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                // Add undo level if needed\r
                                lastLevel = data[index];\r
-                               if (lastLevel && lastLevel.content == level.content) {\r
-                                       if (index > 0 || data.length == 1)\r
-                                               return null;\r
-                               }\r
+                               if (lastLevel && lastLevel.content == level.content)\r
+                                       return null;\r
 \r
                                // Time to compress\r
                                if (settings.custom_undo_redo_levels) {\r
@@ -11521,13 +13026,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                level.bookmark = editor.selection.getBookmark(2, true);\r
 \r
                                // Crop array if needed\r
-                               if (index < data.length - 1) {\r
-                                       // Treat first level as initial\r
-                                       if (index == 0)\r
-                                               data = [];\r
-                                       else\r
-                                               data.length = index + 1;\r
-                               }\r
+                               if (index < data.length - 1)\r
+                                       data.length = index + 1;\r
 \r
                                data.push(level);\r
                                index = data.length - 1;\r
@@ -11543,14 +13043,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                if (self.typing) {\r
                                        self.add();\r
-                                       self.typing = 0;\r
+                                       self.typing = false;\r
                                }\r
 \r
                                if (index > 0) {\r
                                        level = data[--index];\r
 \r
                                        editor.setContent(level.content, {format : 'raw'});\r
-                                       editor.selection.moveToBookmark(level.bookmark);\r
+                                       editor.selection.moveToBookmark(level.beforeBookmark);\r
 \r
                                        self.onUndo.dispatch(self, level);\r
                                }\r
@@ -11575,15 +13075,16 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        clear : function() {\r
                                data = [];\r
-                               index = self.typing = 0;\r
+                               index = 0;\r
+                               self.typing = false;\r
                        },\r
 \r
                        hasUndo : function() {\r
-                               return index > 0 || self.typing;\r
+                               return index > 0 || this.typing;\r
                        },\r
 \r
                        hasRedo : function() {\r
-                               return index < data.length - 1;\r
+                               return index < data.length - 1 && !this.typing;\r
                        }\r
                };\r
        };\r
@@ -11632,24 +13133,15 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                return rng2.cloneContents().textContent.length == 0;\r
        };\r
 \r
-       function isEmpty(n) {\r
-               n = n.innerHTML;\r
-\r
-               n = n.replace(/<(img|hr|table|input|select|textarea)[ \>]/gi, '-'); // Keep these convert them to - chars\r
-               n = n.replace(/<[^>]+>/g, ''); // Remove all tags\r
-\r
-               return n.replace(/[ \u00a0\t\r\n]+/g, '') == '';\r
-       };\r
-\r
        function splitList(selection, dom, li) {\r
                var listBlock, block;\r
 \r
-               if (isEmpty(li)) {\r
+               if (dom.isEmpty(li)) {\r
                        listBlock = dom.getParent(li, 'ul,ol');\r
 \r
                        if (!dom.getParent(listBlock.parentNode, 'ul,ol')) {\r
                                dom.split(listBlock, li);\r
-                               block = dom.create('p', 0, '<br _mce_bogus="1" />');\r
+                               block = dom.create('p', 0, '<br data-mce-bogus="1" />');\r
                                dom.replace(block, li);\r
                                selection.select(block, 1);\r
                        }\r
@@ -11671,33 +13163,16 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        ed.onPreInit.add(t.setup, t);\r
 \r
-                       t.reOpera = new RegExp('(\\u00a0|&#160;|&nbsp;)<\/' + elm + '>', 'gi');\r
-                       t.rePadd = new RegExp('<p( )([^>]+)><\\\/p>|<p( )([^>]+)\\\/>|<p( )([^>]+)>\\s+<\\\/p>|<p><\\\/p>|<p\\\/>|<p>\\s+<\\\/p>'.replace(/p/g, elm), 'gi');\r
-                       t.reNbsp2BR1 = new RegExp('<p( )([^>]+)>[\\s\\u00a0]+<\\\/p>|<p>[\\s\\u00a0]+<\\\/p>'.replace(/p/g, elm), 'gi');\r
-                       t.reNbsp2BR2 = new RegExp('<%p()([^>]+)>(&nbsp;|&#160;)<\\\/%p>|<%p>(&nbsp;|&#160;)<\\\/%p>'.replace(/%p/g, elm), 'gi');\r
-                       t.reBR2Nbsp = new RegExp('<p( )([^>]+)>\\s*<br \\\/>\\s*<\\\/p>|<p>\\s*<br \\\/>\\s*<\\\/p>'.replace(/p/g, elm), 'gi');\r
-\r
-                       function padd(ed, o) {\r
-                               if (isOpera)\r
-                                       o.content = o.content.replace(t.reOpera, '</' + elm + '>');\r
-\r
-                               o.content = o.content.replace(t.rePadd, '<' + elm + '$1$2$3$4$5$6>\u00a0</' + elm + '>');\r
-\r
-                               if (!isIE && !isOpera && o.set) {\r
-                                       // Use &nbsp; instead of BR in padded paragraphs\r
-                                       o.content = o.content.replace(t.reNbsp2BR1, '<' + elm + '$1$2><br /></' + elm + '>');\r
-                                       o.content = o.content.replace(t.reNbsp2BR2, '<' + elm + '$1$2><br /></' + elm + '>');\r
-                               } else\r
-                                       o.content = o.content.replace(t.reBR2Nbsp, '<' + elm + '$1$2>\u00a0</' + elm + '>');\r
-                       };\r
-\r
-                       ed.onBeforeSetContent.add(padd);\r
-                       ed.onPostProcess.add(padd);\r
-\r
                        if (s.forced_root_block) {\r
                                ed.onInit.add(t.forceRoots, t);\r
                                ed.onSetContent.add(t.forceRoots, t);\r
                                ed.onBeforeGetContent.add(t.forceRoots, t);\r
+                               ed.onExecCommand.add(function(ed, cmd) {\r
+                                       if (cmd == 'mceInsertContent') {\r
+                                               t.forceRoots();\r
+                                               ed.nodeChanged();\r
+                                       }\r
+                               });\r
                        }\r
                },\r
 \r
@@ -11758,12 +13233,12 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                        var parent = ed.selection.getStart(), fmt = t._previousFormats;\r
 \r
                                                        // Parent is an empty block\r
-                                                       if (!parent.hasChildNodes()) {\r
+                                                       if (!parent.hasChildNodes() && fmt) {\r
                                                                parent = dom.getParent(parent, dom.isBlock);\r
 \r
-                                                               if (parent) {\r
+                                                               if (parent && parent.nodeName != 'LI') {\r
                                                                        parent.innerHTML = '';\r
-       \r
+\r
                                                                        if (t._previousFormats) {\r
                                                                                parent.appendChild(fmt.wrapper);\r
                                                                                fmt.inner.innerHTML = '\uFEFF';\r
@@ -11771,7 +13246,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                                                parent.innerHTML = '\uFEFF';\r
 \r
                                                                        selection.select(parent, 1);\r
+                                                                       selection.collapse(true);\r
                                                                        ed.getDoc().execCommand('Delete', false, null);\r
+                                                                       t._previousFormats = 0;\r
                                                                }\r
                                                        }\r
                                                }\r
@@ -11824,21 +13301,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                });\r
                        }\r
 \r
-                       // Padd empty inline elements within block elements\r
-                       // For example: <p><strong><em></em></strong></p> becomes <p><strong><em>&nbsp;</em></strong></p>\r
-                       ed.onPreProcess.add(function(ed, o) {\r
-                               each(dom.select('p,h1,h2,h3,h4,h5,h6,div', o.node), function(p) {\r
-                                       if (isEmpty(p)) {\r
-                                               each(dom.select('span,em,strong,b,i', o.node), function(n) {\r
-                                                       if (!n.hasChildNodes()) {\r
-                                                               n.appendChild(ed.getDoc().createTextNode('\u00a0'));\r
-                                                               return FALSE; // Break the loop one padding is enough\r
-                                                       }\r
-                                               });\r
-                                       }\r
-                               });\r
-                       });\r
-\r
                        // IE specific fixes\r
                        if (isIE) {\r
                                // Replaces IE:s auto generated paragraphs with the specified element name\r
@@ -11899,7 +13361,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                nx = nl[i];\r
 \r
                                // Ignore internal elements\r
-                               if (nx.nodeType === 1 && nx.getAttribute('_mce_type')) {\r
+                               if (nx.nodeType === 1 && nx.getAttribute('data-mce-type')) {\r
                                        bl = null;\r
                                        continue;\r
                                }\r
@@ -11911,7 +13373,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                if (nx.nodeType != 3 || /[^\s]/g.test(nx.nodeValue)) {\r
                                                        // Store selection\r
                                                        if (si == -2 && r) {\r
-                                                               if (!isIE) {\r
+                                                               if (!isIE || r.setStart) {\r
                                                                        // If selection is element then mark it\r
                                                                        if (r.startContainer.nodeType == 1 && (n = r.startContainer.childNodes[r.startOffset]) && n.nodeType == 1) {\r
                                                                                // Save the id of the selected element\r
@@ -11970,7 +13432,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        // Restore selection\r
                        if (si != -2) {\r
-                               if (!isIE) {\r
+                               if (!isIE || r.setStart) {\r
                                        bl = b.getElementsByTagName(ed.settings.element)[0];\r
                                        r = d.createRange();\r
 \r
@@ -12002,7 +13464,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                // Ignore\r
                                        }\r
                                }\r
-                       } else if (!isIE && (n = ed.dom.get('__mce'))) {\r
+                       } else if ((!isIE || r.setStart) && (n = ed.dom.get('__mce'))) {\r
                                // Restore the id of the selected element\r
                                if (eid)\r
                                        n.setAttribute('id', eid);\r
@@ -12027,6 +13489,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        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;\r
                        var rb, ra, dir, sn, so, en, eo, sb, eb, bn, bef, aft, sc, ec, n, vp = dom.getViewPort(ed.getWin()), y, ch, car;\r
 \r
+                       ed.undoManager.beforeChange();\r
+\r
                        // If root blocks are forced then use Operas default behavior since it's really good\r
 // Removed due to bug: #1853816\r
 //                     if (se.forced_root_block && isOpera)\r
@@ -12203,7 +13667,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                aft.innerHTML = aft.firstChild.innerHTML;\r
 \r
                        // Padd empty blocks\r
-                       if (isEmpty(bef))\r
+                       if (dom.isEmpty(bef))\r
                                bef.innerHTML = '<br />';\r
 \r
                        function appendStyles(e, en) {\r
@@ -12230,14 +13694,14 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                nn = nn.appendChild(nl[i]);\r
 \r
                                        // Padd most inner style element\r
-                                       nl[0].innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there\r
+                                       nl[0].innerHTML = isOpera ? '\u00a0' : '<br />'; // Extra space for Opera so that the caret can move there\r
                                        return nl[0]; // Move caret to most inner element\r
                                } else\r
-                                       e.innerHTML = isOpera ? '&nbsp;' : '<br />'; // Extra space for Opera so that the caret can move there\r
+                                       e.innerHTML = isOpera ? '\u00a0' : '<br />'; // Extra space for Opera so that the caret can move there\r
                        };\r
 \r
                        // Fill empty afterblook with current style\r
-                       if (isEmpty(aft))\r
+                       if (dom.isEmpty(aft))\r
                                car = appendStyles(aft, en);\r
 \r
                        // Opera needs this one backwards for older versions\r
@@ -12266,14 +13730,20 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        // 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\r
                        y = ed.dom.getPos(aft).y;\r
-                       ch = aft.clientHeight;\r
+                       //ch = aft.clientHeight;\r
 \r
                        // Is element within viewport\r
-                       if (y < vp.y || y + ch > vp.y + vp.h) {\r
+                       if (y < vp.y || y + 25 > vp.y + vp.h) {\r
                                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\r
-                               //console.debug('SCROLL!', 'vp.y: ' + vp.y, 'y' + y, 'vp.h' + vp.h, 'clientHeight' + aft.clientHeight, 'yyy: ' + (y < vp.y ? y : y - vp.h + aft.clientHeight));\r
+\r
+                               /*console.debug(\r
+                                       'Element: y=' + y + ', h=' + ch + ', ' +\r
+                                       'Viewport: y=' + vp.y + ", h=" + vp.h + ', bottom=' + (vp.y + vp.h)\r
+                               );*/\r
                        }\r
 \r
+                       ed.undoManager.add();\r
+\r
                        return FALSE;\r
                },\r
 \r
@@ -12488,7 +13958,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                c = new tinymce.ui.NativeListBox(id, s);\r
                        else {\r
                                cls = cc || t._cls.listbox || tinymce.ui.ListBox;\r
-                               c = new cls(id, s);\r
+                               c = new cls(id, s, ed);\r
                        }\r
 \r
                        t.controls[id] = c;\r
@@ -12543,7 +14013,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        if (s.menu_button) {\r
                                cls = cc || t._cls.menubutton || tinymce.ui.MenuButton;\r
-                               c = new cls(id, s);\r
+                               c = new cls(id, s, ed);\r
                                ed.onMouseDown.add(c.hideMenu, c);\r
                        } else {\r
                                cls = t._cls.button || tinymce.ui.Button;\r
@@ -12590,7 +14060,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        id = t.prefix + id;\r
                        cls = cc || t._cls.splitbutton || tinymce.ui.SplitButton;\r
-                       c = t.add(new cls(id, s));\r
+                       c = t.add(new cls(id, s, ed));\r
                        ed.onMouseDown.add(c.hideMenu, c);\r
 \r
                        return c;\r
@@ -12630,7 +14100,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        id = t.prefix + id;\r
                        cls = cc || t._cls.colorsplitbutton || tinymce.ui.ColorSplitButton;\r
-                       c = new cls(id, s);\r
+                       c = new cls(id, s, ed);\r
                        ed.onMouseDown.add(c.hideMenu, c);\r
 \r
                        // Remove the menu element when the editor is removed\r
@@ -12662,13 +14132,25 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                        id = t.prefix + id;\r
                        cls = cc || t._cls.toolbar || tinymce.ui.Toolbar;\r
-                       c = new cls(id, s);\r
+                       c = new cls(id, s, t.editor);\r
 \r
                        if (t.get(id))\r
                                return null;\r
 \r
                        return t.add(c);\r
                },\r
+               \r
+               createToolbarGroup : function(id, s, cc) {\r
+                       var c, t = this, cls;\r
+                       id = t.prefix + id;\r
+                       cls = cc || this._cls.toolbarGroup || tinymce.ui.ToolbarGroup;\r
+                       c = new cls(id, s, t.editor);\r
+                       \r
+                       if (t.get(id))\r
+                               return null;\r
+                       \r
+                       return t.add(c);\r
+               },\r
 \r
                createSeparator : function(cc) {\r
                        var cls = cc || this._cls.separator || tinymce.ui.Separator;\r
@@ -12805,53 +14287,6 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                }\r
        });\r
 }(tinymce));\r
-(function(tinymce) {\r
-       function CommandManager() {\r
-               var execCommands = {}, queryStateCommands = {}, queryValueCommands = {};\r
-\r
-               function add(collection, cmd, func, scope) {\r
-                       if (typeof(cmd) == 'string')\r
-                               cmd = [cmd];\r
-\r
-                       tinymce.each(cmd, function(cmd) {\r
-                               collection[cmd.toLowerCase()] = {func : func, scope : scope};\r
-                       });\r
-               };\r
-\r
-               tinymce.extend(this, {\r
-                       add : function(cmd, func, scope) {\r
-                               add(execCommands, cmd, func, scope);\r
-                       },\r
-\r
-                       addQueryStateHandler : function(cmd, func, scope) {\r
-                               add(queryStateCommands, cmd, func, scope);\r
-                       },\r
-\r
-                       addQueryValueHandler : function(cmd, func, scope) {\r
-                               add(queryValueCommands, cmd, func, scope);\r
-                       },\r
-\r
-                       execCommand : function(scope, cmd, ui, value, args) {\r
-                               if (cmd = execCommands[cmd.toLowerCase()]) {\r
-                                       if (cmd.func.call(scope || cmd.scope, ui, value, args) !== false)\r
-                                               return true;\r
-                               }\r
-                       },\r
-\r
-                       queryCommandValue : function() {\r
-                               if (cmd = queryValueCommands[cmd.toLowerCase()])\r
-                                       return cmd.func.call(scope || cmd.scope, ui, value, args);\r
-                       },\r
-\r
-                       queryCommandState : function() {\r
-                               if (cmd = queryStateCommands[cmd.toLowerCase()])\r
-                                       return cmd.func.call(scope || cmd.scope, ui, value, args);\r
-                       }\r
-               });\r
-       };\r
-\r
-       tinymce.GlobalCommands = new CommandManager();\r
-})(tinymce);\r
 (function(tinymce) {\r
        tinymce.Formatter = function(ed) {\r
                var formats = {},\r
@@ -12860,7 +14295,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        selection = ed.selection,\r
                        TreeWalker = tinymce.dom.TreeWalker,\r
                        rangeUtils = new tinymce.dom.RangeUtils(dom),\r
-                       isValid = ed.schema.isValid,\r
+                       isValid = ed.schema.isValidChild,\r
                        isBlock = dom.isBlock,\r
                        forcedRootBlock = ed.settings.forced_root_block,\r
                        nodeIndex = dom.nodeIndex,\r
@@ -12929,8 +14364,31 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        }\r
                };\r
 \r
+               var getTextDecoration = function(node) {\r
+                       var decoration;\r
+\r
+                       ed.dom.getParent(node, function(n) {\r
+                               decoration = ed.dom.getStyle(n, 'text-decoration');\r
+                               return decoration && decoration !== 'none';\r
+                       });\r
+\r
+                       return decoration;\r
+               };\r
+\r
+               var processUnderlineAndColor = function(node) {\r
+                       var textDecoration;\r
+                       if (node.nodeType === 1 && node.parentNode && node.parentNode.nodeType === 1) {\r
+                               textDecoration = getTextDecoration(node.parentNode);\r
+                               if (ed.dom.getStyle(node, 'color') && textDecoration) {\r
+                                       ed.dom.setStyle(node, 'text-decoration', textDecoration);\r
+                               } else if (ed.dom.getStyle(node, 'textdecoration') === textDecoration) {\r
+                                       ed.dom.setStyle(node, 'text-decoration', null);\r
+                               }\r
+                       }\r
+               };\r
+\r
                function apply(name, vars, node) {\r
-                       var formatList = get(name), format = formatList[0], bookmark, rng, i;\r
+                       var formatList = get(name), format = formatList[0], bookmark, rng, i, isCollapsed = selection.isCollapsed();\r
 \r
                        function moveStart(rng) {\r
                                var container = rng.startContainer,\r
@@ -13021,6 +14479,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                if (format.selector) {\r
                                                        // Look for matching formats\r
                                                        each(formatList, function(format) {\r
+                                                               // Check collapsed state if it exists\r
+                                                               if ('collapsed' in format && format.collapsed !== isCollapsed) {\r
+                                                                       return;\r
+                                                               }\r
+\r
                                                                if (dom.is(node, format.selector) && !isCaretNode(node)) {\r
                                                                        setElementFormat(node, format);\r
                                                                        found = true;\r
@@ -13035,7 +14498,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                }\r
 \r
                                                // Is it valid to wrap this item\r
-                                               if (isValid(wrapName, nodeName) && isValid(parentName, wrapName)) {\r
+                                               if (isValid(wrapName, nodeName) && isValid(parentName, wrapName) &&\r
+                                                               !(node.nodeType === 3 && node.nodeValue.length === 1 && node.nodeValue.charCodeAt(0) === 65279)) {\r
                                                        // Start wrapping\r
                                                        if (!currentWrapElm) {\r
                                                                // Wrap the node\r
@@ -13060,6 +14524,30 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                        each(nodes, process);\r
                                });\r
 \r
+                               // Wrap links inside as well, for example color inside a link when the wrapper is around the link\r
+                               if (format.wrap_links === false) {\r
+                                       each(newWrappers, function(node) {\r
+                                               function process(node) {\r
+                                                       var i, currentWrapElm, children;\r
+\r
+                                                       if (node.nodeName === 'A') {\r
+                                                               currentWrapElm = wrapElm.cloneNode(FALSE);\r
+                                                               newWrappers.push(currentWrapElm);\r
+\r
+                                                               children = tinymce.grep(node.childNodes);\r
+                                                               for (i = 0; i < children.length; i++)\r
+                                                                       currentWrapElm.appendChild(children[i]);\r
+\r
+                                                               node.appendChild(currentWrapElm);\r
+                                                       }\r
+\r
+                                                       each(tinymce.grep(node.childNodes), process);\r
+                                               };\r
+\r
+                                               process(node);\r
+                                       });\r
+                               }\r
+\r
                                // Cleanup\r
                                each(newWrappers, function(node) {\r
                                        var childCount;\r
@@ -13099,8 +14587,9 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                        childCount = getChildCount(node);\r
 \r
-                                       // Remove empty nodes\r
-                                       if (childCount === 0) {\r
+                                       // Remove empty nodes but only if there is multiple wrappers and they are not block\r
+                                       // elements so never remove single <h1></h1> since that would remove the currrent empty block element where the caret is at\r
+                                       if ((newWrappers.length > 1 || !isBlock(node)) && childCount === 0) {\r
                                                dom.remove(node, 1);\r
                                                return;\r
                                        }\r
@@ -13116,6 +14605,19 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                                        // this: <span style="color:red"><b><span style="color:red; font-size:10px">text</span></b></span>\r
                                                        // will become: <span style="color:red"><b><span style="font-size:10px">text</span></b></span>\r
                                                        each(dom.select(format.inline, node), function(child) {\r
+                                                               var parent;\r
+\r
+                                                               // When wrap_links is set to false we don't want\r
+                                                               // to remove the format on children within links\r
+                                                               if (format.wrap_links === false) {\r
+                                                                       parent = child.parentNode;\r
+\r
+                                                                       do {\r
+                                                                               if (parent.nodeName === 'A')\r
+                                                                                       return;\r
+                                                                       } while (parent = parent.parentNode);\r
+                                                               }\r
+\r
                                                                removeFormat(format, vars, child, format.exact ? child : null);\r
                                                        });\r
                                                });\r
@@ -13156,11 +14658,20 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                        applyRngStyle(expandRng(rng, formatList));\r
                                } else {\r
-                                       if (!selection.isCollapsed() || !format.inline) {\r
+                                       if (!isCollapsed || !format.inline || dom.select('td.mceSelected,th.mceSelected').length) {\r
+                                               // Obtain selection node before selection is unselected by applyRngStyle()\r
+                                               var curSelNode = ed.selection.getNode();\r
+\r
                                                // Apply formatting to selection\r
                                                bookmark = selection.getBookmark();\r
                                                applyRngStyle(expandRng(selection.getRng(TRUE), formatList));\r
 \r
+                                               // Colored nodes should be underlined so that the color of the underline matches the text color.\r
+                                               if (format.styles && (format.styles.color || format.styles.textDecoration)) {\r
+                                                       tinymce.walk(curSelNode, processUnderlineAndColor, 'childNodes');\r
+                                                       processUnderlineAndColor(curSelNode);\r
+                                               }\r
+\r
                                                selection.moveToBookmark(bookmark);\r
                                                selection.setRng(moveStart(selection.getRng(TRUE)));\r
                                                ed.nodeChanged();\r
@@ -13173,6 +14684,45 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                function remove(name, vars, node) {\r
                        var formatList = get(name), format = formatList[0], bookmark, i, rng;\r
 \r
+                       function moveStart(rng) {\r
+                               var container = rng.startContainer,\r
+                                       offset = rng.startOffset,\r
+                                       walker, node, nodes, tmpNode;\r
+\r
+                               // Convert text node into index if possible\r
+                               if (container.nodeType == 3 && offset >= container.nodeValue.length - 1) {\r
+                                       container = container.parentNode;\r
+                                       offset = nodeIndex(container) + 1;\r
+                               }\r
+\r
+                               // Move startContainer/startOffset in to a suitable node\r
+                               if (container.nodeType == 1) {\r
+                                       nodes = container.childNodes;\r
+                                       container = nodes[Math.min(offset, nodes.length - 1)];\r
+                                       walker = new TreeWalker(container);\r
+\r
+                                       // If offset is at end of the parent node walk to the next one\r
+                                       if (offset > nodes.length - 1)\r
+                                               walker.next();\r
+\r
+                                       for (node = walker.current(); node; node = walker.next()) {\r
+                                               if (node.nodeType == 3 && !isWhiteSpaceNode(node)) {\r
+                                                       // IE has a "neat" feature where it moves the start node into the closest element\r
+                                                       // we can avoid this by inserting an element before it and then remove it after we set the selection\r
+                                                       tmpNode = dom.create('a', null, INVISIBLE_CHAR);\r
+                                                       node.parentNode.insertBefore(tmpNode, node);\r
+\r
+                                                       // Set selection and remove tmpNode\r
+                                                       rng.setStart(node, 0);\r
+                                                       selection.setRng(rng);\r
+                                                       dom.remove(tmpNode);\r
+\r
+                                                       return;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       };\r
+\r
                        // Merges the styles for each node\r
                        function process(node) {\r
                                var children, i, l;\r
@@ -13285,8 +14835,8 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                        if (startContainer != endContainer) {\r
                                                // Wrap start/end nodes in span element since these might be cloned/moved\r
-                                               startContainer = wrap(startContainer, 'span', {id : '_start', _mce_type : 'bookmark'});\r
-                                               endContainer = wrap(endContainer, 'span', {id : '_end', _mce_type : 'bookmark'});\r
+                                               startContainer = wrap(startContainer, 'span', {id : '_start', 'data-mce-type' : 'bookmark'});\r
+                                               endContainer = wrap(endContainer, 'span', {id : '_end', 'data-mce-type' : 'bookmark'});\r
 \r
                                                // Split start/end\r
                                                splitToFormatRoot(startContainer);\r
@@ -13309,6 +14859,11 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                rangeUtils.walk(rng, function(nodes) {\r
                                        each(nodes, function(node) {\r
                                                process(node);\r
+\r
+                                               // Remove parent span if it only contains text-decoration: underline, yet a parent node is also underlined.\r
+                                               if (node.nodeType === 1 && ed.dom.getStyle(node, 'text-decoration') === 'underline' && node.parentNode && getTextDecoration(node.parentNode) === 'underline') {\r
+                                                       removeFormat({'deep': false, 'exact': true, 'inline': 'span', 'styles': {'textDecoration' : 'underline'}}, null, node);\r
+                                               }\r
                                        });\r
                                });\r
                        };\r
@@ -13322,17 +14877,25 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                return;\r
                        }\r
 \r
-                       if (!selection.isCollapsed() || !format.inline) {\r
+                       if (!selection.isCollapsed() || !format.inline || dom.select('td.mceSelected,th.mceSelected').length) {\r
                                bookmark = selection.getBookmark();\r
                                removeRngStyle(selection.getRng(TRUE));\r
                                selection.moveToBookmark(bookmark);\r
+\r
+                               // Check if start element still has formatting then we are at: "<b>text|</b>text" and need to move the start into the next text node\r
+                               if (match(name, vars, selection.getStart())) {\r
+                                       moveStart(selection.getRng(true));\r
+                               }\r
+\r
                                ed.nodeChanged();\r
                        } else\r
                                performCaretAction('remove', name, vars);\r
                };\r
 \r
                function toggle(name, vars, node) {\r
-                       if (match(name, vars, node))\r
+                       var fmt = get(name);\r
+\r
+                       if (match(name, vars, node) && (!('toggle' in fmt[0]) || fmt[0]['toggle']))\r
                                remove(name, vars, node);\r
                        else\r
                                apply(name, vars, node);\r
@@ -13596,7 +15159,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        var startContainer = rng.startContainer,\r
                                startOffset = rng.startOffset,\r
                                endContainer = rng.endContainer,\r
-                               endOffset = rng.endOffset, sibling, lastIdx;\r
+                               endOffset = rng.endOffset, sibling, lastIdx, leaf;\r
 \r
                        // This function walks up the tree if there is no siblings before/after the node\r
                        function findParentContainer(container, child_name, sibling_name, root) {\r
@@ -13626,6 +15189,19 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                return container;\r
                        };\r
 \r
+                       // This function walks down the tree to find the leaf at the selection.\r
+                       // The offset is also returned as if node initially a leaf, the offset may be in the middle of the text node.\r
+                       function findLeaf(node, offset) {\r
+                               if (offset === undefined)\r
+                                       offset = node.nodeType === 3 ? node.length : node.childNodes.length;\r
+                               while (node && node.hasChildNodes()) {\r
+                                       node = node.childNodes[offset];\r
+                                       if (node)\r
+                                               offset = node.nodeType === 3 ? node.length : node.childNodes.length;\r
+                               }\r
+                               return { node: node, offset: offset };\r
+                       }\r
+\r
                        // If index based start position then resolve it\r
                        if (startContainer.nodeType == 1 && startContainer.hasChildNodes()) {\r
                                lastIdx = startContainer.childNodes.length - 1;\r
@@ -13651,12 +15227,36 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        if (isBookmarkNode(startContainer))\r
                                startContainer = startContainer.nextSibling || startContainer;\r
 \r
-                       if (isBookmarkNode(endContainer.parentNode))\r
+                       if (isBookmarkNode(endContainer.parentNode)) {\r
+                               endOffset = dom.nodeIndex(endContainer);\r
                                endContainer = endContainer.parentNode;\r
+                       }\r
+\r
+                       if (isBookmarkNode(endContainer) && endContainer.previousSibling) {\r
+                               endContainer = endContainer.previousSibling;\r
+                               endOffset = endContainer.length;\r
+                       }\r
 \r
-                       if (isBookmarkNode(endContainer))\r
-                               endContainer = endContainer.previousSibling || endContainer;\r
+                       if (format[0].inline) {\r
+                               // Avoid applying formatting to a trailing space.\r
+                               leaf = findLeaf(endContainer, endOffset);\r
+                               if (leaf.node) {\r
+                                       while (leaf.node && leaf.offset === 0 && leaf.node.previousSibling)\r
+                                               leaf = findLeaf(leaf.node.previousSibling);\r
 \r
+                                       if (leaf.node && leaf.offset > 0 && leaf.node.nodeType === 3 &&\r
+                                                       leaf.node.nodeValue.charAt(leaf.offset - 1) === ' ') {\r
+\r
+                                               if (leaf.offset > 1) {\r
+                                                       endContainer = leaf.node;\r
+                                                       endContainer.splitText(leaf.offset - 1);\r
+                                               } else if (leaf.node.previousSibling) {\r
+                                                       endContainer = leaf.node.previousSibling;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+                       \r
                        // Move start/end point up the tree if the leaves are sharp and if we are in different containers\r
                        // Example * becomes !: !<p><b><i>*text</i><i>text*</i></b></p>!\r
                        // This will reduce the number of wrapper elements that needs to be created\r
@@ -13669,7 +15269,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        // Expand start/end container to matching selector\r
                        if (format[0].selector && format[0].expand !== FALSE && !format[0].inline) {\r
                                function findSelectorEndPoint(container, sibling_name) {\r
-                                       var parents, i, y;\r
+                                       var parents, i, y, curFormat;\r
 \r
                                        if (container.nodeType == 3 && container.nodeValue.length == 0 && container[sibling_name])\r
                                                container = container[sibling_name];\r
@@ -13677,7 +15277,13 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                        parents = getParents(container);\r
                                        for (i = 0; i < parents.length; i++) {\r
                                                for (y = 0; y < format.length; y++) {\r
-                                                       if (dom.is(parents[i], format[y].selector))\r
+                                                       curFormat = format[y];\r
+\r
+                                                       // If collapsed state is set then skip formats that doesn't match that\r
+                                                       if ("collapsed" in curFormat && curFormat.collapsed !== rng.collapsed)\r
+                                                               continue;\r
+\r
+                                                       if (dom.is(parents[i], curFormat.selector))\r
                                                                return parents[i];\r
                                                }\r
                                        }\r
@@ -13787,7 +15393,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                // Remove style attribute if it's empty\r
                                if (stylesModified && dom.getAttrib(node, 'style') == '') {\r
                                        node.removeAttribute('style');\r
-                                       node.removeAttribute('_mce_style');\r
+                                       node.removeAttribute('data-mce-style');\r
                                }\r
 \r
                                // Remove attributes\r
@@ -13828,7 +15434,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
 \r
                                                // Remove mce prefixed attributes\r
                                                if (MCE_ATTR_RE.test(name))\r
-                                                       node.removeAttribute('_mce_' + name);\r
+                                                       node.removeAttribute('data-mce-' + name);\r
 \r
                                                node.removeAttribute(name);\r
                                        }\r
@@ -13913,7 +15519,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                };\r
 \r
                function isBookmarkNode(node) {\r
-                       return node && node.nodeType == 1 && node.getAttribute('_mce_type') == 'bookmark';\r
+                       return node && node.nodeType == 1 && node.getAttribute('data-mce-type') == 'bookmark';\r
                };\r
 \r
                function mergeSiblings(prev, next) {\r
@@ -13984,7 +15590,7 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                        if (prev && next) {\r
                                function findElementSibling(node, sibling_name) {\r
                                        for (sibling = node; sibling; sibling = sibling[sibling_name]) {\r
-                                               if (sibling.nodeType == 3 && !isWhiteSpaceNode(sibling))\r
+                                               if (sibling.nodeType == 3 && sibling.nodeValue.length !== 0)\r
                                                        return node;\r
 \r
                                                if (sibling.nodeType == 1 && !isBookmarkNode(sibling))\r
@@ -14061,6 +15667,10 @@ tinymce.create('tinymce.ui.Toolbar:tinymce.ui.Container', {
                                // Apply pending formats\r
                                each(pendingFormats.apply.reverse(), function(item) {\r
                                        apply(item.name, item.vars, caret_node);\r
+\r
+                                       // Colored nodes should be underlined so that the color of the underline matches the text color.\r
+                                       if (item.name === 'forecolor' && item.vars.value)\r
+                                               processUnderlineAndColor(caret_node.parentNode);\r
                                });\r
 \r
                                // Remove pending formats\r
@@ -14150,9 +15760,12 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
                fontSizes = tinymce.explode(settings.font_size_style_values);\r
 \r
                function replaceWithSpan(node, styles) {\r
-                       dom.replace(dom.create('span', {\r
-                               style : styles\r
-                       }), node, 1);\r
+                       tinymce.each(styles, function(value, name) {\r
+                               if (value)\r
+                                       dom.setStyle(node, name, value);\r
+                       });\r
+\r
+                       dom.rename(node, 'span');\r
                };\r
 \r
                filters = {\r
@@ -14189,6 +15802,7 @@ tinymce.onAddEditor.add(function(tinymce, ed) {
                };\r
 \r
                ed.onPreProcess.add(convert);\r
+               ed.onSetContent.add(convert);\r
 \r
                ed.onInit.add(function() {\r
                        ed.selection.onSetContent.add(convert);\r
index 2617a26edb2b0a60f2fc986c586214a6e3fa56bb..59da01399e1e7c2fe9025f20db26b300ecf06015 100644 (file)
 var themeBaseURL = tinyMCEPopup.editor.baseURI.toAbsolute('themes/' + tinyMCEPopup.getParam("theme"));\r
 \r
 function getColorPickerHTML(id, target_form_element) {\r
-       var h = "";\r
+       var h = "", dom = tinyMCEPopup.dom;\r
 \r
-       h += '<a id="' + id + '_link" href="javascript:;" onclick="tinyMCEPopup.pickColor(event,\'' + target_form_element +'\');" onmousedown="return false;" class="pickcolor">';\r
-       h += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '">&nbsp;</span></a>';\r
+       if (label = dom.select('label[for=' + target_form_element + ']')[0]) {\r
+               label.id = label.id || dom.uniqueId();\r
+       }\r
+\r
+       h += '<a role="button" aria-labelledby="' + id + '_label" id="' + id + '_link" href="javascript:;" onclick="tinyMCEPopup.pickColor(event,\'' + target_form_element +'\');" onmousedown="return false;" class="pickcolor">';\r
+       h += '<span id="' + id + '" title="' + tinyMCEPopup.getLang('browse') + '">&nbsp;<span id="' + id + '_label" class="mceVoiceLabel mceIconOnly" style="display:none;">' + tinyMCEPopup.getLang('browse') + '</span></span></a>';\r
 \r
        return h;\r
 }\r
@@ -67,6 +71,9 @@ function selectByValue(form_obj, field_name, value, add_custom, ignore_case) {
        if (!form_obj || !form_obj.elements[field_name])\r
                return;\r
 \r
+       if (!value)\r
+               value = "";\r
+\r
        var sel = form_obj.elements[field_name];\r
 \r
        var found = false;\r
@@ -171,7 +178,7 @@ function convertHexToRGB(col) {
 }\r
 \r
 function trimSize(size) {\r
-       return size.replace(/([0-9\.]+)px|(%|in|cm|mm|em|ex|pt|pc)/, '$1$2');\r
+       return size.replace(/([0-9\.]+)(px|%|in|cm|mm|em|ex|pt|pc)/i, '$1$2');\r
 }\r
 \r
 function getCSSSize(size) {\r
@@ -183,6 +190,9 @@ function getCSSSize(size) {
        // Add px\r
        if (/^[0-9]+$/.test(size))\r
                size += 'px';\r
+       // Sanity check, IE doesn't like broken values\r
+       else if (!(/^[0-9\.]+(px|%|in|cm|mm|em|ex|pt|pc)$/i.test(size)))\r
+               return "";\r
 \r
        return size;\r
 }\r
index 825d4c143357516f0be55e2b8e9c8be10c429ceb..458ec86da60a46b3831ac23f9fe981b06bff2089 100644 (file)
@@ -10,6 +10,7 @@
 \r
 function MCTabs() {\r
        this.settings = [];\r
+       this.onChange = tinyMCEPopup.editor.windowManager.createInstance('tinymce.util.Dispatcher');\r
 };\r
 \r
 MCTabs.prototype.init = function(settings) {\r
@@ -28,26 +29,62 @@ MCTabs.prototype.getParam = function(name, default_value) {
        return value;\r
 };\r
 \r
-MCTabs.prototype.displayTab = function(tab_id, panel_id) {\r
-       var panelElm, panelContainerElm, tabElm, tabContainerElm, selectionClass, nodes, i;\r
+MCTabs.prototype.showTab =function(tab){\r
+       tab.className = 'current';\r
+       tab.setAttribute("aria-selected", true);\r
+       tab.setAttribute("aria-expanded", true);\r
+       tab.tabIndex = 0;\r
+};\r
+\r
+MCTabs.prototype.hideTab =function(tab){\r
+       var t=this;\r
+\r
+       tab.className = '';\r
+       tab.setAttribute("aria-selected", false);\r
+       tab.setAttribute("aria-expanded", false);\r
+       tab.tabIndex = -1;\r
+};\r
+\r
+MCTabs.prototype.showPanel = function(panel) {\r
+       panel.className = 'current'; \r
+       panel.setAttribute("aria-hidden", false);\r
+};\r
+\r
+MCTabs.prototype.hidePanel = function(panel) {\r
+       panel.className = 'panel';\r
+       panel.setAttribute("aria-hidden", true);\r
+}; \r
+\r
+MCTabs.prototype.getPanelForTab = function(tabElm) {\r
+       return tinyMCEPopup.dom.getAttrib(tabElm, "aria-controls");\r
+};\r
+\r
+MCTabs.prototype.displayTab = function(tab_id, panel_id, avoid_focus) {\r
+       var panelElm, panelContainerElm, tabElm, tabContainerElm, selectionClass, nodes, i, t = this;\r
+\r
+       tabElm = document.getElementById(tab_id);\r
+\r
+       if (panel_id === undefined) {\r
+               panel_id = t.getPanelForTab(tabElm);\r
+       }\r
 \r
        panelElm= document.getElementById(panel_id);\r
        panelContainerElm = panelElm ? panelElm.parentNode : null;\r
-       tabElm = document.getElementById(tab_id);\r
        tabContainerElm = tabElm ? tabElm.parentNode : null;\r
-       selectionClass = this.getParam('selection_class', 'current');\r
+       selectionClass = t.getParam('selection_class', 'current');\r
 \r
        if (tabElm && tabContainerElm) {\r
                nodes = tabContainerElm.childNodes;\r
 \r
                // Hide all other tabs\r
                for (i = 0; i < nodes.length; i++) {\r
-                       if (nodes[i].nodeName == "LI")\r
-                               nodes[i].className = '';\r
+                       if (nodes[i].nodeName == "LI") {\r
+                               t.hideTab(nodes[i]);\r
+                       }\r
                }\r
 \r
                // Show selected tab\r
-               tabElm.className = 'current';\r
+               t.showTab(tabElm);\r
        }\r
 \r
        if (panelElm && panelContainerElm) {\r
@@ -56,11 +93,15 @@ MCTabs.prototype.displayTab = function(tab_id, panel_id) {
                // Hide all other panels\r
                for (i = 0; i < nodes.length; i++) {\r
                        if (nodes[i].nodeName == "DIV")\r
-                               nodes[i].className = 'panel';\r
+                               t.hidePanel(nodes[i]);\r
+               }\r
+\r
+               if (!avoid_focus) { \r
+                       tabElm.focus();\r
                }\r
 \r
                // Show selected panel\r
-               panelElm.className = 'current';\r
+               t.showPanel(panelElm);\r
        }\r
 };\r
 \r
@@ -73,5 +114,49 @@ MCTabs.prototype.getAnchor = function() {
        return "";\r
 };\r
 \r
-// Global instance\r
+\r
+//Global instance\r
 var mcTabs = new MCTabs();\r
+\r
+tinyMCEPopup.onInit.add(function() {\r
+       var tinymce = tinyMCEPopup.getWin().tinymce, dom = tinyMCEPopup.dom, each = tinymce.each;\r
+\r
+       each(dom.select('div.tabs'), function(tabContainerElm) {\r
+               var keyNav;\r
+\r
+               dom.setAttrib(tabContainerElm, "role", "tablist"); \r
+\r
+               var items = tinyMCEPopup.dom.select('li', tabContainerElm);\r
+               var action = function(id) {\r
+                       mcTabs.displayTab(id, mcTabs.getPanelForTab(id));\r
+                       mcTabs.onChange.dispatch(id);\r
+               };\r
+\r
+               each(items, function(item) {\r
+                       dom.setAttrib(item, 'role', 'tab');\r
+                       dom.bind(item, 'click', function(evt) {\r
+                               action(item.id);\r
+                       });\r
+               });\r
+\r
+               dom.bind(dom.getRoot(), 'keydown', function(evt) {\r
+                       if (evt.keyCode === 9 && evt.ctrlKey && !evt.altKey) { // Tab\r
+                               keyNav.moveFocus(evt.shiftKey ? -1 : 1);\r
+                               tinymce.dom.Event.cancel(evt);\r
+                       }\r
+               });\r
+\r
+               each(dom.select('a', tabContainerElm), function(a) {\r
+                       dom.setAttrib(a, 'tabindex', '-1');\r
+               });\r
+\r
+               keyNav = tinyMCEPopup.editor.windowManager.createInstance('tinymce.ui.KeyboardNavigation', {\r
+                       root: tabContainerElm,\r
+                       items: items,\r
+                       onAction: action,\r
+                       actOnFocus: true,\r
+                       enableLeftRight: true,\r
+                       enableUpDown: true\r
+               }, tinyMCEPopup.dom);\r
+       });\r
+});
\ No newline at end of file
index a6fcf970153598b4acb9db56ff55f49e7fdca72f..27cbfab811e317865dfbda1c690b09c88d3b7b9b 100644 (file)
@@ -32,7 +32,7 @@ var Validator = {
        },\r
 \r
        isSize : function(s) {\r
-               return this.test(s, '^[0-9]+(%|in|cm|mm|em|ex|pt|pc|px)?$');\r
+               return this.test(s, '^[0-9.]+(%|in|cm|mm|em|ex|pt|pc|px)?$');\r
        },\r
 \r
        isId : function(s) {\r
@@ -96,8 +96,10 @@ var AutoValidator = {
                var i, nl, s = this.settings, c = 0;\r
 \r
                nl = this.tags(f, 'label');\r
-               for (i=0; i<nl.length; i++)\r
+               for (i=0; i<nl.length; i++) {\r
                        this.removeClass(nl[i], s.invalid_cls);\r
+                       nl[i].setAttribute('aria-invalid', false);\r
+               }\r
 \r
                c += this.validateElms(f, 'input');\r
                c += this.validateElms(f, 'select');\r
@@ -109,6 +111,33 @@ var AutoValidator = {
        invalidate : function(n) {\r
                this.mark(n.form, n);\r
        },\r
+       \r
+       getErrorMessages : function(f) {\r
+               var nl, i, s = this.settings, field, msg, values, messages = [], ed = tinyMCEPopup.editor;\r
+               nl = this.tags(f, "label");\r
+               for (i=0; i<nl.length; i++) {\r
+                       if (this.hasClass(nl[i], s.invalid_cls)) {\r
+                               field = document.getElementById(nl[i].getAttribute("for"));\r
+                               values = { field: nl[i].textContent };\r
+                               if (this.hasClass(field, s.min_cls, true)) {\r
+                                       message = ed.getLang('invalid_data_min');\r
+                                       values.min = this.getNum(field, s.min_cls);\r
+                               } else if (this.hasClass(field, s.number_cls)) {\r
+                                       message = ed.getLang('invalid_data_number');\r
+                               } else if (this.hasClass(field, s.size_cls)) {\r
+                                       message = ed.getLang('invalid_data_size');\r
+                               } else {\r
+                                       message = ed.getLang('invalid_data');\r
+                               }\r
+                               \r
+                               message = message.replace(/{\#([^}]+)\}/g, function(a, b) {\r
+                                       return values[b] || '{#' + b + '}';\r
+                               });\r
+                               messages.push(message);\r
+                       }\r
+               }\r
+               return messages;\r
+       },\r
 \r
        reset : function(e) {\r
                var t = ['label', 'input', 'select', 'textarea'];\r
@@ -119,8 +148,10 @@ var AutoValidator = {
 \r
                for (i=0; i<t.length; i++) {\r
                        nl = this.tags(e.form ? e.form : e, t[i]);\r
-                       for (j=0; j<nl.length; j++)\r
+                       for (j=0; j<nl.length; j++) {\r
                                this.removeClass(nl[j], s.invalid_cls);\r
+                               nl[j].setAttribute('aria-invalid', false);\r
+                       }\r
                }\r
        },\r
 \r
@@ -201,6 +232,7 @@ var AutoValidator = {
                var s = this.settings;\r
 \r
                this.addClass(n, s.invalid_cls);\r
+               n.setAttribute('aria-invalid', 'true');\r
                this.markLabels(f, n, s.invalid_cls);\r
 \r
                return false;\r
index 3b98e8df7827f56381937611ac124a22804c1459..48df4592c552cb6b7781d8048ce98be418a15489 100644 (file)
@@ -572,9 +572,16 @@ class html2text
      */
     function _convert_pre(&$text)
     {
+        // get the content of PRE element
         while (preg_match('/<pre[^>]*>(.*)<\/pre>/ismU', $text, $matches)) {
-            $result = preg_replace($this->pre_search, $this->pre_replace, $matches[1]);
-            $text = preg_replace('/<pre[^>]*>.*<\/pre>/ismU', '<div><br>' . $result . '<br></div>', $text, 1);
+            // convert the content
+            $this->pre_content = sprintf('<div><br>%s<br></div>',
+                preg_replace($this->pre_search, $this->pre_replace, $matches[1]));
+            // replace the content (use callback because content can contain $0 variable)
+            $text = preg_replace_callback('/<pre[^>]*>.*<\/pre>/ismU', 
+                array('html2text', '_preg_pre_callback'), $text, 1);
+            // free memory
+            $this->pre_content = '';
         }
     }
 
@@ -639,9 +646,8 @@ class html2text
      *
      *  @param  array PREG matches
      *  @return string
-     *  @access private
      */
-    function _preg_callback($matches)
+    private function _preg_callback($matches)
     {
         switch($matches[1]) {
         case 'b':
@@ -652,18 +658,30 @@ class html2text
         case 'h':
             return $this->_strtoupper("\n\n". $matches[2] ."\n\n");
         case 'a':
-            return $this->_build_link_list($matches[3], $matches[4]);
+            // Remove spaces in URL (#1487805)
+            $url = str_replace(' ', '', $matches[3]);
+            return $this->_build_link_list($url, $matches[4]);
         }
     }
-    
+
+    /**
+     *  Callback function for preg_replace_callback use in PRE content handler.
+     *
+     *  @param  array PREG matches
+     *  @return string
+     */
+    private function _preg_pre_callback($matches)
+    {
+        return $this->pre_content;
+    }
+
     /**
      *  Strtoupper multibyte wrapper function
      *
      *  @param  string
      *  @return string
-     *  @access private
      */
-    function _strtoupper($str)
+    private function _strtoupper($str)
     {
         if (function_exists('mb_strtoupper'))
             return mb_strtoupper($str);
index 0f8dc7ee614863ec35cf0fd5f638d8b19510c973..e8befe835e92934d4247875cf8760d237af5cec0 100644 (file)
@@ -273,7 +273,8 @@ class washtml
       $this->config['base_url'] = '';
 
     // Remove invalid HTML comments (#1487759)
-    $html = preg_replace('/<!--[^->]*>/', '', $html);
+    // Don't remove valid conditional comments
+    $html = preg_replace('/<!--[^->[]*>/', '', $html);
 
     @$node->loadHTML($html);
     return $this->dumpHtml($node);
index bb08d33fc891506585fdbb2bb31f5788b087e3c5..691811a4b8d4e5139eabd4d9e3510e8f96a72073 100644 (file)
@@ -13,7 +13,7 @@
 | Author:      Thomas Bruederli <roundcube@gmail.com>                   |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 4346 2010-12-17 14:36:47Z thomasb $
+@version $Id: labels.inc 4578 2011-02-27 13:58:12Z thomasb $
 
 */
 
@@ -174,7 +174,7 @@ $labels['sendmessage'] = 'Nachricht jetzt senden';
 $labels['addattachment'] = 'Datei anfügen';
 $labels['charset'] = 'Zeichensatz';
 $labels['editortype'] = 'Editor-Typ';
-$labels['returnreceipt'] = 'Empfangsbestätigung (MSN)';
+$labels['returnreceipt'] = 'Empfangsbestätigung (MDN)';
 $labels['dsn'] = 'Übermittlungsbestätigung (DSN)';
 $labels['editidents'] = 'Absender bearbeiten';
 $labels['checkspelling'] = 'Rechtschreibung prüfen';
index 5839c410c29afef9d025cfbafdfd443f2d9c3418..9ae0936ca9eab1c03ccfc672ded214dbbda0816c 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Thomas Bruederli <roundcube@gmail.com>                        |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 4345 2010-12-17 14:28:38Z thomasb $
+@version $Id: messages.inc 4666 2011-04-17 09:34:02Z alec $
 
 */
 
@@ -115,7 +115,7 @@ $messages['smtpautherror'] = 'SMTP Fehler ($code): Die Authentisierung ist fehlg
 $messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender "$from" konnte nicht gesetzt werden ($msg)';
 $messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger "$to" konnte nicht gesetzt werden ($msg)';
 $messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden';
-$messages['smtpdsnerror'] = 'SMTP-Fehler: Empfangsbestätigung werden nicht unterstützt';
+$messages['smtpdsnerror'] = 'SMTP-Fehler: Übermittlungsbestätigungen werden nicht unterstützt';
 $messages['smtperror'] = 'SMTP Fehler: $msg';
 $messages['emailformaterror'] = 'Ungültige E-Mail-Adresse: $email';
 $messages['toomanyrecipients'] = 'Zuviele Empfänger angegeben. Reduzieren Sie die Empfängeradressen auf $max.';
@@ -135,7 +135,7 @@ $messages['namecannotbeempty'] = 'Der Name darf nicht leer sein';
 $messages['nametoolong'] = 'Der Name ist zu lang';
 $messages['folderupdated'] = 'Der Ordner wurde erfolgreich aktualisiert';
 $messages['foldercreated'] = 'Der Ordner wurde erfolgreich erstellt';
-$messages['errorreadonly'] = 'Die Aktion nicht ausgeführt werden. Der Ordner ist schreibgeschützt.';
-$messages['errornoperm'] = 'Die Aktion nicht ausgeführt werden. Zugriff verweigert.';
+$messages['errorreadonly'] = 'Die Aktion kann nicht ausgeführt werden. Der Ordner ist schreibgeschützt.';
+$messages['errornoperm'] = 'Die Aktion kann nicht ausgeführt werden. Zugriff verweigert.';
 
 ?>
index 5dd56e0913958e5388c6eb8b57f4494cac45a1cd..05ec7f2585683a5018ab35b0f0cb2528ad6cdab4 100644 (file)
@@ -13,7 +13,7 @@
 | Author: Marcel Schlesinger <info@marcel-schlesinger.de>               |
 +-----------------------------------------------------------------------+
 
-@version $Id: messages.inc 4469 2011-01-29 14:55:12Z thomasb $
+@version $Id: messages.inc 4666 2011-04-17 09:34:02Z alec $
 
 */
 
@@ -24,8 +24,8 @@ $messages['sessionerror'] = 'Ihre Session ist ungültig oder abgelaufen';
 $messages['imaperror'] = 'Keine Verbindung zum IMAP-Server';
 $messages['servererror'] = 'Serverfehler!';
 $messages['servererrormsg'] = 'Serverfehler: $msg';
-$messages['errorreadonly'] = 'Die Aktion nicht ausgeführt werden. Der Ordner ist schreibgeschützt.';
-$messages['errornoperm'] = 'Die Aktion nicht ausgeführt werden. Zugriff verweigert.';
+$messages['errorreadonly'] = 'Die Aktion kann nicht ausgeführt werden. Der Ordner ist schreibgeschützt.';
+$messages['errornoperm'] = 'Die Aktion kann nicht ausgeführt werden. Zugriff verweigert.';
 $messages['invalidrequest'] = 'Ungültige Anfrage! Es wurden keine Daten gespeichert.';
 $messages['nomessagesfound'] = 'Keine Nachrichten in diesem Ordner';
 $messages['loggedout'] = 'Sie haben Ihre Session erfolgreich beendet. Auf Wiedersehen!';
@@ -117,7 +117,7 @@ $messages['smtpautherror'] = 'SMTP Fehler ($code): Die Authentisierung ist fehlg
 $messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender "$from" konnte nicht gesetzt werden ($msg)';
 $messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger "$to" konnte nicht gesetzt werden ($msg)';
 $messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden';
-$messages['smtpdsnerror'] = 'SMTP-Fehler: Empfangsbestätigung werden nicht unterstützt';
+$messages['smtpdsnerror'] = 'SMTP-Fehler: Empfangsbestätigungen werden nicht unterstützt';
 $messages['smtperror'] = 'SMTP Fehler: $msg';
 $messages['emailformaterror'] = 'Ungültige E-Mail-Adresse: $email';
 $messages['toomanyrecipients'] = 'Zuviele Empfänger. Reduzieren Sie die Anzahl Empfängeradressen auf $max.';
index b453fced772aa85096e8823bd3d82391693b6f70..8cb8fa5ce44273d346f0b08d24909b25346f58ed 100644 (file)
@@ -15,7 +15,7 @@
 |         Maximilien Cuony <theglu@theglu.org>                          |
 +-----------------------------------------------------------------------+
 
-@version $Id: labels.inc 4469 2011-01-29 14:55:12Z thomasb $
+@version $Id: labels.inc 4593 2011-03-05 08:10:52Z alec $
 
 */
 
@@ -103,7 +103,7 @@ $labels['replytoallmessage'] = 'Répondre à tous';
 $labels['replyall'] = 'Répondre à tous';
 $labels['replylist'] = 'Répondre à la liste';
 $labels['forwardmessage'] = 'Transmettre le message';
-$labels['deletemessage'] = 'Déplacer le message dans la corbeille';
+$labels['deletemessage'] = 'Supprimer le message';
 $labels['movemessagetotrash'] = 'Déplacer le message dans la corbeille';
 $labels['printmessage'] = 'Imprimer ce message';
 $labels['previousmessage'] = 'Voir le message précédent';
index f8e30de0175136156673dfccda902b20d4504cc6..3182ab8c1f2f8ab2d030b066ff00874296d7ad99 100644 (file)
@@ -16,7 +16,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: index.inc 3989 2010-09-25 13:03:53Z alec $
+ $Id: index.inc 4666 2011-04-17 09:34:02Z alec $
 
 */
 
@@ -32,7 +32,7 @@ $rcube_languages = array(
   'az_AZ' => 'Azerbaijani (Azərbaycanca)',
   'eu_ES' => 'Basque (Euskara)',
   'bn_BD' => 'Bengali (বাংলা)',
-  'bs_BA' => 'Bosnian (Bošnjački)',
+  'bs_BA' => 'Bosnian (Bosanski)',
   'br'   => 'Breton (Brezhoneg)',
   'bg_BG' => 'Bulgarian (Български)',
   'ca_ES' => 'Catalan (Català)',
@@ -42,8 +42,8 @@ $rcube_languages = array(
   'cs_CZ' => 'Czech (Česky)',
   'da_DK' => 'Danish (Dansk)',
   'fa_AF' => 'Dari (ﻯﺭﺩ)',
-  'de_DE' => 'Deutsch (Deutsch)',
-  'de_CH' => 'Deutsch (Schweiz)',
+  'de_DE' => 'German (Deutsch)',
+  'de_CH' => 'German (Schweiz)',
   'nl_NL' => 'Dutch (Nederlands)',
   'en_GB' => 'English (GB)',
   'en_US' => 'English (US)',
index b3c4e63b51ca7c2ee95cc7409726b853dbb8bcda..ea82b9f50408a71fef2556948a195deeb6465274 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: func.inc 4509 2011-02-09 10:51:50Z thomasb $
+ $Id: func.inc 4643 2011-04-11 12:24:00Z alec $
 
 */
 
@@ -726,71 +726,74 @@ function rcmail_plain_body($body, $flowed=false)
   $body = preg_replace_callback($replacer->mailto_pattern, array($replacer, 'mailto_callback'), $body);
 
   // split body into single lines
-  $a_lines = preg_split('/\r?\n/', $body);
+  $body = preg_split('/\r?\n/', $body);
   $quote_level = 0;
   $last = -1;
 
   // find/mark quoted lines...
-  for ($n=0, $cnt=count($a_lines); $n < $cnt; $n++) {
-    if ($a_lines[$n][0] == '>' && preg_match('/^(>+\s*)+/', $a_lines[$n], $regs)) {
+  for ($n=0, $cnt=count($body); $n < $cnt; $n++) {
+    if ($body[$n][0] == '>' && preg_match('/^(>+\s*)+/', $body[$n], $regs)) {
       $q = strlen(preg_replace('/\s/', '', $regs[0]));
-      $a_lines[$n] = substr($a_lines[$n], strlen($regs[0]));
-
-      if ($q > $quote_level)
-        $a_lines[$n] = $replacer->get_replacement($replacer->add(
-          str_repeat('<blockquote>', $q - $quote_level))) . $a_lines[$n];
-      else if ($q < $quote_level)
-        $a_lines[$n] = $replacer->get_replacement($replacer->add(
-          str_repeat('</blockquote>', $quote_level - $q))) . $a_lines[$n];
+      $body[$n] = substr($body[$n], strlen($regs[0]));
+
+      if ($q > $quote_level) {
+        $body[$n] = $replacer->get_replacement($replacer->add(
+          str_repeat('<blockquote>', $q - $quote_level))) . $body[$n];
+      }
+      else if ($q < $quote_level) {
+        $body[$n] = $replacer->get_replacement($replacer->add(
+          str_repeat('</blockquote>', $quote_level - $q))) . $body[$n];
+      }
       else if ($flowed) {
         // previous line is flowed
-        if (isset($a_lines[$last]) && $a_lines[$n]
-          && $a_lines[$last][strlen($a_lines[$last])-1] == ' ') {
+        if (isset($body[$last]) && $body[$n]
+          && $body[$last][strlen($body[$last])-1] == ' ') {
           // merge lines
-          $a_lines[$last] .= $a_lines[$n];
-          unset($a_lines[$n]);
+          $body[$last] .= $body[$n];
+          unset($body[$n]);
         }
-        else
+        else {
           $last = $n;
+        }
       }
     }
     else {
       $q = 0;
       if ($flowed) {
         // sig separator - line is fixed
-        if ($a_lines[$n] == '-- ') {
-          $last = $n;
+        if ($body[$n] == '-- ') {
+          $last = $last_sig = $n;
         }
         else {
           // remove space-stuffing
-          if ($a_lines[$n][0] == ' ')
-            $a_lines[$n] = substr($a_lines[$n], 1);
+          if ($body[$n][0] == ' ')
+            $body[$n] = substr($body[$n], 1);
 
           // previous line is flowed?
-          if (isset($a_lines[$last]) && $a_lines[$n]
-            && $a_lines[$last] != '-- '
-            && $a_lines[$last][strlen($a_lines[$last])-1] == ' '
+          if (isset($body[$last]) && $body[$n]
+            && $last != $last_sig
+            && $body[$last][strlen($body[$last])-1] == ' '
           ) {
-            $a_lines[$last] .= $a_lines[$n];
-            unset($a_lines[$n]);
+            $body[$last] .= $body[$n];
+            unset($body[$n]);
           }
           else {
             $last = $n;
           }
         }
         if ($quote_level > 0)
-          $a_lines[$last] = $replacer->get_replacement($replacer->add(
-            str_repeat('</blockquote>', $quote_level))) . $a_lines[$last];
+          $body[$last] = $replacer->get_replacement($replacer->add(
+            str_repeat('</blockquote>', $quote_level))) . $body[$last];
       }
       else if ($quote_level > 0)
-        $a_lines[$n] = $replacer->get_replacement($replacer->add(
-          str_repeat('</blockquote>', $quote_level))) . $a_lines[$n];
+        $body[$n] = $replacer->get_replacement($replacer->add(
+          str_repeat('</blockquote>', $quote_level))) . $body[$n];
     }
 
     $quote_level = $q;
   }
 
-  $body = join("\n", $a_lines);
+  $body = join("\n", $body);
 
   // quote plain text (don't use Q() here, to display entities "as is")
   $table = get_html_translation_table(HTML_SPECIALCHARS);
@@ -1200,6 +1203,9 @@ function rcmail_alter_html_link($matches)
   $attrib = parse_attrib_string($matches[2]);
   $end = '>';
 
+  // Remove non-printable characters in URL (#1487805)
+  $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']);
+
   if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) {
     $tempurl = 'tmp-' . md5($attrib['href']) . '.css';
     $_SESSION['modcssurls'][$tempurl] = $attrib['href'];
index 1bc98a65b068611eb1b53d7c6e83bd7f4b19329d..7d72bfa93d9b057adaea9e86c7a12d5f926b899f 100644 (file)
@@ -15,7 +15,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: save_prefs.inc 4469 2011-01-29 14:55:12Z thomasb $
+ $Id: save_prefs.inc 4643 2011-04-11 12:24:00Z alec $
 
 */
 
@@ -97,10 +97,10 @@ switch ($CURR_SECTION)
   break;
 }
 
-$data = rcmail::get_instance()->plugins->exec_hook('preferences_save',
+$plugin = rcmail::get_instance()->plugins->exec_hook('preferences_save',
   array('prefs' => $a_user_prefs, 'section' => $CURR_SECTION));
 
-$a_user_prefs = $data['prefs'];
+$a_user_prefs = $plugin['prefs'];
 
 // don't override these parameters
 foreach ((array)$CONFIG['dont_override'] as $p)
@@ -159,10 +159,17 @@ switch ($CURR_SECTION)
   break;
 }
 
-if ($USER->save_prefs($a_user_prefs))
+// Save preferences
+if (!$plugin['abort'])
+  $saved = $USER->save_prefs($a_user_prefs);
+else
+  $saved = $plugin['result'];
+
+if ($saved)
   $OUTPUT->show_message('successfullysaved', 'confirmation');
+else
+  $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error');
 
 // display the form again
 rcmail_overwrite_action('edit-prefs');
 
-
index bfe8f6d48f72397e40afe7b6c669b19dca65e3e7..41fc0261444ccc017a4d52a61b4bb0ee3095e3be 100644 (file)
@@ -18,7 +18,7 @@
  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
  +-----------------------------------------------------------------------+
 
- $Id: spell_googie.inc 3989 2010-09-25 13:03:53Z alec $
+ $Id: spell_googie.inc 4626 2011-03-31 12:32:44Z alec $
 
 */
 
@@ -41,6 +41,8 @@ if (!empty($CONFIG['spellcheck_uri']))
   }
 
 $data = file_get_contents('php://input');
+// Google has some problem with spaces, use \n instead
+$data = str_replace(' ', "\n", $data);
 $store = "";
 
 if ($fp = fsockopen($host, $port, $errno, $errstr, 30))
index 1a4fbd48d2d260e26b19cccd08627c875556e04c..df18c036b8ebd2b56587632302e34c33d3aa6e5d 100644 (file)
@@ -80,7 +80,7 @@ if (!empty($CONFIG['spellcheck_uri']))
   $path = $a_uri['path'] . ($a_uri['query'] ? '?'.$a_uri['query'] : '') . $lang;
   }
 
-$wordstr = implode(' ', (array) $data);
+$wordstr = implode("\n", (array) $data);
 $data = '<?xml version="1.0" encoding="utf-8" ?>'
     .'<spellrequest textalreadyclipped="0" ignoredups="0" ignoredigits="1" ignoreallcaps="1">'
     .'<text>' . $wordstr . '</text>'
index e9b51a7961b109771b86ee7db990d452bf4dca64..a5c65464d1c1855feef679dfeb2c2b2cdf3ff0fc 100644 (file)
@@ -170,6 +170,11 @@ div.message-part div.pre
   height: expression((parseInt(document.documentElement.clientHeight)-105)+'px');
 }
 
+#directorylistbox
+{
+  height: expression((parseInt(document.documentElement.clientHeight)-105)+'px');
+}
+
 #contacts-table
 {
   width: expression(document.getElementById('addresslist').clientWidth);
@@ -236,8 +241,3 @@ table.records-table thead tr td
 {
   margin-top: 2px;
 }
-
-#directorylistbox div
-{
-  min-height: 0;
-}
index cb7ae051f654fe3b5e4e56123b567e9e375f8170..c761fbc9d96de756b60d723b74940ba436f7c586 100644 (file)
Binary files a/skins/default/images/abook_toolbar.png and b/skins/default/images/abook_toolbar.png differ
index e2191c910c9d776ec65e1c97372183be4899ab2d..be39f4a35248db6dae52d1f6097842b4947dbaff 100644 (file)
Binary files a/skins/default/images/buttons/bg.gif and b/skins/default/images/buttons/bg.gif differ
index 58a124594e0fcb96ccc5336efafe3e14e5734f96..7a85e3c5decb8b988ebf5e6ab56951ef2fb6ec35 100644 (file)
Binary files a/skins/default/images/dbutton.png and b/skins/default/images/dbutton.png differ
index d96a5aded6f1e5b29972efe4378d8e6b86fd9335..4de496c87d64feed880d96261dfe886f235120eb 100644 (file)
Binary files a/skins/default/images/dimple.png and b/skins/default/images/dimple.png differ
index 2ab7d43af1842cdffe723c0f1fca5759ca61277f..7bf4278bf8136195ad10e9cb14223b7be6a7eba6 100644 (file)
Binary files a/skins/default/images/display/icons.png and b/skins/default/images/display/icons.png differ
index 1db079b79a953c59f3d664b287723b41998d7670..87e77a477470695558f2b011fa6aac205f64a45f 100644 (file)
Binary files a/skins/default/images/icons/expanded.png and b/skins/default/images/icons/expanded.png differ
index 41dbb3a37e1eee193d184d98f59f3cb7fdb15c3f..eb1b1dc7419155029e73240ac187936860e92a60 100644 (file)
Binary files a/skins/default/images/icons/glass.png and b/skins/default/images/icons/glass.png differ
index a6d975a5ae47955bc7457c5af00d6a8e3208e252..b11b59854b6294202cbf013aeab8fcee2c305f5b 100644 (file)
Binary files a/skins/default/images/icons/glass_roll.png and b/skins/default/images/icons/glass_roll.png differ
index 2e9c5f101f6985097789ca897d1be37fcee9062a..9e39bca2ef97260ce4f47d6a44adf690cd0e43e3 100644 (file)
Binary files a/skins/default/images/icons/groupactions.png and b/skins/default/images/icons/groupactions.png differ
index 2f5c7f862d4bef06655439a2a8e54b62e60ef459..ff28d95efc87fac7fb51f9f55fa156c1a5ce1dd8 100644 (file)
Binary files a/skins/default/images/listheader.gif and b/skins/default/images/listheader.gif differ
index e0f82b578a13006606cf46b5a991060d91af3546..e2f24b28c493ad3b7297bce6e1dfc47a707c896a 100644 (file)
Binary files a/skins/default/images/mail_footer.png and b/skins/default/images/mail_footer.png differ
index 3ee0ce6d886a97bdf9f1ebf6c38fb2104681863d..6ccc9bd9ef93f33aa527244375739b897d71d806 100644 (file)
Binary files a/skins/default/images/mail_toolbar.png and b/skins/default/images/mail_toolbar.png differ
index 5afb4cbf890b478ed241f038a976e0f1813ad46b..3dd37606ef47683abc6924942580314a981dee47 100644 (file)
Binary files a/skins/default/images/messageicons.png and b/skins/default/images/messageicons.png differ
index 92a73a440be4b0394ceee47541434bd93666b0a9..a4644a4e400098cff4179c7e1b06fee9e1d6ff7e 100644 (file)
Binary files a/skins/default/images/pagenav.gif and b/skins/default/images/pagenav.gif differ
index 756a17e47b89e3021ba12b76414d0ead368ff3f7..969f277b3ebcf790a0666a84c78ccd4f892b70af 100644 (file)
Binary files a/skins/default/images/searchfield.gif and b/skins/default/images/searchfield.gif differ
index 3465d1fd13f24f7fe7613dd2b9d74126c63ddff6..c1bf45aa8fe13740de987be6909bb751b109cd51 100644 (file)
Binary files a/skins/default/images/tabs-left.gif and b/skins/default/images/tabs-left.gif differ
index 252463c9a2940a150af8baf3e3606ad9997797a5..9eba9a342f1883a375912b4f677fad862f869a18 100644 (file)
Binary files a/skins/default/images/tabs-right.gif and b/skins/default/images/tabs-right.gif differ
index 53376c3d2209422a023923bd55873627f58ad2dc..feaa9a14e0593d3300e29f7c46eb4ed07e3a5ccd 100644 (file)
Binary files a/skins/default/images/taskicons.gif and b/skins/default/images/taskicons.gif differ
index a6ee706c8c9cd4da9caa363fe3527c2ed93070bb..feaa9a14e0593d3300e29f7c46eb4ed07e3a5ccd 100644 (file)
Binary files a/skins/default/images/taskicons.png and b/skins/default/images/taskicons.png differ
index 7581802ae39ab7d800a0eb4e3a6dba5c4fdbf2dd..d235d0306e39331534b5beddbc183bdacac20e60 100644 (file)
Binary files a/skins/default/images/watermark.gif and b/skins/default/images/watermark.gif differ
index d486f2fe74a5644ec5ac670c934b98179c0b6430..668b309a75f81e572510a9025147b6050bd5ee0c 100644 (file)
@@ -40,7 +40,6 @@
   <roundcube:object name="directorylist" id="directorylist" />
   <roundcube:object name="groupslist" id="contactgroupslist" />
 </div>
-<!--[if lte IE 7]><div></div><![endif]-->
 <div class="boxfooter">
   <roundcube:button command="group-create" type="link" title="newcontactgroup" class="buttonPas addgroup" classAct="button addgroup" content=" " />
   <roundcube:button name="groupmenulink" id="groupmenulink" type="link" title="groupactions" class="button groupactions" onclick="rcmail_ui.show_popup('groupmenu');return false" content=" " />
index 06d0fbee548a41f84519eac8fa168cd6ccce6b73..3c8e9fc9f083d36d326671b50a67b4d1b2846ea6 100644 (file)
@@ -9,7 +9,9 @@
 
 <div id="contact-title" class="boxtitle"><roundcube:label name="contactproperties" /></div>
 <div id="contact-details" class="boxcontent">
+  <div>
   <roundcube:object name="contactdetails" />
+  </div>
   <p>
     <roundcube:button command="edit" type="input" class="button" label="editcontact" condition="!ENV:readonly" />
   </p>
index 1a10f10acddc1a6b43a05af5eeefd188fcfeb32a..dd912c33a4e0d7777dcdcea0a3500033bae43776 100644 (file)
@@ -14,7 +14,6 @@
     <input type="button" value="<roundcube:label name="cancel" />" class="button" onclick="history.back()" />&nbsp;
     <roundcube:button command="save" type="input" class="button mainaction" label="save" />
   </p>
-</form>
 </div>
 <script type="text/javascript">rcube_init_tabs('contact-details')</script>
 
index a15aaf22a4ee4a6a03e00ec03f5a4cd0d439ee00..75e8c843337363555ec48bae3f54c7833e189393 100644 (file)
@@ -14,7 +14,6 @@
     <roundcube:button command="show" type="input" class="button" label="cancel" />&nbsp;
     <roundcube:button command="save" type="input" class="button mainaction" label="save" />
   </p>
-</form>
 </div>
 <script type="text/javascript">rcube_init_tabs('contact-details')</script>
 
index f2775cd61dcd56cd3883fb39126dcc64d9694862..ea7a320f91025844d3831168ead7594aa98213b3 100644 (file)
@@ -2,6 +2,7 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
 <head>
 <title><roundcube:object name="pagetitle" /></title>
+<link rel="shortcut icon" href="/images/favicon.ico"/>
 <link rel="stylesheet" type="text/css" href="/print.css" />
 </head>
 <body>